diff --git a/doc/Doxyfile b/doc/Doxyfile index 45b8630..d4d5a71 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -1029,6 +1029,11 @@ INPUT = include/dpf.hpp \ doc/pages/multipoint.md \ doc/pages/dealer_free.md \ doc/pages/beaver.md \ + doc/pages/yao.md \ + doc/pages/arith.md \ + doc/pages/compose.md \ + doc/pages/network_and_mpc.md \ + doc/pages/experiment.md \ doc/pages/api.md \ doc/pages/bibliography.md \ doc/pages/jet_and_ring.md \ @@ -1489,7 +1494,8 @@ HTML_EXTRA_FILES = doc/doc-extras.js \ doc/papers/storrier-vadapalli-lyons-henry-grotto-eprint-2023-108.pdf \ doc/papers/boyle-gilboa-ishai-kolobov-it-dpf-eprint-2023-028.pdf \ doc/papers/chou-orlandi-simplest-ot-eprint-2015-267.pdf \ - doc/papers/boyar-peralta-aes-sbox-eprint-2011-332.pdf + doc/papers/boyar-peralta-aes-sbox-eprint-2011-332.pdf \ + doc/papers/reis-ugurbil-wagh-henry-de-vega-wave-hello-eprint-2025-013.pdf # The HTML_COLORSTYLE tag can be used to specify if the generated HTML output # should be rendered with a dark or light theme. diff --git a/doc/DoxygenLayout.xml b/doc/DoxygenLayout.xml index 2b7de4f..9331f79 100644 --- a/doc/DoxygenLayout.xml +++ b/doc/DoxygenLayout.xml @@ -22,12 +22,19 @@ - + + + + + + + + diff --git a/doc/doc-extras.js b/doc/doc-extras.js index e677d45..b363f79 100644 --- a/doc/doc-extras.js +++ b/doc/doc-extras.js @@ -116,10 +116,14 @@ function mountPageNav() { var contents = document.querySelector("#doc-content .contents") || document.querySelector(".contents"); if (!contents || contents.querySelector(".page-nav")) return; + // Doxygen's theme makes `.contents` a row so the outline can sit beside + // the prose. A nav inserted as a sibling becomes another column and + // lands on top of the first paragraph. Keep it inside the text column. + var column = contents.querySelector(".textblock") || contents; var top = pageNav("top"); if (!top) return; - contents.insertBefore(top, contents.firstChild); - contents.appendChild(pageNav("bottom")); + column.insertBefore(top, column.firstChild); + column.appendChild(pageNav("bottom")); } if (document.readyState === "loading") { diff --git a/doc/examples.dox b/doc/examples.dox index 0037fa4..d47bfe1 100644 --- a/doc/examples.dox +++ b/doc/examples.dox @@ -105,6 +105,9 @@ /// @example grotto/repr_and_twist.cpp repr_and_twist.cpp /// @brief Fibonacci / geometric representation shift and twisted monomials +/// @example grotto/dwt_lut.cpp dwt_lut.cpp +/// @brief Haar and bior(5,3) compressed lookup tables + /// @} @@ -178,6 +181,9 @@ /// @example applications/sabre.cpp sabre.cpp /// @brief Sabre mailbox write with a verifiable-DPF audit +/// @example protocol/compose_schedule.cpp compose_schedule.cpp +/// @brief Composer schedules: fused audit, early-stop, prefixes, RSS, ABY scale + /// @example applications/ledger23.cpp ledger23.cpp /// @brief (2,3) ledger append with a verified point key @@ -205,4 +211,7 @@ /// @example mwe/ppvc.cpp ppvc.cpp /// @brief a point-programmable vector commitment +/// @example mwe/shamir.cpp shamir.cpp +/// @brief (K,N) Shamir, with (2,3) as the slope specialization + /// @} \ No newline at end of file diff --git a/doc/footer.html b/doc/footer.html index 18dbf1a..4bed83c 100644 --- a/doc/footer.html +++ b/doc/footer.html @@ -14,7 +14,7 @@ $generatedby  - + + diff --git a/doc/ideal_functionalities.dox b/doc/ideal_functionalities.dox index 26f557d..d1a0baa 100644 --- a/doc/ideal_functionalities.dox +++ b/doc/ideal_functionalities.dox @@ -5,13 +5,20 @@ /// outputs, and what is revealed. A protocol may open a masked value or a /// public offset; that appears in the figure only when the parties learn it. /// +/// \htmlonly +///
ELI5. An ideal functionality is the specification the protocol is measured against: who holds what, what goes in, what comes out, and which values become public.
+/// \endhtmlonly +/// +/// /// ## Sharing /// +/// /// - \ref secret_share.hpp "F_Open" /// - \ref shamir3.hpp "F_Shamir" /// /// ## Dealer keys /// +/// /// - \ref dpf_key.hpp "F_DPF" /// - \ref incremental.hpp "F_IDPF" /// - \ref grow.hpp "F_Grow" @@ -23,15 +30,20 @@ /// /// ## Two-party generation and evaluation /// +/// +/// - \ref iknp.hpp "F_IKNP" /// - \ref doerner_shelat.hpp "F_DS" /// - \ref grow_ds.hpp "F_GrowDS" /// - \ref geneval.hpp "F_GenEval" /// - \ref beaver.hpp "F_Beaver and F_BeaverAuth" +/// - \ref yao.hpp "F_Yao" +/// - \ref yao_share.hpp "F_YaoShare" /// - \ref constrained_cmp.hpp "F_CCMP" /// - \ref verifiable.hpp "F_VDPF, F_Sketch, and F_OblivHash" /// /// ## Three evaluators /// +/// /// - \ref dpf3.hpp "F_DPF3" /// - \ref dpf3_ds.hpp "F_DPF3DS" /// - \ref dpf3_cmp.hpp "F_DPF3CMP" @@ -39,6 +51,7 @@ /// /// ## Offset corrections /// +/// /// - \ref offset_horner.hpp "F_Horner" /// - \ref offset_poly.hpp "F_Poly" /// - \ref offset_jet.hpp "F_Jet" @@ -266,6 +279,25 @@ /// } /// \enddot +/// @file dpf/iknp.hpp +/// +/// @par Ideal functionality +/// \dot "Functionality F_IKNP" +/// digraph F_IKNP { +/// graph [bgcolor="transparent"]; +/// node [shape=plaintext, fontname="Helvetica", fontsize=11]; +/// F [label=< +/// +/// +/// +/// +/// +/// +///
F_IKNP
Parties. P0 and P1. Semi-honest. Base OT is Chou-Orlandi.
Input. sample: both parties pass the same lengths
(bit x block, bit x bit, B2A, correction-word pads).
transfer_labels: the sender holds two 128-bit strings per row;
the receiver holds a choice bit per row.
Output. sample gives each party its share of the pads:
bit x block, bit AND, a daBit, and a correction-word gamma
that hides the peer pad bit.
transfer_labels gives the receiver exactly the chosen string.
The sender's output buffer is cleared. An empty transfer sends nothing.
Leakage. Lengths are public. Choice bits, the unchosen string,
and the peer pad bit stay hidden.
One role_state is one direction; the first call runs the base OT.
+/// >]; +/// } +/// \enddot + /// @file dpf/doerner_shelat.hpp /// /// @par Ideal functionality @@ -617,3 +649,45 @@ /// >]; /// } /// \enddot + +/// @file dpf/yao.hpp +/// +/// @par Ideal functionality +/// \dot "Functionality F_Yao" +/// digraph F_Yao { +/// graph [bgcolor="transparent"]; +/// node [shape=plaintext, fontname="Helvetica", fontsize=11]; +/// F [label=< +/// +/// +/// +/// +/// +/// +///
F_Yao
Parties. P0 garbles. P1 evaluates. Semi-honest.
Input. A public straight-line bit netlist.
Each shared input is an XOR share of that bit.
A private input is known to one party.
The usual source of those bits is a DPF leaf, via F_YaoShare.
Output. XOR shares of each output bit.
P0's share is the permute bit of the zero label.
P1's share is the color of the label it holds.
Leakage. None beyond the output shares.
Tables are one-time. P1 does not learn Delta.
P0 does not learn P1's private bits or P1's shares.
+/// >]; +/// } +/// \enddot + +/// @file dpf/yao_share.hpp +/// +/// @par Ideal functionality +/// \dot "Functionality F_YaoShare" +/// digraph F_YaoShare { +/// graph [bgcolor="transparent"]; +/// node [shape=plaintext, fontname="Helvetica", fontsize=11]; +/// F [label=< +/// +/// +/// +/// +/// +/// +///
F_YaoShare
Parties. P0 and P1. For a replicated leaf, P2 is idle.
Input. One share each of an integer the DPF already produced:
subtractive (point leaf), additive (comparison leaf),
an fss_share, or the party-0 and party-1 replicated views.
The reverse calls take XOR shares of the low width bits.
Output. XOR shares of those bits, least-significant bit first,
or ring shares of the integer the bits encode, in the leaf's scheme.
y2rss deals a fresh replicated triple of that integer.
Leakage. A2B opens a masked x - r. B2A opens a masked bit.
Both masks are uniform. The integer stays shared.
This is not the local (3,3) cast dpf::rss2y / dpf::y2rss.
+/// >]; +/// } +/// \enddot + +/// \htmlonly +///
TL;DR. Each figure states the parties, the inputs, the outputs, and what is revealed. A masked value or a public offset appears only when the parties learn it.
+/// \endhtmlonly diff --git a/doc/libdpf.md b/doc/libdpf.md index cbd0047..d73a479 100644 --- a/doc/libdpf.md +++ b/doc/libdpf.md @@ -3,22 +3,14 @@ %LIBDPF_INCLUDE_GETTING_STARTED_INTRODUCTION% - - - - \page basics First program %LIBDPF_INCLUDE_GETTING_DPF_BASICS% - - - - \page getting_started Manual The domain, the payload, and the walk. @@ -31,112 +23,68 @@ Shorter domains make shorter keys. Samples for each of those are under [Code examples](@ref listings). - - - - \page input_types Domains %LIBDPF_INCLUDE_GETTING_STARTED_INPUT_TYPES% - - - - \page output_types Payloads %LIBDPF_INCLUDE_GETTING_STARTED_OUTPUT_TYPES% - - - - \page evaluation Evaluation %LIBDPF_INCLUDE_GETTING_STARTED_EVALUATION% - - - - \page iterables Iterables %LIBDPF_INCLUDE_GETTING_STARTED_ITERABLES% - - - - \page bugs Bugs %LIBDPF_INCLUDE_MISC_BUGS% - - - - \page changes Changelog %LIBDPF_INCLUDE_MISC_CHANGES% - - - - \page todo TODO %LIBDPF_INCLUDE_MISC_TODO% - - - - \page submodules Submodules %LIBDPF_INCLUDE_MISC_SUBMODULES% - - - - \page authors Authors %LIBDPF_INCLUDE_MISC_AUTHORS% - - - - \page license License %LIBDPF_INCLUDE_MISC_LICENSE% - - - - \page listings Code examples %LIBDPF_INCLUDE_CODE_LISTINGS% diff --git a/doc/pages/api.md b/doc/pages/api.md index 61d0a41..4f0a7c4 100644 --- a/doc/pages/api.md +++ b/doc/pages/api.md @@ -30,7 +30,10 @@ you want. | [dpf::eval_interval](@ref dpf/eval_interval.hpp) | An inclusive range, one share per input. | | [dpf::eval_sequence](@ref dpf/eval_sequence.hpp) | A sorted list of inputs. | | [dpf::eval_full](@ref dpf/eval_full.hpp) | Every input in the domain. | -| [dpf::reconstruct](@ref dpf/secret_share.hpp) | Both shares. Leaf shares subtract. Comparison shares add. | +| [dpf::reconstruct](@ref dpf/secret_share.hpp) | Both shares. Leaf shares subtract. Comparison shares add. Shamir shares use Lagrange. | +| [dpf::shamir::deal](@ref dpf/shamir.hpp) / `make_shamir_shares` | (K,N) Shamir shares over `fp61` or `gf2n`. For `gf2n`, `N < 2^k`. `(2,3)` is `make_shamir_shares(secret, slope)`. | +| [dpf::shamir::share_secret](@ref dpf/random.hpp) | The same split with uniform higher coefficients. | +| [dpf::shamir::reconstruct](@ref dpf/shamir.hpp) | Any K shares. Further shares are a consistency check, not a correction. | | [dpf::eval_point](@ref dpf/interval.hpp) `(dpf::ic, ...)` | One public input on an interval key. | ## Comparisons and tags @@ -50,19 +53,55 @@ you want. The catalogs, with the types that are inputs and the types that are outputs: - [Input types](@ref input_types): integers, `modint`, `xint`, `bitstring`, `keyword`, `keyword2`, fixed-point. -- [Output types](@ref output_types): `bit`, `twobit`, `nyble`, fields, curve points, shares, `vec`. +- [Output types](@ref output_types): `bit`, `twobit`, `nyble`, `gf2` through `gf264`, prime fields, curve points, shares, `vec`. -`bit`, `twobit`, and `nyble` are packed output lanes. `keyword2` is a domain, not a leaf. +`bit`, `twobit`, `nyble`, and `gf2` / `gf22` / `gf24` are packed output lanes. `keyword2` is a domain, not a leaf. ## After the offset is public [Grotto](@ref guided_tour) evaluates a function of x once the public offset is open. +Several piecewise LUTs share one comparison via [make_lut_union_plan](@ref grotto/lut_union.hpp). The pages are [offset Horner, jets, and ring switch](@ref jet_and_ring) and [representation shift and twisted jets](@ref repr_and_twist). +Haar and bior(5,3) tables are [make_haar_dwt_lut](@ref grotto/dwt_lut.hpp) +and [make_bior53_dwt_lut](@ref grotto/dwt_lut.hpp). + +## Multiplication and sessions + +| Call | What it does | +| --- | --- | +| [dpf::beavers::session](@ref dpf/beaver.hpp) | ABY2.0 blinds, products, dots, and polynomial schedules. | +| [dpf::yao::b2y](@ref dpf/yao_share.hpp) / `a2y` / `fss2y` / `rss2y` | A leaf share to LSB-first XOR bits. Point leaves use `b2y`. Comparisons use `a2y`. | +| [dpf::yao::y2b](@ref dpf/yao_share.hpp) / `y2a` / `y2fss` / `y2rss` | Those bits back to the leaf's share type. | +| [dpf::yao::netlist](@ref dpf/yao.hpp) / `session::eval` | The boolean circuit on those bits. Party 0 garbles. | +| [dpf::arith_garble::circuit](@ref dpf/arith_garble.hpp) | Free add, public scale, projection. Ball–Malkin–Rosulek. | +| [dpf::flute::eval_pair](@ref dpf/flute.hpp) / `eval_trio` | Public LUT on masked bits. Two or three online bits per output. A DPF point stays a key. | +| [dpf::yao::eval_if](@ref dpf/yao_stack.hpp) / `eval_one_hot` | Stacked branch and k-way switch. Rows follow the heaviest branch. | +| [dpf::yao::aes128](@ref dpf/yao_aes.hpp) / `aes_mmo` | Packaged AES-128 and the zero-key MMO block on that session. | +| [dpf::beavers::schedule_objective](@ref dpf/beaver.hpp) | `prep` peels for Appendix E; `rounds` keeps one online round. | +| [dpf::protocol::composer](@ref dpf/compose.hpp) | Domain-tagged FSS / ABY / RSS strands on one RoundSink plan. | +| [dpf::shuffle::shuffle_hidden_pass](@ref dpf/shuffle.hpp) | Hidden reorder of an RSS column. A secret index stays a DPF. | +| [dpf::protocol::composer::shuffle_hidden](@ref dpf/compose.hpp) | Three `shuffle_send` waves for that reorder. | +| [dpf::protocol::composer::client_servers](@ref dpf/compose.hpp) | PIR: one upload round, one answer round, no server-server open. | +| [dpf::protocol::plan_to_schedule](@ref dpf/compose.hpp) / `drive_via_schedule` | Lower a plan onto `schedule_session` (edge, receive rule, branch/next). | +| [dpf::protocol::schedule_session](@ref dpf/protocol.hpp) | Ready instance runs on this thread; flush sends the largest prefix per edge. | +| [dpf::net::edge_mesh](@ref dpf/net/edge_mesh.hpp) / `make_memory_star` | N duplex RoundSinks (star / clique / dealer). | +| [dpf::protocol::session_host](@ref dpf/session_host.hpp) | Queue micro-plans on a durable mesh. | +| [dpf::protocol::iknp_setup_graph](@ref dpf/iknp_graphs.hpp) / `du_atallah_mul_graph` | IKNP / Du-Atallah / star upload-answer as schedule rounds. | +| [dpf::protocol::pirsona_bitmore_fetch](@ref dpf/mesh_apps.hpp) / `hushmap_add_schedule` | PIRsona BitMore fetch and hushmap ADD skeletons. | +| [dpf::protocol::drive_star](@ref dpf/app_plans.hpp) / named `*_plan` helpers | Star drive + application micro-plans (PIR, mailbox, SUBLEQ, Pika, …). | +| [dpf::app::run](@ref dpf/app_flow.hpp) / `run_plan` | Drive both parties and print `rounds` and `bytes`. | +| [dpf::log](@ref dpf/log.hpp) / [app::start_logging](@ref dpf/run_log.hpp) | Leveled run log and provenance banner. | +| [dpf::experiment](@ref dpf/experiment.hpp) / [Logging & statistics](@ref experiment_costs) | Replayable master seed; CSV cost breakdown. | +| [dpf::app::measure_plan](@ref dpf/app_flow.hpp) / `run_measured` | Drive a plan under an experiment; optional `DPF_EXPERIMENT_DIR` CSV dump. | +| [dpf::app::run_fleet](@ref dpf/app_flow.hpp) | Many instances. Parked receives yield to the side that is behind. | ## Where to read next - [Which DPF?](@ref which_dpf) if you are still choosing the object. - [Evaluating DPFs](@ref evaluation) for point, interval, sequence, and full-domain cost. +- [Network, parties, and MPC](@ref network_and_mpc) for the runtime around the keys. +- [Logging, statistics, and experiments](@ref experiment_costs) for the run log and cost CSVs. +- [Protocol composition](@ref protocol_compose) for fused walks, early-stop, and RSS refresh. - [Bibliography](@ref bibliography) for the papers behind the keys. - [Application mockups](@ref applications) for the DPF step inside a larger protocol. diff --git a/doc/pages/applications.md b/doc/pages/applications.md index 0b654e5..70a93af 100644 --- a/doc/pages/applications.md +++ b/doc/pages/applications.md @@ -5,9 +5,18 @@ Each one is a single process. A dealer stands in where the paper generates keys from shares. They compile from the repository root: - c++ -std=c++17 -march=native -I include -I thirdparty examples/applications/duoram3.cpp + c++ -std=c++17 -march=native -pthread -I include -I thirdparty examples/applications/duoram3.cpp + +The online compose sketch at the end of each file uses +[`dpf::app::run_measured`](@ref dpf/app_flow.hpp): it prints rounds, live +bytes, wall/CPU, PRG evals, random bytes, and the master seed hex. Set +`DPF_EXPERIMENT_DIR=/tmp/run` to also write the CSV tables described in +[Experiments](@ref experiment_costs). +The same compile line with the other filenames builds the rest. Timing for +the party protocols, including word garbling, stacked branches, FLUTE, and +the hidden column reorder, is `party_bench` / `profile_party` (see +[The battery](@ref experiment_costs)). -The same line with the other filenames builds the rest. Optional Python bindings configure with `-DLIBDPF_PYTHON=ON` in the test build directory, then `make pydpf` (and `make pydpf_pytest`). `pydpf` exposes point / interval / full / sequence / recipe eval on @@ -16,7 +25,6 @@ and `it_dpf3`. Not in this module yet: geneval, Doerner–Shelat, VDPF `prove`/`sketch`, DCF, or grotto. What those programs had to do by hand is [the library surface underneath](@ref application_gaps). - | Sketch | What the DPF step is | | --- | --- | | [3-party Duoram](@ref app_duoram) | Unit key, rotate, inner product | @@ -38,17 +46,25 @@ What those programs had to do by hand is [the library surface underneath](@ref a | [Range count](@ref app_range_count) | Interval payload | | [Floram](@ref app_floram) | ORAM read | | [Three-server PIR](@ref app_pir3) | Information-theoretic DPF | +| [Protocol composition](@ref protocol_compose) | Fused walks, early-stop, RSS refresh, ABY scale | +| PIRsona fetch | BitMore star upload+answer (`pirsona_fetch.cpp`) | +| Hushmap ADD | Dealer tape + two opens (`hushmap_add.cpp`) | | [What the walk folds in](@ref application_gaps) | Library surface those programs used to do by hand | - ## 3-party Duoram {#app_duoram} +\htmlonly +
ELI5. Preprocessing plants a unit DPF at a random index r. Online the parties open i* − r, rotate the expanded unit vector by that public shift, and dot with the memory. The update rotates a payload vector the same way and adds it in.
+\endhtmlonly + Vadapalli, Henry, and Goldberg ([USENIX Security 2023](@ref bib_duoram)) keep a memory in shares and read or add at a secret index. Preprocessing builds unit DPFs at a random index `r`. Online, the parties open `i* - r` and cyclic-shift the expanded vector. The read is the dot product of that vector with the memory. The update adds a payload vector, shifted the same way. +Opening the whole memory, rather than one index, is a hidden shuffle of +that column ([an array of shares](@ref share_shuffle)), not another DPF. The program uses one dealer unit key for the read and one payload key for the update. @@ -71,6 +87,10 @@ three evaluators. ## MPC SUBLEQ {#app_subleq} +\htmlonly +
ELI5. The address is not known when the keys are built, so the unit vectors are expanded early into a deferred buffer. Online, opening the address rotates that buffer. The read is a dot with memory; the write adds the scaled unit vector back.
+\endhtmlonly + Jiang and Henry ([MSc thesis, University of Calgary](@ref bib_subleq)) emulate the subtract-and-branch-if-less-than-or-equal-to-zero (SUBLEQ) OISC for private function evaluation. One instruction is @@ -109,6 +129,10 @@ and out-of-bounds prefix-parity checks from the thesis. ## BitMore, `2^L` servers {#app_bitmore} +\htmlonly +
ELI5. The label is L bits. Each bit is its own 1-bit DPF, expanded over the whole domain. Stacking the L bit-vectors and reading a column produces the 2^L-server answer for that label.
+\endhtmlonly + Hafiz and Henry ([PoPETs 2019](@ref bib_bitmore), §5.2) query `ell = 2^L` servers with `L` independent 1-bit DPFs, all at the same row. Server `j` receives key number `j_e` from DPF `e`. @@ -131,6 +155,10 @@ The two answers XOR to the record. ## Keyword PIR {#app_keyword} +\htmlonly +
ELI5. The keyword is hashed into cuckoo buckets. Each bucket is a point key, and the record is the inner product of the probed buckets with the dictionary. The S&P 2025 seed-packing of those buckets is not what this program does.
+\endhtmlonly + Gilboa and Ishai ([EUROCRYPT 2014](@ref bib_dpf2014)) retrieve one record by a keyword. [dpf::keyword](@ref dpf/keyword.hpp) is the domain, so the DPF point is the keyword itself. @@ -158,6 +186,10 @@ stack. ## Prio and the heavy-hitter prefix walk {#app_prio} +\htmlonly +
ELI5. A one-hot vote is a unit DPF in the Prio field. Each server adds the expanded vector into a running histogram. The heavy-hitter pass is the same key read at successive prefixes: the servers add the opened prefix shares and keep the heavy nodes.
+\endhtmlonly + Corrigan-Gibbs and Boneh ([NSDI 2017](@ref bib_prio)) aggregate client encodings. A frequency count is a one-hot vector. A unit DPF is that vector, compressed. @@ -182,6 +214,10 @@ and add the opened values. ## I-DPF max and k-th {#app_idpf_agg} +\htmlonly +
ELI5. Each secret integer is one incremental DPF with a unit payload on every prefix. At each bit the servers open the two children. Max keeps the child that holds mass. The k-th keeps the 1-child when its count covers k, and otherwise descends the 0-child with k reduced.
+\endhtmlonly + Cheng, Mitrokotsa, Zhang, and Hartmann ([ePrint 2024/1190](@ref bib_idpfagg)) aggregate secret values with an incremental DPF. Communication tracks the bit length of the domain, not how many secret @@ -200,6 +236,10 @@ share that walk with the gtest. ## LLAMA {#app_llama} +\htmlonly +
ELI5. The comparison is the gate. eval_point on a gt or lt key opens to the payload when the public query is on the true side of the secret, including across the sign bit, because signed inputs flip the high bit before the walk.
+\endhtmlonly + Gupta, Kumaraswamy, Chandran, and Gupta ([ePrint 2022/793](@ref bib_llama)) evaluate a nonlinear gate from a dealer key and one opened masked input `x_hat = x + r`. @@ -214,6 +254,10 @@ to 1. ## Pika {#app_pika} +\htmlonly +
ELI5. The dealer keys a unit DPF at a fresh r and the parties open x = r − a. Rotating the public table by x and dotting with the DPF reads the entry at a. The sign of an early-stop bit leaf is recorded at keygen, so the evaluators never open r.
+\endhtmlonly + Wagh ([PoPETs 2022](@ref bib_pika), Fig. 1) looks up `Func(a)` in a table of a bounded domain. The dealer keys a unit DPF at a fresh index `r` and the parties open @@ -224,11 +268,17 @@ A word payload of `1` opens to `+1`. The paper's early-stop bit leaf opens to `+1` or `-1`; the dealer records that sign at keygen with `dpf::unit_sign` (the final control bit `Gen` sees), so the evaluators never open `r`. +A networked early-stop *walk* (BGI Remark 3.4) drops ν CW rounds with +`fss_point_early_stop` on a [composer](@ref protocol_compose). \include{cpp} applications/pika.cpp ## Express {#app_express} +\htmlonly +
ELI5. A mailbox write is a full-domain add of one DPF into the shared array. Every box is touched by the expand; only the programmed box survives when the shares are opened.
+\endhtmlonly + Eskandarian, Corrigan-Gibbs, Zaharia, and Boneh ([USENIX Security 2021](@ref bib_express), §3.1) write one mailbox. Two servers hold subtractive shares of the mailboxes. @@ -246,10 +296,19 @@ The extractable full-domain leaf now matches point evaluation on every lane, so this one call replaces the earlier `eval_point`-per-address loop and the separate `sketch_fold` pass. +On a networked walk the audit share rides in the last correction-word +flush — `fss_point_fused` / `level_walk_fused` on a +[composer](@ref protocol_compose) — so the sketch does not add a round. +The same shape is Sabre's proof token. + \include{cpp} applications/express.cpp ## PRAC {#app_prac} +\htmlonly +
ELI5. Binary search needs a unit vector on a stride that grows by one bit per comparison. One incremental key holds all of those prefixes, and a prefix inner product dots a stride without a separate point key per slot. A heap update is a three-lane vector at the parent and its two children.
+\endhtmlonly + Sasy, Vadapalli, and Goldberg ([ePrint 2023/1897](@ref bib_prac)) run dynamic data structures on a 3-party Duoram. The new DPF shapes are an incremental key and a wide leaf. @@ -280,6 +339,10 @@ The protocol appends each comparison bit after the key exists. ## Splinter {#app_splinter} +\htmlonly +
ELI5. The secret WHERE value is a unit DPF. The server dots it with a column that was already summed by attribute, which is the grouped SUM, and with an all-ones column, which is the COUNT. The queried attribute is not revealed.
+\endhtmlonly + Wang, Yun, Goldwasser, Vaikuntanathan, and Zaharia ([NSDI 2017](@ref bib_splinter)) answer private queries on public data with two-server FSS. The client's private `WHERE` value is a unit DPF at that attribute. @@ -296,6 +359,10 @@ one selector DPF; Splinter composes several FSS instances for those. ## Mastic {#app_mastic} +\htmlonly +
ELI5. This is the Poplar prefix walk with a weight instead of 1 on every prefix. Servers sum the prefix shares across clients and drop prefixes under the threshold. A path sketch can check that each client programmed a single path.
+\endhtmlonly + Mastic (private weighted heavy-hitters and attribute-based metrics) is Poplar's prefix walk with a weight payload. Each client keys an [idpf](@ref dpf/placement.hpp) whose β on every @@ -311,6 +378,10 @@ heavy with total weight 8. ## Waldo {#app_waldo} +\htmlonly +
ELI5. Each append is a fresh unit DPF added into the value shares; old events are not rewritten. A threshold query is a comparison inner product of those shares with a public magnitude column, so the sum past a secret threshold does not reveal the threshold or the matches.
+\endhtmlonly + Dauterman, Rathee, Popa, and Stoica ([S&P 2022](@ref bib_waldo)) build a private time-series database from FSS. The store is append-only: each event is a fresh unit DPF folded into the @@ -330,6 +401,10 @@ comparison key. ## Sabre {#app_sabre} +\htmlonly +
ELI5. The write is the same full-domain add as Express. The audit folds a constant-size proof token along that key. verify accepts one honest point and rejects a key that was hot in more than one place.
+\endhtmlonly + Vadapalli, Storrier, and Henry ([S&P 2022](@ref bib_sabre)) send anonymous messages with a fast audit. The write is Express's full-domain add (`eval_full_add_into`). @@ -337,6 +412,8 @@ The audit is a *verifiable* DPF proof rather than Express's `fp61` sketch: `prove_full(key, dpf::prove(π))` folds a constant-size token per party, and `dpf::verify(π0, π1)` accepts an honest single-point write and rejects the mismatched fold a multi-point key produces. +Networked audits pack the proof share into the last CW with +`fss_point_fused` ([protocol composition](@ref protocol_compose)). Still by hand: Sabre's blame / accountability phase that identifies a cheating client is protocol logic above the DPF proof. @@ -345,6 +422,10 @@ cheating client is protocol logic above the DPF proof. ## A (2,3) ledger {#app_ledger23} +\htmlonly +
ELI5. An append is one verifiable three-party point at the slot. The three proof tokens are checked before the point is added into the slot shares. Any two servers reconstruct a balance.
+\endhtmlonly + A replicated ledger held as (2-of-3) shares by three servers, on this group's `dpf3` VDPF+ construction. Each append is one `make_dpf3(slot, amount, dpf::verifiable{})`; a @@ -362,6 +443,10 @@ Still by hand: the transaction / consensus layer around the append ## Private set intersection {#app_psi} +\htmlonly +
ELI5. Each element on one side is a unit DPF. Dotting it with the other side's table is the membership test. The cuckoo layout and the OPRF that would sit around that test are not in the DPF call.
+\endhtmlonly + Kolesnikov, Kumaresan, Rosulek, and Trieu ([CCS 2016](@ref bib_kkrt)) test membership with an oblivious PRF. On this domain the PRF is a table both servers hold. @@ -380,6 +465,10 @@ DMPF seed packing needs a PCG this library does not provide. ## Range count {#app_range_count} +\htmlonly +
ELI5. A value falls in [lo, hi) when the greater-than bit at hi and the greater-than bit at lo differ. Each secret value is one comparison key. The count is the sum of those opened bits.
+\endhtmlonly + Each secret value is one comparison. The interval `[lo, hi)` is public. `eval_point(dpf::cmp, key, q)` opens to 1 when `q` is strictly above the @@ -396,6 +485,10 @@ This program is the other direction, secret values and a public range. ## Floram {#app_floram} +\htmlonly +
ELI5. The address is shared, not known to a dealer. The Doerner–Shelat opening builds the unit key level by level, and the read or write is the inner product of that key with the array.
+\endhtmlonly + Doerner and shelat ([CCS 2017](@ref bib_ds)) read and write an array at a secret address. Both parties see the memory. @@ -413,6 +506,10 @@ is the FSS access. ## Three-server PIR {#app_pir3} +\htmlonly +
ELI5. All three servers hold the database. A Shamir DPF3 key makes each server return an inner product; any two of those field elements open the record. The information-theoretic key instead adds all three inner products.
+\endhtmlonly + The database is public and replicated on three servers. The computational path is one (2,3) point key from @@ -432,8 +529,21 @@ three dots sum to the record. Distinct from `make_dpf3`. ## What the walk now folds in {#application_gaps} +\htmlonly +
ELI5. Rotate-then-dot, the sign of a bit leaf, bit columns, prefix dots, and path sketches used to be loops around eval. They are parameters of one walk now.
+\endhtmlonly + The calls the eight programs used to build by hand are now the library surface. See [dpf/eval_walk.hpp](@ref dpf/eval_walk.hpp). +Multi-protocol *schedules* (FSS + ABY + RSS on one RoundSink) are +[protocol composition](@ref protocol_compose). Each listing under +`examples/applications/` records that paper's online flow on a +`composer` and calls `dpf::app::run`, which drives both parties on an +in-process sink and prints `name rounds= bytes=`. That line is the +experiment: compare it with the round and bandwidth column of the +paper. PIR listings are a client and two or three servers (one upload +round, one answer round). The servers do not open shares with each +other. ## Shift, then add {#gap_shift} @@ -562,3 +672,7 @@ full-domain `H` publishes nothing. The walk is O(|H| · n) and never materializes the domain. An audit opening of a replica-seed pool is that copath with `program_hidden = false`, so the live seeds stay out. The one-point layout stays for PSI; `{α}` with programming agrees with it. + +\htmlonly +
TL;DR. Each program is only the DPF step, in one process, with a dealer standing in for shared keygen. Memory reads are a unit vector, a public shift or a prefix, and a dot. PIR and grouped sums are inner products. Heavy hitters are prefix walks. Mailbox writes and the ledger are full-domain adds, plus a proof when the write must be a single point.
+\endhtmlonly diff --git a/doc/pages/arith.md b/doc/pages/arith.md new file mode 100644 index 0000000..a2d353a --- /dev/null +++ b/doc/pages/arith.md @@ -0,0 +1,151 @@ +# Arithmetic share runtime {#arith_runtime} + +\htmlonly +
ELI5. Beside FSS keys you get ordinary secret shares: add them locally, multiply with Beaver or RSS, flip between bits and numbers with edaBits, and truncate fixed-point products. The composer schedules those opens next to FSS walks.
+\endhtmlonly + +Semi-honest 2PC and honest-majority 3PC. Openings may carry Shark/SPDZ IT-MACs +from the beaver session. A leaf that must enter a boolean netlist uses +[b2y / a2y](@ref yao_leaf) and comes back with `y2b` / `y2a`. There is no +Yao domain on the composer. + +## Domains + +| Domain | Meaning | +| --- | --- | +| `a` / `b` / `fss` | Existing additive, subtractive, FSS leaf | +| `rss` / `y` | Existing replicated / product factor | +| `bin` | (2,2) XOR bit shares (packed) | +| `bin_rss` | (2,3) replicated bits | + +`composer::as` never casts to or from `bin` / `bin_rss`. Use `bin_a2b` / +`bin_b2a` / `bin_inject` (see [compose.hpp](@ref dpf/compose.hpp) opcodes +400–405). + +## Building blocks + +| Header | Role | +| --- | --- | +| [rss_seed.hpp](@ref dpf/rss_seed.hpp) | Pairwise PRG seeds, zero-sharing, RSS mul local | +| [ot_pack.hpp](@ref dpf/ot_pack.hpp) | Consumable B2A / bit pads or dealer dabits | +| [edabit.hpp](@ref dpf/edabit.hpp) | daBits and edaBits; A2B | +| [bit_inject.hpp](@ref dpf/bit_inject.hpp) | Bit × arithmetic (2PC / RSS) | +| [trunc.hpp](@ref dpf/trunc.hpp) | Probabilistic and exact truncate; mul_trunc | +| [share_cmp.hpp](@ref dpf/share_cmp.hpp) | Share–share compare, ReLU, max, range, div | +| [share_vec.hpp](@ref dpf/share_vec.hpp) | Lane-block share vectors | +| [fixed_share.hpp](@ref dpf/fixed_share.hpp) | `fixed` | +| [share_expr.hpp](@ref dpf/share_expr.hpp) | Imperative recorder | +| [gilboa.hpp](@ref dpf/gilboa.hpp) | One-off product / tape fill | +| [matmul.hpp](@ref dpf/matmul.hpp) | Matrix triples and matmul | +| [shuffle.hpp](@ref dpf/shuffle.hpp) | Hidden reorder of an RSS column. A secret index stays a DPF | +| [arith_garble.hpp](@ref dpf/arith_garble.hpp) | Free add and a unary projection, after a word has left the key | +| [flute.hpp](@ref dpf/flute.hpp) | Public table on short masked bits. A DPF point stays a key | +| [cost_pass.hpp](@ref dpf/cost_pass.hpp) | DCF vs edaBit vs A2B strategy | +| [yao.hpp](@ref dpf/yao.hpp) | Half-gates netlist on a leaf's XOR bits. Party 0 garbles | +| [yao_share.hpp](@ref dpf/yao_share.hpp) | Leaf share to those bits and back (`b2y`, `a2y`, `fss2y`, `rss2y`) | +| [yao_aes.hpp](@ref dpf/yao_aes.hpp) | The PRG's zero-key MMO block, and AES-128 under a shared key | + +## When to use which comparison + +- **One input public or keyed:** DCF / `geneval_*` / interval keys. +- **Both inputs arithmetic shares:** `share_cmp` (mask, open, MSB / DCF at the public difference). +- **The leaf must enter a deep bit circuit:** [Yao](@ref yao_leaf). Not a comparison, a mux, or a public-offset LUT. + +## A small word after the key {#arith_garble_word} + +Comparisons, intervals, and public-offset polynomials stay on the key. +[Grotto](@ref jet_and_ring) covers a public offset. This section is the +word you already hold as shares, when the next step is addition, a public +scale, or a unary map, and you do not want an opening between the gates. + +[arith_garble.hpp](@ref dpf/arith_garble.hpp) is that circuit +([Ball, Malkin, and Rosulek, CCS 2016](@ref bib_garble_gadgets)). Addition +is free. Scaling by a public constant coprime to the modulus is free. A +unary map of a mod-`m` wire sends `m − 1` ciphertexts. A threshold of `b` +bits that already live in `Z_{b+1}` is one such map, so the row count is +`b`. A product in a small prime field is the discrete-log reduction: project +to the exponent, add, project back, and drop the zero cases. + +The beaver [session](@ref beaver_triples) is the other tool. It opens one +masked wire and multiplies interactively. It does not garble these gadgets. + +```cpp +dpf::arith_garble::circuit c; +auto x = c.input(7); +auto y = c.input(7); +c.out(c.mul(c.add(x, y), x)); +auto opened = dpf::arith_garble::eval_pair(c, in); +``` + +`opened.mask` is the garbler's share and `opened.color` is the evaluator's. +`open_shares` subtracts them mod the output modulus. + +## A public table on short shares {#flute_lut} + +A secret point in a public table is a DPF dotted with that table. FLUTE is +the case where the index is already a handful of masked bits sitting in an +ABY2.0 or three-party XOR sharing, and the result has to stay in that +sharing. + +[flute.hpp](@ref dpf/flute.hpp) follows Brüggemann, Hundt, Schneider, Suresh, +and Yalame, [IEEE S&P 2023](@ref bib_flute). The table is an inner product of +those bits. The online exchange is two bits per output bit for two parties, +and three bits per output bit for `eval_trio`, independent of how wide the +index is. The index is at most 8 bits. Bit 0 of the index is the least +significant bit of the row. + +```cpp +auto pair = dpf::flute::eval_pair(delta, n_out, columns, bits); +auto trio = dpf::flute::eval_trio(delta, n_out, columns, bits); +``` + +`columns[w * 2^δ + row]` is output bit `w` on that row. `opened` is the +clear bit. `masked` XOR the party's mask shares is the same bit. + +## An array of shares, not a secret index {#share_shuffle} + +A secret index is a DPF. One read of a shared memory is a unit key, a public +rotate, and a dot product, as in [3-party Duoram](@ref app_duoram). The +shuffle is the other job: the parties already hold a share of every row, and +the next step opens values. The opened order must not be the stored order. + +`shuffle_party` derives one permutation from `k01` and applies it to every +component. A caller who passes the whole seed bundle can recompute that +order. Use it when the order is allowed to be known. + +`shuffle_hidden_pass` is the order no single party should learn. Three +passes use the pairwise seeds `k01`, `k12`, and `k20`, leaving out the party +who does not hold that seed (party 2, then 0, then 1). Each party is given +`rss::party_seeds` only. On a pass, the two parties who share the seed +permute a two-party split of the column. The left-out party sends nothing +and receives one fresh component. Both messages go to the sender's RSS +neighbor. `permute` means `out[i] = in[pi[i]]`. Replaying the clear column +is `π01`, then `π12`, then `π20`. + +```cpp +auto opened = dpf::shuffle::shuffle_hidden_triple(column, bundle, /*index=*/0); +``` + +`composer::shuffle_hidden(n, value_bytes)` records those three exchanges as +`shuffle_send`. `aux` on each node is the left-out party. + +This is for a column you already share: a Duoram memory before a bulk open, +a histogram, a PSI payload. It does not replace a key. One hidden cell is +still a DPF. A comparison or a sort by a secret key is a DCF or +`share_cmp`. A gather to data-dependent indices is a DPF per access. The +seed permutation is chosen before the data. + +## Truncation + +- `trunc_prob` — local right shift, error in `{0,1}`, no round. +- `trunc_exact` — edaBit / carry correction. +- `mul_trunc` — product then shift (fixed-point multiply). + +## Networking + +`schedule_round` carries `phase::{setup,online}`, `round_dir::{duplex,send_next,recv_prev}`, +and `receive_rule::ring_next`. `drive_options` adds `pipeline_credit`, `cleartext`, +and `check_open`. Pairwise seeds replace `dealer_zero` via `rss_zero_mask`. + +**Go deeper:** [Beaver](@ref beaver_triples), [compose](@ref protocol_compose), +[Grotto carry](@ref jet_and_ring). diff --git a/doc/pages/basics.md b/doc/pages/basics.md index 52550bd..76b10b7 100644 --- a/doc/pages/basics.md +++ b/doc/pages/basics.md @@ -62,6 +62,10 @@ Width literals (`100_u12`, `7_x12`, `1.5_fixed16`, `1_bit`, `2_twobit`, ## DPF Trees {#dpf_trees} +\htmlonly +
ELI5. A key stores a root seed and one correction word per level. Expanding the seed walks the tree. On the secret path the correction forces the leaf to the programmed value; off that path the two parties' corrections cancel, so the opened value is zero.
+\endhtmlonly + 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 @@ -79,3 +83,7 @@ full-domain evaluation versus `2N`. See [tree_traits.hpp](@ref dpf/tree_traits.h For a slow, friendly walk through every feature, start at the [guided tour](@ref guided_tour). + +\htmlonly +
TL;DR. A (2,2) DPF gives each party a short key for one secret point. make_dpf builds it. Point leaves open by subtraction and comparisons by addition. The key is a seed plus one correction word per level.
+\endhtmlonly diff --git a/doc/pages/beaver.md b/doc/pages/beaver.md index da8da14..5638bc7 100644 --- a/doc/pages/beaver.md +++ b/doc/pages/beaver.md @@ -1,16 +1,39 @@ # Beaver triples {#beaver_triples} +\htmlonly +
ELI5. A product opens as d = x − a and e = y − b, with a and b the preprocessing blinds. The product share is de plus the blinded cross terms, all local once d and e are public. The session keeps blinds that were already opened and only samples monomials it has not seen.
+\endhtmlonly + ABY2.0-style sessions open masked wires once (Patra, Schneider, Suresh, and Yalame, USENIX Security 2021 / [ePrint 2020/1225](@ref bib_aby2)). A fresh triple follows Beaver, [CRYPTO 1991](@ref bib_beaver): both masked factors are reconstructed, and the product share is a local correction. Optional MAC tags are the Shark/SPDZ check. +Constant-round word arithmetic is a separate gadget. [Ball, Malkin, and +Rosulek, CCS 2016](@ref bib_garble_gadgets) give free addition, free scaling +by a public constant, and a unary projection of `m − 1` ciphertexts. +[arith_garble.hpp](@ref dpf/arith_garble.hpp) is that circuit. A session does +not become one: it still opens δ once per wire. A public table on masked +bits is [FLUTE](@ref bib_flute) in [flute.hpp](@ref dpf/flute.hpp): the table +is a multi-fan-in inner product, and the online exchange is two bits per +output bit. `eval_trio` is the same product on three XOR shares of each mask. + One call that samples a list of formulae opens the new wires in one round. Communication is one masked value per newly opened wire, plus a tag share of the same width when MACs are on. Preprocessing is one blind per wire and one product share per monomial. -**Go deeper:** [beaver.hpp](@ref dpf/beaver.hpp), +`schedule_objective::prep` (default) peels shared factors for Appendix-E +prep savings and may add interactive rounds. +`schedule_objective::rounds` emits the polynomial in one online round +(Pika / online Grotto). Composer-owned sessions use `rounds`. + +Compose FSS walks, ABY products, and RSS refreshes on one sink with +[protocol composition](@ref protocol_compose). + +**Go deeper:** [a small word](@ref arith_garble_word), +[a public table](@ref flute_lut), [beaver.hpp](@ref dpf/beaver.hpp), +[compose.hpp](@ref dpf/compose.hpp), [F_Beaver](@ref beaver.hpp), [F_BeaverAuth](@ref beaver.hpp), and the cost notes in the [guided tour](@ref tour_beaver). diff --git a/doc/pages/bibliography.md b/doc/pages/bibliography.md index ae41eac..74feeb1 100644 --- a/doc/pages/bibliography.md +++ b/doc/pages/bibliography.md @@ -169,7 +169,121 @@ USENIX Security 2021. Full version: One public reconstruction per newly opened wire. -**Used in** [Beaver triples](@ref beaver_triples) · [Guided tour](@ref tour_beaver) +**Used in** [Beaver triples](@ref beaver_triples) · [Arithmetic share runtime](@ref arith_runtime) · [Guided tour](@ref tour_beaver) + +### ABY {#bib_aby} + +Daniel Demmler, Thomas Schneider, and Michael Zohner. +*ABY — A Framework for Efficient Mixed-Protocol Secure Two-Party Computation.* +NDSS 2015. +[ePrint 2014/386](https://eprint.iacr.org/2014/386) + +Arithmetic / boolean / Yao sharing and conversions. + +**Used in** [Arithmetic share runtime](@ref arith_runtime) · [A boolean function of a leaf](@ref yao_leaf) + +### Half-gates {#bib_halfgates} + +Samee Zahur, Mike Rosulek, and David Evans. +*Two Halves Make a Whole: Reducing Data Transfer in Garbled Circuits using Half Gates.* +EUROCRYPT 2015. +[ePrint 2014/756](https://eprint.iacr.org/2014/756) + +Free-XOR AND rows. `yao::session` sends two blocks per AND. + +**Used in** [A boolean function of a leaf](@ref yao_leaf) · [Arithmetic share runtime](@ref arith_runtime) + +### Garbling gadgets {#bib_garble_gadgets} + +Marshall Ball, Tal Malkin, and Mike Rosulek. +*Garbling Gadgets for Boolean and Arithmetic Circuits.* +CCS 2016. +[ePrint 2016/969](https://eprint.iacr.org/2016/969) + +Free addition and public scaling in `(Z_m)^k`, and a unary projection of +`m − 1` ciphertexts. A fan-in-`b` symmetric gate is a projection of the sum. +`arith_garble.hpp` is this gadget. The session in `beaver.hpp` stays the +interactive one-open product. + +**Used in** [Beaver triples](@ref beaver_triples) · [Arithmetic share runtime](@ref arith_runtime) + +### Stacked garbling {#bib_stacked} + +David Heath and Vladimir Kolesnikov. +*Stacked Garbling: Garbled Circuit Proportional to Longest Execution Path.* +CRYPTO 2020. +[ePrint 2020/973](https://eprint.iacr.org/2020/973) + +One XOR-stack of the branch materials. Inactive branches are rebuilt from seeds. + +**Used in** [A boolean function of a leaf](@ref yao_leaf) + +### One-hot garbling {#bib_onehot} + +David Heath and Vladimir Kolesnikov. +*One Hot Garbling.* +CCS 2021. + +The same stack over `k` branches. The demux carries the inactive seeds. + +**Used in** [A boolean function of a leaf](@ref yao_leaf) + +### FLUTE {#bib_flute} + +Andreas Brüggemann, Robin Hundt, Thomas Schneider, Ajith Suresh, and Hossein Yalame. +*FLUTE: Fast and Secure Lookup Table Evaluations.* +IEEE S&P 2023. +[ePrint 2023/499](https://eprint.iacr.org/2023/499) + +A public LUT is a multi-fan-in inner product on ABY2.0 masked bits. +Online cost is two bits per output bit. + +**Used in** [Beaver triples](@ref beaver_triples) · [Arithmetic share runtime](@ref arith_runtime) + +### ABY3 {#bib_aby3} + +Payman Mohassel and Peter Rindal. +*ABY3: A Mixed Protocol Framework for Machine Learning.* +CCS 2018. +[ePrint 2018/403](https://eprint.iacr.org/2018/403) + +Honest-majority 3PC, RSS, probabilistic truncation, matrix triples. + +**Used in** [Arithmetic share runtime](@ref arith_runtime) + +### edaBits / CrypTFlow2 {#bib_edabits} + +Daniel Escudero, Satrajit Ghosh, Marcel Keller, Rahul Rachuri, and Peter Scholl. +*Improved Primitives for MPC over Mixed Arithmetic-Binary Circuits.* +CRYPTO 2020. +[ePrint 2020/338](https://eprint.iacr.org/2020/338) + +**Used in** [Arithmetic share runtime](@ref arith_runtime) · [A boolean function of a leaf](@ref yao_leaf) + +### EzPC {#bib_ezpc} + +Nishanth Chandran, Divya Gupta, Aseem Rastogi, Rahul Sharma, and Shardul Tripathi. +*EzPC: Programmable and Efficient Secure Two-Party Computation for Machine Learning.* +EuroS&P 2019. +[ePrint 2017/1109](https://eprint.iacr.org/2017/1109) + +**Used in** [Arithmetic share runtime](@ref arith_runtime) + +### Gilboa multiplication {#bib_gilboa} + +Niv Gilboa. +*Two Party RSA Key Generation.* +CRYPTO 1999, LNCS 1666, pp. 116–129. + +**Used in** [Arithmetic share runtime](@ref arith_runtime) + +### Sharemind {#bib_sharemind} + +Dan Bogdanov, Sven Laur, and Jan Willemson. +*Sharemind: A Framework for Fast Privacy-Preserving Computations.* +ESORICS 2008, LNCS 5283, pp. 192–206. + +**Used in** [Arithmetic share runtime](@ref arith_runtime) ### Beaver triples {#bib_beaver} @@ -221,6 +335,22 @@ Offset Horner is not that piecewise-polynomial construction. **Used in** [Grotto](@ref jet_and_ring) · [Guided tour](@ref tour_grotto) +### Wave Hello {#bib_wave} + +José Reis, Mehmet Ugurbil, Sameer Wagh, Ryan Henry, and Miguel de Vega. +*Wave Hello to Privacy: Efficient Mixed-Mode MPC using Wavelet Transforms.* +PoPETs 2025(2), pp. 697–718. +
Publisher · +[ePrint 2025/013](https://eprint.iacr.org/2025/013) · +PDF + +Equations (7) and (8) are the cleartext Haar and bior(5,3) lookup. +`make_haar_dwt_lut` and `make_bior53_dwt_lut` evaluate those tables. +The online phase pairs Haar with a deterministic Pika truncation and +bior(5,3) with segment parity. + +**Used in** [Wavelet lookup tables](@ref dwt_luts) · [Guided tour](@ref tour_grotto) + ## Protocols {#bib_sec_protocols} ### Duoram {#bib_duoram} @@ -379,3 +509,7 @@ The DPF work is a prepaid wildcard unit vector, rotated once the address is opened. **Used in** [MPC SUBLEQ](@ref app_subleq) + +\htmlonly +
TL;DR. The point key is ePrint 2018/707, not the longer EUROCRYPT 2015 key. Proofs and cuckoo multipoint are 2021/580. Comparisons are 2020/1392. The dealer-free opening is 2017/827, and the pads are IKNP plus the 2015/267 base OT. Three-party spines are 2024/1658. The information-theoretic table is 2023/028. Grotto is 2023/108.
+\endhtmlonly diff --git a/doc/pages/capabilities.md b/doc/pages/capabilities.md index c6d3e7b..23e30cd 100644 --- a/doc/pages/capabilities.md +++ b/doc/pages/capabilities.md @@ -3,13 +3,25 @@ Everything past a plain two-party point key. The home page is the short version. Open a page for the snippet and the header. +## Keys and evaluation + - [Verifiability & authenticity](@ref verifiability) - [Programmability](@ref programmability) - [Comparisons & ranges](@ref comparisons) - [Multipoint keys](@ref multipoint_keys) - [Multiparty & 3-server](@ref multiparty) - [Dealer-free keygen](@ref dealer_free) -- [Beaver triples](@ref beaver_triples) - [Grotto](@ref jet_and_ring) - [Point-programmable vector commitments](@ref ppvc_manual) - [Application sketches](@ref applications) + +## Network and MPC around the keys + +These are first-class in the tree — see the overview, then dig in: + +- [Network, parties, and MPC](@ref network_and_mpc) — map of the runtime stack +- [Protocol composition](@ref protocol_compose) +- [Beaver triples](@ref beaver_triples) +- [Arithmetic share runtime](@ref arith_runtime) +- [A boolean function of a leaf](@ref yao_leaf) +- [Logging, statistics, and experiments](@ref experiment_costs) — run log, CSVs, replayable seeds diff --git a/doc/pages/comparisons.md b/doc/pages/comparisons.md index 05dd422..07b0b90 100644 --- a/doc/pages/comparisons.md +++ b/doc/pages/comparisons.md @@ -1,5 +1,9 @@ # Comparisons & ranges {#comparisons} +\htmlonly +
ELI5. The predicate is part of the key, not a test you run after expanding a point key. Greater-than, less-than, and equality each return one payload on the true side and another on the false side. Interval containment is one key for both endpoints. Shares of a comparison add.
+\endhtmlonly + A distributed comparison function returns a payload when a predicate holds on the secret point. Shares are additive: `reconstruct` adds them. diff --git a/doc/pages/compose.md b/doc/pages/compose.md new file mode 100644 index 0000000..cbc120c --- /dev/null +++ b/doc/pages/compose.md @@ -0,0 +1,204 @@ +# Protocol composition {#protocol_compose} + +\htmlonly +
ELI5. Record every expand, multiply, and open as a node with a share domain. Identical work is interned. Independent opens share one RoundSink round; a dependency chain becomes successive waves. The schedule is what a hand-tuned Express or Duoram party would have written by hand.
+\endhtmlonly + +`dpf::protocol::composer` ([compose.hpp](@ref dpf/compose.hpp)) records +multi-protocol strands on one sink. Values are tagged with a share +domain matching [secret_share.hpp](@ref dpf/secret_share.hpp): + +| Domain | Meaning | +| --- | --- | +| `fss` | FSS / DPF leaf share | +| `a` | (2,2) additive | +| `b` | (2,2) subtractive | +| `rss` | (2,3) replicated | +| `y` | (3,3) additive (RSS product factor) | + +Party-count changes are never implied: use `reshare` (or `rss_from_y` +for `y`→`rss`). Local casts use `as`. + +## Building a schedule + +```cpp +dpf::protocol::composer c(/*party=*/0); +auto seed = c.input(dpf::protocol::domain::fss, 16); +auto leaf = c.fss_point(seed, /*depth=*/8, /*slot_bytes=*/16); +auto p = c.default_plan(); // == schedule(); RoundSink uses this +// p.rounds() == p.exchange_waves() == 8 (no empty compute-only sink rounds) +``` + +Drive with [drive](@ref dpf::protocol::drive) or party +`util::drive_composed` / `util::drive_composed_trio`, optionally with +`drive_options` (`from_exchange_wave`, `compact_sink`, `beavers`). +Express/Sabre audits use `util::schedule_fused_audit` (or `fss_point_fused`). + +The same plan lowers onto the RoundSink batch loop with +`plan_to_schedule` → [`schedule_session`](@ref dpf::protocol::schedule_session) +→ `finish_schedule`, or the one-shot `drive_via_schedule`. Each exchange wave +becomes a [`schedule_round`](@ref dpf::protocol::schedule_round) whose +`produce` runs on this thread when that instance's peer slot is ready (the +`schedule_session::drive` scan). Rounds carry an +[`edge_id`](@ref dpf/net/edge_mesh.hpp) on an [`edge_mesh`](@ref dpf/net/edge_mesh.hpp) +(star / clique / dealer), a [`receive_rule`](@ref dpf::protocol::receive_rule) +(`domain_open`, `copy_peer`, `field_sum`, `any_two`, `verify_*`, `eq_check`), +optional `branch` (skip send) and `next` (jump after an open). +[`session_host`](@ref dpf/session_host.hpp) queues micro-plans on a durable mesh. +Pad graphs live in [pad_graphs.hpp](@ref dpf/pad_graphs.hpp) +(`du_atallah_mul_graph`, `star_upload_answer_graph`); IKNP setup in +[iknp_graphs.hpp](@ref dpf/iknp_graphs.hpp); PIRsona / hushmap builders in +[mesh_apps.hpp](@ref dpf/mesh_apps.hpp). Named application plans and +`drive_star` / `submit_and_drive` live in [app_plans.hpp](@ref dpf/app_plans.hpp). + +Replayable seeds and paper cost CSVs: see [Experiments](@ref experiment_costs). +In short, `dpf::experiment` / `app::measure_plan` / `app::run_measured` attach a +per-thread master seed (default random, or `replay`) and emit CSV breakdowns. + +`plan::rounds()` equals `exchange_waves()` and `slot_bytes_all().size()` — +the sink and the scheduler share one count. Trailing compute-only DAG waves +still appear in `waves()` / `wave(i)` but do not allocate RoundSink rounds. + +Composer-owned ABY sessions default to +`beavers::schedule_objective::rounds` so online sign×polynomial stays +one round. Dealer benches that want Appendix-E peels keep `prep`. +Independent circuits use `aby_lane(i)`. Live δ openings use +`drive_options::beavers` (`util::u64_beaver_host` wraps +`party_batch_stepper`). + +## Hand-schedule shapes the API covers + +| Shape | Call | What it saves | +| --- | --- | --- | +| L‖R PRG stretch | `expand_pair` / default `level_walk` | Half the AES vs separate child expands | +| Shared-seed fan (Grotto LUT) | `fan` of `fss_cmp` on one seed | One expand per level, not N×depth | +| Several piecewise LUTs | `schedule_lut_union` | One `fss_cmp`; the union's prefix walk is local | +| Express / Sabre audit | `fss_point_fused` / `schedule_fused_audit` | Sketch in last CW — no +1 exchange wave | +| BGI Remark 3.4 early-stop | `fss_point_early_stop` | Drop ν interactive CW rounds | +| Poplar / idpf prefix checkpoints | `level_walk_prefixes` | Prefix share after each CW, no extra rounds | +| Adaptive idpf_agg | `step` → drive tail → `retain` → `step`… | One packed L‖R open per depth; child bit never on the wire | +| DCF `block_width` | `level_walk_sized` | Per-level CW slot bytes | +| Doerner–Shelat keygen | `level_walk_ds` / `level_walk_ds_sized` | blind‖CW‖advice‖AND + OH AND-layers | +| Keyword PIR / PSI buckets | `multipoint_fan` / `exchange_pack` | Bucket CWs pack; answers one open | +| RSS mul + neighbor refresh | `rss_product_replicated` / `rss_from_y` | One y-exchange, not a reconstructing open | +| FSS leaf → ABY scale | `aby_product` after `fss_point` | Leaf stays on the beaver barrier critical path | +| Multi-lane ABY | `aby_lane(i)` / `aby_product(..., lane)` | Independent barriers, shared wave | +| Round-aware Beaver | `composer::aby()` | `schedule_objective::rounds` | +| Prepaid expand / rotate | `defer_expand` / `rotate_share` | Zero online FSS rounds (SUBLEQ offline) | +| Duoram leaf_later | `leaf_later_walk` / `apply_leaf_correction` | Path CWs only; leaf apply is local | +| RSS column, hidden order | `shuffle_hidden` | Three `shuffle_send` waves. `aux` is the left-out party: 2, then 0, then 1 | + +Adaptive prefixes: `step_adaptive_prefix` schedules only the next packed +open; drive with `from_exchange_wave = exchanges_flushed` and a sink sized +by `plan::slot_bytes_from` (`compact_sink = true`); then +`retain_adaptive_prefix` adds one local tip. Never unroll a full-depth +adaptive walk into one static schedule. + +3PC RSS: `rss_from_y` schedules a `domain::y` exchange (neighbor receive). +`util::drive_composed_trio` splits peer maps per exchange — `y` on the +neighbor ring, `dealer_deliver` from p2, everything else on p0↔p1. +Cross-party `reshare` refuses a reconstructing open; use +`reshare_with_mask`. Opens use domain algebra (`a`/`fss` sum, `b` +subtractive, `y` copy, optional `field_open::fp61`). Authenticated Beaver +sessions size barriers as `auth_opening` and drive through +`u64_auth_beaver_host`. `exchange_fuse` packs extra payloads into one open. +`schedule_cuckoo_probes` turns occupied bucket ids into `multipoint_fan`. + +## Client and servers {#compose_client} + +Keyword PIR and both three-server PIRs are a star, not a correction-word +walk. `client_servers(servers, query_bytes, answer_bytes)` records two +waves and nothing between the servers: + +1. Upload. The slot is `servers * query_bytes` (every key in one round). +2. Answer. The slot is `servers * answer_bytes`. It depends on the upload, + so it cannot share that wave. + +`drive` copies the peer's message into the exchange node. It does not add +the shares. A two-party sink stands in for one client and one server; the +slot width is still the full parallel payload, which is what +`dpf::app::exercise` reports as `bytes`. + +```cpp +auto q = c.client_servers(/*servers=*/2, /*query_bytes=*/256, /*answer_bytes=*/4); +auto p = c.default_plan(); +// p.rounds() == 2 +// p.slot_bytes(0) == 512, p.slot_bytes(1) == 8 +``` + +## Parking and the fleet {#compose_fleet} + +`drive` used to spin until the peer flushed, then throw. A step that +simply takes a long time looks like that failure, and a pool that always +resumes the side already waiting on a receive never runs the peer who +could unblock it. + +`drive_options::park_if_waiting` returns instead. `drive_cursor` remembers +the wave, the exchange index, and whether the submit already happened. +The next `drive` with that cursor receives if the peer has caught up, or +parks again. `one_exchange` stops after a single completed round so a +scheduler can interleave other instances. + +`dpf::app::run_fleet(composer, instances, chaos_seed)` is that scheduler. +Each instance is a pair of parties on an in-process sink. Workers prefer +a side that still has a submit to do over a side parked on a receive, and +among those they prefer the one further behind. Delays are per side and +per step. They do not line up, which is the case that makes round-robin +and "always resume the waiter" stall. + +`dpf::app::run(name, composer, expect_rounds)` is the one-shot experiment +used by `examples/applications/`. It drives both parties and prints + +``` +name rounds=R bytes=B +``` + +`bytes` is the sum of one lane's exchange slots. + +Opcodes from `beaver_delta` (300) through `beaver_delta + 1023` are δ +barriers. `user_base` (1000) sits inside that window, so a hand-rolled +kernel opcode in that range is skipped as a beaver. Use 5000 and up for +kernels `drive` must run or reject. + +## What eval_full reuses + +`eval_full(key, buffer)` keeps a thread-local workspace for that key type. +The same key evaluated again does not rebuild the interior. A different +key still does. Leaves of one block are stretched eight at a time +(`eval_x8`). Pass your own memoizer when two evaluations on one thread +must not share that cache. + +DS OH: `level_walk_ds(..., oh=true)` emits +`net::ds_oh_exchanges_per_level` (80) AND-layer opens per level. Size sinks +with `net::compose_ds_slot_bytes` (schedule-exact) or the conservative +`net::ds_walk_slot_bytes` for hand `dist_ds` paths. + +\include{cpp} protocol/compose_schedule.cpp + +## Gap analysis {#compose_gaps} + +| Item | Status | +| --- | --- | +| Point-key stretch | Builtin `fss_expand_pair` runs `prg::aes128`; `fss_step+1` XORs the opened correction onto the children | +| Setup plus walk | `iknp_setup_graph` / `plan_with_pad_setup` — pad frames are `schedule_round`s | +| Edge mesh | `edge_mesh` + `make_memory_star` / `make_memory_clique`; `drive_via_schedule(plan, mesh, …)` | +| Receive rules | `field_sum`, `any_two`, `verify_sketch` / `verify_proof`, `eq_check` in `apply_peer_slot` | +| Jump / host | `schedule_round::next` + `session_host` for SUBLEQ / idpf_agg / hushmap ops | +| PIRsona / hushmap | `pirsona_bitmore_fetch`, `pirsona_gd_update_graph`, `hushmap_add_schedule` | +| 2PC → RSS | `reshare` casts to a `y` share (p2 holds 0) and `rss_from_y`. `reshare_fresh` adds a dealer-sampled zero mask | +| Auth openings | `auth_beaver_host` / `u64_auth_beaver_host`. `party_auth_batch_stepper::apply_peer` rejects a bad tag | +| One DS sink | `ds_walk_slot_bytes` is the envelope of the hand walk and `compose_ds_slot_bytes` (5 peer opens per level + OH + mux) | +| Wide opens | Every multiple of 8 bytes is a lane add/sub (`field_open::fp61` for the Mersenne field) | +| Fuse offset | `exchange_fuse` stores the segment offset in `aux` (`uint32_t`) | + +Still outside this scheduler: the cuckoo PRP, OPRF evaluation, the full IKNP wire body inside each pad `produce` (frames and count are in the schedule; `iknp::sample` still owns the crypto), and key-specific control-bit / verifiable / Doerner–Shelat advice logic. Those last ones override the builtin kernels. Trio multi-edge `drive_via_schedule` still needs `edge_sinks` wired from the party helper. + +### Closed earlier + +Incremental drive, domain-correct `a`/`b`/`y` opens, split y/2PC peer maps, OH AND-layers, `level_walk_ds_sized`, `default_plan`, staged adaptive retain, multipoint fan, multi-lane ABY, `defer_expand` / `leaf_later_walk`, Express trailer fuse. + +**Go deeper:** [compose.hpp](@ref dpf/compose.hpp), +[beaver.hpp](@ref dpf/beaver.hpp), +[sink_exchange.hpp](@ref dpf/net/sink_exchange.hpp), +[Application sketches](@ref applications), +[guided tour](@ref tour_party). diff --git a/doc/pages/dealer_free.md b/doc/pages/dealer_free.md index 7ce5c67..cf1b71f 100644 --- a/doc/pages/dealer_free.md +++ b/doc/pages/dealer_free.md @@ -1,5 +1,9 @@ # Dealer-free keygen {#dealer_free} +\htmlonly +
ELI5. The index is already split. Doerner–Shelat turns those shares into a reusable key by opening one masked correction per level. geneval stops after a single public query and returns answer shares, not a key. IKNP is how the pads are sampled when no dealer supplies them.
+\endhtmlonly + The two parties already hold shares of the secret index. Nobody sends `alpha` to a dealer. diff --git a/doc/pages/evaluation.md b/doc/pages/evaluation.md index 64a8c60..85b27ab 100644 --- a/doc/pages/evaluation.md +++ b/doc/pages/evaluation.md @@ -75,6 +75,10 @@ mockup [I-DPF max and k-th](@ref app_idpf_agg). ## Assigning a wildcard leaf {#wildcard_assign} +\htmlonly +
ELI5. The blank leaf is a Beaver slot from keygen. Filling it in rewrites the correction word: the parties exchange one blinded share of the new payload and both apply the same patch. assign_cmp rewrites the n comparison words locally and sends nothing. An updatable leaf is the same patch later, O(λ) and independent of the depth.
+\endhtmlonly + An output wildcard is a placeholder for a payload filled after keygen. The type and the `dpf::wildcards` names are on [Output types](@ref output_types). Evaluation of an unassigned slot throws @@ -149,6 +153,10 @@ either party's type accepts both parties. Name that type with ## Memoizers {#memoizers} +\htmlonly +
ELI5. The first walk stores interior nodes. The next query starts from the deepest stored node that still lies on its path, instead of from the root. An interval memoizer stores the nodes that cover a range; a sequence memoizer stores the nodes along a sorted list.
+\endhtmlonly + ## Path memoizers {#path_memoizers} `eval_point` walks one root-to-leaf path. `make_basic_path_memoizer()` @@ -331,6 +339,10 @@ size both for that domain. ## Deferred input evaluation {#defer_eval} +\htmlonly +
ELI5. The PRG expand runs once, into a full-domain buffer, before the index is known. When the offset opens, get() rotates that buffer. The tree is not expanded again.
+\endhtmlonly + Additive input blinding evaluates in tree coordinates `x ↦ x + δ`, where `δ` is reconstructed by `assign_wildcard_input` into `offset_x`. Eager `eval_interval` folds that map into the traversed range and throws if the @@ -364,6 +376,10 @@ Buffers must outlive both. ## dpf::eval_inner_product {#eval_inner_product} +\htmlonly +
ELI5. The walk is the same as an interval or full-domain eval, but each leaf is multiplied by a public weight and added into one accumulator. The expanded vector is not stored. A sequence inner product does that only at the listed points.
+\endhtmlonly + `eval_inner_product` multiply-accumulates DPF shares against another vector during the walk. It does not write the output vector. @@ -469,6 +485,10 @@ on that list: at most `O(n m)` expands and `m` output slots. ## Buffered PRG {#buffered_prg} +\htmlonly +
ELI5. One AES expand produces more blocks than a single tree node needs. The buffered PRG keeps the leftover blocks and serves the next nodes from them, so a wide walk makes fewer expands. The keys do not change.
+\endhtmlonly + `dpf::randomness::buffered_prg` (alias `dpf::randomness::aes_buffered_prg`) is a forward cursor with one PRG stream per value type. `get()` and `fill(out, n)` consume the @@ -496,6 +516,10 @@ element. `fill_values` / `fill_masks` of `q` elements are `Θ(q)`. ## Three-party (2,3) DPF {#dpf3} +\htmlonly +
ELI5. Each evaluator key is two VDPF+ spines. eval_point walks both, Θ(n) expands, then scales into fp61. Opening two or three as_share values is a constant amount of field arithmetic. An updatable rewrite patches four leaves and refreshes an offset, independent of n.
+\endhtmlonly + `make_dpf3(α, β)` builds three evaluator keys after Guy Zyskind, Avishay Yanai, and Alex "Sandy" Pentland, [ePrint 2024/1658](@ref bib_dpf3), Figure 3: two VDPF+ spines plus Shamir embedding in `fp61`. `eval_point` returns a field share; open with `dpf::reconstruct` on any two (or all three) @@ -525,6 +549,10 @@ two-party comparison, interval, or cuckoo packing, on top of those spines. ## Information-theoretic 3-server DPF {#it_dpf3} +\htmlonly +
ELI5. There is no PRG tree. For this domain each key is an additive share of a 256-word table. The three shares sum to beta at alpha and to zero elsewhere. A PIR answer is three inner products with the database; those three dots sum to the record.
+\endhtmlonly + `make_it_dpf3(α, β)` ([ePrint 2023/028](@ref bib_itdpf)) is a different object from `make_dpf3`. Each of three parties holds an additive share of the characteristic vector on `{0..255}`; the **sum** of all three @@ -573,7 +601,13 @@ claimed speedup over dealer keygen or over Half-Tree §5.2.
- eval_dpf3_point.cpp \include{cpp} evaluation/eval_dpf3_point.cpp + - eval_dpf3_doerner_shelat.cpp \include{cpp} evaluation/eval_dpf3_doerner_shelat.cpp + - eval_dpf3_cmp_ic.cpp \include{cpp} evaluation/eval_dpf3_cmp_ic.cpp
+ +\htmlonly +
TL;DR. eval_point is one path. An interval costs the path plus the length of the range. A full domain costs the size of the domain; an inner product does that walk and keeps only the accumulator. Wildcard assign and an updatable rewrite patch the leaf and do not depend on the depth. Three-party eval is two walks and a short field open. The information-theoretic key is a 256-word share, not a walk.
+\endhtmlonly diff --git a/doc/pages/experiment.md b/doc/pages/experiment.md new file mode 100644 index 0000000..1f0d5e5 --- /dev/null +++ b/doc/pages/experiment.md @@ -0,0 +1,192 @@ +# Logging, statistics, and experiments {#experiment_costs} + +Paper and production runs need three things the bare key API does not: +**leveled run logs**, **granular cost statistics**, and **replayable coins**. +All three live in the same measurement stack — +[`dpf/log.hpp`](@ref dpf/log.hpp), [`dpf/run_log.hpp`](@ref dpf/run_log.hpp), +[`dpf::experiment`](@ref dpf/experiment.hpp), and the +[`prg::count`](@ref dpf/prg_count.hpp) / [`thread_work`](@ref dpf/thread_work.hpp) +counters. + +Uninstrumented code stays quiet and keeps reading `/dev/urandom`. Logging and +experiments are opt-in. `run_measured`, the battery, and `party_node` call +[`app::start_logging`](@ref dpf/run_log.hpp) and install an experiment covering +the thread that constructs it. `run_parties`, `measure_plan`, and the battery +give party `i` its own stream, `ex.derive_party(i)`, whose master is SHA-256 of +the experiment's master and `i`, and they use it for every trial, warmup +included. A kernel handed to a compute pool draws from its party's stream. +Replaying the master replays every party, as long as each party makes the same +draws in the same order. The party masters are noted as `p0/master`, +`p1/master`, and so on. + +## Run log {#run_log} + +[`dpf/log.hpp`](@ref dpf/log.hpp) writes one `key=value` line per event to +stderr, syslog, or a file. Nothing is written until `log::configure` runs +(normally through `app::start_logging`), so library code can log freely and a +test that never configures the log stays quiet. Every line starts with +`ts`, `lvl`, `inv` (invocation id), `pid`, `tid`, then `role=` when the +thread has one, then `ev=` and the event's fields. Seed bytes go through +`record::seed` as hex, as a SHA-256 fingerprint, or not at all. + +[`app::start_logging`](@ref dpf/run_log.hpp) turns it on and writes the +provenance banner first, at `info`: + +| Event | Contents | +| --- | --- | +| `ev=start` | program, cwd, UTC/local start, invocation id shared with `runs.csv` | +| `ev=build` | git rev (`LIBDPF_GIT_REV`), compiler, `NDEBUG`, ISA, sanitizers | +| `ev=host` | hostname, kernel, CPU model, affinity, governor, turbo, memory, load; `ev=if` per interface | +| `ev=argv` | shell-quoted command line | +| `ev=env` | `DPF_*` / `LIBDPF_*` and perf-relevant vars (`LD_PRELOAD`, …) | +| `ev=config` | every `run_config` setting | + +After that come seeds with their source, listeners and links (endpoints, peer +authentication, encryption, applied socket options, kernel RTT), each party's +plan and costs, trial statistics, and failures. `ev=end` at exit gives elapsed +time. The settings are `run_config` keys: + +``` +DPF_LOG_LEVEL=debug DPF_LOG=file:/tmp/run.log,stderr DPF_LOG_SEEDS=hash +--log_level=debug --log=syslog --log_seeds=off +``` + +Levels are `silent`, `error`, `warning`, `info` (the default), `debug`, and +`trace`. With `log_seeds=full` the log holds every master, so anyone who has +the file can regenerate that party's randomness. `hash` prints a SHA-256 +fingerprint instead. + +## Replayable seeds + +```cpp +dpf::experiment ex("keyword_pir"); // fresh 32-byte master +auto master = ex.seed(); // record for the paper +auto x = dpf::uniform_sample(); + +auto again = dpf::experiment::replay("keyword_pir", master); +assert(dpf::uniform_sample() == x); +``` + +While the experiment is installed, every `uniform_fill` / `uniform_sample` +draw on that thread (DPF roots, Beaver default sampler, pads, Shamir, IKNP, +field rejection) comes from AES-CTR of the master. The master itself is always +drawn from OS entropy, even when nested under another experiment. + +Constructors that already own a seed note it automatically: + +| Type | Seed name | +| --- | --- | +| (master) | `master` | +| `beavers::oracle` | `beavers::oracle` (+ `lane_table`) | +| `buffered_prg` | `buffered_prg` | +| `prg_pad_rng` | `prg_pad_rng` | +| `pseudorandom_root_sampler` | `pseudorandom_root_sampler` | + +Call `ex.note_seed("label", value)` for anything else. Replay is +**order-sensitive**: the same party must make the same `uniform_sample` calls. +Indexed `beavers::oracle(seed)` stays the seekable Beaver path; its seed still +appears in the report when constructed under the experiment. + +## Measuring a compose plan {#statistics} + +```cpp +auto plan = dpf::protocol::fss_point_plan(0); +auto ex = dpf::app::measure_plan("fss_point", plan); +ex.write_csv("/tmp/run1"); +``` + +Or from an application sketch: + +```cpp +// Prints rounds, live bytes, wall/CPU, PRG evals, random bytes, seed hex. +// Set DPF_EXPERIMENT_DIR=/tmp/run1 to also emit CSVs. +dpf::app::run_measured("keyword_pir", + dpf::protocol::keyword_pir_compose_plan(0, depth), 2); +``` + +What is recorded: + +| Metric | Source | +| --- | --- | +| Interactive rounds / DAG depth | `plan::exchange_waves()` / `plan::waves()` | +| Critical path | back-walk of max-`wave_of` inputs | +| Schedule bytes per edge | `slot_bytes` + `wave_channel` | +| Bytes out/in per round | the round's send and receive slots, on its own channel | +| Wall / CPU | `steady_clock` / party 0's thread CPU plus its pool kernels' CPU | +| Symmetric-key blocks | `prg::count(purpose, primitive)` per thread | +| Random bytes | `uniform_fill` TLS counter | +| Seeds | master + every `note_experiment_seed` | + +Symmetric-key blocks are counted by purpose and primitive. The purposes are +`expand` (tree expansion, leaf conversion, label and column PRGs), `hash` +(IKNP row hashes, garbled-gate hashes), and `harness` (the experiment's own +seed stream). The primitives are AES-128, AES-256, ChaCha, and LowMC. +`prg_evals` is `expand` plus `hash` over every primitive. Harness blocks are +never part of it. The counters are per thread; a kernel a party hands to a +compute pool (`compute_threads > 0`) is charged to that party when it returns +([`dpf/thread_work.hpp`](@ref dpf/thread_work.hpp)). + +## CSV layout + +`write_csv(dir)` appends. Every row ends with the id of the process that +wrote it (`invocation`), so rows from different runs into one directory stay +apart. A file whose header differs from this layout is renamed to +`.before-.csv` before new rows go in. + +- `summary.csv` — one row per run, including `master_seed` hex. `wall_ns`, + `cpu_ns`, and the counters come from the last (instrumented) trial; + `median_ns` and `slowest_median_ns` are medians over the timed trials for + party 0 and for the slowest party. +- `rounds.csv` — per-round deltas and edge name +- `edges.csv` — protocol totals per peer / rss_next / dealer +- `seeds.csv` — every noted seed as hex +- `critical_path.csv` — node id, wave, opcode, effect +- `config.csv` — every `run_config` setting +- `trials.csv` — every party's wall time for each timed trial +- `wire.csv` — party 0's link counters, headers included +- `sym.csv` — symmetric-key blocks by purpose and primitive +- `runs.csv` — the invocation id that ties rows to the run log, and whether + the master was fresh, provided, or derived + +Before any party starts its clock, all parties wait at a start gate until +every one has finished setup. + +## The battery + +The harness is `party_bench` and `profile_party`. Both spawn `p0`, `p1`, and +`p2` and dial [`net::trio`](@ref dpf/net/trio.hpp), the library's localhost +mesh (`p0-p1`, `p0-p2`, `p1-p2`). A flow's bytes and rounds are the frames on +that mesh. The repeat barrier is not included. + +``` +party_bench --tag bench --repeat 3 --warmup 1 +party_bench --case arith_mul_p11 --repeat 5 +profile_party --suite gadget --repeat 3 --warmup 1 +``` + +`--tag bench` is the default list. The gadget rows are tagged `bench` as well, +so they sit on that list. `profile_party --suite gadget` runs only those rows. +`profile_party --suite all` appends them after the core and extreme suites. + +A secret index stays a DPF. The gadget rows time what you do after a key, or +on shares the parties already hold: + +- `arith_proj_*`, `arith_mul_*`, `arith_thresh_*`, `arith_chain_mul4` — + Ball–Malkin–Rosulek word garbling. Party 0 sends the evaluator view on the + p0–p1 link. Party 1 evaluates that view and opens. +- `yao_if_*`, `yao_onehot_*` — stacked and one-hot garbling on the garbler. + The active branch's tables and the evaluator's labels go across the p0–p1 + channel, and party 1 evaluates those bytes. Base OT stays on the `iknp` tag. +- `flute_d*` — FLUTE. Party 2 deals the mask shares. Parties 0 and 1 exchange + the online bits and open. +- `shuffle_n*` — three hidden-shuffle passes. Each pass's array is sent on + the ring and consumed as the next party's inbound. Party 0 opens the sum. + +Sizes are the modulus, the branch width, the table width, and the column +length. The manual pages are [a small word](@ref arith_garble_word), +[a public table](@ref flute_lut), [a secret branch](@ref yao_stack), and +[an array of shares](@ref share_shuffle). + +See also [Network, parties, and MPC](@ref network_and_mpc), +[Protocol composition](@ref protocol_compose), and the +[application mockups](@ref applications). diff --git a/doc/pages/guided_tour.md b/doc/pages/guided_tour.md index 7dca21f..54028db 100644 --- a/doc/pages/guided_tour.md +++ b/doc/pages/guided_tour.md @@ -19,7 +19,12 @@ A *distributed point function* (DPF) is a way to share it with short keys. `libdpf++` builds those keys and evaluates them quickly in C++17. People use DPFs for private lookup (PIR), multi-party computation (MPC), -and other privacy tools. See also the [ideal functionalities](@ref ideal_functionalities) +and other privacy tools. This tree also ships the **network and MPC stack** +those protocols need: TLS party sessions, RoundSink rounds, Beaver / Yao / +arithmetic shares on leaf values, composition, leveled run logs, and +paper-cost statistics. That map is [Network, parties, and MPC](@ref network_and_mpc); +logging and CSVs are [Logging, statistics, and experiments](@ref experiment_costs). +See also the [ideal functionalities](@ref ideal_functionalities) for what each protocol is allowed to learn. ## Prior work {#tour_prior} @@ -87,8 +92,8 @@ auto [k0, k1] = dpf::make_dpf(X{1000}, std::uint64_t{1}); Width literals sit next to those types: `100_u12` (`modint`), `7_x12` (`xint`), `dpf::literals::operator""_bitstring`, and `1.5_fixed16` through -`_fixed64`. `dpf::bit`, `dpf::twobit`, and `dpf::nyble` are outputs, not -domains. See [Input types](@ref input_types). +`_fixed64`. `dpf::bit`, `dpf::twobit`, `dpf::nyble`, and `dpf::gf2` through +`dpf::gf264` are outputs, not domains. See [Input types](@ref input_types). ## Outputs: what sits at that point {#tour_outputs} @@ -102,6 +107,7 @@ Many outputs can share one leaf when they fit. | `dpf::bit` | One XOR bit, packed | [bit.hpp](@ref dpf/bit.hpp) | | `dpf::twobit` | Z/4Z, packed 2-bit lanes | [twobit.hpp](@ref dpf/twobit.hpp) | | `dpf::nyble` | Z/16Z, packed nibbles | [nyble.hpp](@ref dpf/nyble.hpp) | +| `gf2` … `gf264` | GF(2^k), XOR add, field multiply | [gf2.hpp](@ref dpf/gf2.hpp) | | `dpf::bitstring` | XOR string | [bitstring.hpp](@ref dpf/bitstring.hpp) | | `grotto::fixedpoint` | Fixed-point raw word | [fixedpoint.hpp](@ref grotto/fixedpoint.hpp) | | `dpf::vec` | `N` lanes, no carry between them | [vec.hpp](@ref dpf/vec.hpp) | @@ -109,7 +115,7 @@ Many outputs can share one leaf when they fit. | `field64` / `field128` | Prime fields | [field64.hpp](@ref dpf/field64.hpp) | | `fp61` | Field for 3-party DPFs | [fp61.hpp](@ref dpf/fp61.hpp) | | `p256` / `p256_scalar` | Curve and order | [p256.hpp](@ref dpf/p256.hpp) | -| Typed shares | (2,2) additive and subtractive, (3,3) additive, (2,3) replicated | [secret_share.hpp](@ref dpf/secret_share.hpp) | +| Typed shares | (2,2) additive and subtractive, (3,3) additive, (2,3) replicated, (K,N) Shamir | [secret_share.hpp](@ref dpf/secret_share.hpp), [shamir.hpp](@ref dpf/shamir.hpp) | ```cpp auto [k0, k1] = dpf::make_dpf( @@ -118,6 +124,12 @@ auto [k0, k1] = dpf::make_dpf( // assign the payload later; eval before assign throws ``` +Shamir shares are `shamir::share`. Any `K` of `N` open the +constant term. `(2,3)` is `shamir_share`. The fields are `fp61` and `gf2n`. +For `gf2n`, `N` must be less than `2^k`. `make_dpf3` uses the `(2,3)` case +on `fp61`. `examples/mwe/shamir.cpp` deals a `(3,5)` secret in `fp61` and a +`(2,3)` secret in `gf28`. + Packed output literals are `1_bit`, `2_twobit`, and `10_nyble`. `dpf::vec` is `N` lanes of an ordinary output with no carry between lanes; the construction is on [Output types](@ref output_types). @@ -216,6 +228,10 @@ or zip two parties' buffers. ## Comparisons and ranges {#tour_dcf} +\htmlonly +
ELI5. A comparison key is not a single spike. It returns the true payload on one side of the secret point and the false payload on the other, and the shares add instead of subtract. An interval key packs the two endpoint comparisons into one key. idcf repeats a correction at every depth; cmp_prefix stops after L bits.
+\endhtmlonly + A *distributed comparison function* (DCF) returns a payload when a predicate holds on the secret point. The four predicates are `dpf::lt`, `dpf::leq`, `dpf::gt`, and `dpf::geq`. Each takes the true payload and an optional false @@ -284,6 +300,10 @@ ideal figures [F_DCF](@ref dcf.hpp), [F_BDCF](@ref blocked_dcf.hpp), [F_IC](@ref ## Verifiable and extractable keys {#tour_vdpf} +\htmlonly +
ELI5. verifiable carries an extra seed on each correction word and folds it into one proof token. Equal tokens across parties mean the seeds were the honest ones. extractable is a separate weight-1 sketch in fp61: any second hot point fails it. output_mac authenticates the opened leaf, not the path.
+\endhtmlonly + Pass `dpf::verifiable{}` or `dpf::extractable{}` as an extra `make_dpf` argument. `verifiable` follows de Castro and Polychroniadou, EUROCRYPT 2022 ([ePrint 2021/580](@ref bib_vdpf)): one extra correction seed per level (their hash @@ -308,6 +328,10 @@ auto [e0, e1] = dpf::make_dpf(std::uint8_t{42}, std::uint64_t{7}, ## Many points at once {#tour_multipoint} +\htmlonly +
ELI5. The m secret points are placed in cuckoo buckets with three hashes, one ordinary point key per bucket, so the key grows with m and not with the domain. Evaluation probes the three buckets that could hold the query. One verifiable tag is a single proof for the whole set.
+\endhtmlonly + `make_multipoint(alphas, betas)` packs many points into cuckoo buckets, following de Castro and Polychroniadou, EUROCRYPT 2022, §4 (ePrint 2021/580): `κ = 3` hashes, one point key per bucket. @@ -326,6 +350,10 @@ auto [k0, k1] = dpf::make_multipoint(alphas, betas); ## A vector with one programmable coordinate {#tour_ppvc} +\htmlonly +
ELI5. Commit binds both roots of each aligned 1-bit DPF pair under a Naor string, before anyone chooses the coordinate. Open reveals one side of each pair, which writes that coordinate or the sum of the vector onto a public index. verify checks the opened roots against the committed strings.
+\endhtmlonly + `dpf::ppvc` commits to a vector in `(Z/2^s Z)^n` before the hidden coordinate is chosen. The commitment binds both roots of `s` aligned 1-bit DPF pairs. Opening one side of each pair writes that coordinate, @@ -343,6 +371,10 @@ const auto op = scheme::open(st, 0, 0x5a, std::uint8_t{40}); ## Tree shapes: classic and Half-Tree {#tour_trees} +\htmlonly +
ELI5. The default key is the CCS 2016 layout: one correction word per level, with the last few levels packed into the leaf when the output group is small. Half-Tree keeps that key shape and changes the expand to H(s) and H(s) XOR s, which is about half as many permutation calls. Section 5.2 of that paper is a different thing: two-party keygen in the COT/OLE hybrid, which this generator does not use.
+\endhtmlonly + The default interior PRG walks a Boyle–Gilboa–Ishai tree (CCS 2016, full version [ePrint 2018/707](@ref bib_fss2018)). Select `prg::aes128_ccr` as the *interior* PRG to use Half-Tree expands @@ -358,6 +390,10 @@ about `4n`, and `1.5N` calls for a full-domain evaluation versus `2N`. ## Two-party keygen without a dealer: Doerner–Shelat {#tour_ds} +\htmlonly +
ELI5. Each party holds a share of the index and neither sends the index. Level by level they open a masked correction word. The key that comes out is the same object a dealer would have built with make_dpf. geneval uses the same opening on one public query and does not return a reusable key.
+\endhtmlonly + Two parties hold XOR (or additive) shares of `alpha`. A third party deals pads and learns nothing. The result matches what an honest `make_dpf` would emit. @@ -410,6 +446,10 @@ a round of its own beyond that split. ### Two-party socket walk without p2 (IKNP) {#tour_iknp} +\htmlonly +
ELI5. IKNP turns a few slow base oblivious transfers into a long tape of correlated pads. Those pads stand in for the dealer in the Doerner–Shelat walk. The base OTs are Chou–Orlandi on P-256. When a level must stay hidden, the hash is the Boyar–Peralta AES S-box: 32 ANDs per block, which is why an oblivious tape is much longer than a reveal tape.
+\endhtmlonly + When there is no pad dealer, p0 and p1 sample the same Doerner–Shelat pad correlations with semi-honest OT extension after Yuval Ishai, Joe Kilian, Kobbi Nissim, and Erez Petrank, CRYPTO 2003 (`dpf::iknp::sample`), @@ -482,6 +522,10 @@ party mesh [trio.hpp](@ref dpf/net/trio.hpp). ## Multiplication and circuits: Beaver {#tour_beaver} +\htmlonly +
ELI5. Preprocessing gives every wire a blind. To multiply, the parties open the two inputs masked by those blinds, then fix the product with a local correction. A later gate reuses blinds it already holds and only samples new monomials. A MAC is a second share of the same width, checked in batch.
+\endhtmlonly + ABY2.0-style sessions open masked wires once, following Patra, Schneider, Suresh, and Yalame, USENIX Security 2021 (full version [ePrint 2020/1225](@ref bib_aby2)). A fresh triple follows Donald Beaver, [CRYPTO 1991](@ref bib_beaver), which reconstructs @@ -497,12 +541,75 @@ A later round reuses blinds it already holds and samples only the new monomials. The dealer keeps each full blind; the parties receive the additive splits. +A word that has already left the key can be added and projected in one shot +([a small word](@ref arith_garble_word)). A public table on a short masked +index is [FLUTE](@ref flute_lut). A secret point in a public table stays a +DPF. The session above is still the interactive product. + **Go deeper:** [beaver.hpp](@ref dpf/beaver.hpp), [F_Beaver](@ref beaver.hpp), [F_BeaverAuth](@ref beaver.hpp), [constrained_cmp.hpp](@ref dpf/constrained_cmp.hpp) for `F_CCMP`. +## A column of shares {#tour_shuffle} + +The secret position in this library is a key. One cell of a shared array is +a unit DPF, a public rotate, and a dot product +([Duoram](@ref app_duoram)). + +A hidden shuffle is what you do when you already hold every row and you are +about to open the column. Three passes, from the pairwise seeds `k01`, +`k12`, and `k20`, leave one party out of each permutation. The opened order +is not the stored order, and no single party can recompute it. +`shuffle_hidden_pass` is one party's step. `shuffle_party` is the other +helper: one permutation from `k01`, which every holder of that seed can +recompute. + +The shuffle does not look up a cell, and it does not sort. Those stay a DPF +and a DCF. + +**Go deeper:** [An array of shares](@ref share_shuffle), +[shuffle.hpp](@ref dpf/shuffle.hpp). + +## When the leaf is a circuit {#tour_yao} + +\htmlonly +
ELI5. Eval already gave you a share of the leaf. If the next step is a bit circuit the key does not contain, split that share into XOR bits, garble the circuit, and share the answer back as a leaf.
+\endhtmlonly + +A point leaf is subtractive, so the split is `b2y` and the return is `y2b`. +A comparison leaf is additive, so the split is `a2y`. An `fss_share` opens +like a point leaf. Parties 0 and 1 garbling a replicated leaf use `rss2y`; +party 2 does not send. The bits are least-significant first. Both shares +are arguments to the conversion. The masked `x - r` that A2B opens is uniform. + +The netlist is XOR, AND, XNOR, and NOT. Party 0 garbles with half-gates +([ePrint 2014/756](@ref bib_halfgates)): 32 bytes per AND, one message, XOR +shares out. The block this is for is `yao::aes_mmo`, the same zero-key +Matyas–Meyer–Oseas block `prg::aes128::eval` uses on a tree expand, 5120 +ANDs. AES-128 under a shared key is the other packaged netlist, 6400 ANDs. +The Doerner–Shelat oblivious hash still evaluates that S-box as GMW layers +in [the dealer-free section](@ref tour_ds). `aes_mmo` is one of those blocks +in constant rounds, for a leaf or a seed you already hold as bits. + +A comparison, an interval, a public-offset polynomial, and a product of +two leaves do not come here. Those are a key, Grotto, or one Beaver open. +`cost_pass` does not grow a Yao strategy for them. + +A secret if/else or a menu of blocks on those bits is stacked garbling +([a secret branch](@ref yao_stack)). The transmitted rows follow the heavier +block. The leaf is still split in and shared back out. A comparison stays +on the key. + +**Go deeper:** [A boolean function of a leaf](@ref yao_leaf), +[yao.hpp](@ref dpf/yao.hpp), [yao_share.hpp](@ref dpf/yao_share.hpp), +[F_Yao](@ref yao.hpp), [F_YaoShare](@ref yao_share.hpp). + ## Three evaluators {#tour_dpf3} +\htmlonly +
ELI5. make_dpf3 gives each of three parties a pair of two-party keys, and the payload is a Shamir share in fp61, so any two evaluation shares open the value and one share is independent of it. make_it_dpf3 is not that object: each party holds an additive share of a length-256 table, and the three shares sum to the point function.
+\endhtmlonly + `(2,3)` point keys follow Zyskind, Yanai, and Pentland, [ePrint 2024/1658](@ref bib_dpf3), Figure 3: each evaluator key is a pair of `(2,2)`-VDPF+ keys. Each key is a Shamir share in `fp61`. @@ -554,6 +661,10 @@ three `eval_it_dpf3` values is the point function. See ## Grotto: math after a public offset {#tour_grotto} +\htmlonly +
ELI5. The parties open the public distance eta = x − r. A polynomial, a binomial jet, a carry, or a table lookup is then a correction of shares they already have. That correction does not walk another DPF.
+\endhtmlonly + Open `eta = x - r`. Then cheap public corrections give rich functions of `x` without another tree walk. @@ -567,7 +678,8 @@ without another tree walk. | Twisted jets | `c^m \lambda^c`, including dyadic `1/2` | | Carry | Truncate, arithmetic shift, extend on shared limbs | | Prefix parity | XOR or signed prefix sums along a key | -| LUTs | Constant, easy, dyadic, range, window, principal | +| LUT union | Several piecewise tables on one comparison and one prefix walk | +| LUTs | Constant, easy, dyadic, range, window, principal, Haar and bior(5,3) | | Closed form / exact steps | Compositions and digit or bit counts | | `fixed_mul` | Fixed-point product into a chosen width | @@ -599,8 +711,15 @@ local fixed-width arithmetic (`fixed_mul` uses at most 8 limbs). Carry keys are one comparison per live recipe flag, on the limb width, plus one Beaver bit-opening when the recipe multiplies share MSBs. Prefix parity on `m` endpoints is one resumed path walk, `O(m n)` expands in -the worst case; that walk follows [ePrint 2023/108](@ref bib_grotto). The degree-0 exact -LUTs follow Appendix D of the same paper. Other LUT calls are a knot +the worst case; that walk follows [ePrint 2023/108](@ref bib_grotto). +Several piecewise LUTs share one such comparison: +[make_lut_union_plan](@ref grotto/lut_union.hpp) unions their breakpoints, +and [schedule_lut_union](@ref grotto/lut_union.hpp) is one `fss_cmp` of +`n` rounds. The prefix walk over the union is local. +The degree-0 exact +LUTs follow Appendix D of the same paper. Haar and bior(5,3) tables +compress a uniform grid and evaluate in \f$\Theta(1)\f$ arithmetic +([ePrint 2025/013](@ref bib_wave)). Other LUT calls are a knot search plus a constant-size Horner; exact steps loop over the word. Detail is on the Grotto pages. @@ -618,17 +737,55 @@ Ship keys over ASIO peers with `dpf::asio::make_dpf`. ## Running protocols {#tour_party} +The overview of links, composition, leaf MPC, and measurement is +[Network, parties, and MPC](@ref network_and_mpc). + The `party/` programs run a three-role mesh (`p0`, `p1`, dealer `p2`). Flows cover Beaver, geneval, DCF, DPF3, Grotto, and adversarial checks. Use `--list` and `--tag` to filter. +Composed protocols record strands on a `dpf::protocol::composer` +([compose.hpp](@ref dpf/compose.hpp)). Values are tagged with a share +domain (`fss`, `a`, `b`, `rss`, `y`). An FSS leaf consumed by an ABY2.0 +product gets a local `b2a` (or `fss2a`) inserted by `as`, and the leaf stays +on the beaver barrier's critical path so Duoram / SUBLEQ scale cannot float +before the walk. Like blinds and expansions are interned across sub-strands, +and independent opens share one RoundSink round. Party-count changes use an +explicit `reshare` (`rss_from_y` for y→rss). Composer-owned Beaver sessions use +`beavers::schedule_objective::rounds` so sign×polynomial stays one online +round; dealer benches that want Appendix-E peels keep the default `prep` +objective. Express/Sabre-style audits use `fss_point_fused` / +`level_walk_fused` so the sketch rides in the last CW flush. +BGI early-stop is `fss_point_early_stop`; Poplar checkpoints are +`level_walk_prefixes`; DCF `block_width` sizes are `level_walk_sized`. +Doerner–Shelat is `level_walk_ds` / `level_walk_ds_sized` (OH AND-layers +match `ds_oh_exchanges_per_level`); adaptive idpf_agg is staged +`step_adaptive_prefix` → drive tail (`from_exchange_wave`) → +`retain_adaptive_prefix`; keyword PIR buckets are `multipoint_fan`; +multi-lane ABY is `aby_lane`; prepaid SUBLEQ expands are `defer_expand`. +Party drivers use `util::drive_composed` / `util::drive_composed_trio` on +`composer::default_plan()` with `u64_beaver_host` or +`u64_auth_beaver_host`. A client/server query is `client_servers` +(one upload, one answer). Many instances with uneven stalls are +`dpf::app::run_fleet`: a worker parks instead of spinning and runs +whichever side can still submit. Cross-party reshare is `reshare_with_mask`; +pads are `dealer_deliver`; extra payloads share a round via +`exchange_fuse`; occupied cuckoo buckets are `schedule_cuckoo_probes`. +The full API and what stays outside compose are +[Protocol composition](@ref protocol_compose). + **Go deeper:** [trio.hpp](@ref dpf/net/trio.hpp), +[compose.hpp](@ref dpf/compose.hpp), `party/registry.hpp` (in-tree). ## Suggested reading order {#tour_order} 1. [First program](@ref basics), then this tour if you want the map in prose. -2. [Capabilities](@ref capabilities): verifiability, programmability, comparisons, multipoint, three servers, dealer-free keygen, Beaver, Grotto. +2. [Capabilities](@ref capabilities) for key features; [Network, parties, and MPC](@ref network_and_mpc) for the runtime; [Logging, statistics, and experiments](@ref experiment_costs) for the run log and CSV costs. 3. [Domains](@ref input_types) and [Payloads](@ref output_types). 4. [Evaluation](@ref evaluation) and the [code examples](@ref listings). 5. [Application sketches](@ref applications). + +\htmlonly +
TL;DR. Point keys are make_dpf: subtract to open, one correction word per level, early-stop packing when the output is small. Comparisons and intervals add instead of subtract. verifiable, extractable, and cuckoo multipoint share one paper (ePrint 2021/580). Dealer-free keygen is the Doerner–Shelat opening, with IKNP pads when nobody deals them. Three parties are either Shamir spines (any two open) or an information-theoretic table (all three add). After a public offset, Grotto corrects polynomials, carries, and tables without another walk. Live runs use the party mesh, composer, Beaver/Yao/arith on leaves, start_logging, and experiment CSVs — see Network & MPC and Logging & statistics.
+\endhtmlonly diff --git a/doc/pages/input_types.md b/doc/pages/input_types.md index 23eaf46..0bcd3d2 100644 --- a/doc/pages/input_types.md +++ b/doc/pages/input_types.md @@ -1,3 +1,5 @@ + + An *input type* is the domain of the secret index. Shorter domains make shorter keys and faster walks. Prefer `std::uint16_t` over `unsigned short` so the depth is obvious. @@ -52,7 +54,8 @@ Three names cover every integer width: in `GF(2)^N`. See `xor_wrapper` below. `dpf::bit`, `dpf::twobit`, and `dpf::nyble` are packed output lanes of width -1, 2, and 4. They are not domains. A domain of that width is `modint<1>`, +1, 2, and 4. `dpf::gf2`, `gf22`, and `gf24` are the same widths in GF(2^k). +They are not domains. A domain of that width is `modint<1>`, `modint<2>`, or `modint<4>` (or the matching `xint`). **See also**\n @@ -70,7 +73,6 @@ and [Output types](@ref output_types) for the packed lanes.
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 @@ -93,6 +95,9 @@ to declare such 128-bit integers in compiler-independent way.
dpf::modint<Nbits> +\htmlonly +
ELI5. modint<N> is an integer modulo 2^N. The DPF depth is N, not the width of the integer stored underneath. Arithmetic uses that underlying integer and masks on read, so it is as fast as the raw word and still wraps at N bits.
+\endhtmlonly Arbitrary-, yet fixed-bitlength unsigned integer types. `dpf::modint` is a lightweight class template that adapts one of the above-mentioned integer @@ -127,7 +132,6 @@ Here are some examples of arithmetic operations with `dpf::modint`:
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 @@ -162,7 +166,6 @@ shortest length -- and with the fastest evaluations -- possible.
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 @@ -175,6 +178,7 @@ internal representation. This produces representations that are when `alphabet` comprises few elements. For example + \code{cpp} const char cstr[] = "7fffae02"; std::cout << (sizeof(cstr) - 1) * CHAR_BIT << "\n"; // prints 64 @@ -218,6 +222,9 @@ The `dpf::alphabets` namespace for a catalog of predefined alphabets.
dpf::xor_wrapper<T> +\htmlonly +
ELI5. The group operation is XOR of the underlying word, not addition. A domain of this type walks the bits in GF(2)^N. A leaf of this type opens by XORing the two shares.
+\endhtmlonly 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 @@ -246,7 +253,6 @@ when the index is an ordinary integer of the same width.
dpf::keyword2<Pattern> - A ranked string whose language is a static pattern. `dpf::keyword2` is the replacement for `dpf::keyword`: the pattern is the type, and each accepted string has one rank in `0 .. |L|-1`. That rank is the DPF input. The type @@ -290,6 +296,9 @@ auto [k0, k1] = dpf::make_dpf(alpha, std::uint64_t{1});
grotto::fixedpoint<FractionalBits, IntegralType> +\htmlonly +
ELI5. The value is an integer with a public split between integer bits and fraction bits. Leaf addition is integer addition of the raw word. It does not shift the binary point.
+\endhtmlonly A fixed-point value stored in an integer backend. `FractionalBits` is the number of bits after the binary point. `IntegralType` defaults to @@ -323,6 +332,9 @@ auto [k0, k1] = dpf::make_dpf(half, std::uint64_t{1});
dpf::wildcard_value<T> as a domain +\htmlonly +
ELI5. Keygen plants a random mask instead of the index. The parties later open mask − alpha, not alpha. Until that offset is reconstructed, evaluation throws.
+\endhtmlonly A wildcard input defers the secret index. `make_dpf(dpf::wildcard_value{}, beta)` plants a random mask in each key's `offset_x`. The public value the parties later open is `mask - alpha`, not `alpha`. @@ -352,7 +364,6 @@ auto [k0, k1] = dpf::make_dpf(dpf::wildcard_value{}, std::uint32_t
Custom input type requirements - A type can be a DPF input when the library can walk its bits and, for interval or full-domain evaluation, order its values. @@ -392,3 +403,7 @@ template <> struct mod_pow_2 { } \endcode
+ +\htmlonly +
TL;DR. Shorter domains make shorter keys. Use a fixed-width integer when it fits, modint or xint for any other width up to 256, and bitstring or keyword when the index is not a number. bit, twobit, and nyble are payloads, not domains. A wildcard index is filled in after keygen.
+\endhtmlonly diff --git a/doc/pages/introduction.md b/doc/pages/introduction.md index af1192b..78a68b3 100644 --- a/doc/pages/introduction.md +++ b/doc/pages/introduction.md @@ -1,5 +1,5 @@ \htmlonly -

libdpf++ is a header-only C++17 library of distributed point functions: short keys that hide one secret index, then answer at public points as secret shares.

+

libdpf++ is a header-only C++17 library of distributed point functions: short keys that hide one secret index, then answer at public points as secret shares. The same tree ships a TLS party mesh, round scheduling, MPC on those leaf shares, leveled run logs, and paper-cost statistics — so readers do not have to dig the API to find them.

What it does

+

Around the keys

+

Live parties, composition, MPC on leaf shares, logging, and statistics — first-class, not buried in the reference.

+ \endhtmlonly diff --git a/doc/pages/iterables.md b/doc/pages/iterables.md index a5cdf16..0a35845 100644 --- a/doc/pages/iterables.md +++ b/doc/pages/iterables.md @@ -158,3 +158,7 @@ grotto::offset_iterable shifted(knots.begin(), knots.end(), 10); **Defined in**\n @ref grotto/offset_iterable.hpp + +\htmlonly +
TL;DR. eval_interval and eval_full walk a subinterval; eval_sequence walks the listed points. indices_set_in, advice_bits_of, batch_of, tuple_as_zip, and rotated_by only change the step. None of them copy the buffer.
+\endhtmlonly diff --git a/doc/pages/jet_and_ring.md b/doc/pages/jet_and_ring.md index c9e743d..495591f 100644 --- a/doc/pages/jet_and_ring.md +++ b/doc/pages/jet_and_ring.md @@ -12,6 +12,10 @@ The same offset also drives [offset Horner](@ref offset_horner), ## Binomial jet {#offset_jet} +\htmlonly +
ELI5. The dealer keys the binomial coefficients of (center + eta) up to a chosen degree. After eta is public, a dot with those shares is the monomial or the polynomial, with no further tree walk.
+\endhtmlonly + `make_offset_jet_keys(center, degree)` keys one incremental `gt` whose payload is the vector of \f$\binom{\mathrm{center}}{k}\f$ in \f$\mathbb{Z}/2^{64}\f$. After `eta` opens, @@ -61,6 +65,10 @@ one reciprocal after the shares are opened. Those are not separate APIs. ## Exact ring switch {#ring_switch} +\htmlonly +
ELI5. An n-bit limb is rewritten into another modulus, a field, or a P-256 scalar by an exact map on the opened residue. The value does not go through floating point, and the map does not expand another key.
+\endhtmlonly + For an unsigned \f$n\f$-bit limb (\f$n\le 64\f$) with representatives in \f$[0,2^n)\f$, @@ -117,6 +125,10 @@ See also [representation shift and twisted jets](@ref repr_and_twist). ## Offset Horner {#offset_horner} +\htmlonly +
ELI5. Powers of a public center are already shared. Shifting them by the opened eta, the binomial way, evaluates the polynomial at the secret. The degree here is fixed in the template.
+\endhtmlonly + `make_offset_horner_keys(center)` keys one `gt` whose payload is `center^m` for `m = 0 .. Degree`. `Degree` is at most 3 (`offset_horner_max_degree`). Pass `dpf::verifiable{}` for proof tokens. @@ -147,6 +159,10 @@ reusable key. ## Offset polynomial {#offset_poly} +\htmlonly +
ELI5. Same shift as offset Horner, but the degree is an argument, so the number of powered shares is chosen when the keys are built.
+\endhtmlonly + `make_offset_poly_keys(center, degree)` is offset Horner at a runtime degree, at most 16 (`offset_poly_max_degree`). One incremental `gt` whose payload is the vector of powers. `offset_poly_eval` dots the shifted powers. @@ -176,6 +192,10 @@ auto opened = s0 + grotto::offset_poly_eval<1>(mat, knots, coeff, eta); ## Carry {#carry} +\htmlonly +
ELI5. A carry across a shift is a short list of comparisons and bit corrections, not a generic circuit. The request names the source width, the shift, and the width of what comes out. Truncate, arithmetic shift, and sign-extend are the same plan with different output widths.
+\endhtmlonly + A `carry_request` names the source width `n`, the shift `s`, the output width `out_n`, a `carry_mode` (`truncate_reduce`, `same_ring`, `extend`, `window`), and a `sign_knowledge` (`unknown`, `nonnegative`, `negative`). @@ -210,6 +230,10 @@ auto clear = grotto::eval_carry_clear(keys.recipe, x0, x1); ## Prefix parity {#prefix_parity} +\htmlonly +
ELI5. One walk of an existing key stops at the public endpoints and folds XOR or addition along that prefix. The fold is O(number of endpoints), not a new key per prefix.
+\endhtmlonly + `prefix_parities(key, endpoints)` walks a key to the sorted endpoints and returns XOR shares of the prefix parities, plus the index of the first endpoint on the wrap. `segment_parities` turns those into one share per @@ -241,6 +265,67 @@ auto signs = grotto::signed_prefix_parities(cmp0, ends); **Defined in**\n @ref grotto/prefix_parity.hpp +## Several LUTs, one comparison {#lut_union} + +\htmlonly +
ELI5. Stack the breakpoints of every table into one sorted list. One comparison and one prefix walk label the pieces of that list. Each table then sums the labels that fall inside its own intervals.
+\endhtmlonly + +`make_lut_union_plan(luts, eta)` shifts every piecewise LUT by the public +`eta`, inserts the same domain-minimum and carry cuts as +[offset polynomial](@ref offset_poly), and sorts the union. A piece of one +LUT is a span of those union knots: `[begin, end)`, or +`[begin, end-of-union) ∪ [0, end)` when the piece wraps. The span stores +that piece's binomial shift by its public `kappa`. Spans of one LUT +partition the union. + +The interactive plan is one comparison, whatever the number of LUTs and +whatever the number of union knots: + +- `plan.comparisons` and `plan.prefix_walks` are 1. +- `plan.depth` and `plan.geneval_rounds()` are the bitlength of the input. +- `plan.degree` is the widest polynomial. The payload is + `1, center, …, center^degree`. +- `schedule_lut_union` records one `fss_cmp` of that depth. The slot is + `lut_union_slot_bytes`: one AES block, or `lanes * 8` when the power + vector is wider. Prefix parity of the union is local after that + comparison. + +`lut_union_eval` reads one `make_offset_poly_keys` key of degree +at least `plan.degree` and returns a share per LUT. `geneval_lut_union` +opens that comparison from XOR shares of the center, as in +`geneval_offset_horner`. Pass `dpf::arith_input` when the shares add to +the center in the input group. + +`piecewise_from_easy` and `piecewise_from_constant` adapt the cleartext +tables. An `easy_lut` denominator other than 1 is a rounding division, so +`piecewise_from_easy` rejects it. Powers that are zero on every piece are +dropped, and the shared payload stays only as wide as the widest remaining +degree. + +\code{cpp} +grotto::piecewise_lut low{{0, 10}, {{1, 0}, {0, 2}}}; +grotto::piecewise_lut high{{0, 4, 12}, {{3, 0}, {1, 1}, {9, 4}}}; +const std::uint8_t center = 12; +const std::uint8_t eta = 3; +auto plan = grotto::make_lut_union_plan({low, high}, eta); +auto mat = grotto::make_offset_poly_keys(center, plan.degree); +auto s0 = grotto::lut_union_eval<0>(mat, plan); +auto s1 = grotto::lut_union_eval<1>(mat, plan); +dpf::protocol::composer composer(0); +grotto::schedule_lut_union(composer, plan); // rounds == plan.depth +\endcode + +**Code samples**\n +
+ + - lut_union.cpp \include{cpp} grotto/lut_union.cpp + +
+ +**Defined in**\n +@ref grotto/lut_union.hpp + ## Cleartext maps {#grotto_luts} These functions take a raw fixed-point word (`n << fractional_bits`) and @@ -250,6 +335,10 @@ return a raw word. They do not build a DPF. The type ## Fixed-point product {#fixedpoint_mul} +\htmlonly +
ELI5. The product lives in a ring wide enough for both fixed-point operands. One Beaver triple in that ring is the product; the binary point is placed by a public shift afterward.
+\endhtmlonly + `fixed_mul(lhs, rhs)` multiplies two `fixedpoint` values and keeps that many integer bits (including the sign) and fraction bits. Bits below the fraction are floored. The product type @@ -267,6 +356,10 @@ auto prod = grotto::fixed_mul<16, 16>(q16{1.5}, q16{2.0}); ## Lookup tables {#lookup_tables} +\htmlonly +
ELI5. A cleartext approximation is replaced by a table addressed with the secret. Constant, easy, range, window, and principal tables differ in how many bits of the input they consume and how the correction is added.
+\endhtmlonly + Constant, easy, principal, range, and window tables are included from `grotto.hpp`. The dyadic table comes in through `exact_steps.hpp`, which `grotto.hpp` also includes. @@ -303,6 +396,8 @@ Constant, easy, principal, range, and window tables are included from (`principal_precision`). Names: `ln`, `exp`, `sin`, `tanf`, `tang`, `sinh`, `cosh`, `sqrt`, `coth`, `sec`, `gsec`, `csch`, `inv`, `rsqrt`, `invsq`. +- **Wavelet.** Haar and bior(5,3) compressed tables: + [Wavelet lookup tables](@ref dwt_luts). \code{cpp} auto sign = grotto::make_exact_constant_lut( @@ -368,6 +463,69 @@ picks the piece and calls that Horner step. @ref grotto/window_lut.hpp, @ref grotto/principal_lut.hpp, @ref grotto/piecewise.hpp +## Wavelet lookup tables {#dwt_luts} + +\htmlonly +
ELI5. A wavelet step is a fixed linear combination. The LUT stores that combination so the signal stays in shares and never enters a floating-point routine. Haar and biorthogonal 5/3 are the two filters.
+\endhtmlonly + +`make_haar_dwt_lut` and `make_bior53_dwt_lut` compress a real signal of +length \f$2^n\f$ and evaluate it as a fixed-point word. The construction +is the cleartext Haar and bior(5,3) lookup of Reis, Ugurbil, Wagh, Henry, +and de Vega, [ePrint 2025/013](@ref bib_wave), Equations (7) and (8). +`sample_dwt_signal(domain_bits, fractional_bits, f)` writes the grid +\f$i \cdot 2^{-f}\f$ for \f$i \in [0, 2^n)\f$. + +Both builders run the depth-\f$j\f$ low-pass with the smooth edge +extension used for that paper's accuracy tables. PyWavelets calls these +filters `haar` and `bior2.2`; bior(5,3) is the same pair, named there by +vanishing moments. Building either table is \f$\Theta(N)\f$ arithmetic +and extra memory, \f$N = 2^n\f$. + +Haar then multiplies the approximation coefficients by \f$2^{-j/2}\f$ +and rounds down to \f$f\f$ fraction bits. On this grid that coefficient +is the mean of each block of \f$2^j\f$ samples. Evaluation reads +`coeff[raw >> j]`, one indexing step, \f$\Theta(1)\f$. + +bior(5,3) multiplies by \f$2^{j/2}\f$ and rounds down the same way. +Smooth extension prepends two coefficients, so the bin `msb = raw >> j` +lives at index `msb + 2`, and the next tap at `msb + 3`, wrapping in the +stored vector. With `lsb = raw mod 2^j`, + +\f[ +y = \bigl\lfloor\bigl(c_{\mathrm{msb}+2}\,(2^j - \mathrm{lsb}) + + c_{\mathrm{msb}+3}\,\mathrm{lsb}\bigr) / 2^{2j}\bigr\rfloor. +\f] + +That is Equation (8): the Lemma 6 weights \f$(2^j - \mathrm{lsb}_j)\f$ +and \f$\mathrm{lsb}_j\f$, in integer arithmetic. Two multiplications and +a shift, \f$\Theta(1)\f$. + +The paper's online protocols look these tables up under a DPF. Haar is +paired there with a deterministic Pika truncation; bior(5,3) is paired +with segment parity. Those protocols are not a key type here. The value +they open is `table(raw)`. + +\code{cpp} +auto samples = grotto::sample_dwt_signal(6, 4, [](double x) { + return 1.0 / (1.0 + std::exp(-(x - 2.0))); +}); +auto haar = grotto::make_haar_dwt_lut(samples, 4, 2); +auto bior = grotto::make_bior53_dwt_lut(samples, 4, 2); +auto h = haar(std::uint64_t{32}); +auto b = bior(std::uint64_t{33}); +\endcode + +**Code samples**\n +
+ + - dwt_lut.cpp \include{cpp} grotto/dwt_lut.cpp + +
+ +**Defined in**\n +@ref grotto/dwt_lut.hpp + ## Closed form {#closed_form} `eval_closed(closed::atanh, fractional_bits, raw)` composes @@ -423,3 +581,7 @@ for a functor type. **Defined in**\n @ref grotto/gadgets.hpp, @ref grotto/gadget_hints.hpp + +\htmlonly +
TL;DR. Open eta = x − r once. Jets and Horner turn that public distance into polynomial powers. Ring switch and carry move the integer. Prefix parity folds a key you already hold. Lookup tables, including the wavelet tables, replace cleartext math. A fixed-point product is one Beaver triple.
+\endhtmlonly diff --git a/doc/pages/listings.md b/doc/pages/listings.md index 4c9717a..689b325 100644 --- a/doc/pages/listings.md +++ b/doc/pages/listings.md @@ -4,6 +4,7 @@ - \subpage output_type_examples - \subpage evaluation_examples - \subpage grotto_examples + - \subpage protocol_examples - \subpage iteratable_examples \page input_type_examples Domain samples @@ -17,24 +18,31 @@ - \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 Payload samples @@ -42,30 +50,42 @@ - \subpage output_types_2integral_types_8cpp - \subpage output_types_2extended_types_8cpp - \subpage output_types_2bit_8cpp + - \subpage output_types_2gf2_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_2gf2_8cpp" output_types/gf2.cpp + + \include{cpp} output_types/gf2.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 samples @@ -84,52 +104,84 @@ - \subpage evaluation_2eval_dpf3_cmp_ic_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_2defer_eval_8cpp" evaluation/defer_eval.cpp + \include{cpp} evaluation/defer_eval.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 "evaluation_2eval_inner_product_8cpp" evaluation/eval_inner_product.cpp + \include{cpp} evaluation/eval_inner_product.cpp \page "evaluation_2buffered_prg_8cpp" evaluation/buffered_prg.cpp + \include{cpp} evaluation/buffered_prg.cpp \page "evaluation_2eval_dpf3_point_8cpp" evaluation/eval_dpf3_point.cpp + \include{cpp} evaluation/eval_dpf3_point.cpp \page "evaluation_2eval_dpf3_doerner_shelat_8cpp" evaluation/eval_dpf3_doerner_shelat.cpp + \include{cpp} evaluation/eval_dpf3_doerner_shelat.cpp \page "evaluation_2eval_dpf3_cmp_ic_8cpp" evaluation/eval_dpf3_cmp_ic.cpp + \include{cpp} evaluation/eval_dpf3_cmp_ic.cpp \page grotto_examples Grotto samples - \subpage grotto_2jet_and_ring_8cpp - \subpage grotto_2repr_and_twist_8cpp + - \subpage grotto_2lut_union_8cpp + - \subpage grotto_2dwt_lut_8cpp \page "grotto_2jet_and_ring_8cpp" grotto/jet_and_ring.cpp + \include{cpp} grotto/jet_and_ring.cpp \page "grotto_2repr_and_twist_8cpp" grotto/repr_and_twist.cpp + \include{cpp} grotto/repr_and_twist.cpp + \page "grotto_2lut_union_8cpp" grotto/lut_union.cpp + + \include{cpp} grotto/lut_union.cpp + + \page "grotto_2dwt_lut_8cpp" grotto/dwt_lut.cpp + + \include{cpp} grotto/dwt_lut.cpp + +\page protocol_examples Protocol composition samples + + - \subpage protocol_2compose_schedule_8cpp + + \page "protocol_2compose_schedule_8cpp" protocol/compose_schedule.cpp + + \include{cpp} protocol/compose_schedule.cpp + \page iteratable_examples Iterable samples - \subpage iterables_2setbit_index_iterable_8cpp @@ -140,19 +192,25 @@ - \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 \ No newline at end of file diff --git a/doc/pages/multiparty.md b/doc/pages/multiparty.md index 90588f8..1624e6f 100644 --- a/doc/pages/multiparty.md +++ b/doc/pages/multiparty.md @@ -1,5 +1,9 @@ # Multiparty & 3-server {#multiparty} +\htmlonly +
ELI5. make_dpf3 is two ordinary spines per party and a Shamir payload, so any two parties open and the third key is independent of the value. make_it_dpf3 shares the whole truth table instead, and all three shares are required. Doerner–Shelat and geneval are the two-party, no-dealer alternatives.
+\endhtmlonly + Two-party keys are the default. The library also builds three-evaluator `(2,3)` keys, information-theoretic three-server DPFs, and dealer-free two-party keygen when the index is already shared. @@ -12,6 +16,13 @@ two-party keygen when the index is already shared. | [dpf::make_it_dpf3](@ref dpf/it_dpf3.hpp) | Information-theoretic 3-server DPF ([ePrint 2023/028](@ref bib_itdpf)) | `it_dpf3.hpp` | | [dpf::make_dpf_doerner_shelat](@ref dpf/doerner_shelat.hpp) | Two parties, shared index, no dealer for the point | `doerner_shelat.hpp` | | [dpf::geneval_*](@ref dpf/geneval.hpp) | Answer shares for one query, no reusable key | `geneval.hpp` | +| [dpf::shamir::deal](@ref dpf/shamir.hpp) | (K,N) Shamir. `(2,3)` is the `make_dpf3` payload | `shamir.hpp` | + +The payload inside `make_dpf3` is degree-1 Shamir on the points `1`, `2`, +and `3`. That access structure is `shamir::two_of_three`, the type +`shamir_share`. The same split takes other thresholds: +`shamir::deal` and `shamir::share_secret`. `make_dpf3` stays +`(2,3)`. See [secret shares](@ref secret_shares) and `examples/mwe/shamir.cpp`. ```cpp auto [k1, k2, k3] = dpf::make_dpf3(std::uint8_t{42}, dpf::fp61{7}); diff --git a/doc/pages/multipoint.md b/doc/pages/multipoint.md index cf0ce42..175b10d 100644 --- a/doc/pages/multipoint.md +++ b/doc/pages/multipoint.md @@ -1,5 +1,9 @@ # Multipoint keys {#multipoint_keys} +\htmlonly +
ELI5. Cuckoo hashing puts each secret point in one of a few buckets, with three hash functions and one point key per bucket. A query probes its three candidate buckets. Key size is linear in the number of points. The S&P 2025 PCG packing, which would derive those buckets from one seed, is not implemented.
+\endhtmlonly + `make_multipoint(alphas, betas)` packs many secret points into cuckoo buckets (de Castro–Polychroniadou, EUROCRYPT 2022, §4 / [ePrint 2021/580](@ref bib_vdpf)): `κ = 3` hashes, one point key per bucket. The bucket count is linear in diff --git a/doc/pages/network_and_mpc.md b/doc/pages/network_and_mpc.md new file mode 100644 index 0000000..369c573 --- /dev/null +++ b/doc/pages/network_and_mpc.md @@ -0,0 +1,92 @@ +# Network, parties, and MPC around the keys {#network_and_mpc} + +\htmlonly +
ELI5. The library is about DPFs first. The same headers also wire the parties together, schedule rounds, multiply and garble leaf shares, write leveled run logs, and emit paper-cost statistics — so a PIR or Duoram sketch does not start from bare sockets.
+\endhtmlonly + +Keys and evaluation are the core story. This page is the map of everything +that sits *around* those keys when you run a real protocol: links, party +roles, composition, arithmetic and boolean MPC on leaf shares, logging, and +cost instrumentation. Open a linked page for the details; the [call index](@ref api_reference) +lists the headers. + +## Network and party mesh + +| Piece | Role | +| --- | --- | +| [party_session](@ref dpf/net/party_session.hpp) | One role joins a mesh: dial/accept, lanes, reconnect, dealer link | +| [trio](@ref dpf/net/trio.hpp) | Convenience `(2+1)` mesh (`p0`, `p1`, dealer `p2`) | +| [TLS 1.3](@ref dpf/net/tls.hpp) / [security](@ref dpf/net/security.hpp) | Default on peer links; `--encryption=off` for plaintext benches | +| [RoundSink](@ref dpf/net/round_sink.hpp) / [edge_mesh](@ref dpf/net/edge_mesh.hpp) | Batched exchange rounds on star / clique / dealer topologies | +| [stream arrays](@ref dpf/net/stream_array.hpp) | Sync or async TCP (and optional SCTP) byte lanes | + +Processes may start in any order: lower ids accept, higher ids connect and +retry. After connect (or TLS handshake) both ends exchange a fixed hello so +mismatched party id, epoch, transport, or lane count fail at join time. + +```cpp +// Conceptual shape — see party_session / trio headers for the full API. +dpf::net::session_options opt; // TLS on by default +dpf::net::party_session session(/*role*/, opt); +session.join(/*host:port table*/); // or in-process rendezvous +auto & sink = session.round_sink(/*peer*/); +``` + +**Go deeper:** [trio.hpp](@ref dpf/net/trio.hpp), +[party_session.hpp](@ref dpf/net/party_session.hpp), +[secure_channel.hpp](@ref dpf/net/secure_channel.hpp), +examples under `examples/protocol/`. + +## Protocol composition + +[dpf::protocol::composer](@ref protocol_compose) records FSS walks, Beaver +opens, and reshares as one RoundSink plan. Share domains are tagged +(`fss`, `a`, `b`, `rss`, `y`); party-count changes are explicit `reshare`. +Independent opens share a wave; dependency chains become successive waves. + +Drive with `drive` / `drive_via_schedule`, or party helpers +`util::drive_composed` / `util::drive_composed_trio`. Named application +skeletons (PIR upload/answer, SUBLEQ, hushmap, …) live in +[app_plans.hpp](@ref dpf/app_plans.hpp). + +**Go deeper:** [Protocol composition](@ref protocol_compose). + +## MPC on leaf shares + +The DPF answers the secret index. What you do *with* the opened (or still +shared) leaf is ordinary MPC in the same library: + +| Tool | When you reach for it | +| --- | --- | +| [Beaver triples](@ref beaver_triples) | Products, dots, polynomials, optional MACs (ABY2.0) | +| [Arithmetic share runtime](@ref arith_runtime) | edaBits, truncate, share compare, matmul, hidden shuffle | +| [Yao on a leaf](@ref yao_leaf) | A boolean circuit the key does not contain; half-gates | +| [Dealer-free keygen](@ref dealer_free) | Doerner–Shelat / IKNP when nobody deals the pads | +| [Multiparty & 3-server](@ref multiparty) | `(2,3)` Shamir spines or IT three-server tables | + +**Go deeper:** those capability pages, then the [guided tour](@ref guided_tour) +sections on Beaver, Yao, and running protocols. + +## Logging and statistics + +Observability is first-class, not an afterthought: + +| Facility | Role | +| --- | --- | +| [Run log](@ref run_log) (`log.hpp` / `run_log.hpp`) | Leveled `key=value` lines to stderr, syslog, or a file; provenance banner (build, host, argv, env, config); link and trial events | +| [Statistics & CSVs](@ref statistics) (`experiment.hpp`) | Replayable master seeds, per-party streams, wire bytes, rounds, wall/CPU, symmetric-key blocks by purpose×primitive | +| [`prg::count`](@ref dpf/prg_count.hpp) | Thread-local expand / hash / harness counters (AES, ChaCha, LowMC) | +| [`thread_work`](@ref dpf/thread_work.hpp) | Charge compute-pool kernels back to the owning party | + +In-tree `party/` drivers and `run_parties` / `app::run` / `app::run_measured` +call `app::start_logging` and drive the mesh end-to-end. Before any party +starts its clock, all parties wait at a start gate. + +**Go deeper:** [Logging, statistics, and experiments](@ref experiment_costs), +[compose.hpp](@ref dpf/compose.hpp), +[experiment.hpp](@ref dpf/experiment.hpp), +[log.hpp](@ref dpf/log.hpp). + +\htmlonly +
TL;DR. Start with make_dpf and eval. When you need live parties, party_session / trio give TLS links and RoundSink rounds; the composer schedules FSS next to Beaver and Yao; start_logging and experiment stamp the run log and paper CSVs. The keys stay the product — the net, MPC, logging, and statistics stack is how you run and measure them.
+\endhtmlonly diff --git a/doc/pages/output_types.md b/doc/pages/output_types.md index 7c17e8d..621b7c9 100644 --- a/doc/pages/output_types.md +++ b/doc/pages/output_types.md @@ -1,3 +1,5 @@ + + An output type is the group element at the secret index. Every output on one key has the same width, and the type is trivially copyable. Leaf addition is the group operation. @@ -11,8 +13,9 @@ Leaf addition is the group operation. | `vec` | `N` lanes, no carry between them | [vec.hpp](@ref dpf/vec.hpp) | | `wildcard_value` | Filled in later | [wildcard.hpp](@ref dpf/wildcard.hpp) | | `field64` / `field128` / `fp61` | Prime field | [fp61.hpp](@ref dpf/fp61.hpp) | +| `gf2` / `gf22` / `gf24` / `gf28` / `gf216` / `gf232` / `gf264` | GF(2^k) | [gf2.hpp](@ref dpf/gf2.hpp) | | `p256` / `p256_scalar` | Curve point or scalar | [p256.hpp](@ref dpf/p256.hpp) | -| Shares | (2,2), (3,3), or (2,3) replicated | [secret shares](@ref secret_shares) | +| Shares | (2,2), (3,3), (2,3) replicated, (K,N) Shamir | [secret shares](@ref secret_shares) | | `fixedpoint` | Fixed-point word | [fixedpoint.hpp](@ref grotto/fixedpoint.hpp) | `bool` is an 8-bit integer. A one-bit payload is `dpf::bit`. @@ -27,7 +30,6 @@ The notes below are closed. Open one when you need the rules.
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 @@ -46,6 +48,9 @@ add the underlying word; values wider than one AES block add with
Secret shares +\htmlonly +
ELI5. The wrapper is the same bits as the payload, plus a rule for opening. Subtractive shares open as share0 − share1, which is what a point leaf returns. Additive shares open as a sum, which is what a comparison returns. A replicated share gives two of the three additive pieces to each party, so any two parties suffice. A Shamir share is one point on a polynomial; any K of the N points open the constant term.
+\endhtmlonly `dpf::additive_share` and `dpf::subtractive_share` are (2,2) shares, layout-identical to `T` (`Party` is `0` or `1`). @@ -62,6 +67,38 @@ so the secret is `x_0 + x_1 + x_2`. Any two parties reconstruct. `as_additive3()` is that party's (3,3) component. `add_replicated` folds a (3,3) sharing in by updating both holders of each component. +`dpf::shamir::share` is a Shamir share over a field. +The secret is the constant term of a polynomial of degree `K - 1`. +Party `i` holds that polynomial at `x = i + 1`. Any `K` shares open it. +`make_shamir_shares` and `shamir::deal` are the deterministic split. +`shamir::share_secret` draws the higher coefficients with `uniform_sample`. +`shamir::reconstruct` opens typed shares, or runtime `shamir::point_share`s. +The first `K` shares are the interpolating set and are not checked. +Each further share must lie on that polynomial. That catches a share that +does not belong. It does not name the bad share, and it does not correct it. +Exactly `K` shares accept any values. When `K = N` that is every share, so +a tampered full set is not detected. A complete set of shares of a different +secret is consistent and opens that secret. A zero leading coefficient is a +lower threshold than `K`. + +`(2,3)` is `shamir::two_of_three`. `shamir::share` is +`dpf::shamir_share` (`sharing::shamir`). +`make_shamir_shares(secret, slope)` is that case with one coefficient. +`shamir3` is the same polynomial on `fp61`, with party indices `1`, `2`, +and `3`. `make_dpf3` uses that case. The field inverse is +`detail::shamir_field`. `fp61` and `gf2n` specialize it. For `gf2n` +the integers `1 .. N` are bit patterns, so `N` must be less than `2^k` +or a party lands on `0` or on another party's point. Addition in that +field is XOR, so a share added to itself opens `0`. +A complete program is `examples/mwe/shamir.cpp`. + +\code{cpp} +const std::array coeff{{dpf::fp61{2}, dpf::fp61{3}}}; +auto shares = dpf::make_shamir_shares<3, 5>(dpf::fp61{10}, coeff); +auto opened = dpf::shamir::reconstruct( + std::get<0>(shares), std::get<2>(shares), std::get<4>(shares)); +\endcode + Creating from a plaintext puts the value on party 0. For a replicated share that value is component `x_0`, which party 2 also stores as `next`. @@ -84,7 +121,8 @@ Conversions that keep the secret on one party are `a2b`, `b2a`, `a2fss`, `fss2a`, `b2fss`, and `fss2b` (`a` additive, `b` subtractive, `fss` the leaf share), plus `rss2y` and `y2rss` between a replicated share and its (3,3) components (`y`). `s2y`, `y2s`, `s2rss`, and `rss2s` open a reconstructing -set and split again (`s` is (2,3) Shamir, `shamir_share`, points 1, 2, 3). +set and split again (`s` is the (2,3) case of (K,N) Shamir, `shamir_share`, +points 1, 2, 3). A cast that changes how many parties hold the secret, including anything that would need a garbled circuit, is not a conversion. `rss_mul` is the replicated product: each party forms `x_i y_i + x_i y_{i+1} + x_{i+1} y_i`, @@ -94,7 +132,6 @@ and the three terms are an additive sharing of the product.
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.
@@ -102,7 +139,6 @@ 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, low bit first. `dpf::bit::zero` and @@ -123,7 +159,6 @@ auto [k0, k1] = dpf::make_dpf(std::uint8_t{3}, dpf::bit::one);
dpf::twobit - A 2-bit output in the ring Z/4Z. Values are `0` through `3` (`twobit::zero` .. `twobit::three`). Scalar `+` and `-` wrap modulo 4. A leaf packs one lane every two bits, low lane in the low bits of the first @@ -144,7 +179,6 @@ auto [k0, k1] = dpf::make_dpf(std::uint8_t{3}, dpf::twobit::two);
dpf::nyble - A 4-bit output in the ring Z/16Z. Values are `0` through `15`. Scalar `+` and `-` wrap modulo 16. A leaf packs one lane every four bits, low nibble first. Leaf addition is not XOR and is not a byte add: a carry must not @@ -165,7 +199,6 @@ auto [k0, k1] = dpf::make_dpf(std::uint8_t{3}, dpf::to_nyble(0xau));
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 @@ -176,7 +209,6 @@ part of the value. `dpf::bitN_t` is `bitstring` for `N` from 1 through
dpf::vec<T, N> - `N` lanes of an ordinary output `T`, stored with lane 0 in the least-significant place. `T` is an integer, `modint`, `xint` / `xor_wrapper`, `fixedpoint`, `twobit`, or `nyble`. `+`, `-`, and `*` on a `vec` run per lane and do not @@ -200,6 +232,9 @@ auto [k0, k1] = dpf::make_dpf(std::uint8_t{3}, beta);
dpf::wildcard_value<T> +\htmlonly +
ELI5. The leaf group is the group of T, but the correction word is withheld. Evaluation throws until assign writes it. The assign itself is a Beaver correction, not a new tree.
+\endhtmlonly A placeholder for an output of type `T`. The leaf group is the group of `T`. `make_dpf` accepts an empty `wildcard_value{}` (or `dpf::wildcard`, or @@ -245,6 +280,9 @@ A wildcard *input* is separate: it masks the secret index. See
dpf::xor_wrapper<T> +\htmlonly +
ELI5. The group operation is XOR of the underlying word, not addition. A domain of this type walks the bits in GF(2)^N. A leaf of this type opens by XORing the two shares.
+\endhtmlonly An element of `GF(2)^n` for `n = 8 * sizeof(T)`, or `n = N` for `dpf::xint`. `operator+` and `operator-` are XOR, `operator*` is AND, and @@ -258,8 +296,42 @@ leaf scaling is AND.
-Prime fields and P-256 +GF(2^k) +`dpf::gf2`, `gf22`, `gf24`, `gf28`, `gf216`, `gf232`, and `gf264` are +GF(2^k) for k = 1, 2, 4, 8, 16, 32, and 64. Leaf addition is XOR. Leaf +scaling is field multiplication. Widths below 8 bits pack one field +element per lane, low lane first, and addition XORs that lane. A negative +integer constructs the same element as its magnitude. + +`shamir::deal` and `shamir::reconstruct` run over these fields. The +shareholder count `N` must be less than `2^k`: the point integers are +stored as bit patterns, and `2^k` itself is `0`. `gf2` can hold one +shareholder. `gf22` can hold three, which is a `(2,3)` sharing. A share +added to itself is `0`. + +| Type | Modulus | +| --- | --- | +| `gf2` | `x + 1` | +| `gf22` | `x^2 + x + 1` | +| `gf24` | `x^4 + x + 1` | +| `gf28` | `x^8 + x^4 + x^3 + x + 1` (AES, `0x11B`) | +| `gf216` | `x^16 + x^5 + x^3 + x^2 + 1` | +| `gf232` | `x^32 + x^31 + x^28 + x^21 + 1` | +| `gf264` | `x^64 + x^63 + x^62 + x^53 + 1` | + +```cpp +auto [k0, k1] = dpf::make_dpf(std::uint8_t{3}, dpf::gf28{0x1b}); +auto [s0, s1, s2] = dpf::make_shamir_shares(dpf::gf28{0x1b}, dpf::gf28{0x5a}); +auto opened = dpf::reconstruct(s0, s2); +``` + +**Defined in**\n +@ref dpf/gf2.hpp +
+ +
+Prime fields and P-256 `dpf::field64` is GF(2^64 − 2^32 + 1), the same prime as libprio `Field64`. `dpf::field128` is GF(340282366920938462946865773367900766209), the same @@ -294,6 +366,9 @@ recipes still use the integer limb channel.
grotto::fixedpoint<FractionalBits, IntegralType> +\htmlonly +
ELI5. The value is an integer with a public split between integer bits and fraction bits. Leaf addition is integer addition of the raw word. It does not shift the binary point.
+\endhtmlonly A fixed-point output stored in an integer backend. `FractionalBits` is the number of bits after the binary point. `IntegralType` defaults to @@ -318,7 +393,6 @@ auto [k0, k1] = dpf::make_dpf(std::uint8_t{3}, fp{1});
Custom output type requirements - 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 @@ -335,3 +409,7 @@ Outputs must be trivially copyable and standard layout. `dpf::utils::make_from_i 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`.
+ +\htmlonly +
TL;DR. One key, one leaf width. Integers and modint add; xint, bit, bitstring, and GF(2^k) XOR; twobit and nyble wrap inside their lane. Typed shares remember whether opening adds or subtracts, and whether any two parties suffice. A wildcard leaf throws until it is assigned.
+\endhtmlonly diff --git a/doc/pages/ppvc.md b/doc/pages/ppvc.md index 2ea999e..49d3797 100644 --- a/doc/pages/ppvc.md +++ b/doc/pages/ppvc.md @@ -1,5 +1,9 @@ # Point-programmable vector commitments {#ppvc_manual} +\htmlonly +
ELI5. The vector is bound before the coordinate is chosen. Each coordinate is a pair of 1-bit DPF roots, and both roots are committed with a Naor string. Opening one side of each pair writes the hidden coordinate, or the sum, onto a public index.
+\endhtmlonly + A point-programmable vector commitment binds a vector `x` in `(Z/2^s Z)^n` and still lets one hidden coordinate be chosen after the commitment is published. @@ -53,6 +57,10 @@ storage, so two expansions on one thread must not overlap. ## What an opening proves {#ppvc_verify} +\htmlonly +
ELI5. verify recomputes the Naor string on each opened root and compares it to the commitment. A root that was not the committed one fails. The check does not reveal the other coordinates.
+\endhtmlonly + `verify` checks each opened root against its Naor string. `accept` also checks the programmed statement: the rotated coordinate when `mu` is 0, the column sum when `mu` is 1. @@ -89,3 +97,7 @@ The generator is `dpf::prg::aes128` unless another 128-bit PRG is named. Naor's string commitment is Moni Naor, [Bit Commitment Using Pseudorandomness](@ref bib_naor), Journal of Cryptology 1991. The point keys are the Boyle–Gilboa–Ishai construction named in [DPF basics](@ref point_functions). + +\htmlonly +
TL;DR. Commit binds the vector before the coordinate is chosen, by committing both DPF roots. Open writes one coordinate or the sum onto a public index. verify checks those roots against the Naor strings.
+\endhtmlonly diff --git a/doc/pages/programmability.md b/doc/pages/programmability.md index b3f9dae..2c5ebf9 100644 --- a/doc/pages/programmability.md +++ b/doc/pages/programmability.md @@ -1,5 +1,9 @@ # Programmability {#programmability} +\htmlonly +
ELI5. A wildcard is a placeholder with the correction word not yet fixed. Assigning an input or a leaf is a Beaver multiplication against that placeholder: one blinded share is exchanged, then both parties write the same correction. An updatable leaf can be patched again the same way.
+\endhtmlonly + Fill in a secret index or payload after the key exists, rewrite an updatable leaf, or commit to a vector before choosing which coordinate to open. diff --git a/doc/pages/repr_and_twist.md b/doc/pages/repr_and_twist.md index 61b7614..7d31aff 100644 --- a/doc/pages/repr_and_twist.md +++ b/doc/pages/repr_and_twist.md @@ -7,6 +7,10 @@ with a public Pascal shift plus \f$\lambda^{\kappa}\f$. ## Representation shift {#offset_repr} +\htmlonly +
ELI5. Offset Horner is the Pascal-matrix case of a shift-invariant recurrence. Representation shift is the same idea for a general linear recurrence: a public step count kappa advances the shared state without rebuilding the key.
+\endhtmlonly + Offset Horner is the unipotent (Pascal) case of a shift-invariant module. Here the dealer keys an arbitrary state \f$S_c\in(\mathbb{Z}/2^{64})^d\f$ at the hidden center. After `eta` opens, each @@ -55,6 +59,10 @@ squaring, at most 63 squarings) and applies it on every refined piece, ## Twisted jets {#offset_twist} +\htmlonly +
ELI5. The dealer keys one comparison whose payload is the vector of twisted powers c^m λ^c, including the dyadic case c = 1/2. After eta opens, the parties scale that vector. They do not re-expand the tree.
+\endhtmlonly + The dealer keys one comparison whose payload is the vector of twisted powers \f$c^{m}\lambda^{c}\f$ in \f$\mathbb{Z}/2^{64}\f$. After `eta` opens, the segment walk returns those shares on the hot piece. A public binomial shift of the @@ -112,5 +120,10 @@ auto half_keys = grotto::make_offset_twist_keys( center, 2, grotto::twist_half); \endcode -Offset Horner, offset polynomials, carry, prefix parity, and the cleartext +Offset Horner, offset polynomials, a union of several LUTs on one +comparison, carry, prefix parity, and the cleartext LUTs are on [jet and ring](@ref jet_and_ring). + +\htmlonly +
TL;DR. Both start from the opened offset eta = x − r. Representation shift advances a linear recurrence by a public step count. Twisted jets scale a vector of powers that already includes the constant factor.
+\endhtmlonly diff --git a/doc/pages/verifiability.md b/doc/pages/verifiability.md index c3dd2a5..1bf27b5 100644 --- a/doc/pages/verifiability.md +++ b/doc/pages/verifiability.md @@ -1,5 +1,9 @@ # Verifiability & authenticity {#verifiability} +\htmlonly +
ELI5. The proof rides on the same walk as the payload. verifiable checks that the correction seeds were the honest ones. extractable checks that the path is weight 1, so a second programmed point fails. A MAC checks the leaf share after it is opened.
+\endhtmlonly + Prove that a DPF walk used honest correction seeds, or that a weight-1 sketch over the path is consistent. The tags ride along as extra `make_dpf` arguments; eval still returns the usual leaf share. diff --git a/doc/pages/which_dpf.md b/doc/pages/which_dpf.md index 6dcfac5..3e5cecf 100644 --- a/doc/pages/which_dpf.md +++ b/doc/pages/which_dpf.md @@ -17,11 +17,13 @@ Types in full are on [Input types](@ref input_types) and [Output types](@ref out - The parties already share `alpha` and want a reusable key: [dpf::make_dpf_doerner_shelat](@ref dpf/doerner_shelat.hpp). - The parties want the answer and no key: [dpf::geneval_point](@ref dpf/geneval.hpp), [dpf::geneval_interval](@ref dpf/geneval.hpp), [dpf::geneval_cmp](@ref dpf/geneval.hpp). - Three evaluators: [dpf::make_dpf3](@ref dpf/dpf3.hpp) and [dpf::make_dpf3_doerner_shelat](@ref dpf/dpf3_ds.hpp). +- A Shamir secret for any threshold, not only (2,3): [shamir::deal](@ref dpf/shamir.hpp) and `examples/mwe/shamir.cpp`. - One point, a comparison, or a public interval: [dpf::gt](@ref dpf/dcf.hpp) and the other predicates, and [dpf::ic](@ref dpf/interval.hpp). - Many secret points: [dpf::make_multipoint](@ref dpf/multipoint.hpp). - A vector whose hidden coordinate is chosen after the commitment: [point-programmable vector commitments](@ref ppvc_manual). - Several lanes at one leaf: [dpf::vec](@ref dpf/vec.hpp). - A payload filled in later: [dpf::wildcard_value](@ref dpf/wildcard.hpp). - A proof the key is well formed: [dpf::verifiable](@ref dpf/verifiable.hpp). +- A leaf share must enter a bit circuit the key does not compute: [b2y](@ref yao_leaf) and the netlist on that page. A comparison, an interval, or a public-offset polynomial stays a key. The call index, with one line each, is the [API reference](@ref api_reference). diff --git a/doc/pages/yao.md b/doc/pages/yao.md new file mode 100644 index 0000000..06790d1 --- /dev/null +++ b/doc/pages/yao.md @@ -0,0 +1,124 @@ +# A boolean function of a leaf {#yao_leaf} + +\htmlonly +
ELI5. The key still answers the point, the comparison, and the interval. When the leaf you already hold has to go through a bit circuit the key does not contain, split that leaf into XOR bits, garble the circuit, and share the result back in the leaf's own type.
+\endhtmlonly + +Party 0 garbles. Party 1 evaluates. Free-XOR, half-gates +([ePrint 2014/756](@ref bib_halfgates)). One table row is 32 bytes. +Outputs are XOR shares of the output bits: the garbler's share is the +permute bit, the evaluator's share is the color of the label it holds. + +The circuit this library is built around is the zero-key AES-MMO block +`prg::aes128::eval` already uses on every tree expand. A seed or a leaf +can enter that block without being opened. The same netlist is a hand-built +straight line of XOR, AND, XNOR, and NOT. Inputs are declared first. + +| Leaf you hold | Into the netlist | Back out | +| --- | --- | --- | +| Point leaf (subtractive) | `b2y` | `y2b` | +| Comparison leaf (additive) | `a2y` | `y2a` | +| `fss_share` | `fss2y` | `y2fss` | +| Replicated, parties 0 and 1 garble | `rss2y` | `y2rss` | + +Bits are least-significant first, one byte each, 0 or 1. `width` 0 means +the whole ring on the way in, and the vector length on the way out. +Both parties' shares are arguments. The edaBit open of `x - r` and the +daBit open of `b ⊕ r` are resolved inside the call, the same way +`edabit::a2b_gmw_pair` does. Those masked values are uniform. The integer +stays shared. + +`rss2y` does not wake party 2. Party 0 already holds `x0` and `x1`. Party 1 +already holds `x2`. `r0.next` must equal `r1.own`. Top-level `dpf::rss2y` +and `dpf::y2rss` are the local (3,3) casts and are different functions. + +```cpp +auto [k0, k1] = dpf::make_dpf(std::uint8_t{42}, std::uint32_t{0x6b}); +auto s0 = *dpf::eval_point(k0, std::uint8_t{42}); +auto s1 = *dpf::eval_point(k1, std::uint8_t{42}); +auto [y0, y1] = dpf::yao::b2y(s0, s1, 8); + +dpf::yao::netlist n; +dpf::yao::bit in[8]; +for (int i = 0; i < 8; ++i) + in[i] = n.shared_in(); +n.out(n.and_(in[0], in[1])); + +dpf::yao::session garbler; +auto out0 = garbler.eval(0, n, y0.data(), link); // party 1 passes y1 +auto [z0, z1] = dpf::yao::y2b(out0, out1, 1); +// reconstruct(z0, z1) == (0x6b & 1) & ((0x6b >> 1) & 1) +``` + +`session` keeps the IKNP base OT. The first `eval` that needs a choice +label runs Chou–Orlandi. Later evals on that session only extend. Do not +interleave `iknp::sample` on the same channel. Party 0 is the garbler for +the life of the session. Tables are one-time. The model is semi-honest. + +## What stays a key {#yao_not} + +A public query against a secret point is a comparison key. An interval is +an interval key. A polynomial in a public offset is Grotto, one comparison +and a local dot. A product of two leaf shares is a Beaver triple. A word +mux is one bit×ring inject. `cost_pass` still chooses among a DCF mask, an +edaBit MSB, and a full adder for those. + +Garble when the AND depth is the cost and the circuit is this shape: the +MMO block (5120 ANDs, one message, about 160 KiB of tables), the AES-128 +block under a shared key (6400 ANDs, key schedule included), or a netlist +you built because the leaf bits are the input. The Boyar–Peralta S-box +inside those blocks is 32 ANDs. `correction_level` is that hash as one garble: eight MMO blocks, lanes +`0..3` on each seed, 40960 ANDs, XOR shares of the four-block digest. +The level and the prefix share are packed into the inputs +(`pack_correction_level`); the netlist itself does not change per level. +`party/oblivious_hash.hpp` still walks the same S-box as GMW AND layers, +80 opens per level. + +## A secret branch {#yao_stack} + +The netlist above is a straight line. A secret if/else, or a secret choice +among a few blocks, still belongs on that leaf circuit: the bits came from +`b2y` / `a2y` / `rss2y`, and the answer goes back with `y2b` / `y2a` / +`y2rss`. It is not a reason to open the leaf. + +`yao::eval_if` stacks the two branches +([Heath and Kolesnikov, CRYPTO 2020](@ref bib_stacked)). Each branch is +garbled from the hash of the control label for that semantic bit. The +generator XORs the materials. The evaluator rebuilds the inactive branch +from a seed under the control label and XORs it out. Transmitted AND rows +follow the heavier branch, plus four translation rows per output bit so the +garbler's share does not depend on the branch. + +`yao::eval_one_hot` is the same stack for `k` netlists, `k` from 2 to 8 +([Heath and Kolesnikov, CCS 2021](@ref bib_onehot)). The index is +`index_p0 XOR index_p1`. The demux row for the selector color carries the +inactive seeds. + +Both parties pass the same netlists. Branch inputs use the same layout as +`eval_pair`: a shared entry is that party's XOR share, `priv0` is read on +party 0, `priv1` on party 1. The reconstructed bit is `share0[i] XOR share1[i]`. +`stack_blocks` is the stacked material. `naive_blocks` is the sum of the +branches. A comparison or a public-offset polynomial still stays on the key. + +## Calls {#yao_calls} + +| Call | What it does | +| --- | --- | +| `yao::netlist` | XOR, AND, XNOR, NOT, XOR with a public bit. `n_and()` is the row count | +| `yao::eval_plain` | The same wires in the clear | +| `yao::eval_local` / `eval_pair` | Garble and evaluate in one process | +| `yao::session::eval` | Garble on the peer channel. Party 0 sends the tables | +| `yao::a2y` `b2y` `fss2y` `rss2y` | Ring share to LSB-first XOR bits | +| `yao::y2a` `y2b` `y2fss` `y2rss` | Those bits back to a ring share | +| `yao::aes_mmo` | One zero-key MMO block on a session. `pos` is public | +| `yao::correction_level` | Eight of those blocks: the correction-seed hash for one tree level | +| `yao::aes128` | AES-128 of a shared block under a shared key | +| `yao::eval_if` | Stacked if/else. Rows follow the heavier branch ([CRYPTO 2020](@ref bib_stacked)) | +| `yao::eval_one_hot` | One stack over `k` branches ([CCS 2021](@ref bib_onehot)) | + +**Go deeper:** [a secret branch](@ref yao_stack), [yao.hpp](@ref dpf/yao.hpp), +[yao_stack.hpp](@ref dpf/yao_stack.hpp), [yao_share.hpp](@ref dpf/yao_share.hpp), +[yao_aes.hpp](@ref dpf/yao_aes.hpp), [F_Yao](@ref yao.hpp), +[F_YaoShare](@ref yao_share.hpp), [half-gates](@ref bib_halfgates), +[edaBits](@ref bib_edabits). The walk that still uses GMW for the hash is +[the dealer-free tour](@ref tour_ds). diff --git a/doc/papers/reis-ugurbil-wagh-henry-de-vega-wave-hello-eprint-2025-013.pdf b/doc/papers/reis-ugurbil-wagh-henry-de-vega-wave-hello-eprint-2025-013.pdf new file mode 100644 index 0000000..fd4ceb6 Binary files /dev/null and b/doc/papers/reis-ugurbil-wagh-henry-de-vega-wave-hello-eprint-2025-013.pdf differ diff --git a/doc/stylesheet.css b/doc/stylesheet.css index 42c9b54..885ee0e 100644 --- a/doc/stylesheet.css +++ b/doc/stylesheet.css @@ -386,6 +386,8 @@ details.type-note > p:first-of-type { justify-content: space-between; align-items: center; gap: 1rem; + width: 100%; + box-sizing: border-box; margin: 0 0 1.1rem; padding: 0.45rem 0 0.7rem; border-bottom: 1px solid var(--separator-color); @@ -416,3 +418,28 @@ pre.fragment { background: var(--fragment-background); border: 1px solid var(--separator-color); } + +.eli5, .tldr { + margin: 0.85rem 0 1rem; + padding: 0.7rem 0.95rem; + border-radius: 8px; + line-height: 1.45; +} + +.eli5 { + border-left: 3px solid var(--primary-color); + background: var(--fragment-background); +} + +.tldr { + border-top: 1px solid var(--separator-color); + background: var(--page-background-color); +} + +.eli5 b, .tldr b { + display: inline-block; + margin-right: 0.4rem; + color: var(--primary-color); + font-size: 0.75rem; + letter-spacing: 0.06em; +} diff --git a/docs/STREAM_ARRAY_GAP_REPORT.md b/docs/STREAM_ARRAY_GAP_REPORT.md new file mode 100644 index 0000000..800404a --- /dev/null +++ b/docs/STREAM_ARRAY_GAP_REPORT.md @@ -0,0 +1,139 @@ +# Stream-array / network layer report + +Interactive MPC/FSS that is prep plus message rounds runs on +`net::async_stream_array` (in-process memory, unix sockets, TCP mux, parallel +TCP, SCTP) through `async_round_sink`, `compose_async`, and the N-party runner. +Every decision the network layer makes is an explicit, per-object setting; the +library reads no environment variables. + +## Configuration + +| Setting | Type / where | +|---------|--------------| +| Wire policy: window, max frame, chunk size, coalescing (frames and bytes), inbox compaction, socket options | `net::wire_policy` (`net/policy.hpp`), passed to every backend constructor; `set_window_bytes` at run time | +| Socket options: `TCP_NODELAY`, quickack, keepalive (idle/interval/count), `SO_SNDBUF`/`SO_RCVBUF`, `SCTP_NODELAY` | `net::socket_options` inside `wire_policy` | +| Setup deadlines: join, connect, accept, handshake, drain | `net::deadlines` | +| Lanes and framing | `drive_options::n_lanes` (`0` = 8, `lanes_one_per_round`), `framing_mode {automatic, always, never}` | +| Wait budgets | `drive_options::wait_timeout` per round wait, `edge_timeout[edge]`, `round_timeout[round]`; the clock restarts whenever an instance advances, so a long healthy run never times out | +| Kernels | `drive_options::workers` (compute pool) and `pump` (the sink's `io_context`, serviced while a kernel runs) | +| Harness | `app::run_config`: transport, host, lanes, framing, instances, wire policy, pipeline credit, wait budget, compute threads, warmup, trials, CPU pins, deadlines. `from_env()` (`DPF_`) and `apply_args()` (`--key=value`) share one parser; unknown keys and bad values throw | + +`pipeline_credit` only lets a session submit rounds whose bytes do not depend on +the peer, and only while that edge's window has room (`RoundSink::can_send_ahead`). +Compose plans are fully dependent; overlap them with `instances`. + +## Backends + +| Backend | Notes | +|---------|-------| +| `async_dual_memory_hub` / `make_async_dual_memory_stream_pair` | One `io_context` per side; per-writer window; closing a side still delivers accepted writes, then EOF | +| `async_mux_stream_array` | One TCP socket; writes are chunked and round-robined across lanes so a small write is not queued behind a large one; up to `coalesce_frames` / `coalesce_bytes` per syscall; reads land directly in a waiting reader's buffer | +| `basic_async_parallel_stream_array` (TCP and unix) | One socket per lane with its own strand, queue, and window (`lane_window_bytes`); `accept_parallel_tcp` / `connect_parallel_tcp` use one port and a lane-index handshake | +| `async_sctp_stream_array` (Linux + libsctp) | Lane `i` = SCTP stream `i`; per-stream chunked round-robin sends straight from the owned payload; window; `sctp_available()` checks support up front | +| `mux_stream_array` (synchronous) | Same wire format as the async mux (interoperates with it); a poll-based pump drains reads while writing, so two large cross flushes do not deadlock | + +All backends report `stream_stats` (wire bytes including headers, payload +bytes, frames, write calls, buffered/unread bytes, last activity, error). +`close()` aborts; destruction is graceful and drains accepted writes. + +## Round sink + +`async_round_sink(streams, slots, instances, sink_options)`: + +* Plan-shape hello (rounds, slot widths, lanes, instances, framing, epoch); a + mismatch fails both ends with a message naming the field. +* Framed lanes carry `{round, nbytes}`; partial instance prefixes are ready as + they land. Unframed lanes carry one round each. +* `flush_round` waits while the lane's window is full, up to `drain_timeout`. +* `sink_options::reconnect` supplies a replacement link after a transport error + (for example `party_session::reconnector(peer)`). Both ends exchange what + they received and resend the rest, so a plan resumes mid-run + (`sink_stats::resumes`, `resent_bytes`). +* Separate out and in links (`async_round_sink(out, in, ...)`) for the RSS ring. + +## Sessions and multi-party runs + +| Surface | Where | +|---------|-------| +| `party_session`: static `host:port` table (any start order), connect with retry to a deadline, per-edge transport (mux / parallel / SCTP) and wire policy, handshake that names mismatches, per-edge stats and epochs, `reconnect` / `reconnector` | `net/party_session.hpp` | +| Dealer link in its own failure domain with its own epoch, policy, and `io_context`; `dealer_session` serves several parties | `net/party_session.hpp` | +| `run_parties` (2 or 3 parties, dealer and RSS-ring edges) on every transport; `run_two_party` / `run_three_party` | `party_runner.hpp`, `launch.hpp` | +| One process per party: `parse_node_args` (`--party=i --peers=host:port,...` plus any `run_config` key) and `run_node` | `party_runner.hpp`, `examples/protocol/party_node.cpp` | +| Prep over a dealer session on the configured transport | `session::ship_prep(demand, cfg)` | + +## Link security + +Party links (party to party, and the dealer) run TLS 1.3 through OpenSSL on +every socket edge unless `encryption=off`. Each party has a raw Ed25519 key +(`identity = FILE`, made with `examples/tools/dpf_keygen.cpp`; 44 characters of +base64, like a WireGuard key). There are no certificate files and no CA: the +certificate TLS needs is generated in memory from the key, and peers check the +key inside it. + +| Configured | Effect | +|------------|--------| +| no keys at all | links are encrypted to a fresh key per run; nobody is authenticated; each side logs `security.no_identity` and `security.unauthenticated` | +| `peer.N = KEY` on party M | M authenticates N; N still does not authenticate M unless it holds M's key | +| a held key that does not match | the link fails at setup with both keys in the message | +| `dealer_key = KEY` | the party authenticates the dealer (the dealer uses `peer.N` for parties) | +| SCTP edge while encrypted | refused at setup (no TLS over SCTP streams); `encryption=off` allows it | + +The session hello (party id, epoch, transport, lanes) travels inside TLS and +carries whether the sender authenticated the receiver, so every `link.up` record +shows `encryption=TLSv1.3/`, `auth=key|none`, `peer_key`, and +`peer_verified_us`. + +Client links (`dpf/net/client_link.hpp`): a `client_listener` presents +`server_cert`/`server_key` (PEM, CA-issued), or `server_identity`, or, with +neither, the built-in development certificate. `connect_server` always verifies +the server unless `client_verify=off`: a pinned key (`client_pin`), a CA chain +for the host name (`client_ca = FILE|system`, `client_server_name`), or, when +neither is configured, the development certificate. That certificate's private +key is public, so the default pairing works out of the box and both ends log +that it provides no security. A server may check client keys +(`server_client_pin`, with `client_identity` on the client). + +All of it is `run_config` keys, as flags, `DPF_*` variables, or a file of +`key = value` lines (`--config=FILE`, `DPF_CONFIG`; relative paths resolve +against the file): + +```text +# p0.conf +identity = p0.key +peer.1 = file:p1.pub +dealer_key = 8s3b...= +transport = mux +``` + +## Harness + +`app::exercise_parties(plans, inputs, kernels, ex, cfg)` runs each party's plan +from fresh inputs for `warmup` untimed and `trials` timed repetitions and +records the median. `experiment` writes `config.csv` (every `run_config` +setting), `trials.csv`, and `wire.csv` (party 0's link counters) next to the +existing tables. `experiment_bench` takes every setting as a flag. + +## Remaining + +1. QUIC: fits the `async_stream_array` interface; not implemented. +2. Synchronous entry points (`tcp_pair`, `tcp_pair_mux`, `join_*_tcp_mesh`, `trio`) go through the same `peer_security` / `party_session` framework as async edges (TLS 1.3 by default). Sync mux is a blocking face over `async_stream_array`. +3. SCTP links cannot be encrypted. +4. The synchronous `sctp_stream_array` face still throws; use `async_sctp_stream_array`. +5. Non-Linux SCTP is not supported; constructors throw and `sctp_available()` is false. + +## Verification + +`net_control_test` (27 tests) covers the controls above: config parsing, framing +modes, hello mismatches, partial prefixes, window gating, per-edge and per-round +budgets, a healthy run longer than its wait budget, mux round-robin and graceful +close, per-lane parallel windows, sync/async mux interop, connect deadlines, +static tables, transport mismatch, parallel and SCTP edges, mid-plan reconnect, +dealer epochs, every transport through `run_parties`, a 3-party dealer and ring +plan, separate processes from a static table, harness trials and CSVs, and prep +over a dealer session. `share_runtime_test` (91 tests) covers the rest of the stack. +`security_test` covers key files, TLS in every authentication combination, a +recording relay that sees only ciphertext, wrong keys, mixed encryption +settings, the SCTP refusal, missing-key logging, dealer keys, every client-link +mode (development default, pins, CA chain and host name, verify off, client +keys), config files, and two processes that authenticate each other from key +files. diff --git a/examples/applications/bitmore.cpp b/examples/applications/bitmore.cpp new file mode 100644 index 0000000..92f5058 --- /dev/null +++ b/examples/applications/bitmore.cpp @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// BitMore, the DPF query only (Hafiz and Henry, PoPETs 2019 §5.2). +// ell = 2^L servers. The client samples L independent 1-bit DPFs at the +// secret row. Server j, whose label bits are j_{L-1} ... j_0, receives +// key j_e of DPF e and expands it. Concatenating those bits per row is +// the query string the information-theoretic response then consumes. +// +// `dpf::pack_bit_columns(keys...)` runs the full-domain bit walk once per +// key and writes lane e = key e into one integer per row, so the server +// loop reads `symbol[row]` instead of unpacking one int per bit. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/bitmore.cpp + +namespace +{ + +constexpr int bits_l = 2; +constexpr int nservers = 1 << bits_l; +constexpr std::size_t nrows = 256; + +} // namespace + +int main() +{ + constexpr std::uint8_t alpha = 42; + + // L independent 1-bit DPFs at the secret row; keep both parties' keys. + auto [e0k0, e0k1] = dpf::make_dpf(alpha, dpf::bit::one); + auto [e1k0, e1k1] = dpf::make_dpf(alpha, dpf::bit::one); + + // Server j reads key (j>>e)&1 of DPF e. Pack those L bits per row into + // one digit with pack_bit_columns; lane e is DPF e. + std::array, nservers> symbol{}; + symbol[0] = dpf::pack_bit_columns(e0k0, e1k0); // parties (0,0) + symbol[1] = dpf::pack_bit_columns(e0k1, e1k0); // parties (1,0) + symbol[2] = dpf::pack_bit_columns(e0k0, e1k1); // parties (0,1) + symbol[3] = dpf::pack_bit_columns(e0k1, e1k1); // parties (1,1) + + std::array at_alpha{}; + for (std::size_t row = 0; row < nrows; ++row) + { + if (row == alpha) + { + for (int j = 0; j < nservers; ++j) + at_alpha[static_cast(j)] = + symbol[static_cast(j)][row]; + continue; + } + for (int j = 1; j < nservers; ++j) + { + if (symbol[static_cast(j)][row] + != symbol[0][row]) + { + std::cerr << "bitmore off-row\n"; + return 1; + } + } + } + + // On the secret row the server digits are a translate of the server + // ids: symbol(j) = symbol(0) XOR j. That is a permutation of 0 .. ell-1. + for (int j = 0; j < nservers; ++j) + { + const std::uint64_t expect = at_alpha[0] ^ static_cast(j); + if (at_alpha[static_cast(j)] != expect) + { + std::cerr << "bitmore secret row\n"; + return 1; + } + } + + // L = 1 is the 2-server member of the same family: XOR the rows each + // party's bit selects, read off the packed digit's low bit. + std::vector records(nrows); + records[alpha] = 99; + records[7] = 3; + auto [q0, q1] = dpf::make_dpf(alpha, dpf::bit::one); + const auto s0 = dpf::pack_bit_columns(q0); + const auto s1 = dpf::pack_bit_columns(q1); + std::uint64_t a0 = 0; + std::uint64_t a1 = 0; + for (std::size_t i = 0; i < nrows; ++i) + { + if (s0[i] & 1u) + a0 ^= records[i]; + if (s1[i] & 1u) + a1 ^= records[i]; + } + if ((a0 ^ a1) != records[alpha]) + { + std::cerr << "bitmore two-server\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("bitmore", + dpf::protocol::bitmore_fan_plan(0, 4, 6), 6)) + return rc; + } + + std::cout << (a0 ^ a1) << "\n"; + return 0; +} diff --git a/examples/applications/duoram3.cpp b/examples/applications/duoram3.cpp new file mode 100644 index 0000000..bfd90fa --- /dev/null +++ b/examples/applications/duoram3.cpp @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// 3-party Duoram, the DPF steps only (Vadapalli, Henry, Goldberg, USENIX +// Security 2023). Online update: expand with `leaf_later`, rotate value and +// control together, then `apply_leaf_correction` once F is known. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/duoram3.cpp + +namespace +{ + +constexpr std::size_t n = 256; +using output_t = simde_uint128; + +template +output_t leaf_cw_of(const Key & key) +{ + using exterior = typename Key::exterior_node; + return dpf::extract_leaf(key.template leaf<0>(), 0); +} + +} // namespace + +int main() +{ + constexpr std::uint8_t r = 10; + constexpr std::uint8_t i_star = 42; + constexpr unsigned shift = static_cast(i_star - r); + const output_t message = output_t{7}; + + std::vector memory(n); + memory[i_star] = output_t{100}; + memory[r] = output_t{5}; + + auto [u0, u1] = dpf::make_dpf(r, output_t{1}); + const auto read = dpf::reconstruct( + dpf::eval_full_inner_product(dpf::paired, u0, memory, dpf::rotate{shift}), + dpf::eval_full_inner_product(dpf::paired, u1, memory, dpf::rotate{shift})); + if (read != memory[i_star]) + { + std::cerr << "duoram read\n"; + return 1; + } + + auto [w0, w1] = dpf::make_dpf(r, message); + const output_t F = leaf_cw_of(w0); + std::vector d0 = memory; + std::vector d1(n); + std::vector t0(n), t1(n); + dpf::eval_full_add_into(d0, t0, w0, dpf::leaf_later{}, dpf::rotate{shift}); + dpf::eval_full_add_into(d1, t1, w1, dpf::leaf_later{}, dpf::rotate{shift}); + dpf::apply_leaf_correction(d0, t0, F); + dpf::apply_leaf_correction(d1, t1, F); + + if ((d0[i_star] - d1[i_star]) != memory[i_star] + message + || (d0[r] - d1[r]) != memory[r]) + { + std::cerr << "duoram update\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("duoram3", + dpf::protocol::duoram_update_plan(0), 8)) + return rc; + } + + std::cout << static_cast(d0[i_star] - d1[i_star]) << "\n"; + return 0; +} diff --git a/examples/applications/experiment_bench.cpp b/examples/applications/experiment_bench.cpp new file mode 100644 index 0000000..fc4cd03 --- /dev/null +++ b/examples/applications/experiment_bench.cpp @@ -0,0 +1,222 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" +#include "dpf/bench_cells.hpp" +#include "dpf/experiment.hpp" +#include "dpf/party_runner.hpp" +#include "dpf/run_log.hpp" + +// Every cell is a compose plan driven by `run_parties` on one `run_config`: +// the party mesh over in-process async memory, unix sockets, TCP mux, parallel +// TCP, or SCTP. `memory` and `stream` are the older paired sinks; this harness +// uses the mesh, so those two names run as async. Every `run_config` key is a +// flag (`--transport=mux --lanes=4 --window=262144 --warmup=2 --trials=9`) or +// the matching `DPF_*` variable; flags win. Lanes default to 1 here. Each cell +// runs `warmup` untimed and `trials` timed repetitions and records every +// party's trial times, party 0's and the slowest party's medians, the +// configuration, and party 0's wire counters in the CSVs. Every repetition +// draws from streams derived from the cell's master, so replaying the master +// replays the cell. +// +// c++ -std=c++17 -march=native -pthread -I include -I thirdparty \ +// examples/applications/experiment_bench.cpp -lsctp +// DPF_EXPERIMENT_DIR=/tmp/libdpf_bench ./a.out --transport=mux --trials=5 +// +// The first block is the DPF plans. The second block is the work that is not +// a key: word gadgets, stacked branches, short tables, and a hidden reorder +// of a column the parties already share. + +namespace +{ + +dpf::app::run_config mesh_config(int argc, char ** argv, std::string & replaced) +{ + dpf::app::run_config cfg; + cfg.n_lanes = 1; + cfg.merge_env(); + const auto rest = cfg.apply_args(argc, argv); + if (!rest.empty()) + throw std::invalid_argument("unexpected argument '" + rest.front() + + "' (flags are --key=value)"); + if (cfg.kind == dpf::net::transport::memory_sink + || cfg.kind == dpf::net::transport::memory_stream) + { + std::cout << "transport " + << dpf::net::transport_name(cfg.kind) + << " is a paired sink; the battery uses the party mesh (async)\n"; + replaced = dpf::net::transport_name(cfg.kind); + cfg.kind = dpf::net::transport::async_memory; + } + return cfg; +} + +int measure_plans(const char * name, std::vector plans, + std::uint64_t run_id, const std::string & dir, const dpf::app::run_config & cfg, + dpf::protocol::cell_fn cell) +{ + if (plans.empty() || plans[0].rounds() == 0) + { + std::cerr << name << " has no exchange rounds\n"; + return 1; + } + dpf::experiment ex(name, "p0"); + ex.set_run_id(run_id); + ex.ingest_plan(plans[0]); + ex.set_config(cfg.describe()); + dpf::app::parties_result result; + const std::size_t total = cfg.warmup + std::max(1, cfg.trials); + try + { + for (std::size_t t = 0; t < total; ++t) + { + std::vector values(plans.size()); + const bool last = t + 1 == total; + result = dpf::app::run_parties(plans, values, {}, cfg, + last ? &ex : nullptr, cell, &ex); + if (t >= cfg.warmup) + ex.add_trial(result.party0_wall_ns, result.party_wall_ns); + } + } + catch (const std::exception & err) + { + std::cerr << name << " flow: " << err.what() << "\n"; + return 1; + } + const auto wire = result.wire.empty() ? dpf::net::stream_stats{} : result.wire[0]; + dpf::experiment::wire_counts w; + w.bytes_out = wire.bytes_out; + w.bytes_in = wire.bytes_in; + w.payload_out = wire.payload_out; + w.payload_in = wire.payload_in; + w.frames_out = wire.frames_out; + w.frames_in = wire.frames_in; + w.write_calls = wire.write_calls; + ex.set_wire(w); + ex.write_csv(dir); + std::cout << name << " parties=" << plans.size() + << " run_id=" << run_id + << " rounds=" << ex.interactive_rounds() + << " bytes=" << ex.plan_bytes_out() + << " wire_out=" << wire.bytes_out + << " wire_in=" << wire.bytes_in + << " payload_out=" << wire.payload_out + << " median_ns=" << ex.median_trial_ns() + << " slowest_median_ns=" << ex.slowest_median_ns() + << " trials=" << ex.trials().size() + << " prg_evals=" << ex.prg_evals() + << " seed=" << ex.seed_hex() << "\n"; + return 0; +} + +} // namespace + +int main(int argc, char ** argv) +{ + const char * env = std::getenv("DPF_EXPERIMENT_DIR"); + const std::string dir = (env && env[0] != '\0') ? env + : "/tmp/libdpf_experiment_bench"; + dpf::app::run_config cfg; + std::string replaced; + try + { + cfg = mesh_config(argc, argv, replaced); + dpf::app::start_logging(cfg); + } + catch (const std::exception & err) + { + std::cerr << "experiment_bench: " << err.what() << "\n"; + return 2; + } + if (!replaced.empty()) + DPF_LOG(warning, "config.override").kv("key", "transport") + .kv("requested", replaced).kv("used", "async") + .kv("detail", "paired sinks cannot carry the party mesh"); + std::cout << cfg.summary() << "\n"; + + struct named + { + const char * name; + int parties; + dpf::protocol::plan (*make)(std::size_t party); + }; + const named dpf_plans[] = { + {"keyword_pir", 2, [](std::size_t p) { + return dpf::protocol::keyword_pir_compose_plan(p, 8); + }}, + {"express", 2, [](std::size_t p) { + return dpf::protocol::mailbox_write_fused_plan(p); + }}, + {"subleq", 2, [](std::size_t p) { + return dpf::protocol::subleq_instruction_plan(p); + }}, + {"pika", 2, [](std::size_t p) { + return dpf::protocol::pika_lookup_plan(p); + }}, + {"duoram3", 2, [](std::size_t p) { + return dpf::protocol::duoram_update_plan(p); + }}, + {"poplar", 2, [](std::size_t p) { + return dpf::protocol::poplar_prefix_plan(p); + }}, + {"poplar_fan4", 2, [](std::size_t p) { + return dpf::protocol::poplar_prefix_fan_plan(p, 4); + }}, + {"ledger23", 2, [](std::size_t p) { + return dpf::protocol::ledger23_append_plan(p); + }}, + {"bitmore", 2, [](std::size_t p) { + return dpf::protocol::bitmore_fan_plan(p); + }}, + {"floram", 2, [](std::size_t p) { + return dpf::protocol::floram_ds_plan(p); + }}, + {"fss_point", 2, [](std::size_t p) { + return dpf::protocol::fss_point_plan(p); + }}, + {"fss_cmp", 2, [](std::size_t p) { + return dpf::protocol::fss_cmp_plan(p); + }}, + {"range_count", 2, [](std::size_t p) { + return dpf::protocol::range_count_plan(p); + }}, + {"psi_cuckoo", 2, [](std::size_t p) { + return dpf::protocol::psi_cuckoo_plan(p, {0, 2, 5, 7}); + }}, + {"idpf_agg", 2, [](std::size_t p) { + return dpf::protocol::idpf_agg_plan(p, 8); + }}, + }; + + std::uint64_t run_id = 0; + for (const auto & row : dpf_plans) + { + std::vector plans; + plans.reserve(static_cast(row.parties)); + for (int p = 0; p < row.parties; ++p) + plans.push_back(row.make(static_cast(p))); + if (int rc = measure_plans(row.name, std::move(plans), run_id++, dir, cfg, + nullptr)) + return rc; + } + + for (const auto & cell : dpf::bench::battery()) + { + std::vector plans; + plans.reserve(static_cast(cell.parties)); + for (int p = 0; p < cell.parties; ++p) + plans.push_back(dpf::bench::plan_for(static_cast(p), cell.id)); + if (int rc = measure_plans(cell.name, std::move(plans), run_id++, dir, cfg, + &dpf::bench::run_cell)) + return rc; + } + std::cout << "wrote CSVs under " << dir << "\n"; + return 0; +} diff --git a/examples/applications/express.cpp b/examples/applications/express.cpp new file mode 100644 index 0000000..d92ecc0 --- /dev/null +++ b/examples/applications/express.cpp @@ -0,0 +1,84 @@ +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Express, the mailbox write (Eskandarian, Corrigan-Gibbs, Zaharia, Boneh, +// USENIX Security 2021 §3.1). Two servers hold XOR shares of every mailbox +// row. The client sends one `blob` DPF key each. Each server adds its +// expansion into its share and folds the one-hot audit in the same walk. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/express.cpp + +namespace +{ + +constexpr std::size_t nboxes = 256; +constexpr std::size_t row_bytes = 100; +using row_t = dpf::blob; + +} // namespace + +int main() +{ + constexpr std::uint8_t address = 9; + row_t message{}; + for (std::size_t i = 0; i < row_bytes; ++i) + message.bytes[i] = static_cast(i + 1); + + auto [k0, k1] = dpf::make_dpf(address, message); + + std::vector box0(nboxes), box1(nboxes); + // One-pass caller fold: count how many non-zero shares each server sees. + std::size_t hot0 = 0, hot1 = 0; + dpf::eval_full_add_into(box0, k0, [&](std::size_t, const row_t & s) { + if (s != row_t{}) + ++hot0; + }); + dpf::eval_full_add_into(box1, k1, [&](std::size_t, const row_t & s) { + if (s != row_t{}) + ++hot1; + }); + (void)hot0; + (void)hot1; + + if ((box0[address] ^ box1[address]) != message) + { + std::cerr << "express mailbox\n"; + return 1; + } + if ((box0[0] ^ box1[0]) != row_t{}) + { + std::cerr << "express neighbor\n"; + return 1; + } + + // fp61 one-hot audit on a parallel extractable key (same walk shape). + auto [a0, a1] = dpf::make_dpf(address, dpf::fp61{1}, dpf::extractable{}); + std::vector challenge(nboxes); + for (std::size_t i = 0; i < nboxes; ++i) + challenge[i] = dpf::fp61{static_cast(i + 1)}; + std::vector audit0(nboxes), audit1(nboxes); + dpf::sketch_share s0{}, s1{}; + dpf::eval_full_add_into(audit0, a0, dpf::sketch(s0, challenge)); + dpf::eval_full_add_into(audit1, a1, dpf::sketch(s1, challenge)); + if (!dpf::sketch_verify(s0, s1)) + { + std::cerr << "express audit\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("express", + dpf::protocol::mailbox_write_fused_plan(0, 8), 8)) + return rc; + } + + std::cout << static_cast(message.bytes[0]) << "\n"; + return 0; +} diff --git a/examples/applications/floram.cpp b/examples/applications/floram.cpp new file mode 100644 index 0000000..0434302 --- /dev/null +++ b/examples/applications/floram.cpp @@ -0,0 +1,61 @@ +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Floram, the FSS read and write (Doerner and shelat, CCS 2017). Both +// parties see the memory. The address is secret-shared, so keygen is +// Doerner–Shelat rather than a dealer who knows the index. The read is +// the inner product of a unit key with that memory. The write adds a +// payload key, built from the same address shares, into subtractive +// copies of the array. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/floram.cpp + +int main() +{ + constexpr std::size_t n = 256; + constexpr std::uint8_t address = 42; + constexpr std::uint8_t a0 = 0x15; + constexpr std::uint8_t a1 = static_cast(address ^ a0); + constexpr std::uint64_t message = 9; + + std::vector memory(n); + memory[address] = 100; + memory[7] = 3; + + auto [r0, r1] = dpf::make_dpf_doerner_shelat(a0, a1, std::uint64_t{1}); + const auto word = dpf::reconstruct( + dpf::eval_full_inner_product(dpf::paired, r0, memory), + dpf::eval_full_inner_product(dpf::paired, r1, memory)); + if (word != memory[address]) + { + std::cerr << "floram read\n"; + return 1; + } + + auto [w0, w1] = dpf::make_dpf_doerner_shelat(a0, a1, message); + std::vector s0 = memory; + std::vector s1(n); + dpf::eval_full_add_into(s0, w0); + dpf::eval_full_add_into(s1, w1); + if (s0[address] - s1[address] != memory[address] + message + || s0[7] - s1[7] != memory[7]) + { + std::cerr << "floram write\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("floram", + dpf::protocol::floram_ds_plan(0), 40)) + return rc; + } + + std::cout << word << "\n"; + return 0; +} diff --git a/examples/applications/hushmap_add.cpp b/examples/applications/hushmap_add.cpp new file mode 100644 index 0000000..53d376c --- /dev/null +++ b/examples/applications/hushmap_add.cpp @@ -0,0 +1,38 @@ +#include +#include + +#include "dpf/online_session.hpp" +#include "dpf/prep_source.hpp" + +// Hushmap KHM ADD: dealer tape + two online opens on async round sinks, +// then a real prep shipment (deal_views over async streams). +// +// c++ -std=c++17 -pthread -I include -I thirdparty \ +// examples/applications/hushmap_add.cpp + +int main() +{ + constexpr std::size_t layers = 3; + try + { + dpf::session::drive_hushmap_add(layers); + dpf::prep::demand d; + d.ring_triples = static_cast(layers); + const auto shipped = dpf::session::ship_prep(d); + std::uint8_t a0[8]{}, b0[8]{}, c0[8]{}; + std::uint8_t a1[8]{}, b1[8]{}, c1[8]{}; + auto c0p = shipped.party0; + auto c1p = shipped.party1; + c0p.take_ring(a0, b0, c0); + c1p.take_ring(a1, b1, c1); + std::cout << "hushmap_add layers=" << layers + << " rounds=" << (layers + 2) + << " prep_bytes=" << shipped.bytes0 << "\n"; + } + catch (const std::exception & ex) + { + std::cerr << "hushmap_add: " << ex.what() << "\n"; + return 1; + } + return 0; +} diff --git a/examples/applications/idpf_agg.cpp b/examples/applications/idpf_agg.cpp new file mode 100644 index 0000000..d76dc4c --- /dev/null +++ b/examples/applications/idpf_agg.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Max and k-th order statistic over secret uint16 values. Each value is +// one incremental DPF with a unit payload on every prefix length. Servers +// resume only the live prefixes with eval_until (ePrint 2024/1190). +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/idpf_agg.cpp + +int main() +{ + const std::vector values{12, 80, 3, 80, 40}; + using key0_t = decltype(dpf::make_dpf(std::uint16_t{0}, + dpf::idpf_ones<16>()).first); + using key1_t = decltype(dpf::make_dpf(std::uint16_t{0}, + dpf::idpf_ones<16>()).second); + std::vector k0; + std::vector k1; + for (auto v : values) + { + auto [a, b] = dpf::make_dpf(v, dpf::idpf_ones<16>()); + k0.push_back(std::move(a)); + k1.push_back(std::move(b)); + } + + const auto opened_max = dpf::idpf_agg_max(k0, k1); + const auto opened_k2 = dpf::idpf_agg_kth(k0, k1, 2); + + auto sorted = values; + std::sort(sorted.begin(), sorted.end(), std::greater<>{}); + if (opened_max != sorted[0] || opened_k2 != sorted[1]) + { + std::cerr << "idpf_agg " << opened_max << " " << opened_k2 << "\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("idpf_agg", + dpf::protocol::idpf_agg_plan(0, 16), 16)) + return rc; + } + + std::cout << opened_max << "\n"; + return 0; +} diff --git a/examples/applications/it_pir3.cpp b/examples/applications/it_pir3.cpp new file mode 100644 index 0000000..b5ef792 --- /dev/null +++ b/examples/applications/it_pir3.cpp @@ -0,0 +1,49 @@ +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Three-server index PIR with the information-theoretic DPF +// (ePrint 2023/028). The database is public and replicated. Each server +// dots its additive share with the table; the three dots sum to the record. +// make_dpf3 remains the computational (2,3) Shamir key. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/it_pir3.cpp + +int main() +{ + constexpr std::size_t n = 256; + constexpr std::uint8_t index = 42; + + std::vector database(n); + for (std::size_t i = 0; i < n; ++i) + database[i] = i * i + 1; + + auto [k0, k1, k2] = dpf::make_it_dpf3(index, 1); + const auto s0 = dpf::eval_it_dpf3_inner_product(k0, database); + const auto s1 = dpf::eval_it_dpf3_inner_product(k1, database); + const auto s2 = dpf::eval_it_dpf3_inner_product(k2, database); + const auto opened = s0 + s1 + s2; + if (opened != database[index]) + { + std::cerr << "it_pir3\n"; + return 1; + } + + { + constexpr std::size_t query_bytes = + dpf::it_dpf3_key::domain_size * sizeof(std::uint64_t); + if (int rc = dpf::app::run_measured("it_pir3", + dpf::protocol::n_server_pir_plan(0, 3, query_bytes, + sizeof(std::uint64_t)), + 2)) + return rc; + } + + std::cout << opened << "\n"; + return 0; +} diff --git a/examples/applications/keyword_pir.cpp b/examples/applications/keyword_pir.cpp new file mode 100644 index 0000000..90d3e46 --- /dev/null +++ b/examples/applications/keyword_pir.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Two-server keyword PIR, the DPF step (Gilboa and Ishai, EUROCRYPT 2014). +// `eval_sequence_xor` folds the selected records into one XOR accumulator +// without materializing a bit vector. +// +// c++ -std=c++17 -march=native -pthread -I include -I thirdparty \ +// examples/applications/keyword_pir.cpp +// DPF_EXPERIMENT_DIR=/tmp/kw ./a.out # optional CSV dump + +namespace +{ + +using keyword = dpf::keyword<3, dpf::alphabets::lowercase_alpha>; + +} // namespace + +int main() +{ + const std::vector dict{keyword{"bat"}, keyword{"cat"}, + keyword{"dog"}, keyword{"pig"}}; + const std::vector records{56, 12, 34, 78}; + + auto [k0, k1] = dpf::make_dpf(keyword{"bat"}, dpf::bit::one); + const int selected = dpf::eval_sequence_xor(k0, dict.begin(), dict.end(), + records) + ^ dpf::eval_sequence_xor(k1, dict.begin(), dict.end(), records); + if (selected != 56) + { + std::cerr << "keyword hit\n"; + return 1; + } + + auto [m0, m1] = dpf::make_dpf(keyword{"rat"}, dpf::bit::one); + const int missing = dpf::eval_sequence_xor(m0, dict.begin(), dict.end(), + records) + ^ dpf::eval_sequence_xor(m1, dict.begin(), dict.end(), records); + if (missing != 0) + { + std::cerr << "keyword miss\n"; + return 1; + } + + { + constexpr std::size_t depth = dpf::utils::bitlength_of::value; + if (int rc = dpf::app::run_measured("keyword_pir", + dpf::protocol::keyword_pir_compose_plan(0, depth), 2)) + return rc; + } + + std::cout << selected << "\n"; + return 0; +} diff --git a/examples/applications/ledger23.cpp b/examples/applications/ledger23.cpp new file mode 100644 index 0000000..3886d7b --- /dev/null +++ b/examples/applications/ledger23.cpp @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// A (2,3) ledger, the DPF step. Three servers replicate a ledger as +// Shamir-style (2-of-3) shares (this group's dpf3 / VDPF+ construction). Each +// append writes one point (slot -> amount) into all three shares; any two +// servers reconstruct a slot. A verifiable proof (verify_dpf3) rejects an +// append that is not a single well-formed point before it is applied. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/ledger23.cpp + +namespace +{ + +using dpf::fp61; +constexpr std::size_t nslots = 256; // uint8 slot domain + +fp61 open2(fp61 a, fp61 b) // any two of three shares reconstruct +{ + return dpf::shamir3::reconstruct(dpf::shamir3::share{1, a}, + dpf::shamir3::share{2, b}); +} + +} // namespace + +int main() +{ + std::vector l1(nslots), l2(nslots), l3(nslots); + + // Each append is a verified (2,3) point key. + const std::pair entries[] = { + {5, 100}, {40, 25}, {5, 7}}; + for (auto [slot, amount] : entries) + { + auto [k1, k2, k3] = dpf::make_dpf3(slot, fp61{amount}, dpf::verifiable{}); + if (!dpf::verify_dpf3(dpf::prove_dpf3(k1, slot), + dpf::prove_dpf3(k2, slot), dpf::prove_dpf3(k3, slot))) + { + std::cerr << "ledger append audit\n"; + return 1; + } + // Fold the (2,3) expansion into each party's ledger shares. + dpf::eval_full_add_into(l1, k1); + dpf::eval_full_add_into(l2, k2); + dpf::eval_full_add_into(l3, k3); + } + + // Slot 5 got two credits (100 + 7); slot 40 got 25; the rest are 0. + if (open2(l1[5], l2[5]) != fp61{107} + || open2(l1[40], l2[40]) != fp61{25} + || open2(l1[0], l2[0]).raw() != 0) + { + std::cerr << "ledger balance\n"; + return 1; + } + + // A proof that does not come from the same append is rejected: mixing one + // party's token from an independent key triple fails verification. + auto [b1, b2, b3] = dpf::make_dpf3(std::uint8_t{9}, fp61{1}, dpf::verifiable{}); + auto [c1, c2, c3] = dpf::make_dpf3(std::uint8_t{9}, fp61{1}, dpf::verifiable{}); + if (dpf::verify_dpf3(dpf::prove_dpf3(b1, std::uint8_t{9}), + dpf::prove_dpf3(b2, std::uint8_t{9}), + dpf::prove_dpf3(c3, std::uint8_t{9}))) + { + std::cerr << "ledger accepted a bad append\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("ledger23", + dpf::protocol::ledger23_append_plan(0), 2)) + return rc; + } + + std::cout << open2(l1[5], l2[5]).raw() << "\n"; + return 0; +} diff --git a/examples/applications/llama.cpp b/examples/applications/llama.cpp new file mode 100644 index 0000000..ce13352 --- /dev/null +++ b/examples/applications/llama.cpp @@ -0,0 +1,98 @@ +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" +#include "grotto/carry.hpp" +#include "grotto/carry_plan.hpp" + +// LLAMA, the FSS gates that touch a DPF (Gupta, Kumaraswamy, Chandran, +// and Gupta, ePrint 2022/793). Width gates call `grotto::sign_extend` and +// `grotto::truncate_reduce`. A degree-0 spline is one interval key per piece. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/llama.cpp + +int main() +{ + constexpr std::uint8_t r = 20; + constexpr std::uint8_t knot = 16; + const std::uint8_t threshold = static_cast(knot + r); + + auto [c0, c1] = dpf::make_dpf(threshold, dpf::gt(std::uint64_t{1})); + const auto above = dpf::reconstruct( + dpf::eval_point(dpf::cmp, c0, static_cast(30 + r)), + dpf::eval_point(dpf::cmp, c1, static_cast(30 + r))); + const auto below = dpf::reconstruct( + dpf::eval_point(dpf::cmp, c0, static_cast(4 + r)), + dpf::eval_point(dpf::cmp, c1, static_cast(4 + r))); + if (above != 1 || below != 0) + { + std::cerr << "llama comparison\n"; + return 1; + } + + auto [lo0, lo1] = dpf::make_dpf(r, dpf::ic(std::uint8_t{0}, std::uint8_t{15}, + std::uint64_t{2})); + auto [hi0, hi1] = dpf::make_dpf(r, dpf::ic(std::uint8_t{16}, std::uint8_t{31}, + std::uint64_t{5})); + + auto piece = [&](std::uint8_t x) { + const std::uint8_t x_hat = static_cast(x + r); + const auto lo = dpf::reconstruct( + dpf::eval_point(dpf::ic, lo0, x_hat), + dpf::eval_point(dpf::ic, lo1, x_hat)); + const auto hi = dpf::reconstruct( + dpf::eval_point(dpf::ic, hi0, x_hat), + dpf::eval_point(dpf::ic, hi1, x_hat)); + return lo + hi; + }; + if (piece(4) != 2 || piece(20) != 5 || piece(40) != 0) + { + std::cerr << "llama spline\n"; + return 1; + } + + // Truncate-reduce: drop 3 low bits of an 8-bit opening. + { + auto keys = grotto::make_truncate_reduce_keys(8, 3); + const std::uint64_t x0 = 0x05, x1 = 0x03; + const std::uint64_t opened = (x0 + x1 + keys.rin) & 0xffu; + const auto y0 = grotto::truncate_reduce(keys, 0, opened); + const auto y1 = grotto::truncate_reduce(keys, 1, opened); + const auto got = (y0.value + y1.value) & 0x1fu; + const auto want = grotto::eval_carry_clear(keys.recipe, x0, x1); + if (got != want) + { + std::cerr << "llama truncate_reduce\n"; + return 1; + } + } + + // Sign-extend: 8 → 16 bits. + { + auto keys = grotto::make_sign_extend_keys(8, 16); + const std::uint64_t x0 = 0x80, x1 = 0; + const std::uint64_t opened = (x0 + x1 + keys.rin) & 0xffu; + const std::uint64_t msb_high = 1; // 0x80 is negative + const auto y0 = grotto::sign_extend(keys, 0, opened, msb_high); + const auto y1 = grotto::sign_extend(keys, 1, opened, msb_high); + const auto got = (y0.value + y1.value) & 0xffffu; + const auto want = grotto::carry_extend_clear(x0, x1, 8, 16); + if (got != want) + { + std::cerr << "llama sign_extend\n"; + return 1; + } + } + + { + if (int rc = dpf::app::run_measured("llama", + dpf::protocol::range_count_plan(0), 8)) + return rc; + } + + std::cout << above << " " << piece(20) << "\n"; + return 0; +} diff --git a/examples/applications/mastic.cpp b/examples/applications/mastic.cpp new file mode 100644 index 0000000..7c0a1b3 --- /dev/null +++ b/examples/applications/mastic.cpp @@ -0,0 +1,94 @@ +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Mastic, the DPF step (private weighted heavy-hitters / attribute-based +// metrics). Each client keys an incremental DPF whose payload is its weight +// instead of a plain 1. Servers sum the weighted prefix shares at each depth +// and keep the heavy prefixes. This is Poplar's prefix walk with a weight +// payload; VIDPF path-consistency is `verify_idpf_path` below. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/mastic.cpp + +namespace +{ + +// Weighted counts of all 2^length prefixes, summed over the two clients. +template +std::vector weighted_level(Tag tag, std::size_t nprefix, + const A0 & a0, const A1 & a1, const Kb0 & b0, const Kb1 & b1) +{ + auto [ba0, ia0] = dpf::eval_prefixes(tag, a0); + auto [ba1, ia1] = dpf::eval_prefixes(tag, a1); + auto [bb0, ib0] = dpf::eval_prefixes(tag, b0); + auto [bb1, ib1] = dpf::eval_prefixes(tag, b1); + std::vector w(nprefix); + for (std::size_t p = 0; p < nprefix; ++p) + w[p] = dpf::reconstruct(ba0[p], ba1[p]) + + dpf::reconstruct(bb0[p], bb1[p]); + return w; +} + +std::vector path_challenges(std::size_t n) +{ + std::vector rs(n); + for (auto & r : rs) + r = dpf::uniform_sample(); + return rs; +} + +} // namespace + +int main() +{ + // Two clients report strings 0xA0 and 0xB0 (both begin "101"), with + // weights 5 and 3. A heavy-hitter threshold of 6 should keep prefix 101. + auto [a0, a1] = dpf::make_dpf(std::uint8_t{0xA0}, + dpf::idpf(std::uint64_t{5}, std::uint64_t{5}, std::uint64_t{5})); + auto [b0, b1] = dpf::make_dpf(std::uint8_t{0xB0}, + dpf::idpf(std::uint64_t{3}, std::uint64_t{3}, std::uint64_t{3})); + + // One-time VIDPF path check per client (weight-1 / parent consistency). + const auto rs = path_challenges(dpf::path_sketch_challenge_count(3)); + if (!dpf::verify_idpf_path<3>(a0, a1, rs) + || !dpf::verify_idpf_path<3>(b0, b1, rs)) + { + std::cerr << "mastic path sketch\n"; + return 1; + } + + // Length 1: prefix "1" carries the full weight 8; "0" carries 0. + const auto lvl1 = weighted_level(dpf::out<0, 1>, 2, a0, a1, b0, b1); + if (lvl1[1] != 8 || lvl1[0] != 0) + { + std::cerr << "mastic level1\n"; + return 1; + } + + // Length 3: prefix 101 (=5) is the heavy hitter with weight 8. + const auto lvl3 = weighted_level(dpf::out<2, 3>, 8, a0, a1, b0, b1); + constexpr std::uint64_t threshold = 6; + std::size_t heavy = 0, nheavy = 0; + for (std::size_t p = 0; p < lvl3.size(); ++p) + if (lvl3[p] >= threshold) { heavy = p; ++nheavy; } + if (nheavy != 1 || heavy != 0b101 || lvl3[0b101] != 8) + { + std::cerr << "mastic heavy\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("mastic", + dpf::protocol::poplar_prefix_plan(0), 8)) + return rc; + } + + std::cout << lvl3[0b101] << "\n"; + return 0; +} diff --git a/examples/applications/pika.cpp b/examples/applications/pika.cpp new file mode 100644 index 0000000..72be440 --- /dev/null +++ b/examples/applications/pika.cpp @@ -0,0 +1,72 @@ +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Pika, the lookup (Wagh, PoPETs 2022, Fig. 1). Party P2 is the dealer. +// P2 keys a unit DPF at a fresh index r and shares r. P0 and P1 open +// x = r - a, and take the inner product of the DPF with the table rotated +// by x. A word payload of 1 reconstructs to +1. A 1-bit payload lifts to +// +1 or -1; the dealer reads that sign off Gen's final control bit. +// +// The rotation is folded into the walk with `dpf::rotate{s}` (no rotated +// copy of the table), and the sign is recorded at keygen with +// `dpf::unit_sign` (no evaluator-side eval_point). +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/pika.cpp + +int main() +{ + constexpr std::size_t n = 256; + constexpr std::uint8_t r = 50; + constexpr std::uint8_t a0 = 10; + constexpr std::uint8_t a1 = 7; + constexpr std::uint8_t a = static_cast(a0 + a1); + constexpr std::uint8_t x = static_cast(r - a); + + std::vector table(n); + for (std::size_t i = 0; i < n; ++i) + table[i] = static_cast(i) * i; + + // Lookup: DPF at r dotted with the table read at (i - x) mod n, i.e. + // rotated by s = (n - x) mod n. The walk applies the offset; no copy. + auto [k0, k1] = dpf::make_dpf(r, std::uint64_t{1}); + const std::size_t s = (n - static_cast(x)) % n; + const auto value = dpf::reconstruct( + dpf::eval_full_inner_product(dpf::paired, k0, table, dpf::rotate{s}), + dpf::eval_full_inner_product(dpf::paired, k1, table, dpf::rotate{s})); + if (value != table[a]) + { + std::cerr << "pika lookup\n"; + return 1; + } + + // The early-stop bit leaf. The dealer, who sees both keys, records a + // sign of +1 or -1 at r via `unit_sign`; the evaluators never open r. + int w0 = 0, w1 = 0; + auto [b0, b1] = dpf::make_dpf(r, dpf::bit::one, dpf::unit_sign{w0, w1}); + const int sign = w0 - w1; + if (sign != 1 && sign != -1) + { + std::cerr << "pika sign\n"; + return 1; + } + if (dpf::reconstruct(*dpf::eval_point(k0, r), *dpf::eval_point(k1, r)) != 1) + { + std::cerr << "pika unit\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("pika", + dpf::protocol::pika_lookup_plan(0, 8, 3), 5)) + return rc; + } + + std::cout << value << "\n"; + return 0; +} diff --git a/examples/applications/pir3.cpp b/examples/applications/pir3.cpp new file mode 100644 index 0000000..62908d6 --- /dev/null +++ b/examples/applications/pir3.cpp @@ -0,0 +1,55 @@ +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Three-server index PIR. The database is public and replicated. The +// secret index is one (2,3) point key: each server holds one share and +// dots it with the database. Any two of those dots reconstruct the +// record. This is the library's three-evaluator key (ePrint 2024/1658), +// the same sharing the ledger appends with. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/pir3.cpp + +int main() +{ + constexpr std::size_t n = 256; + constexpr std::uint8_t index = 42; + + std::vector database(n); + for (std::size_t i = 0; i < n; ++i) + database[i] = dpf::fp61{static_cast(i * i + 1)}; + + auto [k1, k2, k3] = dpf::make_dpf3(index, dpf::fp61{1}); + const auto s1 = dpf::eval_full_inner_product(k1, database); + const auto s2 = dpf::eval_full_inner_product(k2, database); + const auto s3 = dpf::eval_full_inner_product(k3, database); + + const auto opened = dpf::shamir3::reconstruct( + dpf::as_share(k1, s1), dpf::as_share(k2, s2)); + const auto opened_13 = dpf::shamir3::reconstruct( + dpf::as_share(k1, s1), dpf::as_share(k3, s3)); + if (opened != database[index] || opened_13 != database[index]) + { + std::cerr << "pir3\n"; + return 1; + } + + { + // Client uploads one (2,3) key (two point-key spines) to each server. + constexpr std::size_t depth = 8; + constexpr std::size_t query_bytes = 2 * (16 + depth * 16); + if (int rc = dpf::app::run_measured("pir3", + dpf::protocol::n_server_pir_plan(0, 3, query_bytes, + sizeof(dpf::fp61)), + 2)) + return rc; + } + + std::cout << opened.raw() << "\n"; + return 0; +} diff --git a/examples/applications/pirsona_fetch.cpp b/examples/applications/pirsona_fetch.cpp new file mode 100644 index 0000000..a3f4bff --- /dev/null +++ b/examples/applications/pirsona_fetch.cpp @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +#include "dpf/online_session.hpp" + +// PIRsona BitMore fetch on a split-io async star (L=1 → 2 servers). +// +// c++ -std=c++17 -pthread -I include -I thirdparty \ +// examples/applications/pirsona_fetch.cpp + +int main() +{ + constexpr std::size_t L = 1; + constexpr std::size_t n = 1u << L; + auto seeds = std::make_shared>>(n); + auto answers = std::make_shared>>(n); + for (std::size_t i = 0; i < n; ++i) + { + (*seeds)[i].assign(16 * L, static_cast(i + 1)); + (*answers)[i].assign(8, static_cast(0x40 + i)); + } + try + { + auto client = dpf::protocol::pirsona_bitmore_fetch(L, 16, 8, seeds, answers); + const std::vector slots{16u * L, 8u}; + dpf::session::drive_async_star(n, slots, std::move(client), + [&](std::size_t i) { + return dpf::protocol::star_server_reply_rounds(16 * L, 8, + (*answers)[i]); + }); + std::cout << "pirsona_fetch rounds=" << (2 * n) << " servers=" << n + << "\n"; + } + catch (const std::exception & ex) + { + std::cerr << "pirsona_fetch: " << ex.what() << "\n"; + return 1; + } + return 0; +} diff --git a/examples/applications/prac.cpp b/examples/applications/prac.cpp new file mode 100644 index 0000000..bff5566 --- /dev/null +++ b/examples/applications/prac.cpp @@ -0,0 +1,97 @@ +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// PRAC, the DPF steps that are not Duoram (Sasy, Vadapalli, and Goldberg, +// ePrint 2023/1897). Binary search builds the path with `make_dpf` / +// `extend`, one prefix at a time. Heapify uses a wide `vec` leaf. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/prac.cpp + +namespace +{ + +constexpr std::size_t n = 256; +constexpr std::size_t bitlen = 8; +using beta_t = std::uint64_t; +using input_t = std::uint8_t; +using wide3 = dpf::vec; + +template +beta_t open_prefix(const Key0 & k0, const Key1 & k1, std::size_t level, + input_t x) +{ + auto one = [&](auto lvl) { + return dpf::reconstruct( + *dpf::eval_point(dpf::out, k0, x), + *dpf::eval_point(dpf::out, k1, x)); + }; + switch (level) + { + case 0: return one(std::integral_constant{}); + case 1: return one(std::integral_constant{}); + default: throw std::logic_error("prac: level"); + } +} + +} // namespace + +int main() +{ + constexpr std::array memory{ + 1, 3, 5, 7, 9, 11, 13, 15}; + constexpr std::uint64_t needle = 10; + + // Search path bits (MSB first): 1, then 0 → prefix 0b10...... + constexpr input_t path = 0x80; + auto [p0, p1] = dpf::make_dpf(path, dpf::at<1>(beta_t{1})); + auto [q0, q1] = dpf::extend(p0, p1, path, dpf::at<2>(beta_t{1})); + + constexpr std::uint64_t stride2[] = {memory[1], memory[5]}; + constexpr std::uint64_t stride4[] = {memory[0], memory[2], memory[4], memory[6]}; + + const auto sel1 = open_prefix(q0, q1, 0, path); + const auto sel2 = open_prefix(q0, q1, 1, path); + const auto at_5 = sel1 * stride2[1]; + const auto at_4 = sel2 * stride4[2]; + if (memory[3] != 7 || at_5 != 11 || at_4 != 9 + || sel1 != 1 || sel2 != 1) + { + std::cerr << "prac search " << at_5 << " " << at_4 << "\n"; + return 1; + } + constexpr unsigned answer = 0b101; + if (answer != 5 || memory[answer] < needle) + { + std::cerr << "prac index\n"; + return 1; + } + + // Heapify: one wide leaf of three lanes at the answer index. + wide3 payload{}; + payload.lanes = {1, 2, 3}; + auto [h0, h1] = dpf::make_dpf(static_cast(answer), payload); + const auto w0 = *dpf::eval_point(h0, static_cast(answer)); + const auto w1 = *dpf::eval_point(h1, static_cast(answer)); + const auto opened = dpf::reconstruct(w0, w1); + if (opened.lanes[0] != 1 || opened.lanes[1] != 2 || opened.lanes[2] != 3) + { + std::cerr << "prac heapify\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("prac", + dpf::protocol::poplar_prefix_plan(0), 8)) + return rc; + } + + std::cout << "prac ok\n"; + return 0; +} diff --git a/examples/applications/prio.cpp b/examples/applications/prio.cpp new file mode 100644 index 0000000..18f3012 --- /dev/null +++ b/examples/applications/prio.cpp @@ -0,0 +1,88 @@ +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Prio's frequency count, with the one-hot vector replaced by a DPF, and +// the prefix walk Poplar uses for heavy hitters (Boneh, Boyle, +// Corrigan-Gibbs, Gilboa, Ishai). Classic Prio proves an encoding with a +// SNIP; this file is only the DPF-shaped encoding. +// field64 is libprio's Field64. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/prio.cpp + +namespace +{ + +constexpr int nbins = 256; + +} // namespace + +int main() +{ + // Histogram. Each client sends one unit DPF at a secret bin. + // Each server adds the expansion into its running share with + // `eval_full_add_into` (no separate expansion buffer). The opened bin + // is the count. + const std::array bins{3, 3, 7, 3}; + std::vector h0(nbins); + std::vector h1(nbins); + for (std::uint8_t bin : bins) + { + auto [k0, k1] = dpf::make_dpf(bin, dpf::field64{1}); + dpf::eval_full_add_into(h0, k0); + dpf::eval_full_add_into(h1, k1); + } + // Leaf shares are subtractive, so the opened bin is share0 - share1. + const dpf::field64 c3 = h0[3] - h1[3]; + const dpf::field64 c7 = h0[7] - h1[7]; + const dpf::field64 c0 = h0[0] - h1[0]; + if (c3.raw() != 3 || c7.raw() != 1 || c0.raw() != 0) + { + std::cerr << "prio histogram\n"; + return 1; + } + + // Heavy-hitter prefixes. idpf plants a 1 on each prefix length. + // Length 1 is the high bit. 0xA0 and 0xB0 share 101; they split at bit 4. + constexpr std::uint8_t left = 0xA0; + constexpr std::uint8_t right = 0xB0; + auto [a0, a1] = dpf::make_dpf(left, + dpf::idpf(std::uint64_t{1}, std::uint64_t{1}, std::uint64_t{1})); + auto [b0, b1] = dpf::make_dpf(right, + dpf::idpf(std::uint64_t{1}, std::uint64_t{1}, std::uint64_t{1})); + + auto one = [](auto tag, auto k0, auto k1, std::uint8_t node) { + return dpf::reconstruct(*dpf::eval_point(tag, k0, node), + *dpf::eval_point(tag, k1, node)); + }; + auto count = [&](auto tag, std::uint8_t node) { + return one(tag, a0, a1, node) + one(tag, b0, b1, node); + }; + + // out<0> is prefix length 1, out<1> length 2, out<2> length 3. + const auto high = count(dpf::out<0, 1>, std::uint8_t{0x80}); + const auto low = count(dpf::out<0, 1>, std::uint8_t{0x00}); + const auto shared = count(dpf::out<2, 3>, std::uint8_t{0xA0}); + const auto split = count(dpf::out<2, 3>, std::uint8_t{0x80}); + if (high != 2 || low != 0 || shared != 2 || split != 0) + { + std::cerr << "prio prefixes " << high << " " << low << " " << shared + << " " << split << "\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("prio", + dpf::protocol::poplar_prefix_plan(0), 8)) + return rc; + } + + std::cout << c3.raw() << "\n"; + return 0; +} diff --git a/examples/applications/psi.cpp b/examples/applications/psi.cpp new file mode 100644 index 0000000..c90a3fd --- /dev/null +++ b/examples/applications/psi.cpp @@ -0,0 +1,75 @@ +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Private set intersection, the DPF step (Kolesnikov, Kumaresan, Rosulek, +// and Trieu, CCS 2016). The sender keeps a puncturable-PRF master. Each +// receiver element is a puncture; the servers evaluate the punctured key +// and test whether the tag sits in the sender's image. No full-domain table. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/psi.cpp + +namespace +{ + +using domain_t = std::uint8_t; + +bool blocks_eq(simde__m128i a, simde__m128i b) +{ + return std::memcmp(&a, &b, sizeof(a)) == 0; +} + +bool in_image(simde__m128i tag, const std::vector & image) +{ + for (auto v : image) + if (blocks_eq(v, tag)) + return true; + return false; +} + +} // namespace + +int main() +{ + auto master = dpf::make_pprf_master(); + + const domain_t sender[] = {4, 10, 42}; + const domain_t receiver[] = {42, 7}; + + std::vector image; + for (auto x : sender) + image.push_back(dpf::pprf_eval(master, x)); + + auto punctured_hit = dpf::puncture(master, receiver[0]); + auto punctured_miss = dpf::puncture(master, receiver[1]); + + // Off-path points agree with the master; the programmed leaf at alpha + // matches the master leaf (sender who keeps the master set it). + const auto hit = dpf::pprf_eval(punctured_hit, receiver[0]); + const auto miss_off = dpf::pprf_eval(punctured_miss, domain_t{0}); + const auto master_miss_off = dpf::pprf_eval(master, domain_t{0}); + + if (!blocks_eq(hit, dpf::pprf_eval(master, receiver[0])) + || !in_image(hit, image) + || in_image(dpf::pprf_eval(master, receiver[1]), image) + || !blocks_eq(miss_off, master_miss_off)) + { + std::cerr << "psi\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("psi", + dpf::protocol::psi_cuckoo_plan(0, {0, 1, 0}), 9)) + return rc; + } + + std::cout << "1\n"; + return 0; +} diff --git a/examples/applications/range_count.cpp b/examples/applications/range_count.cpp new file mode 100644 index 0000000..ace85ea --- /dev/null +++ b/examples/applications/range_count.cpp @@ -0,0 +1,61 @@ +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// A private range count. Each secret value is one comparison key. The +// public interval is [lo, hi). The comparison opens to 1 at a query q +// when q is strictly above the secret value, so the two endpoints +// differ by 1 exactly on lo <= v < hi. The count is the sum of those +// bits. The servers never see a value, and the interval is public. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/range_count.cpp + +namespace +{ + +std::uint64_t inside(std::uint8_t value, std::uint8_t lo, std::uint8_t hi) +{ + auto [k0, k1] = dpf::make_dpf(value, dpf::gt(std::uint64_t{1})); + const auto above_lo = dpf::reconstruct( + dpf::eval_point(dpf::cmp, k0, lo), + dpf::eval_point(dpf::cmp, k1, lo)); + const auto above_hi = dpf::reconstruct( + dpf::eval_point(dpf::cmp, k0, hi), + dpf::eval_point(dpf::cmp, k1, hi)); + // eval(q) = 1 iff q > value, so eval(hi) - eval(lo) = 1{lo <= value < hi}. + return above_hi - above_lo; +} + +} // namespace + +int main() +{ + constexpr std::uint8_t lo = 10; + constexpr std::uint8_t hi = 20; + const std::uint8_t values[] = {3, 10, 12, 19, 20, 40}; + + std::uint64_t count = 0; + for (auto v : values) + count += inside(v, lo, hi); + + // 10, 12, and 19. 3 and 40 are outside. 20 is the open end. + if (count != 3 || inside(10, lo, hi) != 1 || inside(20, lo, hi) != 0 + || inside(9, lo, hi) != 0) + { + std::cerr << "range count " << count << "\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("range_count", + dpf::protocol::range_count_plan(0), 8)) + return rc; + } + + std::cout << count << "\n"; + return 0; +} diff --git a/examples/applications/sabre.cpp b/examples/applications/sabre.cpp new file mode 100644 index 0000000..90679b6 --- /dev/null +++ b/examples/applications/sabre.cpp @@ -0,0 +1,79 @@ +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Sabre, the mailbox write with a fast audit (Vadapalli, Storrier, and Henry, +// S&P 2022). Sender-anonymous messaging: two servers hold subtractive shares +// of every mailbox and the client sends one key each. Like Express the write +// is a full-domain add; unlike Express the audit is a *verifiable* DPF proof +// (Boyle et al. once-per-node fold), a constant-size token per party that +// opens to accept iff the key is a single honest point. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/sabre.cpp + +namespace +{ + +constexpr std::size_t nboxes = 256; + +} // namespace + +int main() +{ + constexpr std::uint8_t address = 17; + constexpr std::uint64_t message = 42; + + auto [k0, k1] = dpf::make_dpf(address, message, dpf::verifiable{}); + + // Each server folds the write into its mailbox shares (one full walk). + std::vector box0(nboxes, 0), box1(nboxes, 0); + dpf::eval_full_add_into(box0, k0); + dpf::eval_full_add_into(box1, k1); + if (box0[address] - box1[address] != message) + { + std::cerr << "sabre mailbox\n"; + return 1; + } + if (box0[0] - box1[0] != 0) + { + std::cerr << "sabre neighbor\n"; + return 1; + } + + // Fast audit: a full-domain VDPF proof. Each party folds a constant-size + // token; the tokens open to accept an honest single-point write. + dpf::proof_token pi0{}, pi1{}; + dpf::prove_full(k0, dpf::prove(pi0)); + dpf::prove_full(k1, dpf::prove(pi1)); + if (!dpf::verify(pi0, pi1)) + { + std::cerr << "sabre audit\n"; + return 1; + } + + // A proof folded over a mismatched pair of points (the shape a malformed, + // multi-point write produces) fails the same check. + dpf::proof_token bad0{}, bad1{}; + dpf::prove_interval(k0, std::uint8_t{0}, std::uint8_t{7}, dpf::prove(bad0)); + dpf::prove_interval(k1, std::uint8_t{8}, std::uint8_t{15}, dpf::prove(bad1)); + if (dpf::verify(bad0, bad1)) + { + std::cerr << "sabre audit accepted a mismatch\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("sabre", + dpf::protocol::mailbox_write_fused_plan(0, 8), 8)) + return rc; + } + + std::cout << (box0[address] - box1[address]) << "\n"; + return 0; +} diff --git a/examples/applications/splinter.cpp b/examples/applications/splinter.cpp new file mode 100644 index 0000000..e466a15 --- /dev/null +++ b/examples/applications/splinter.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Splinter, the DPF query step (Wang, Yun, Goldwasser, Vaikuntanathan, and +// Zeldovich, NSDI 2017). Private queries on public data with two-server FSS. +// The client's private selector is a unit DPF at a secret attribute value. +// Each server dots that selector with a public aggregate column, so the +// answer is the SUM (or COUNT) for the private key without either server +// learning which key was asked. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/splinter.cpp + +int main() +{ + constexpr std::size_t domain = 256; // attribute values + + // Public data, pre-aggregated by attribute: group_sum[v] is the SUM of a + // value column over the rows whose attribute equals v. + std::vector group_sum(domain); + std::vector group_cnt(domain, 1); + for (std::size_t v = 0; v < domain; ++v) + group_sum[v] = (v * 37 + 11) % 1000; + + constexpr std::uint8_t secret_key = 88; // the private WHERE value + + // One selector key per server. reconstruct = the two servers' shares. + auto [k0, k1] = dpf::make_dpf(secret_key, std::uint64_t{1}); + + // SELECT SUM(value) WHERE attribute = secret_key. + const auto sum = dpf::reconstruct( + dpf::eval_full_inner_product(dpf::paired, k0, group_sum), + dpf::eval_full_inner_product(dpf::paired, k1, group_sum)); + if (sum != group_sum[secret_key]) + { + std::cerr << "splinter sum\n"; + return 1; + } + + // SELECT COUNT(*) WHERE attribute = secret_key is the same selector on an + // all-ones column. + const auto cnt = dpf::reconstruct( + dpf::eval_full_inner_product(dpf::paired, k0, group_cnt), + dpf::eval_full_inner_product(dpf::paired, k1, group_cnt)); + if (cnt != 1) + { + std::cerr << "splinter count\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("splinter", + dpf::protocol::fss_point_plan(0), 8)) + return rc; + } + + std::cout << sum << "\n"; + return 0; +} diff --git a/examples/applications/subleq.cpp b/examples/applications/subleq.cpp new file mode 100644 index 0000000..f80de37 --- /dev/null +++ b/examples/applications/subleq.cpp @@ -0,0 +1,132 @@ +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// MPC SUBLEQ, the DPF steps of one instruction (Jiang and Henry). +// Offline: expand wildcard unit keys with `defer_eval_full` before the +// addresses are known. Online: assign each address into `offset_x`, read +// by rotating the prepaid buffer (no second AES pass), write by scaling +// the same `e_B` view, and branch with a path evaluation of `x ≤ 0`. +// +// Instruction fetch is the same prepaid unit dotted against three sliding +// windows of D; this listing starts after (A, B, C) are already shares. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/subleq.cpp + +namespace +{ + +using addr_t = std::uint8_t; +using word_t = std::uint32_t; +constexpr std::size_t n = 256; + +template +void assign_input(Key0 & k0, Key1 & k1, T alpha) +{ + const T a0 = static_cast(0x12); + const T a1 = static_cast(alpha - a0); + const auto s0 = k0.offset_x.compute_and_get_share(a0); + const auto s1 = k1.offset_x.compute_and_get_share(a1); + k0.offset_x.reconstruct(s1); + k1.offset_x.reconstruct(s0); +} + +/// Opened unit · public memory over `[0, n)`. +template +word_t dot_prefix(View0 && v0, View1 && v1, const std::vector & mem) +{ + word_t acc = 0; + auto it0 = std::begin(v0); + auto it1 = std::begin(v1); + for (std::size_t i = 0; i < n; ++i, ++it0, ++it1) + acc += dpf::reconstruct(*it0, *it1) * mem[i]; + return acc; +} + +template +void add_scaled_prefix(std::vector & mem, View0 && v0, View1 && v1, + word_t scale) +{ + auto it0 = std::begin(v0); + auto it1 = std::begin(v1); + for (std::size_t i = 0; i < n; ++i, ++it0, ++it1) + mem[i] += scale * dpf::reconstruct(*it0, *it1); +} + +} // namespace + +int main() +{ + // Two's-complement words in a uint32_t container (same bits as int32_t). + constexpr addr_t A = 3; + constexpr addr_t B = 7; + constexpr addr_t C = 2; + constexpr addr_t pc = 0; + std::vector D(n); + D[A] = 5; + D[B] = 3; // after SUBLEQ: D[B] = 3 - 5 = -2 ≤ 0 → pc' = C + + // --- Offline: wildcard unit keys, full-domain expand at identity ----- + auto [kA0, kA1] = dpf::make_dpf(dpf::wildcard_value{}, word_t{1}); + auto [kB0, kB1] = dpf::make_dpf(dpf::wildcard_value{}, word_t{1}); + auto bufA0 = dpf::make_output_buffer_for_full(kA0); + auto bufA1 = dpf::make_output_buffer_for_full(kA1); + auto bufB0 = dpf::make_output_buffer_for_full(kB0); + auto bufB1 = dpf::make_output_buffer_for_full(kB1); + auto defA0 = dpf::defer_eval_full(kA0, bufA0); + auto defA1 = dpf::defer_eval_full(kA1, bufA1); + auto defB0 = dpf::defer_eval_full(kB0, bufB0); + auto defB1 = dpf::defer_eval_full(kB1, bufB1); + + // --- Online: open addresses, rotate prepaid unit vectors ------------- + assign_input(kA0, kA1, A); + assign_input(kB0, kB1, B); + + const word_t DA = dot_prefix(defA0.get(), defA1.get(), D); + const word_t DB = dot_prefix(defB0.get(), defB1.get(), D); + if (DA != D[A] || DB != D[B]) + { + std::cerr << "subleq read\n"; + return 1; + } + + const word_t x = static_cast(DB - DA); // wraps to -2 as uint32_t + + // Write D[B] ← D[B] - D[A] by adding (-DA) · e_B. The protocol Beavers + // the scale; the opened -DA stands in here. + add_scaled_prefix(D, defB0.get(), defB1.get(), static_cast(-DA)); + if (D[B] != static_cast(3 - 5) || D[A] != 5) + { + std::cerr << "subleq write\n"; + return 1; + } + + // Branch: path eval only — never expand the word-domain key. + // `leq` at knot 0, evaluated at x: 1 iff x ≤ 0 in signed order. + auto [kZ0, kZ1] = dpf::make_dpf(std::int32_t{0}, dpf::leq(std::uint64_t{1})); + const auto b = dpf::reconstruct( + dpf::eval_point(dpf::cmp, kZ0, static_cast(x)), + dpf::eval_point(dpf::cmp, kZ1, static_cast(x))); + const addr_t pc_next = b ? C : static_cast(pc + 3); + if (b != 1 || pc_next != C) + { + std::cerr << "subleq branch\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("subleq", + dpf::protocol::subleq_instruction_plan(0), 8)) + return rc; + } + + std::cout << static_cast(D[B]) << " " + << static_cast(pc_next) << "\n"; + return 0; +} diff --git a/examples/applications/waldo.cpp b/examples/applications/waldo.cpp new file mode 100644 index 0000000..a6bb94a --- /dev/null +++ b/examples/applications/waldo.cpp @@ -0,0 +1,69 @@ +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" + +// Waldo, the FSS steps (Dauterman, Fang, Crooks, and Popa, S&P 2022). A +// private time-series database. The store is append-only: a new event writes +// a fresh point and never updates an old one. A range/threshold aggregate +// uses the comparison (DCF) channel: the parties dot the per-timestamp +// comparison shares with a public value column, so a SUM over the timestamps +// past a *secret* threshold reveals neither the threshold nor the matches. +// +// c++ -std=c++17 -march=native -I include -I thirdparty \ +// examples/applications/waldo.cpp + +int main() +{ + constexpr std::size_t horizon = 256; // timestamp domain + + // Append-only writes. Each event is a unit DPF at its timestamp; the + // servers fold it into their subtractive value shares. Never an update. + std::vector col0(horizon, 0), col1(horizon, 0); + const std::pair events[] = { + {30, 5}, {90, 8}, {200, 3}}; + for (auto [ts, val] : events) + { + auto [k0, k1] = dpf::make_dpf(ts, val); + dpf::eval_full_add_into(col0, k0); + dpf::eval_full_add_into(col1, k1); + } + if (col0[90] - col1[90] != 8 || col0[30] - col1[30] != 5) + { + std::cerr << "waldo append\n"; + return 1; + } + + // Public per-timestamp magnitudes (metadata the response consumes). + std::vector magnitude(horizon, 0); + for (auto [ts, val] : events) + magnitude[ts] = val; + + // Private-threshold aggregate: SUM of magnitudes at timestamps > T, with + // T secret. Key a gt comparison at T and dot its per-timestamp shares + // with the public magnitude column in one comparison walk. + constexpr std::uint8_t secret_T = 50; + auto [c0, c1] = dpf::make_dpf(secret_T, dpf::gt(std::uint64_t{1})); + const auto h0 = dpf::eval_full_inner_product(dpf::cmp, c0, magnitude); + const auto h1 = dpf::eval_full_inner_product(dpf::cmp, c1, magnitude); + const auto after = dpf::reconstruct_cmp_halves(h0, h1).raw(); + // Timestamps 90 and 200 are past T=50: 8 + 3 = 11. + if (after != 11) + { + std::cerr << "waldo threshold aggregate " << after << "\n"; + return 1; + } + + { + if (int rc = dpf::app::run_measured("waldo", + dpf::protocol::fss_cmp_plan(0), 8)) + return rc; + } + + std::cout << after << "\n"; + return 0; +} diff --git a/examples/evaluation/defer_eval.cpp b/examples/evaluation/defer_eval.cpp new file mode 100644 index 0000000..6b66791 --- /dev/null +++ b/examples/evaluation/defer_eval.cpp @@ -0,0 +1,57 @@ +#include +#include + +#include "dpf.hpp" + +/// Pre-assign full-domain expand, then rotate after the input wildcard opens. +int main() +{ + using input_type = std::uint8_t; + using output_type = std::uint64_t; + const output_type beta = 7; + const input_type alpha = 42; + const input_type from = 40; + const input_type to = 50; + + auto [k0, k1] = dpf::make_dpf(dpf::wildcard_value{}, beta); + + //! [defer-eval] + auto buf0 = dpf::make_output_buffer_for_full(k0); + auto buf1 = dpf::make_output_buffer_for_full(k1); + auto deferred0 = dpf::defer_eval_interval(k0, from, to, buf0); + auto deferred1 = dpf::defer_eval_interval(k1, from, to, buf1); + + // Parties open mask - alpha into offset_x (local demo of the exchange). + const input_type a0 = 0x12; + const input_type a1 = static_cast(alpha - a0); + const auto sh0 = k0.offset_x.compute_and_get_share(a0); + const auto sh1 = k1.offset_x.compute_and_get_share(a1); + k0.offset_x.reconstruct(sh1); + k1.offset_x.reconstruct(sh0); + + auto view0 = deferred0.get(); + auto view1 = deferred1.get(); + //! [defer-eval] + + auto it0 = std::begin(view0); + auto it1 = std::begin(view1); + for (input_type x = from; x <= to; ++x, ++it0, ++it1) + { + const output_type got = dpf::reconstruct(*it0, *it1); + const output_type expect = (x == alpha) ? beta : 0; + if (got != expect) + { + std::cerr << "defer_eval\n"; + return 1; + } + } + if (it0 != std::end(view0) || it1 != std::end(view1)) + { + std::cerr << "defer_eval length\n"; + return 1; + } + + std::cout << dpf::reconstruct(*std::begin(view0), *std::begin(view1)) + << "\n"; + return 0; +} diff --git a/examples/evaluation/eval_dpf3_cmp_ic.cpp b/examples/evaluation/eval_dpf3_cmp_ic.cpp new file mode 100644 index 0000000..f7eb0ee --- /dev/null +++ b/examples/evaluation/eval_dpf3_cmp_ic.cpp @@ -0,0 +1,44 @@ +#include +#include + +#include "dpf.hpp" + +/// Three-party comparison and interval-containment keys (one DCF share each). +int main() +{ + using Input = std::uint8_t; + const Input thresh = 100; + const std::uint64_t beta = 5; + + //! [eval-dpf3-cmp] + auto [c1, c2, c3] = dpf::make_dpf3_cmp(thresh, beta); + // Parties 1 and 3 hold the k0 half; party 2 holds k1. Open any complementary pair. + const dpf::fp61 hot = + dpf::reconstruct_cmp_halves(dpf::eval_point(c1, Input{10}), + dpf::eval_point(c2, Input{10})); + const dpf::fp61 cold = + dpf::reconstruct_cmp_halves(dpf::eval_point(c3, Input{200}), + dpf::eval_point(c2, Input{200})); + //! [eval-dpf3-cmp] + if (hot.raw() != beta || cold.raw() != 0) + { + std::cerr << "dpf3 cmp\n"; + return 1; + } + + //! [eval-dpf3-ic] + auto [i1, i2, i3] = dpf::make_dpf3_ic(Input{10}, Input{20}, Input{40}, beta); + // Interval is relative to the public shift `r`; x=35 is on for (20,40)@r=10. + const dpf::fp61 inside = + dpf::reconstruct_cmp_halves(dpf::eval_point(i1, Input{35}), + dpf::eval_point(i2, Input{35})); + //! [eval-dpf3-ic] + if (inside.raw() != beta) + { + std::cerr << "dpf3 ic\n"; + return 1; + } + + std::cout << hot.raw() << "\n"; + return 0; +} diff --git a/examples/evaluation/eval_dpf3_doerner_shelat.cpp b/examples/evaluation/eval_dpf3_doerner_shelat.cpp new file mode 100644 index 0000000..f160797 --- /dev/null +++ b/examples/evaluation/eval_dpf3_doerner_shelat.cpp @@ -0,0 +1,36 @@ +#include +#include + +#include "dpf.hpp" + +/// Dual-spine Doerner–Shelat (2,3) keygen: XOR shares of `α`, same clear `β` +/// as honest-dealer `make_dpf3(α, β)`. +int main() +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x13; + const Input x1 = static_cast(alpha ^ x0); + const dpf::fp61 beta{99}; + + //! [eval-dpf3-ds] + auto [d1, d2, d3] = dpf::make_dpf3(alpha, beta); + auto [s1, s2, s3] = dpf::make_dpf3_doerner_shelat(x0, x1, beta); + const dpf::fp61 dealer = dpf::reconstruct( + dpf::as_share(d1, dpf::eval_point(d1, alpha)), + dpf::as_share(d2, dpf::eval_point(d2, alpha)), + dpf::as_share(d3, dpf::eval_point(d3, alpha))); + const dpf::fp61 dual = dpf::reconstruct( + dpf::as_share(s1, dpf::eval_point(s1, alpha)), + dpf::as_share(s2, dpf::eval_point(s2, alpha)), + dpf::as_share(s3, dpf::eval_point(s3, alpha))); + //! [eval-dpf3-ds] + if (dealer != beta || dual != beta) + { + std::cerr << "dealer vs dual-spine disagree\n"; + return 1; + } + + std::cout << dual.raw() << "\n"; + return 0; +} diff --git a/examples/evaluation/eval_dpf3_point.cpp b/examples/evaluation/eval_dpf3_point.cpp new file mode 100644 index 0000000..142d8e9 --- /dev/null +++ b/examples/evaluation/eval_dpf3_point.cpp @@ -0,0 +1,42 @@ +#include +#include + +#include "dpf.hpp" + +/// Three-evaluator point DPF (ePrint 2024/1658 Fig. 3). Each key is a Shamir +/// share; open with any two (or all three) via `dpf::reconstruct`. +int main() +{ + using Input = std::uint8_t; + const Input alpha = 42; + const dpf::fp61 beta{7}; + + //! [eval-dpf3-point] + auto [k1, k2, k3] = dpf::make_dpf3(alpha, beta); + const dpf::fp61 y1 = dpf::eval_point(k1, alpha); + const dpf::fp61 y2 = dpf::eval_point(k2, alpha); + const dpf::fp61 y3 = dpf::eval_point(k3, alpha); + const dpf::fp61 opened = dpf::reconstruct( + dpf::as_share(k1, y1), dpf::as_share(k2, y2), dpf::as_share(k3, y3)); + //! [eval-dpf3-point] + if (opened != beta) + { + std::cerr << "dpf3 at the programmed input\n"; + return 1; + } + + const dpf::fp61 z1 = dpf::eval_point(k1, Input{41}); + const dpf::fp61 z2 = dpf::eval_point(k2, Input{41}); + const dpf::fp61 z3 = dpf::eval_point(k3, Input{41}); + if (dpf::reconstruct(dpf::as_share(k1, z1), dpf::as_share(k2, z2), + dpf::as_share(k3, z3)) + .raw() + != 0) + { + std::cerr << "dpf3 off the programmed input\n"; + return 1; + } + + std::cout << opened.raw() << "\n"; + return 0; +} diff --git a/examples/evaluation/eval_inner_product.cpp b/examples/evaluation/eval_inner_product.cpp new file mode 100644 index 0000000..3198d6a --- /dev/null +++ b/examples/evaluation/eval_inner_product.cpp @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include + +#include "dpf.hpp" + +/// Fused inner product: do not materialize the DPF vector. +/// A scalar weight vector dots with one output. A row of a tuple or +/// `std::array` dots with several outputs, including an ancestor slot +/// and the leaf, read off one path. +int main() +{ + using In = std::uint8_t; + + //! [eval-inner-product-scalar] + // Trivial: sum_x DPF(x) * w[x] over a short interval. + const In alpha = 42; + const std::uint64_t beta = 7; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + const In from = 40; + const In to = 50; + std::vector w(to - from + 1); + for (std::size_t i = 0; i < w.size(); ++i) + w[i] = i + 1; + const auto s0 = dpf::eval_inner_product(dpf::paired, k0, from, to, w); + const auto s1 = dpf::eval_inner_product(dpf::paired, k1, from, to, w); + //! [eval-inner-product-scalar] + if (dpf::reconstruct(s0, s1) != beta * w[alpha - from]) + { + std::cerr << "scalar interval\n"; + return 1; + } + + //! [eval-inner-product-full] + // Trivial full domain. Only α contributes. + std::vector wall(256, 1); + const auto f0 = dpf::eval_full_inner_product(dpf::paired, k0, wall); + const auto f1 = dpf::eval_full_inner_product(dpf::paired, k1, wall); + //! [eval-inner-product-full] + if (dpf::reconstruct(f0, f1) != beta) + { + std::cerr << "full\n"; + return 1; + } + + //! [eval-inner-product-paired] + // Two outputs on the same leaf. rows[i] = {weight for output 0, output 1}. + auto [p0, p1] = dpf::make_dpf(In{9}, std::uint32_t{3}, std::uint32_t{5}); + std::vector> rows; + for (In x = 8;; ++x) + { + rows.push_back({std::uint32_t{1}, std::uint32_t{x}}); + if (x == 10) + break; + } + const auto a0 = dpf::eval_inner_product<0, 1>(dpf::paired, p0, In{8}, In{10}, rows); + const auto a1 = dpf::eval_inner_product<0, 1>(dpf::paired, p1, In{8}, In{10}, rows); + //! [eval-inner-product-paired] + // x=9 is hot: output0 * 1 + output1 * 9. + if (dpf::reconstruct(a0, a1) != std::uint64_t{3} * 1u + std::uint64_t{5} * 9u) + { + std::cerr << "paired leaf\n"; + return 1; + } + + //! [eval-inner-product-ancestor] + // Prefix slot at<4> and the full-domain leaf, one path per point. + // 0x2a and 0x2b share the high nibble 0x2, so both see payload 5 there. + // 0x10 is a different nibble. Only 0x2a is hot on the leaf. + auto [h0, h1] = dpf::make_dpf(In{0x2a}, dpf::at<4>(std::uint8_t{5}), std::uint8_t{9}); + const std::vector pts{0x10, 0x2a, 0x2b}; + const std::vector> hw{ + {1u, 0u}, {1u, 1u}, {2u, 4u}}; + const auto q0 = dpf::eval_sequence_inner_product<0, 1>(h0, pts.begin(), pts.end(), hw); + const auto q1 = dpf::eval_sequence_inner_product<0, 1>(h1, pts.begin(), pts.end(), hw); + //! [eval-inner-product-ancestor] + // 0x10 is off. 0x2a: 5*1 + 9*1. 0x2b: prefix still 5, leaf 0, times (2, 4). + const std::uint64_t ancestor_expect = 5u * 1u + 9u * 1u + 5u * 2u; + if (dpf::reconstruct(q0, q1) != ancestor_expect) + { + std::cerr << "ancestor\n"; + return 1; + } + + //! [eval-inner-product-recipe] + const auto recipe = dpf::make_sequence_recipe(pts.begin(), pts.end()); + const auto r0 = dpf::eval_sequence_inner_product<0, 1>( + h0, recipe, pts.begin(), pts.end(), hw); + const auto r1 = dpf::eval_sequence_inner_product<0, 1>( + h1, recipe, pts.begin(), pts.end(), hw); + //! [eval-inner-product-recipe] + if (dpf::reconstruct(r0, r1) != ancestor_expect) + { + std::cerr << "recipe\n"; + return 1; + } + + std::cout << dpf::reconstruct(s0, s1) << "\n"; + return 0; +} diff --git a/examples/grotto/dwt_lut.cpp b/examples/grotto/dwt_lut.cpp new file mode 100644 index 0000000..e04c32d --- /dev/null +++ b/examples/grotto/dwt_lut.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +#include + +#include "grotto.hpp" + +// Haar and bior(5,3) lookup tables (Reis, Ugurbil, Wagh, Henry, de Vega, +// PoPETs 2025, ePrint 2025/013). The grid is sigmoid on [0, 4), stored as +// Q4.4. Depth 2 keeps the top 4 bits of a 6-bit index. +// +// c++ -std=c++17 -march=native -I include -I thirdparty examples/grotto/dwt_lut.cpp + +int main() +{ + //! [dwt-lut] + constexpr unsigned domain_bits = 6; + constexpr unsigned fractional_bits = 4; + constexpr unsigned depth = 2; + auto samples = grotto::sample_dwt_signal(domain_bits, fractional_bits, + [](double x) { + return 1.0 / (1.0 + std::exp(-(x - 2.0))); + }); + auto haar = grotto::make_haar_dwt_lut(samples, fractional_bits, depth); + auto bior = grotto::make_bior53_dwt_lut(samples, fractional_bits, depth); + + // Haar is the mean of each block of 2^depth samples, then quantized. + const std::uint64_t raw = 32; + double block = 0; + for (unsigned k = 0; k < 4; ++k) + block += samples[(raw & ~std::uint64_t{3}) + k]; + const auto haar_expect = static_cast( + std::floor(block / 4.0 * 16.0)); + + // bior(5,3), lsb = 0: only the first tap, at index msb+2, divided by 2^j. + const std::uint64_t msb = raw >> depth; + const auto c0 = bior.coeff[(msb + 2) % bior.coeff.size()]; + const auto bior_at_32 = c0 / 4; + + // lsb = 1: both taps, weights (2^j - lsb) and lsb, then divide by 2^{2j}. + const auto c1 = bior.coeff[(msb + 3) % bior.coeff.size()]; + const auto bior_at_33 = (c0 * 3 + c1) / 16; + //! [dwt-lut] + + if (haar(raw) != haar_expect || haar(raw) != 8) + { + std::cerr << "haar lut\n"; + return 1; + } + if (bior(raw) != bior_at_32 || bior(33) != bior_at_33 || bior(raw) != 8) + { + std::cerr << "bior lut\n"; + return 1; + } + + std::cout << haar(raw) << " " << bior(raw) << " " << bior(33) << "\n"; + return 0; +} diff --git a/examples/grotto/jet_and_ring.cpp b/examples/grotto/jet_and_ring.cpp new file mode 100644 index 0000000..bfe37ab --- /dev/null +++ b/examples/grotto/jet_and_ring.cpp @@ -0,0 +1,98 @@ +#include +#include +#include + +#include "grotto.hpp" + +/// Binomial jet readouts and an exact ring switch from one public offset. +int main() +{ + //! [jet-and-ring] + // --- Binomial jet ------------------------------------------------------- + // After eta opens, the jet is the binomial basis at the wrapped + // center+kappa. Degree 3 leaves room for a degree-2 hockey-stick prefix. + const std::uint8_t center = 12; + const std::uint8_t eta = 3; + const std::uint8_t point = static_cast(center + eta); // 15 + const std::size_t degree = 3; + auto jet_keys = grotto::make_offset_jet_keys(center, degree); + // f(t) = 4 + 2 C(t,1) + C(t,2) (padded to degree 3). + const std::vector poly{4, 2, 1}; + std::vector coeff = poly; + coeff.push_back(0); + const std::vector knots{0}; + + const auto j0 = grotto::offset_jet_shares<0>(jet_keys, knots, eta); + const auto j1 = grotto::offset_jet_shares<1>(jet_keys, knots, eta); + std::vector jet(degree + 1); + for (std::size_t k = 0; k <= degree; ++k) + jet[k] = j0[k] + j1[k]; + + const std::uint64_t value = grotto::offset_jet_dot(coeff, jet); + const std::uint64_t diff = grotto::offset_jet_dot( + grotto::offset_jet_difference_coeff(coeff), jet); + const std::uint64_t prefix = grotto::offset_jet_dot( + grotto::offset_jet_prefix_coeff(poly), jet); + + // Padé / Newton are public dots against the same jet, then one reciprocal + // after the shares are opened. For a seed p(t)/p'(t): + // auto num = offset_jet_dot(coeff, jet); + // auto den = offset_jet_dot(offset_jet_difference_coeff(coeff), jet); + // // open num, den; one masked reciprocal; Newton: t - num/den. + + // --- Exact ring switch -------------------------------------------------- + // Same public-offset pattern: eta = x - r, then x lands in the residue. + const std::uint8_t r = 200; + const std::uint8_t x = 44; + const std::uint8_t ring_eta = static_cast(x - r); // 100, wraps + using Z = grotto::zn64<1009>; + auto ring = grotto::make_ring_switch_keys(r); + const Z x_mod = grotto::ring_switch_eval<0>(ring, ring_eta) + + grotto::ring_switch_eval<1>(ring, ring_eta); + + auto field = grotto::make_ring_switch_keys(r); + const dpf::field128 x_field = grotto::ring_switch_eval<0>(field, ring_eta) + + grotto::ring_switch_eval<1>(field, ring_eta); + //! [jet-and-ring] + + auto c = [](std::uint64_t t, unsigned k) { + return grotto::offset_jet_binom(t, k); + }; + const std::uint64_t expect_v = + 4 + 2 * c(point, 1) + c(point, 2); + if (value != expect_v) + { + std::cerr << "jet value\n"; + return 1; + } + const std::uint64_t expect_fx1 = + 4 + 2 * c(static_cast(point + 1), 1) + + c(static_cast(point + 1), 2); + if (diff != expect_fx1 - expect_v) + { + std::cerr << "jet difference\n"; + return 1; + } + std::uint64_t expect_p = 0; + for (std::uint8_t i = 0; i < point; ++i) + expect_p += 4 + 2 * c(i, 1) + c(i, 2); + if (prefix != expect_p) + { + std::cerr << "jet prefix\n"; + return 1; + } + if (x_mod.raw() != static_cast(x) % 1009) + { + std::cerr << "ring zn64\n"; + return 1; + } + if (x_field != dpf::field128{x}) + { + std::cerr << "ring field128\n"; + return 1; + } + + std::cout << value << " " << diff << " " << prefix << " " + << x_mod.raw() << "\n"; + return 0; +} diff --git a/examples/grotto/lut_union.cpp b/examples/grotto/lut_union.cpp new file mode 100644 index 0000000..97c8a91 --- /dev/null +++ b/examples/grotto/lut_union.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "grotto.hpp" + +/// Two piecewise LUTs, one comparison, one prefix walk of the union. +int main() +{ + //! [lut-union] + grotto::piecewise_lut low{{0, 10}, {{1, 0}, {0, 2}}}; + grotto::piecewise_lut high{{0, 4, 12}, {{3, 0}, {1, 1}, {9, 4}}}; + const std::uint8_t center = 12; + const std::uint8_t eta = 3; + + auto plan = grotto::make_lut_union_plan({low, high}, eta); + auto mat = grotto::make_offset_poly_keys(center, plan.degree); + auto s0 = grotto::lut_union_eval<0>(mat, plan); + auto s1 = grotto::lut_union_eval<1>(mat, plan); + + dpf::protocol::composer composer(0); + grotto::schedule_lut_union(composer, plan); + //! [lut-union] + + if (plan.comparisons != 1 || plan.prefix_walks != 1) + { + std::cerr << "plan shape\n"; + return 1; + } + if (composer.default_plan().rounds() != plan.depth) + { + std::cerr << "geneval rounds\n"; + return 1; + } + const std::uint64_t opened[2] = {s0[0] + s1[0], s0[1] + s1[1]}; + if (opened[0] != grotto::offset_poly_clear(center, low.knots, low.coeff, eta) + || opened[1] != grotto::offset_poly_clear(center, high.knots, high.coeff, eta)) + { + std::cerr << "opened value\n"; + return 1; + } + return 0; +} diff --git a/examples/grotto/repr_and_twist.cpp b/examples/grotto/repr_and_twist.cpp new file mode 100644 index 0000000..3b1a0bb --- /dev/null +++ b/examples/grotto/repr_and_twist.cpp @@ -0,0 +1,132 @@ +#include +#include +#include + +#include "grotto.hpp" + +namespace +{ + +std::uint64_t pow_u64(std::uint64_t base, std::uint64_t exp) +{ + std::uint64_t acc = 1; + while (exp != 0) + { + if (exp & 1u) + acc *= base; + base *= base; + exp >>= 1; + } + return acc; +} + +} // namespace + +/// Representation shift (Fibonacci / geometric / CRC) and twisted monomials. +int main() +{ + //! [repr-and-twist] + // --- Representation shift: Fibonacci checkpoint ---------------------- + // Dealer keys S_c = (F_{c+1}, F_c). After eta opens, each party applies + // the public companion-matrix power M^kappa to its share of S_c. + const std::uint8_t center = 10; + const std::uint8_t eta = 5; + const std::uint8_t point = static_cast(center + eta); // 15 + const auto fib_state = grotto::offset_repr_fibonacci_state(center); + const auto M = grotto::offset_repr_fibonacci_matrix(); + auto fib_keys = grotto::make_offset_repr_keys(center, fib_state); + const std::vector knots{0}; + + const auto f0 = grotto::offset_repr_eval<0>(fib_keys, M, knots, eta); + const auto f1 = grotto::offset_repr_eval<1>(fib_keys, M, knots, eta); + const std::vector S{f0[0] + f1[0], f0[1] + f1[1]}; + + // Geometric twin: 1x1 matrix [lambda] advances lambda^c by lambda^kappa. + const std::uint64_t lambda_geo = 3; + const auto G = grotto::offset_repr_geometric_matrix(lambda_geo); + auto geo_keys = grotto::make_offset_repr_keys( + center, {pow_u64(lambda_geo, center)}); + const auto g0 = grotto::offset_repr_eval<0>(geo_keys, G, knots, eta); + const auto g1 = grotto::offset_repr_eval<1>(geo_keys, G, knots, eta); + const std::uint64_t geo = g0[0] + g1[0]; + + // Clear CRC-32 jump documents the GF(2) twin (XOR shares, not additive). + const std::uint32_t crc_seed = 0x12345678u; + const std::uint32_t crc_jumped = grotto::offset_repr_crc32_jump(crc_seed, 64); + + // --- Twisted monomials: (a0 + a1 x + a2 x^2) * lambda^x ------------- + const std::uint64_t lambda = 3; + const std::size_t degree = 2; + auto twist_keys = grotto::make_offset_twist_keys( + center, degree, lambda); + // h(x) = (2 + 5x + x^2) * 3^x + const std::vector coeff{2, 5, 1}; + const std::uint64_t twisted = + grotto::offset_twist_eval<0>(twist_keys, knots, coeff, eta) + + grotto::offset_twist_eval<1>(twist_keys, knots, coeff, eta); + + // Dyadic decay: masked carry shift. The sum of the shares is the shifted value. + auto half_keys = grotto::make_offset_twist_keys( + center, degree, grotto::twist_half); + const std::uint64_t half = + grotto::offset_twist_eval<0>(half_keys, knots, coeff, eta) + + grotto::offset_twist_eval<1>(half_keys, knots, coeff, eta); + + // Closed form sum_{k=1}^n k * lambda^k from the same twisted table. + const std::uint64_t ag = grotto::offset_twist_arithmetico_geometric(point, lambda); + //! [repr-and-twist] + + const auto expect_S = grotto::offset_repr_fibonacci_state(point); + if (S != expect_S) + { + std::cerr << "fibonacci state\n"; + return 1; + } + if (geo != pow_u64(lambda_geo, point)) + { + std::cerr << "geometric\n"; + return 1; + } + std::uint64_t expect_t = 0; + std::uint64_t xp = 1; + for (std::uint64_t c : coeff) + { + expect_t += c * xp; + xp *= point; + } + expect_t *= pow_u64(lambda, point); + if (twisted != expect_t) + { + std::cerr << "twisted poly\n"; + return 1; + } + std::uint64_t expect_h = 0; + xp = 1; + for (std::uint64_t c : coeff) + { + expect_h += c * xp; + xp *= point; + } + expect_h >>= point; + if (half != expect_h) + { + std::cerr << "twist half\n"; + return 1; + } + std::uint64_t expect_ag = 0; + for (std::uint64_t k = 1; k <= point; ++k) + expect_ag += k * pow_u64(lambda, k); + if (ag != expect_ag) + { + std::cerr << "arithmetico-geometric\n"; + return 1; + } + if (crc_jumped == 0 && crc_seed != 0) + { + // Jump can legally land on zero; only used as a smoke output. + } + + std::cout << S[1] << " " << geo << " " << twisted << " " << half << " " + << ag << " " << crc_jumped << "\n"; + return 0; +} diff --git a/examples/mwe/chooser.html b/examples/mwe/chooser.html new file mode 100644 index 0000000..a4da755 --- /dev/null +++ b/examples/mwe/chooser.html @@ -0,0 +1,131 @@ +
+

Who knows the secret index?

+ + + + + + + + +
+

What should be nonzero?

+ + + + + + +
+

dpf::make_dpf

+

Dealer point key. Leaf shares are subtractive, so reconstruct subtracts them. This prints 7 0.

+

dpf/incremental.hpp

+ +
#include <cstdint>
+#include <iostream>
+#include "dpf.hpp"
+int main()
+{
+    const std::uint8_t alpha = 42;
+    const std::uint64_t beta = 7;
+    auto [k0, k1] = dpf::make_dpf(alpha, beta);
+    const std::uint64_t at = dpf::reconstruct(
+        *dpf::eval_point(k0, alpha),
+        *dpf::eval_point(k1, alpha));
+    const std::uint64_t off = dpf::reconstruct(
+        *dpf::eval_point(k0, std::uint8_t{0}),
+        *dpf::eval_point(k1, std::uint8_t{0}));
+    std::cout << at << " " << off << "\n";
+    return (at == beta && off == 0) ? 0 : 1;
+}
+

c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/point.cpp

+
+
+

dpf::gt

+

One comparison on the same key. Comparison shares are additive, so reconstruct adds them. This prints 1 0.

+

dpf/dcf.hpp

+ +
#include <cstdint>
+#include <iostream>
+#include "dpf.hpp"
+int main()
+{
+    const std::uint8_t alpha = 40;
+    auto [k0, k1] = dpf::make_dpf(alpha, dpf::gt(std::uint64_t{1}));
+    const auto above = dpf::reconstruct(
+        dpf::eval_point(dpf::cmp, k0, std::uint8_t{50}),
+        dpf::eval_point(dpf::cmp, k1, std::uint8_t{50}));
+    const auto below = dpf::reconstruct(
+        dpf::eval_point(dpf::cmp, k0, std::uint8_t{10}),
+        dpf::eval_point(dpf::cmp, k1, std::uint8_t{10}));
+    std::cout << above << " " << below << "\n";
+    return (above == 1 && below == 0) ? 0 : 1;
+}
+

c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/compare.cpp

+
+
+

dpf::ic

+

The secret is a mask. The public interval is on x - r. This prints 9 0: 14 - 10 = 4, which sits in [3, 5].

+

dpf/interval.hpp

+ +
#include <cstdint>
+#include <iostream>
+#include "dpf.hpp"
+int main()
+{
+    const std::uint8_t r = 10;
+    const std::uint64_t beta = 9;
+    auto [k0, k1] = dpf::make_dpf(r, dpf::ic(std::uint8_t{3}, std::uint8_t{5}, beta));
+    const auto inside = dpf::reconstruct(
+        dpf::eval_point(dpf::ic, k0, std::uint8_t{14}),
+        dpf::eval_point(dpf::ic, k1, std::uint8_t{14}));
+    const auto outside = dpf::reconstruct(
+        dpf::eval_point(dpf::ic, k0, std::uint8_t{0}),
+        dpf::eval_point(dpf::ic, k1, std::uint8_t{0}));
+    std::cout << inside << " " << outside << "\n";
+    return (inside == beta && outside == 0) ? 0 : 1;
+}
+

c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/interval.cpp

+
+
+
+

dpf::make_dpf_doerner_shelat

+

Each party holds an XOR share of alpha. A pad dealer supplies the tape and does not learn alpha. The key is reusable. This prints 7.

+

dpf/doerner_shelat.hpp

+ +
#include <cstdint>
+#include <iostream>
+#include "dpf.hpp"
+int main()
+{
+    const std::uint8_t alpha = 42;
+    const std::uint64_t beta = 7;
+    const std::uint8_t x0 = 7;
+    const std::uint8_t x1 = static_cast<std::uint8_t>(alpha ^ x0);
+    auto root = []() { return dpf::uniform_sample<simde__m128i>(); };
+    struct pad {
+        simde__m128i block() { return dpf::uniform_sample<simde__m128i>(); }
+        std::uint8_t bit() {
+            return static_cast<std::uint8_t>(dpf::uniform_sample<unsigned>() & 1u);
+        }
+    };
+    dpf::ds_randomness<decltype(root), pad> rng{root, {}};
+    auto keys = dpf::make_dpf_doerner_shelat(x0, x1, rng, beta);
+    const std::uint64_t opened = dpf::reconstruct(
+        *dpf::eval_point(keys.first, alpha),
+        *dpf::eval_point(keys.second, alpha));
+    std::cout << opened << "\n";
+    return opened == beta ? 0 : 1;
+}
+

c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/shared_index.cpp

+
+
+

dpf::geneval_point

+

Same share convention as the reusable key, and the parties open the value along the query. The call does not hand back a key you can evaluate again. The openings are on dpf/geneval.hpp: geneval_point, geneval_interval, geneval_sequence, geneval_full, and geneval_cmp.

+
+
+

dpf::make_dpf3

+

Three evaluators, any two open. Spines are Shamir shares in fp61. The dealerless form is make_dpf3_doerner_shelat. Comparisons for that setting are make_dpf3_cmp and make_dpf3_ic.

+

dpf/dpf3.hpp · dpf/dpf3_cmp.hpp

+
+
diff --git a/examples/mwe/compare.cpp b/examples/mwe/compare.cpp new file mode 100644 index 0000000..4940f51 --- /dev/null +++ b/examples/mwe/compare.cpp @@ -0,0 +1,24 @@ +#include +#include + +#include "dpf.hpp" + +// Complete program. Comparison shares are additive: reconstruct is share0 + share1. +// gt(1) is 1 where x > alpha and 0 elsewhere. +// +// c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/compare.cpp +int main() +{ + const std::uint8_t alpha = 40; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::gt(std::uint64_t{1})); + + const auto above = dpf::reconstruct( + dpf::eval_point(dpf::cmp, k0, std::uint8_t{50}), + dpf::eval_point(dpf::cmp, k1, std::uint8_t{50})); + const auto below = dpf::reconstruct( + dpf::eval_point(dpf::cmp, k0, std::uint8_t{10}), + dpf::eval_point(dpf::cmp, k1, std::uint8_t{10})); + + std::cout << above << " " << below << "\n"; + return (above == 1 && below == 0) ? 0 : 1; +} diff --git a/examples/mwe/interval.cpp b/examples/mwe/interval.cpp new file mode 100644 index 0000000..16b97db --- /dev/null +++ b/examples/mwe/interval.cpp @@ -0,0 +1,28 @@ +#include +#include + +#include "dpf.hpp" + +// Complete program. The secret is a mask r. The public interval is [p, q] +// on the unmasked input x - r. ic returns `beta` inside that interval. +// +// c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/interval.cpp +int main() +{ + const std::uint8_t r = 10; + const std::uint8_t p = 3; + const std::uint8_t q = 5; + const std::uint64_t beta = 9; + auto [k0, k1] = dpf::make_dpf(r, dpf::ic(p, q, beta)); + + // x = 14 means x - r = 4, which is inside [3, 5]. + const auto inside = dpf::reconstruct( + dpf::eval_point(dpf::ic, k0, std::uint8_t{14}), + dpf::eval_point(dpf::ic, k1, std::uint8_t{14})); + const auto outside = dpf::reconstruct( + dpf::eval_point(dpf::ic, k0, std::uint8_t{0}), + dpf::eval_point(dpf::ic, k1, std::uint8_t{0})); + + std::cout << inside << " " << outside << "\n"; + return (inside == beta && outside == 0) ? 0 : 1; +} diff --git a/examples/mwe/point.cpp b/examples/mwe/point.cpp new file mode 100644 index 0000000..1b912f0 --- /dev/null +++ b/examples/mwe/point.cpp @@ -0,0 +1,24 @@ +#include +#include + +#include "dpf.hpp" + +// Complete program. Leaf shares are subtractive: reconstruct is share0 - share1. +// +// c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/point.cpp +int main() +{ + const std::uint8_t alpha = 42; + const std::uint64_t beta = 7; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + + const std::uint64_t at = dpf::reconstruct( + *dpf::eval_point(k0, alpha), + *dpf::eval_point(k1, alpha)); + const std::uint64_t off = dpf::reconstruct( + *dpf::eval_point(k0, std::uint8_t{0}), + *dpf::eval_point(k1, std::uint8_t{0})); + + std::cout << at << " " << off << "\n"; + return (at == beta && off == 0) ? 0 : 1; +} diff --git a/examples/mwe/shamir.cpp b/examples/mwe/shamir.cpp new file mode 100644 index 0000000..838fcb6 --- /dev/null +++ b/examples/mwe/shamir.cpp @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include + +#include "dpf.hpp" + +// (K,N) Shamir. The secret is the constant term of a degree K-1 polynomial. +// Party i holds that polynomial at x = i+1. Any K shares open it. (2,3) is +// shamir_share: make_shamir_shares(secret, slope) is deal. +// fp61 and gf2n both open. For gf2n, N must be less than 2^k. +// +// c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/shamir.cpp + +int main() +{ + using F = dpf::fp61; + const F secret{10}; + // p(x) = 10 + 2x + 3x^2. Parties 0, 2, and 4 are enough. + const std::array coeff{{F{2}, F{3}}}; + auto shares = dpf::make_shamir_shares<3, 5>(secret, coeff); + const F opened = dpf::shamir::reconstruct( + std::get<0>(shares), std::get<2>(shares), std::get<4>(shares)); + + const F slope{3}; + auto [s0, s1, s2] = dpf::make_shamir_shares(secret, slope); + static_assert(std::is_same_v>); + const F opened23 = dpf::reconstruct(s1, s2); + const bool on_line = s0.raw() == secret + slope * F{1} + && s2.raw() == secret + slope * F{3}; + + using G = dpf::gf28; + auto [g0, g1, g2] = dpf::make_shamir_shares(G{0x1b}, G{0x5a}); + const G gopen = dpf::reconstruct(g0, g2); + const G gopen13 = dpf::reconstruct(g1, g2); + + std::cout << opened.raw() << " " << opened23.raw() << " " + << static_cast(gopen.raw()) << "\n"; + return (opened == secret && opened23 == secret && on_line + && gopen == G{0x1b} && gopen13 == G{0x1b}) + ? 0 : 1; +} diff --git a/examples/mwe/shared_index.cpp b/examples/mwe/shared_index.cpp new file mode 100644 index 0000000..76045f2 --- /dev/null +++ b/examples/mwe/shared_index.cpp @@ -0,0 +1,36 @@ +#include +#include + +#include "dpf.hpp" + +// Complete program. The parties already hold XOR shares of alpha. +// The pad stream is local here; a real protocol would draw it from a dealer +// who never sees alpha. +// +// c++ -std=c++17 -march=native -I include -I thirdparty examples/mwe/shared_index.cpp +int main() +{ + const std::uint8_t alpha = 42; + const std::uint64_t beta = 7; + const std::uint8_t x0 = 7; + const std::uint8_t x1 = static_cast(alpha ^ x0); + + auto root = []() { return dpf::uniform_sample(); }; + struct pad + { + simde__m128i block() { return dpf::uniform_sample(); } + std::uint8_t bit() + { + return static_cast(dpf::uniform_sample() & 1u); + } + }; + dpf::ds_randomness rng{root, {}}; + + auto keys = dpf::make_dpf_doerner_shelat(x0, x1, rng, beta); + const std::uint64_t opened = dpf::reconstruct( + *dpf::eval_point(keys.first, alpha), + *dpf::eval_point(keys.second, alpha)); + + std::cout << opened << "\n"; + return opened == beta ? 0 : 1; +} diff --git a/examples/output_types/gf2.cpp b/examples/output_types/gf2.cpp new file mode 100644 index 0000000..0c701c0 --- /dev/null +++ b/examples/output_types/gf2.cpp @@ -0,0 +1,10 @@ +#include +#include "dpf.hpp" + +int main() +{ + auto [k0, k1] = dpf::make_dpf(std::uint8_t{3}, dpf::gf28{0x1b}); + auto y0 = *dpf::eval_point(k0, std::uint8_t{3}); + auto y1 = *dpf::eval_point(k1, std::uint8_t{3}); + std::cout << dpf::reconstruct(y0, y1) << "\n"; +} diff --git a/examples/protocol/client_shares.cpp b/examples/protocol/client_shares.cpp new file mode 100644 index 0000000..747507a --- /dev/null +++ b/examples/protocol/client_shares.cpp @@ -0,0 +1,154 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/launch.hpp" +#include "dpf/net/client_link.hpp" +#include "dpf/run_log.hpp" + +// A client splits a secret into two additive shares and sends share i to party +// i over a client link; the two parties then open the sum over their own +// party link. Both links are TLS 1.3; each end logs how it authenticated the +// other. +// +// c++ -std=c++17 -march=native -pthread -I include -I thirdparty \ +// examples/protocol/client_shares.cpp -lsctp -lssl -lcrypto -o client_shares +// ./client_shares # development certificate (logged) +// ./dpf_keygen srv.key # prints srv's public key +// ./client_shares --server_identity=srv.key --client_pin= +// ./client_shares --client_verify=off # accepts any server (logged) +// +// With --server_identity and no --client_pin the client refuses the server: +// clients always verify unless told not to. + +int main(int argc, char ** argv) +{ + try + { + auto cfg = dpf::app::run_config::from_env(); + for (const auto & extra : cfg.apply_args(argc, argv)) + throw std::invalid_argument("unknown argument " + extra); + if (cfg.kind != dpf::net::transport::mux && cfg.kind != dpf::net::transport::parallel) + cfg.kind = dpf::net::transport::mux; + dpf::app::start_logging(cfg); + + // Each party accepts one client and keeps the share it sends. + std::atomic ports[2] = {{0}, {0}}; + std::uint64_t shares[2] = {0, 0}; + std::string errors[2]; + std::vector parties; + for (int p = 0; p < 2; ++p) + parties.emplace_back([&, p] { + try + { + asio::io_context io; + dpf::net::client_listener l(io, cfg.server, 1, cfg.policy, cfg.limits); + ports[p].store(l.listen()); + auto c = l.accept(); + bool done = false; + std::error_code ec; + c.link->async_read(0, &shares[p], 8, [&](const std::error_code & e) { + ec = e; + done = true; + }); + while (!done) + { + if (io.stopped()) + io.restart(); + io.run_one(); + } + if (ec) + throw std::system_error(ec, "reading the client's share"); + } + catch (const std::exception & e) + { + errors[p] = e.what(); + ports[p].store(1); + } + }); + + // The client: one fresh share per party, each on its own verified link. + const std::uint64_t secret = 42; + std::random_device rd; + const std::uint64_t r = (static_cast(rd()) << 32) | rd(); + const std::uint64_t mine[2] = {r, secret - r}; + std::string client_error; + for (int p = 0; p < 2 && client_error.empty(); ++p) + { + while (ports[p].load() == 0) + std::this_thread::yield(); + try + { + asio::io_context io; + auto c = dpf::net::connect_server(io, cfg.host, ports[p].load(), cfg.client, + 1, cfg.policy, cfg.limits); + std::cout << "client -> party " << p << ": " << c.security.protocol << " " + << c.security.cipher << ", server auth=" << c.security.peer_auth + << "\n"; + bool done = false; + c.link->async_write(0, &mine[p], 8, [&](const std::error_code &) { + done = true; + }); + while (!done) + { + if (io.stopped()) + io.restart(); + io.run_one(); + } + c.link.reset(); + io.poll(); + } + catch (const std::exception & e) + { + client_error = e.what(); + } + } + if (!client_error.empty()) + { + // Unblock the listeners that are still waiting for this client. + for (int p = 0; p < 2; ++p) + { + std::error_code ec; + asio::io_context io; + asio::ip::tcp::socket s(io); + if (ports[p].load() > 1) + s.connect({asio::ip::make_address("127.0.0.1"), ports[p].load()}, ec); + } + } + for (auto & t : parties) + t.join(); + if (!client_error.empty()) + throw std::runtime_error("client: " + client_error); + for (const auto & e : errors) + if (!e.empty()) + throw std::runtime_error("party: " + e); + + // The parties open the sum over their party link. + dpf::protocol::composer c0(0), c1(1); + auto x0 = c0.input(dpf::protocol::domain::a, 8); + auto x1 = c1.input(dpf::protocol::domain::a, 8); + auto o0 = c0.exchange(x0); + (void)c1.exchange(x1); + auto p0 = c0.schedule(); + auto p1 = c1.schedule(); + dpf::app::party_values v0(p0.nodes().size()), v1(p1.nodes().size()); + v0[x0.id].assign(8, 0); + v1[x1.id].assign(8, 0); + std::memcpy(v0[x0.id].data(), &shares[0], 8); + std::memcpy(v1[x1.id].data(), &shares[1], 8); + (void)dpf::run_two_party(p0, p1, v0, v1, {}, cfg); + std::uint64_t open = 0; + std::memcpy(&open, v0[o0.id].data(), 8); + std::cout << "parties opened " << open << " (share 0 = " << shares[0] << ")\n"; + return open == secret ? 0 : 1; + } + catch (const std::exception & e) + { + std::cerr << "client_shares: " << e.what() << "\n"; + return 1; + } +} diff --git a/examples/protocol/compose_schedule.cpp b/examples/protocol/compose_schedule.cpp new file mode 100644 index 0000000..2dd0ea6 --- /dev/null +++ b/examples/protocol/compose_schedule.cpp @@ -0,0 +1,285 @@ +#include +#include +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/protocol_factory.hpp" + +// Protocol composition schedules (compose.hpp). Records FSS walks, ABY +// products, and RSS refreshes on one RoundSink plan — the shapes Express, +// Sabre, Pika early-stop, Poplar prefixes, and Duoram scale use by hand. +// +// The final block drives a composed open on the stream framework +// (drive_both_on_streams). The identical schedule also runs over the truly +// asynchronous backends (dpf::net::async_stream_array + async_round_sink, or +// dpf::async::overlapped_byte_protocol) and, on Linux, over real SCTP +// (async_sctp_stream_array). The experiment_bench harness picks the transport +// via DPF_TRANSPORT=memory|stream|async|mux|parallel|sctp. +// +// c++ -std=c++17 -march=native -I include -I thirdparty +// examples/protocol/compose_schedule.cpp + +namespace +{ + +using dpf::protocol::composer; +using dpf::protocol::domain; +using dpf::protocol::effect; +namespace opcodes = dpf::protocol::opcodes; + +} // namespace + +int main() +{ + // Express / Sabre: audit rides in the last CW flush (depth exchanges, not + // depth+1). + { + composer naive(0); + auto seed = naive.input(domain::fss, 16); + auto sketch = naive.input(domain::a, 8); + auto leaf = naive.fss_point(seed, 4, 16); + auto dep = naive.compute(opcodes::user_base + 1, {leaf, sketch}, + domain::a, 8); + (void)naive.exchange(dep); + const auto naive_ex = naive.schedule().exchange_waves(); + + composer fused(0); + auto seed_f = fused.input(domain::fss, 16); + auto sketch_f = fused.input(domain::a, 8); + auto wr = fused.fss_point_fused(seed_f, 4, 16, sketch_f); + const auto fused_ex = fused.schedule().exchange_waves(); + if (fused_ex >= naive_ex || fused.domain_of(wr.trailer_open) != domain::a) + { + std::cerr << "compose fuse\n"; + return 1; + } + std::cout << "express_fuse " << naive_ex << "->" << fused_ex << "\n"; + } + + // Pika / small-output PIR: BGI Remark 3.4 early-stop drops ν CW rounds. + { + composer full(0); + auto seed = full.input(domain::fss, 16); + (void)full.fss_point(seed, 8, 16); + composer early(0); + auto seed_e = early.input(domain::fss, 16); + (void)early.fss_point_early_stop(seed_e, 8, /*early_stop=*/3, 16); + const auto a = full.schedule().exchange_waves(); + const auto b = early.schedule().exchange_waves(); + if (b != a - 3) + { + std::cerr << "compose early_stop\n"; + return 1; + } + std::cout << "early_stop " << a << "->" << b << "\n"; + } + + // Poplar: prefix share after each CW, same exchange-wave depth. + { + composer c(0); + auto seed = c.input(domain::fss, 16); + auto wr = c.level_walk_prefixes(seed, 5, 16, /*prefix_bytes=*/8); + auto p = c.schedule(); + if (wr.at_level.size() != 5 || p.exchange_waves() != 5) + { + std::cerr << "compose prefixes\n"; + return 1; + } + std::cout << "prefixes " << p.exchange_waves() << "\n"; + } + + // DCF block_width: variable CW slot sizes. + { + composer c(0); + auto seed = c.input(domain::fss, 16); + const std::vector slots = {16, 4, 4, 16}; + (void)c.level_walk_sized(seed, slots); + auto p = c.schedule(); + if (p.value_bytes_of(p.wave(1).exchanges[0].id) != 4) + { + std::cerr << "compose sized\n"; + return 1; + } + std::cout << "sized_slots ok\n"; + } + + // RSS product → neighbor y-exchange → RSS (one round). + { + composer c(0); + auto x = c.input(domain::rss, 16); + auto y = c.input(domain::rss, 16); + auto z = c.rss_product_replicated(x, y); + if (c.domain_of(z) != domain::rss || c.schedule().exchange_waves() != 1) + { + std::cerr << "compose rss\n"; + return 1; + } + std::cout << "rss_refresh 1\n"; + } + + // Duoram write-scale: FSS leaf feeds ABY; beaver waits for the leaf wave. + { + composer c(0); + auto seed = c.input(domain::fss, 16); + auto leaf = c.fss_point(seed, 4, 16); + auto scale = c.input(domain::a, 8); + auto scaled = c.aby_product(leaf, scale); + auto p = c.schedule(); + if (p.wave_of(scaled) < p.wave_of(leaf)) + { + std::cerr << "compose duoram_scale\n"; + return 1; + } + std::cout << "duoram_scale wave " << p.wave_of(scaled) << "\n"; + } + + // Round-aware ABY: sign×linear stays one online round. + { + composer c(0); + auto & s = c.aby(); + auto sgn = s.input(); + auto x = s.input(); + auto a0 = s.input(); + auto a1 = s.input(); + auto lin = s(sgn * (a1 * x + a0)); + if (s.round_of(lin) != 1) + { + std::cerr << "compose aby_rounds\n"; + return 1; + } + std::cout << "aby_rounds 1\n"; + } + + // Doerner–Shelat: 5 opens per level; OH adds 80 AND-layers / level. + { + composer c(0); + auto seed = c.input(domain::fss, 16); + auto tip = c.level_walk_ds(seed, 2, 16); + if (c.schedule().exchange_waves() != 10 || tip.id == seed.id) + { + std::cerr << "compose ds_walk\n"; + return 1; + } + std::cout << "ds_walk 10\n"; + composer c_oh(0); + auto tip_oh = c_oh.level_walk_ds(c_oh.input(domain::fss, 16), 1, 16, + /*oh=*/true); + (void)tip_oh; + const auto want = dpf::net::compose_ds_slot_bytes(1, 16, true).size(); + if (c_oh.schedule().exchange_waves() != want) + { + std::cerr << "compose ds_oh\n"; + return 1; + } + std::cout << "ds_oh " << want << "\n"; + } + + // Adaptive idpf: one packed L‖R open per step. + { + composer c(0); + auto seed = c.input(domain::fss, 16); + auto f = c.begin_adaptive_prefix(seed); + f = c.step_adaptive_prefix(f, 16, 8); + f = c.retain_adaptive_prefix(f, 0); + if (c.schedule().exchange_waves() != 1) + { + std::cerr << "compose adaptive\n"; + return 1; + } + std::cout << "adaptive 1\n"; + } + + // default_plan: rounds == exchange_waves (sink-aligned). + { + composer c(0); + auto leaf = c.fss_point(c.input(domain::fss, 16), 4, 16); + (void)leaf; + auto p = c.default_plan(); + if (p.rounds() != p.exchange_waves() + || p.rounds() != p.slot_bytes_all().size() || p.rounds() != 4) + { + std::cerr << "compose default_plan\n"; + return 1; + } + std::cout << "default_plan 4\n"; + } + + // Multipoint buckets: CW waves pack; answers one open. + { + composer c(0); + auto mr = c.multipoint_fan(2, + [&](std::size_t) { return c.input(domain::fss, 16); }, 3, 16, 8); + (void)mr; + if (c.schedule().exchange_waves() != 4) + { + std::cerr << "compose multipoint\n"; + return 1; + } + std::cout << "multipoint 4\n"; + } + + // Multi-lane ABY: independent barriers, one wave. + { + composer c(0); + auto z0 = c.aby_product(c.input(domain::a, 8), + c.input(domain::a, 8), 0); + auto z1 = c.aby_product(c.input(domain::a, 8), + c.input(domain::a, 8), 1); + if (c.schedule().exchange_waves() != 1 + || c.schedule().effect_count(effect::exchange) != 2 + || z0.id == z1.id) + { + std::cerr << "compose multilane\n"; + return 1; + } + std::cout << "multilane 1\n"; + } + + // Prepaid defer + rotate: zero online FSS rounds. + { + composer c(0); + auto buf = c.defer_expand(c.input(domain::fss, 16), 4, 16); + auto rot = c.rotate_share(buf, 7); + if (c.schedule().exchange_waves() != 0 || rot.id == buf.id) + { + std::cerr << "compose defer\n"; + return 1; + } + std::cout << "defer 0\n"; + } + + // stream_array: drive a compose open through drive_both_on_streams. + { + composer c0(0); + composer c1(1); + auto x0 = c0.input(domain::a, 8); + auto x1 = c1.input(domain::a, 8); + auto e0 = c0.exchange(x0); + auto e1 = c1.exchange(x1); + auto p0 = c0.schedule(); + auto p1 = c1.schedule(); + std::vector> v0(p0.nodes().size()), + v1(p1.nodes().size()); + const std::uint64_t a = 3, b = 5; + v0[x0.id].assign(8, 0); + v1[x1.id].assign(8, 0); + std::memcpy(v0[x0.id].data(), &a, 8); + std::memcpy(v1[x1.id].data(), &b, 8); + dpf::protocol::drive_both_on_streams(p0, p1, v0, v1); + std::uint64_t open0 = 0, open1 = 0; + std::memcpy(&open0, v0[e0.id].data(), 8); + std::memcpy(&open1, v1[e1.id].data(), 8); + if (open0 != 8 || open1 != 8) + { + std::cerr << "drive_plan_on_streams open\n"; + return 1; + } + std::cout << "drive_plan_on_streams_ok " << open0 << "\n"; + } + + return 0; +} diff --git a/examples/protocol/party_node.cpp b/examples/protocol/party_node.cpp new file mode 100644 index 0000000..71fadad --- /dev/null +++ b/examples/protocol/party_node.cpp @@ -0,0 +1,86 @@ +#include +#include +#include +#include + +#include "dpf/launch.hpp" +#include "dpf/run_log.hpp" + +// One party of a two- or three-party run, one process per party. +// +// c++ -std=c++17 -march=native -pthread -I include -I thirdparty \ +// -DLIBDPF_GIT_REV="\"$(git describe --always --dirty)\"" \ +// examples/protocol/party_node.cpp -lsctp -lssl -lcrypto -o party_node +// ./party_node --party=0 --peers=127.0.0.1:9100,127.0.0.1:9101 & +// ./party_node --party=1 --peers=127.0.0.1:9100,127.0.0.1:9101 +// +// Any run_config key works as a flag (--transport=parallel --lanes=2 ...). +// Start order does not matter: connects retry until --connect_ms. +// +// Links are TLS 1.3. With no keys they are encrypted but unauthenticated (and +// the log says so). To authenticate, give each party a key and the others' +// public keys (dpf_keygen p0.key prints p0's), for example in p0.conf: +// identity = p0.key +// peer.1 = +// and run ./party_node --config=p0.conf --party=0 --peers=... +// The run log goes to stderr at info; --log=file:/tmp/p0.log --log_level=debug +// or DPF_LOG / DPF_LOG_LEVEL redirect it (see dpf/run_log.hpp). +// +// With three peers the protocol adds a dealer-delivered mask: party 2 is the +// dealer, and parties 0 and 1 each open (input + mask share). + +int main(int argc, char ** argv) +{ + try + { + const auto args = dpf::app::parse_node_args(argc, argv); + dpf::app::start_logging(args.cfg); + const unsigned me = args.party; + const bool dealer = args.peers.size() == 3; + + dpf::protocol::composer c(me); + auto x = c.input(dpf::protocol::domain::a, 8); + dpf::protocol::node opened{}; + dpf::protocol::node mask{}; + if (dealer) + { + auto pad = c.input(dpf::protocol::domain::a, 8); + mask = c.dealer_deliver(pad); + opened = c.exchange(x); + (void)pad; + } + else + opened = c.exchange(x); + auto plan = c.schedule(); + dpf::app::party_values values(plan.nodes().size()); + for (auto & v : values) + v.assign(8, 0); + const std::uint64_t mine = me == 0 ? 11 : 31; + std::memcpy(values[x.id].data(), &mine, 8); + if (dealer && me == 2) + { + const std::uint64_t pad = 7; + std::memcpy(values[plan.inputs_of(mask.id)[0]].data(), &pad, 8); + } + + const auto wire = dpf::app::run_node(args, plan, values); + std::uint64_t got = 0; + std::memcpy(&got, values[opened.id].data(), 8); + std::cout << "party " << me << " open=" << got; + if (dealer && me < 2) + { + std::uint64_t m = 0; + std::memcpy(&m, values[mask.id].data(), 8); + std::cout << " mask=" << m; + } + std::cout << " wire_out=" << wire.bytes_out << " wire_in=" << wire.bytes_in + << "\n"; + return (me == 2 || got == 42) ? 0 : 1; + } + catch (const std::exception & e) + { + DPF_LOG(error, "node.failed").kv("what", e.what()); + std::cerr << "party_node: " << e.what() << "\n"; + return 1; + } +} diff --git a/examples/protocol/share_runtime.cpp b/examples/protocol/share_runtime.cpp new file mode 100644 index 0000000..ead8701 --- /dev/null +++ b/examples/protocol/share_runtime.cpp @@ -0,0 +1,99 @@ +/// @file examples/protocol/share_runtime.cpp +/// @brief Smoke demo: stream_array dealer/peer gadgets and clear sanity checks. +/// @details Also drives a composed open on the stream framework +/// (`drive_both_on_streams`). The same protocol runs unchanged over the +/// truly asynchronous backends (`dpf::net::async_stream_array` + +/// `dpf::async::overlapped_byte_protocol`, or `async_round_sink`), and +/// on Linux over real SCTP (`async_sctp_stream_array`, index i -> SCTP +/// stream i). The performance harness (experiment_bench) selects any of +/// these with `DPF_TRANSPORT=memory|stream|async|mux|parallel|sctp`. +#include +#include +#include +#include +#include + +#include "dpf/compose.hpp" +#include "dpf/factory_gadgets.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/protocol_factory.hpp" +#include "dpf/rss_seed.hpp" + +int main() +{ + auto bundle = dpf::rss::sample_seed_bundle(); + auto z0 = dpf::rss::zero_share( + dpf::rss::party_seeds::from_bundle(bundle, 0), 0); + auto z1 = dpf::rss::zero_share( + dpf::rss::party_seeds::from_bundle(bundle, 1), 0); + auto z2 = dpf::rss::zero_share( + dpf::rss::party_seeds::from_bundle(bundle, 2), 0); + std::cout << "rss_zero_sum=" << (z0 + z1 + z2) << "\n"; + + // Dealer: one ring triple per party; peer: d and e opens. + auto peer = dpf::net::make_memory_stream_pair(2); + auto d0 = dpf::net::make_memory_stream_pair(1); + auto d1 = dpf::net::make_memory_stream_pair(1); + constexpr std::uint16_t limb = 8; + dpf::factory::make_dealer(d0.first, d1.first, 1, [limb] { + return dpf::factory::deal_ring_triple(limb); + }); + + std::uint64_t prod0 = 0, prod1 = 0; + std::thread t0([&] { + prod0 = dpf::factory::beaver_mul_online(0, 6, 7, peer.first, d0.second, + 0, 0, 1, limb); + }); + std::thread t1([&] { + prod1 = dpf::factory::beaver_mul_online(1, 0, 0, peer.second, d1.second, + 0, 0, 1, limb); + }); + t0.join(); + t1.join(); + std::cout << "beaver_mul_open=" << (prod0 + prod1) << "\n"; + + // GMW AND 1∧1 via make_protocol_factory. + auto and_peer = dpf::net::make_memory_stream_pair(1); + auto ad0 = dpf::net::make_memory_stream_pair(1); + auto ad1 = dpf::net::make_memory_stream_pair(1); + dpf::factory::make_dealer(ad0.first, ad1.first, 1, + dpf::factory::make_gmw_and_dealer_functor()); + std::uint8_t z0b = 0, z1b = 0; + std::thread a0([&] { + z0b = dpf::factory::gmw_and_online(0, 1, 1, and_peer.first, ad0.second); + }); + std::thread a1([&] { + z1b = dpf::factory::gmw_and_online(1, 0, 0, and_peer.second, ad1.second); + }); + a0.join(); + a1.join(); + std::cout << "gmw_and_xor=" << static_cast(z0b ^ z1b) << "\n"; + + // Compose an open and drive both parties on the stream framework. This is + // the same schedule the async backends run; here it uses in-process memory + // stream arrays via drive_both_on_streams. + { + using dpf::protocol::domain; + dpf::protocol::composer comp0(0), comp1(1); + auto a = comp0.input(domain::a, 8); + auto b = comp1.input(domain::a, 8); + auto oa = comp0.exchange(a); + auto ob = comp1.exchange(b); + auto p0 = comp0.schedule(); + auto p1 = comp1.schedule(); + std::vector> va(p0.nodes().size()), + vb(p1.nodes().size()); + const std::uint64_t xa = 17, xb = 25; + va[a.id].assign(8, 0); + vb[b.id].assign(8, 0); + std::memcpy(va[a.id].data(), &xa, 8); + std::memcpy(vb[b.id].data(), &xb, 8); + dpf::protocol::drive_both_on_streams(p0, p1, va, vb); + std::uint64_t open0 = 0; + std::memcpy(&open0, va[oa.id].data(), 8); + (void)ob; + std::cout << "compose_open_on_streams=" << open0 << "\n"; + } + + return 0; +} diff --git a/examples/protocol/stream_app_smoke.cpp b/examples/protocol/stream_app_smoke.cpp new file mode 100644 index 0000000..e4f3a42 --- /dev/null +++ b/examples/protocol/stream_app_smoke.cpp @@ -0,0 +1,83 @@ +/// @file examples/protocol/stream_app_smoke.cpp +/// @brief Thin app-runtime smoke: prep files or memory dealer + compose on streams. +/// @details Drives a composed open via `drive_both_on_streams` (the stream +/// framework). The same schedule runs unchanged over the event-driven +/// backends (`dpf::net::async_stream_array` + `async_round_sink` / +/// `dpf::async::overlapped_byte_protocol`) and, on Linux, over real +/// SCTP (`async_sctp_stream_array`). The `experiment_bench` harness +/// selects the transport with +/// `DPF_TRANSPORT=memory|stream|async|mux|parallel|sctp`. +#include +#include +#include +#include + +#include "dpf/app_runtime.hpp" +#include "dpf/compose.hpp" +#include "dpf/prep_source.hpp" +#include "dpf/protocol_roles.hpp" + +namespace +{ + +void put_raw(std::vector> & values, + dpf::protocol::node n, const void * src, std::size_t nbyte) +{ + values[n.id].assign(nbyte, 0); + std::memcpy(values[n.id].data(), src, nbyte); +} + +} // namespace + +int main() +{ + // Prep: file dealer round-trip (roles helper + app_runtime reader). + { + const std::string base = "/tmp/libdpf_stream_app_smoke_prep"; + dpf::prep::demand d{}; + d.ring_triples = 1; + dpf::roles::dealer_write_files(base, d); + auto c0 = dpf::app::open_file_prep_cursor(base, 0); + auto c1 = dpf::app::open_file_prep_cursor(base, 1); + if (c0.limb() != 8 || c1.limb() != 8) + { + std::cerr << "prep cursor\n"; + return 1; + } + } + + // Online: memory dealer + single-wave exchange plan on stream arrays. + dpf::protocol::composer c0(0); + dpf::protocol::composer c1(1); + auto x0 = c0.input(dpf::protocol::domain::a, 8); + auto x1 = c1.input(dpf::protocol::domain::a, 8); + auto e0 = c0.exchange(x0); + auto e1 = c1.exchange(x1); + auto p0 = c0.schedule(); + auto p1 = c1.schedule(); + + dpf::prep::demand d{}; + d.ring_triples = 1; + auto [d0, d1] = dpf::prep::deal_memory_pair(d); + (void)d0; + (void)d1; + + std::vector> v0(p0.nodes().size()); + std::vector> v1(p1.nodes().size()); + const std::uint64_t a = 5, b = 9; + put_raw(v0, x0, &a, 8); + put_raw(v1, x1, &b, 8); + dpf::protocol::drive_both_on_streams(p0, p1, v0, v1); + + std::uint64_t open0 = 0, open1 = 0; + std::memcpy(&open0, v0[e0.id].data(), 8); + std::memcpy(&open1, v1[e1.id].data(), 8); + if (open0 != 14u || open1 != 14u) + { + std::cerr << "exchange " << open0 << " " << open1 << "\n"; + return 1; + } + + std::cout << "ok\n"; + return 0; +} diff --git a/examples/protocol/stream_dpf3_smoke.cpp b/examples/protocol/stream_dpf3_smoke.cpp new file mode 100644 index 0000000..2df94f3 --- /dev/null +++ b/examples/protocol/stream_dpf3_smoke.cpp @@ -0,0 +1,145 @@ +/// @file examples/protocol/stream_dpf3_smoke.cpp +/// @brief Local DPF3 eval plus trio-shaped stream edges (peer / rss_next / dealer). +#include +#include +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/net/stream_mesh.hpp" +#include "dpf/protocol_factory.hpp" + +namespace +{ + +struct trio_edge_ping +{ + std::uint32_t from = 0; + std::uint32_t to = 0; + std::uint64_t nonce = 0; +}; + +struct trio_party_streams +{ + dpf::net::memory_stream_array & peer; + dpf::net::memory_stream_array & rss_next; + dpf::net::memory_stream_array & dealer; +}; + +template +void exchange_pod(dpf::net::memory_stream_array & link, std::size_t stream, + const T & mine, T & theirs) +{ + static_assert(std::is_trivially_copyable_v, "pod"); + link.write(stream, &mine, sizeof(T)); + link.flush(stream); + link.read(stream, &theirs, sizeof(T)); +} + +void ping_edge(trio_party_streams s, unsigned me, unsigned peer_id, + std::uint64_t nonce, std::size_t stream_idx) +{ + trio_edge_ping mine{me, peer_id, nonce}; + trio_edge_ping theirs{}; + exchange_pod(s.peer, stream_idx, mine, theirs); + if (theirs.from != peer_id || theirs.to != me) + throw std::runtime_error("stream_dpf3_smoke: peer edge"); +} + +} // namespace + +int main() +{ + using Input = std::uint8_t; + const Input alpha = 42; + const dpf::fp61 beta{7}; + + auto [k1, k2, k3] = dpf::make_dpf3(alpha, beta); + const dpf::fp61 y1 = dpf::eval_point(k1, alpha); + const dpf::fp61 y2 = dpf::eval_point(k2, alpha); + const dpf::fp61 y3 = dpf::eval_point(k3, alpha); + const dpf::fp61 opened = dpf::reconstruct( + dpf::as_share(k1, y1), dpf::as_share(k2, y2), dpf::as_share(k3, y3)); + if (opened != beta) + { + std::cerr << "dpf3 local eval\n"; + return 1; + } + + // Dealer delivers a keyed marker on stream 0 to each evaluator. + auto dealer0 = dpf::net::make_memory_stream_pair(1); + auto dealer1 = dpf::net::make_memory_stream_pair(1); + struct key_delivery + { + std::uint32_t party = 0; + std::uint64_t beta_raw = 0; + }; + key_delivery m0{0, beta.raw()}, m1{1, beta.raw()}; + dealer0.first.write(0, &m0, sizeof(m0)); + dealer0.first.flush(0); + dealer1.first.write(0, &m1, sizeof(m1)); + dealer1.first.flush(0); + key_delivery got0{}, got1{}; + dealer0.second.read(0, &got0, sizeof(got0)); + dealer1.second.read(0, &got1, sizeof(got1)); + if (got0.beta_raw != beta.raw() || got1.beta_raw != beta.raw()) + { + std::cerr << "dealer stream delivery\n"; + return 1; + } + + // Trio-shaped edges on a 3-party clique (p2 = dealer): peer + rss_next + dealer. + constexpr std::size_t k_peer = 0; + constexpr std::size_t k_rss = 1; + auto clique = dpf::net::make_memory_stream_clique(3, 2); + std::exception_ptr err; + std::thread t0([&] { + try + { + trio_party_streams s{clique.end(0, 1), clique.end(0, 1), clique.end(0, 2)}; + ping_edge(s, 0, 1, 11, k_peer); + const trio_edge_ping rss_out{0, 1, 99}; + s.rss_next.write(k_rss, &rss_out, sizeof(rss_out)); + s.rss_next.flush(k_rss); + } + catch (...) + { + err = std::current_exception(); + } + }); + std::thread t1([&] { + try + { + trio_party_streams s{clique.end(1, 0), clique.end(1, 0), clique.end(1, 2)}; + ping_edge(s, 1, 0, 22, k_peer); + trio_edge_ping rss_in{}; + s.rss_next.read(k_rss, &rss_in, sizeof(rss_in)); + if (rss_in.from != 0u) + throw std::runtime_error("stream_dpf3_smoke: rss_next"); + const trio_edge_ping dealer_out{1, 2, 88}; + s.dealer.write(k_rss, &dealer_out, sizeof(dealer_out)); + s.dealer.flush(k_rss); + } + catch (...) + { + err = std::current_exception(); + } + }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); + trio_edge_ping dealer_in{}; + clique.end(2, 1).read(k_rss, &dealer_in, sizeof(dealer_in)); + if (dealer_in.from != 1u || dealer_in.to != 2u) + { + std::cerr << "dealer edge\n"; + return 1; + } + + std::cout << "stream_trio_ok\n"; + return 0; +} diff --git a/examples/protocol/two_party_exchange.cpp b/examples/protocol/two_party_exchange.cpp new file mode 100644 index 0000000..412e3e9 --- /dev/null +++ b/examples/protocol/two_party_exchange.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include "dpf/launch.hpp" +#include "dpf/run_log.hpp" + +// Two-party open. Every run choice is a flag: +// +// c++ -std=c++17 -march=native -pthread -I include -I thirdparty \ +// examples/protocol/two_party_exchange.cpp -lsctp +// ./a.out # in-process async memory +// ./a.out --transport=mux --lanes=1 # TCP mux on localhost +// ./a.out --transport=parallel --window=65536 +// +// For separate processes, see party_node.cpp. + +int main(int argc, char ** argv) +{ + try + { + auto cfg = dpf::app::run_config::from_env(); + for (const auto & extra : cfg.apply_args(argc, argv)) + throw std::invalid_argument("unknown argument " + extra); + dpf::app::start_logging(cfg); + + dpf::protocol::composer c0(0); + dpf::protocol::composer c1(1); + auto x0 = c0.input(dpf::protocol::domain::a, 8); + auto x1 = c1.input(dpf::protocol::domain::a, 8); + auto o0 = c0.exchange(x0); + (void)c1.exchange(x1); + auto p0 = c0.schedule(); + auto p1 = c1.schedule(); + // One 8-byte input per instance; every instance opens to 42. + dpf::app::party_values v0(p0.nodes().size()), v1(p1.nodes().size()); + v0[x0.id].assign(8 * cfg.instances, 0); + v1[x1.id].assign(8 * cfg.instances, 0); + for (std::size_t i = 0; i < cfg.instances; ++i) + { + const std::uint64_t a = 11 + i, b = 31 - i; + std::memcpy(v0[x0.id].data() + 8 * i, &a, 8); + std::memcpy(v1[x1.id].data() + 8 * i, &b, 8); + } + + const auto r = dpf::run_two_party(p0, p1, v0, v1, {}, cfg); + bool all = true; + std::uint64_t open = 0; + for (std::size_t i = 0; i < cfg.instances; ++i) + { + std::memcpy(&open, v0[o0.id].data() + 8 * i, 8); + all = all && open == 42; + } + std::cout << "two_party_exchange " << (all ? 42 : open) << " " + << cfg.summary() << " wire_out=" << r.wire[0].bytes_out << "\n"; + return all ? 0 : 1; + } + catch (const std::exception & e) + { + std::cerr << "two_party_exchange: " << e.what() << "\n"; + return 1; + } +} diff --git a/examples/tools/dpf_keygen.cpp b/examples/tools/dpf_keygen.cpp new file mode 100644 index 0000000..7253576 --- /dev/null +++ b/examples/tools/dpf_keygen.cpp @@ -0,0 +1,42 @@ +#include +#include +#include + +#include "dpf/net/identity.hpp" + +// Party identity keys for encrypted, authenticated party links. +// +// c++ -std=c++17 -I include -I thirdparty examples/tools/dpf_keygen.cpp \ +// -lssl -lcrypto -o dpf_keygen +// ./dpf_keygen p0.key # new key file (mode 600); prints the public key +// ./dpf_keygen --public p0.key # public key of an existing key file +// +// Give each party its own key file (`identity = p0.key` in its config) and +// give the parties that should authenticate it the printed public key +// (`peer.0 = `). + +int main(int argc, char ** argv) +{ + try + { + if (argc == 3 && std::strcmp(argv[1], "--public") == 0) + { + std::cout << dpf::net::identity::load(argv[2]).key().base64() << "\n"; + return 0; + } + if (argc == 2 && argv[1][0] != '-') + { + const auto id = dpf::net::identity::generate(); + id.save(argv[1]); + std::cout << id.key().base64() << "\n"; + return 0; + } + std::cerr << "usage: dpf_keygen KEYFILE | dpf_keygen --public KEYFILE\n"; + return 2; + } + catch (const std::exception & e) + { + std::cerr << "dpf_keygen: " << e.what() << "\n"; + return 1; + } +} diff --git a/include/dpf.hpp b/include/dpf.hpp index 8d77538..57ea0fa 100644 --- a/include/dpf.hpp +++ b/include/dpf.hpp @@ -26,14 +26,18 @@ #include "dpf/bitstring.hpp" +#include "dpf/blob.hpp" + +#include "dpf/pprf.hpp" + #include "dpf/dpf_key.hpp" #include "dpf/doerner_shelat.hpp" -#include "dpf/geneval.hpp" - #include "dpf/incremental.hpp" +#include "dpf/geneval.hpp" + #include "dpf/eval_common.hpp" #include "dpf/eval_interval.hpp" @@ -46,8 +50,28 @@ #include "dpf/eval_sequence.hpp" +#include "dpf/cohort.hpp" + +#include "dpf/interleave_leaves.hpp" + #include "dpf/eval_unified.hpp" +#include "dpf/eval_walk.hpp" + +#include "dpf/eval_until.hpp" + +#include "dpf/idpf_agg.hpp" + +#include "dpf/it_dpf3.hpp" + +#include "dpf/caller_fold.hpp" + +#include "dpf/leaf_later.hpp" + +#include "dpf/grow.hpp" + +#include "dpf/grow_ds.hpp" + #include "dpf/interval_memoizer.hpp" #ifdef LIBDPF_HAS_NLOHMANN_JSON @@ -88,6 +112,34 @@ #include "dpf/beaver.hpp" +#include "dpf/compose.hpp" + +#include "dpf/rss_seed.hpp" + +#include "dpf/ot_pack.hpp" + +#include "dpf/edabit.hpp" + +#include "dpf/bit_inject.hpp" + +#include "dpf/trunc.hpp" + +#include "dpf/share_cmp.hpp" + +#include "dpf/share_vec.hpp" + +#include "dpf/fixed_share.hpp" + +#include "dpf/gilboa.hpp" + +#include "dpf/share_expr.hpp" + +#include "dpf/matmul.hpp" + +#include "dpf/shuffle.hpp" + +#include "dpf/cost_pass.hpp" + #include "dpf/secret_share.hpp" #include "dpf/rotation_iterable.hpp" @@ -102,6 +154,8 @@ #include "dpf/subinterval_iterable.hpp" +#include "dpf/deferred_rotated_subinterval.hpp" + #include "dpf/subsequence_iterable.hpp" #include "dpf/twiddle.hpp" @@ -118,14 +172,42 @@ #include "dpf/fp61.hpp" +#include "dpf/gf2.hpp" + +#include "dpf/field64.hpp" + +#include "dpf/field128.hpp" + +#include "dpf/p256.hpp" + +#include "dpf/p256_scalar.hpp" + +#include "dpf/shamir.hpp" + +#include "dpf/shamir3.hpp" + #include "dpf/verifiable.hpp" +#include "dpf/path_sketch.hpp" + +#include "dpf/sfss.hpp" + #include "dpf/multipoint.hpp" #include "dpf/ppvc.hpp" +#include "dpf/dpf3.hpp" + +#include "dpf/dpf3_ds.hpp" + +#include "dpf/dpf3_multipoint.hpp" + +#include "dpf/dpf3_cmp.hpp" + #include "dpf/vec.hpp" #include "dpf/interval.hpp" +#include "dpf/eval_peel.hpp" + #endif // LIBDPF_INCLUDE_DPF_HPP__ diff --git a/include/dpf/advice_bit_iterable.hpp b/include/dpf/advice_bit_iterable.hpp index c6edd4d..a83e7db 100644 --- a/include/dpf/advice_bit_iterable.hpp +++ b/include/dpf/advice_bit_iterable.hpp @@ -47,6 +47,7 @@ #include "portable-snippets/exact-int/exact-int.h" #include "dpf/utils.hpp" +#include "dpf/twiddle.hpp" #include "dpf/bit_array.hpp" namespace dpf @@ -55,16 +56,6 @@ namespace dpf namespace detail { -template -struct extract_bit_simde_node -{ - bool operator()(Iterator it) const - { - auto buf = reinterpret_cast(&*it); - return buf[0] & 1; - } -}; - template struct extract_bit; @@ -72,11 +63,23 @@ HEDLEY_PRAGMA(GCC diagnostic push) HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") template struct extract_bit - : public extract_bit_simde_node { }; +{ + bool operator()(Iterator it) const + { + // Same lo-bit extract used by tree walk / correction packing. + return static_cast(dpf::get_lo_bit(*it)); + } +}; template struct extract_bit - : public extract_bit_simde_node { }; +{ + bool operator()(Iterator it) const + { + auto buf = reinterpret_cast(&*it); + return buf[0] & 1; + } +}; HEDLEY_PRAGMA(GCC diagnostic pop) } // namespace detail diff --git a/include/dpf/aes_sbox_bp.hpp b/include/dpf/aes_sbox_bp.hpp new file mode 100644 index 0000000..0fd40a3 --- /dev/null +++ b/include/dpf/aes_sbox_bp.hpp @@ -0,0 +1,161 @@ +/// @file dpf/aes_sbox_bp.hpp +/// @brief Boyar–Peralta AES S-box (Yale CMT SLP, 32 ANDs) over XOR bit shares. +/// @details Circuit: http://www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt +/// (Boyar and Peralta, ePrint 2011/332). Matches the AES S-box used +/// by `aes_ref` / hardware AES. `#` is XNOR. + +#ifndef LIBDPF_INCLUDE_DPF_AES_SBOX_BP_HPP__ +#define LIBDPF_INCLUDE_DPF_AES_SBOX_BP_HPP__ + +#include +#include + +namespace aes_bp +{ + +inline constexpr std::size_t wire_count = 121; +inline constexpr std::size_t op_count = 113; +inline constexpr std::size_t and_count = 32; +/// @brief Multiplicative depth of the SLP (XOR/XNOR are free). +inline constexpr std::size_t and_layer_count = 6; +inline constexpr std::uint8_t out_wire[8] = {114,117,119,107,116,120,115,111}; + +/// @brief AND-op indices in `ops` grouped by multiplicative depth. +/// @details XOR/XNOR between layers stay local. Every AND in a layer has +/// both inputs ready, so one exchange covers the whole layer +/// (and every S-box byte sharing that schedule). +inline constexpr std::uint8_t and_layer_size[and_layer_count] = {9, 1, 2, 7, 5, 8}; +inline constexpr std::uint8_t and_layer_ops[and_layer_count][9] = { + {23, 24, 26, 28, 29, 31, 33, 34, 36}, + {47}, + {49, 53}, + {57, 69, 72, 73, 78, 81, 82}, + {60, 67, 68, 76, 77}, + {70, 71, 74, 75, 79, 80, 83, 84}, +}; +static_assert( + and_layer_size[0] + and_layer_size[1] + and_layer_size[2] + + and_layer_size[3] + and_layer_size[4] + and_layer_size[5] + == and_count, + "Boyar–Peralta AND layer sizes must cover every AND"); + +// kind: 0=XOR, 1=AND, 2=XNOR. Each row is {kind, dst, a, b}. +inline constexpr std::uint8_t ops[op_count][4] = { + {0, 8, 3, 5}, + {0, 9, 0, 6}, + {0, 10, 0, 3}, + {0, 11, 0, 5}, + {0, 12, 1, 2}, + {0, 13, 12, 7}, + {0, 14, 13, 3}, + {0, 15, 9, 8}, + {0, 16, 13, 0}, + {0, 17, 13, 6}, + {0, 18, 17, 11}, + {0, 19, 4, 15}, + {0, 20, 19, 5}, + {0, 21, 19, 1}, + {0, 22, 20, 7}, + {0, 23, 20, 12}, + {0, 24, 21, 10}, + {0, 25, 7, 24}, + {0, 26, 23, 24}, + {0, 27, 23, 11}, + {0, 28, 12, 24}, + {0, 29, 9, 28}, + {0, 30, 0, 28}, + {1, 31, 15, 20}, + {1, 32, 18, 22}, + {0, 33, 32, 31}, + {1, 34, 14, 7}, + {0, 35, 34, 31}, + {1, 36, 9, 28}, + {1, 37, 17, 13}, + {0, 38, 37, 36}, + {1, 39, 16, 25}, + {0, 40, 39, 36}, + {1, 41, 10, 24}, + {1, 42, 8, 26}, + {0, 43, 42, 41}, + {1, 44, 11, 23}, + {0, 45, 44, 41}, + {0, 46, 33, 21}, + {0, 47, 35, 45}, + {0, 48, 38, 43}, + {0, 49, 40, 45}, + {0, 50, 46, 43}, + {0, 51, 47, 27}, + {0, 52, 48, 29}, + {0, 53, 49, 30}, + {0, 54, 50, 51}, + {1, 55, 50, 52}, + {0, 56, 53, 55}, + {1, 57, 54, 56}, + {0, 58, 57, 51}, + {0, 59, 52, 53}, + {0, 60, 51, 55}, + {1, 61, 60, 59}, + {0, 62, 61, 53}, + {0, 63, 52, 62}, + {0, 64, 56, 62}, + {1, 65, 53, 64}, + {0, 66, 65, 63}, + {0, 67, 56, 65}, + {1, 68, 58, 67}, + {0, 69, 54, 68}, + {0, 70, 69, 66}, + {0, 71, 58, 62}, + {0, 72, 58, 69}, + {0, 73, 62, 66}, + {0, 74, 71, 70}, + {1, 75, 73, 20}, + {1, 76, 66, 22}, + {1, 77, 62, 7}, + {1, 78, 72, 28}, + {1, 79, 69, 13}, + {1, 80, 58, 25}, + {1, 81, 71, 24}, + {1, 82, 74, 26}, + {1, 83, 70, 23}, + {1, 84, 73, 15}, + {1, 85, 66, 18}, + {1, 86, 62, 14}, + {1, 87, 72, 9}, + {1, 88, 69, 17}, + {1, 89, 58, 16}, + {1, 90, 71, 10}, + {1, 91, 74, 8}, + {1, 92, 70, 11}, + {0, 93, 90, 91}, + {0, 94, 85, 93}, + {0, 95, 84, 94}, + {0, 96, 75, 77}, + {0, 97, 76, 75}, + {0, 98, 78, 79}, + {0, 99, 87, 96}, + {0, 100, 82, 98}, + {0, 101, 83, 99}, + {0, 102, 100, 101}, + {0, 103, 98, 97}, + {0, 104, 78, 80}, + {0, 105, 88, 93}, + {0, 106, 96, 104}, + {0, 107, 95, 103}, + {0, 108, 81, 100}, + {0, 109, 89, 102}, + {0, 110, 105, 106}, + {2, 111, 87, 110}, + {0, 112, 90, 108}, + {0, 113, 94, 86}, + {0, 114, 95, 108}, + {2, 115, 102, 110}, + {0, 116, 106, 107}, + {2, 117, 107, 108}, + {0, 118, 109, 112}, + {2, 119, 118, 92}, + {0, 120, 113, 109}, +}; + +} // namespace aes_bp + +#endif // LIBDPF_INCLUDE_DPF_AES_SBOX_BP_HPP__ diff --git a/include/dpf/app_flow.hpp b/include/dpf/app_flow.hpp new file mode 100644 index 0000000..3f6509e --- /dev/null +++ b/include/dpf/app_flow.hpp @@ -0,0 +1,633 @@ +/// @file dpf/app_flow.hpp +/// @brief Measure an application plan on an explicit `run_config`. +/// @details `exercise_plan(p, ex, cfg)` drives both parties of `p` over +/// `cfg.kind` (in-process memory, sync streams, async memory, unix +/// sockets, TCP mux, parallel TCP, or SCTP) with the configured lanes, +/// framing, instances, window, chunking, pipelining, compute threads, +/// warmup, and trials. Link setup is outside the timed region. The +/// overloads without a config read `run_config::from_env()` once, for +/// the example binaries. +#ifndef LIBDPF_INCLUDE_DPF_APP_FLOW_HPP__ +#define LIBDPF_INCLUDE_DPF_APP_FLOW_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/app_runtime.hpp" +#include "dpf/compose.hpp" +#include "dpf/compose_async.hpp" +#include "dpf/experiment.hpp" +#include "dpf/net/async_round_sink.hpp" +#include "dpf/net/memory_sink.hpp" +#include "dpf/net/round_lane.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/online_session.hpp" +#include "dpf/party_runner.hpp" +#include "dpf/run_config.hpp" +#include "dpf/run_log.hpp" + +namespace dpf +{ +namespace app +{ + +using transport_kind = net::transport; + +inline const char * transport_name(transport_kind t) noexcept +{ + return net::transport_name(t); +} + +/// @brief `DPF_TRANSPORT` (default `async`). Unknown names throw. +inline transport_kind transport_from_env() +{ + return run_config::from_env().kind; +} + +/// @brief Drive a plan through `schedule_session` on an `async_round_sink`. +inline void drive_via_schedule_async(const protocol::plan & p, + net::async_round_sink & sink, + std::vector> & values, + const std::map & kernels, + std::size_t party, const protocol::drive_options & opt = {}) +{ + protocol::drive_via_schedule(p, sink, values, kernels, party, opt); +} + +/// @brief What one `exercise_plan` measured. +/// @details `bytes` is the plan's slot bytes (one instance). `wire_*` are +/// party 0's link counters including every header. `wall_ns` is the +/// median party-0 drive time over the timed trials. +struct cost +{ + std::size_t rounds = 0; + std::size_t bytes = 0; + std::uint64_t wire_out = 0; + std::uint64_t wire_in = 0; + std::uint64_t frames_out = 0; + std::uint64_t frames_in = 0; + std::uint64_t write_calls = 0; + std::uint64_t wall_ns = 0; +}; + +inline cost plan_cost(const protocol::plan & p) +{ + cost out; + out.rounds = p.rounds(); + for (auto n : p.slot_bytes_all()) + out.bytes += n; + return out; +} + +namespace detail +{ + +struct once +{ + std::uint64_t wall_ns = 0; + net::stream_stats wire; + /// Every party's drive time (`party_walls[0] == wall_ns`). + std::vector party_walls; +}; + +/// @brief Parties 0 and 1 on two threads over a paired in-process sink. Party +/// `p` draws from `seeds->derive_party(p)` when `seeds` is set; `ex` +/// records party 0 and receives both parties' noted seeds. +template +inline once two_threads(experiment * ex, const experiment * seeds, Drive drive) +{ + once out; + out.party_walls.assign(2, 0); + std::exception_ptr err[2]; + std::vector noted[2]; + start_gate gate(2); + auto side = [&](unsigned party) { + try + { + std::optional stream; + if (seeds != nullptr) + stream.emplace(seeds->derive_party(party)); + if (!gate.arrive_and_wait()) + throw gate_broken(); + experiment * mine = party == 0 ? ex : nullptr; + protocol::round_probe probe{}; + if (mine != nullptr) + { + probe = mine->probe(); + mine->begin_timing(); + } + const auto a = std::chrono::steady_clock::now(); + drive(party, mine != nullptr ? &probe : nullptr); + out.party_walls[party] = static_cast( + std::chrono::duration_cast( + std::chrono::steady_clock::now() - a) + .count()); + if (mine != nullptr) + mine->end_timing(); + if (stream) + noted[party] = stream->seeds(); + } + catch (...) + { + err[party] = std::current_exception(); + gate.fail(); + } + }; + std::thread t0(side, 0u); + std::thread t1(side, 1u); + t0.join(); + t1.join(); + for (auto & e : err) + { + if (!e) + continue; + try + { + std::rethrow_exception(e); + } + catch (const gate_broken &) + { + continue; + } + catch (...) + { + } + std::rethrow_exception(e); + } + out.wall_ns = out.party_walls[0]; + if (ex != nullptr && seeds != nullptr) + for (unsigned p = 0; p < 2; ++p) + ex->fold_seeds("p" + std::to_string(p), noted[p]); + return out; +} + +/// @brief One run of `plans` on `cfg.kind` from fresh copies of `inputs`; +/// `ex` records party 0 when set, and parties draw from `seeds`'s +/// derived streams when it is set. +inline once run_once(const std::vector & plans, + const std::vector & inputs, + const std::map & kernels, + const run_config & cfg, experiment * ex, const experiment * seeds = nullptr) +{ + std::vector values = inputs; + values.resize(plans.size()); + const auto slots = plans[0].slot_bytes_all(); + auto opt = cfg.drive(); + const bool in_memory = cfg.kind == net::transport::memory_sink + || cfg.kind == net::transport::memory_stream; + if (in_memory && plans.size() != 2) + throw std::invalid_argument(std::string("transport ") + + net::transport_name(cfg.kind) + " runs two parties"); + switch (cfg.kind) + { + case net::transport::memory_sink: + { + auto sl = slots.empty() ? std::vector{0} : slots; + auto sinks = net::make_memory_sink_pair(cfg.instances, sl); + return two_threads(ex, seeds, [&](unsigned party, const protocol::round_probe * pr) { + auto o = opt; + o.probe = pr; + protocol::drive_via_schedule(plans[party], + party == 0 ? sinks.first : sinks.second, values[party], kernels, + party, o); + }); + } + case net::transport::memory_stream: + { + const std::size_t nstreams = + slots.empty() ? 1 : protocol::lanes_for_plan(slots.size(), opt); + auto ends = net::make_memory_stream_pair(nstreams); + return two_threads(ex, seeds, [&](unsigned party, const protocol::round_probe * pr) { + auto o = opt; + o.probe = pr; + protocol::drive_plan_on_streams(plans[party], + party == 0 ? ends.first : ends.second, values[party], kernels, + party, cfg.instances, o); + }); + } + default: + { + const auto r = run_parties(plans, values, kernels, cfg, ex, nullptr, seeds); + once out; + out.wall_ns = r.party0_wall_ns; + out.wire = r.wire[0]; + out.party_walls = r.party_wall_ns; + return out; + } + } +} + +} // namespace detail + +/// @brief Drive every party's plan over `cfg` and return party 0's cost. +/// @details `plans[i]` is party `i`'s plan (2 or 3 parties); each trial starts +/// from a fresh copy of `inputs` (missing entries start empty). +/// Warmup runs are not timed; `wall_ns` is the median timed trial. +inline cost exercise_parties(const std::vector & plans, + const std::vector & inputs, + const std::map & kernels, experiment * ex, + const run_config & cfg) +{ + if (plans.size() < 2 || plans.size() > 3) + throw std::invalid_argument("exercise_parties needs 2 or 3 plans"); + const protocol::plan & p = plans[0]; + cost out = plan_cost(p); + if (ex != nullptr) + { + ex->ingest_plan(p); + ex->set_config(cfg.describe()); + } + if (p.slot_bytes_all().empty() && cfg.kind != net::transport::memory_sink) + { + DPF_LOG(warning, "trials.skipped") + .kv("experiment", ex != nullptr ? ex->name() : std::string("none")) + .kv("detail", "the plan has no exchange rounds; nothing was timed and " + "wall_ns stays 0"); + return out; + } + const std::size_t total = cfg.warmup + std::max(1, cfg.trials); + std::vector walls; + std::vector slowest; + detail::once last; + for (std::size_t t = 0; t < total; ++t) + { + const bool timed = t >= cfg.warmup; + const bool record = t + 1 == total; + last = detail::run_once(plans, inputs, kernels, cfg, record ? ex : nullptr, ex); + DPF_LOG(debug, "trial").kv("index", t).kv("timed", timed) + .kv("instrumented", record && ex != nullptr).kv("p0_wall_ns", last.wall_ns) + .kv("wire_out", last.wire.bytes_out).kv("wire_in", last.wire.bytes_in); + if (timed) + { + walls.push_back(last.wall_ns); + std::uint64_t w = last.wall_ns; + for (auto p : last.party_walls) + w = std::max(w, p); + slowest.push_back(w); + if (ex != nullptr) + ex->add_trial(last.wall_ns, last.party_walls); + } + } + std::sort(walls.begin(), walls.end()); + std::sort(slowest.begin(), slowest.end()); + out.wall_ns = walls.empty() ? 0 : walls[walls.size() / 2]; + if (!walls.empty() && log::enabled(log::level::info)) + { + double mean = 0; + for (auto w : walls) + mean += static_cast(w); + mean /= static_cast(walls.size()); + double var = 0; + for (auto w : walls) + var += (static_cast(w) - mean) * (static_cast(w) - mean); + const double sd = walls.size() > 1 + ? std::sqrt(var / static_cast(walls.size() - 1)) : 0.0; + DPF_LOG(info, "trials") + .kv("experiment", ex != nullptr ? ex->name() : std::string("none")) + .kv("transport", net::transport_name(cfg.kind)).kv("n", walls.size()) + .kv("warmup", cfg.warmup).kv("median_ns", out.wall_ns) + .kv("min_ns", walls.front()).kv("max_ns", walls.back()) + .kv("mean_ns", mean).kv("sd_ns", sd) + .kv("slowest_median_ns", slowest[slowest.size() / 2]) + .kv("instrumented_trial", "last") + .kv("links", "rebuilt per trial"); + } + out.wire_out = last.wire.bytes_out; + out.wire_in = last.wire.bytes_in; + out.frames_out = last.wire.frames_out; + out.frames_in = last.wire.frames_in; + out.write_calls = last.wire.write_calls; + if (ex != nullptr) + { + experiment::wire_counts w; + w.bytes_out = last.wire.bytes_out; + w.bytes_in = last.wire.bytes_in; + w.payload_out = last.wire.payload_out; + w.payload_in = last.wire.payload_in; + w.frames_out = last.wire.frames_out; + w.frames_in = last.wire.frames_in; + w.write_calls = last.wire.write_calls; + ex->set_wire(w); + } + return out; +} + +/// @brief Drive `p` as both parties' plan over `cfg` and return its cost. +inline cost exercise_plan(const protocol::plan & p, experiment * ex, + const run_config & cfg, + const std::map & kernels = {}) +{ + return exercise_parties({p, p}, {}, kernels, ex, cfg); +} + +/// @brief `exercise_plan` on `run_config::from_env()`. +inline cost exercise_plan(const protocol::plan & p, experiment * ex = nullptr) +{ + return exercise_plan(p, ex, run_config::from_env()); +} + +inline experiment measure_plan(const char * name, const protocol::plan & p, + const run_config & cfg) +{ + experiment ex(name, "p0"); + (void)exercise_plan(p, &ex, cfg); + return ex; +} + +inline experiment measure_plan(const char * name, const protocol::plan & p) +{ + return measure_plan(name, p, run_config::from_env()); +} + +/// @brief Schedule `c`, then `exercise_plan`. +inline cost exercise(protocol::composer & c) +{ + return exercise_plan(c.default_plan()); +} + +/// @brief Exercise `p` and require `expect_rounds`. Prints `name rounds= bytes=`. +inline int run_plan(const char * name, const protocol::plan & p, + std::size_t expect_rounds, const run_config & cfg = run_config::from_env()) +{ + try + { + start_logging(cfg); + const cost got = exercise_plan(p, nullptr, cfg); + std::cout << name << " rounds=" << got.rounds << " bytes=" << got.bytes + << " wire_out=" << got.wire_out << " wire_in=" << got.wire_in + << "\n"; + if (got.rounds != expect_rounds) + { + std::cerr << name << " expected " << expect_rounds << " rounds\n"; + return 1; + } + } + catch (const std::exception & ex) + { + DPF_LOG(error, "run.failed").kv("name", name).kv("what", ex.what()); + std::cerr << name << " flow: " << ex.what() << "\n"; + return 1; + } + return 0; +} + +/// @brief Measure `p`, print cost, and write CSVs under `DPF_EXPERIMENT_DIR`. +/// @details When `prep` is set, the prep for that demand is dealt and shipped +/// over `cfg`'s transport and its size is printed. +inline int run_measured(const char * name, const protocol::plan & p, + std::size_t expect_rounds, const run_config & cfg = run_config::from_env(), + const prep::demand * prep = nullptr) +{ + try + { + start_logging(cfg); + auto ex = measure_plan(name, p, cfg); + std::cout << name << " transport=" << net::transport_name(cfg.kind) + << " rounds=" << ex.interactive_rounds() + << " bytes=" << ex.plan_bytes_out() + << " wire_out=" << ex.wire().bytes_out + << " wire_in=" << ex.wire().bytes_in + << " wall_ns=" << ex.wall_ns() + << " median_ns=" << ex.median_trial_ns() + << " cpu_ns=" << ex.cpu_ns() + << " prg_evals=" << ex.prg_evals() + << " random_bytes=" << ex.random_bytes() + << " seed=" << ex.seed_hex(); + if (prep != nullptr) + { + const auto shipped = session::ship_prep(*prep, cfg); + std::cout << " prep_bytes=" << shipped.bytes0; + } + std::cout << "\n"; + if (ex.interactive_rounds() != expect_rounds) + { + std::cerr << name << " expected " << expect_rounds << " rounds\n"; + return 1; + } + if (const char * dir = std::getenv("DPF_EXPERIMENT_DIR")) + { + if (dir[0] != '\0') + ex.write_csv(dir); + } + } + catch (const std::exception & ex) + { + DPF_LOG(error, "run.failed").kv("name", name).kv("what", ex.what()); + std::cerr << name << " measure: " << ex.what() << "\n"; + return 1; + } + return 0; +} + +/// @brief Exercise `c` and require `expect_rounds`. +inline int run(const char * name, protocol::composer & c, std::size_t expect_rounds) +{ + return run_plan(name, c.default_plan(), expect_rounds); +} + +/// @brief `run_measured` on `c.default_plan()`. +inline int run_measured(const char * name, protocol::composer & c, + std::size_t expect_rounds) +{ + return run_measured(name, c.default_plan(), expect_rounds); +} + +/// @brief Many instances, both parties, delays that do not line up. +/// @details A worker never sits on a side whose peer is the one that still +/// has to submit. Parked receives yield the thread to whichever +/// side is behind, so a slow step does not stall the rest and a +/// round-robin that always resumes the waiter cannot deadlock. +inline void run_fleet(protocol::composer & c, std::size_t instances, + std::uint32_t chaos_seed) +{ + if (instances == 0) + throw std::invalid_argument("run_fleet needs instances"); + auto plan = c.default_plan(); + auto slots = plan.slot_bytes_all(); + if (slots.empty()) + slots.push_back(0); + + struct side + { + protocol::drive_cursor cursor{}; + std::vector> values; + net::memory_sink * sink = nullptr; + std::chrono::steady_clock::time_point ready_at{}; + bool busy = false; + }; + struct inst + { + std::pair sinks; + side party[2]{}; + }; + std::vector all; + all.reserve(instances); + auto chaos_us = [&](std::size_t id, int party, std::size_t step) { + std::uint32_t x = chaos_seed + ^ static_cast(id * 0x9E3779B9u) + ^ static_cast(party * 0x85EBCA6Bu) + ^ static_cast(step * 0xC2B2AE35u); + x ^= x << 13; + x ^= x >> 17; + // Mostly short, with occasional long stalls. Not sorted by instance. + const std::uint32_t bucket = x % 17u; + if (party == 0 && step == 0 && (id % 5u) == 0) + return 12000; + if (bucket == 0) + return 1500; + if (bucket < 4) + return static_cast(x % 400u); + return static_cast(x % 40u); + }; + for (std::size_t i = 0; i < instances; ++i) + { + all.push_back(inst{net::make_memory_sink_pair(1, slots), {}}); + auto & created = all.back(); + created.party[0].sink = &created.sinks.first; + created.party[1].sink = &created.sinks.second; + const auto now = std::chrono::steady_clock::now(); + created.party[0].ready_at = now + std::chrono::microseconds( + chaos_us(i, 0, 0)); + created.party[1].ready_at = now + std::chrono::microseconds( + chaos_us(i, 1, 0)); + } + + std::mutex mu; + std::condition_variable cv; + std::map kernels; + std::size_t finished = 0; + const std::size_t workers = std::min( + std::thread::hardware_concurrency() == 0 + ? 4 + : std::thread::hardware_concurrency(), + instances); + + auto pick = [&](std::unique_lock & lock) -> side * { + for (;;) + { + const auto now = std::chrono::steady_clock::now(); + side * best = nullptr; + int best_score = 0x7fffffff; + std::chrono::steady_clock::time_point soonest = + now + std::chrono::hours(1); + bool any_left = false; + for (auto & item : all) + { + for (int p = 0; p < 2; ++p) + { + side & s = item.party[p]; + if (s.cursor.done) + continue; + if (s.busy) + { + any_left = true; + continue; + } + any_left = true; + if (s.ready_at > now) + { + if (s.ready_at < soonest) + soonest = s.ready_at; + continue; + } + // A side still submitting outranks one parked on a receive. + // Among those, the one further behind runs first. + const int score = static_cast(s.cursor.exchange_i) + + (s.cursor.awaiting_peer ? 100000 : 0); + if (score < best_score) + { + best_score = score; + best = &s; + } + } + } + if (best != nullptr) + { + best->busy = true; + return best; + } + if (!any_left) + return nullptr; + cv.wait_until(lock, soonest); + } + }; + + auto worker = [&] { + std::unique_lock lock(mu); + for (;;) + { + side * s = pick(lock); + if (s == nullptr) + return; + std::size_t inst_i = 0; + int party = 0; + for (; inst_i < all.size(); ++inst_i) + { + if (&all[inst_i].party[0] == s) + { + party = 0; + break; + } + if (&all[inst_i].party[1] == s) + { + party = 1; + break; + } + } + protocol::drive_options opt; + opt.park_if_waiting = true; + opt.one_exchange = true; + opt.cursor = &s->cursor; + auto * sink = s->sink; + auto * values = &s->values; + const std::size_t step = s->cursor.exchange_i; + lock.unlock(); + + protocol::drive(plan, *sink, *values, kernels, + static_cast(party), opt); + + lock.lock(); + s->busy = false; + if (s->cursor.done) + ++finished; + else + { + s->ready_at = std::chrono::steady_clock::now() + + std::chrono::microseconds(chaos_us(inst_i, party, step)); + } + cv.notify_all(); + } + }; + + std::vector pool; + pool.reserve(workers); + for (std::size_t i = 0; i < workers; ++i) + pool.emplace_back(worker); + for (auto & th : pool) + th.join(); + if (finished != instances * 2) + throw std::runtime_error("run_fleet: not every side finished"); +} + +} // namespace app +} // namespace dpf + +#endif diff --git a/include/dpf/app_plans.hpp b/include/dpf/app_plans.hpp new file mode 100644 index 0000000..977bd96 --- /dev/null +++ b/include/dpf/app_plans.hpp @@ -0,0 +1,312 @@ +/// @file dpf/app_plans.hpp +/// @brief Named compose plans and star drivers for the application sketches. +#ifndef LIBDPF_INCLUDE_DPF_APP_PLANS_HPP__ +#define LIBDPF_INCLUDE_DPF_APP_PLANS_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/compose.hpp" +#include "dpf/mesh_apps.hpp" +#include "dpf/net/edge_mesh.hpp" +#include "dpf/pad_graphs.hpp" +#include "dpf/protocol.hpp" +#include "dpf/session_host.hpp" + +namespace dpf +{ +namespace protocol +{ + +/// @brief Drive every session until all instances are done (interleaved). +/// @details Callers must `submit` each live index first (see `submit_and_drive`). +inline void drive_sessions(std::vector sessions, + unsigned max_spins = 100000u) +{ + if (sessions.empty()) + return; + for (auto * s : sessions) + { + if (s == nullptr) + throw std::invalid_argument("drive_sessions null"); + } + for (unsigned spins = 0;; ++spins) + { + if (spins > max_spins) + throw std::runtime_error("drive_sessions: peer not ready"); + bool all_done = true; + for (auto * s : sessions) + { + s->drive(); + for (std::size_t i = 0; i < s->count(); ++i) + all_done = all_done && s->done(i); + } + if (all_done) + return; + } +} + +/// @brief Submit every unfinished index, then `drive_sessions`. +inline void submit_and_drive(std::vector sessions, + unsigned max_spins = 100000u) +{ + for (auto * s : sessions) + { + if (s == nullptr) + throw std::invalid_argument("submit_and_drive null"); + for (std::size_t i = 0; i < s->count(); ++i) + if (!s->done(i)) + s->submit(i); + } + drive_sessions(std::move(sessions), max_spins); +} + +/// @brief Client↔N-server star: build sessions from round lists and drive. +inline void drive_star(net::memory_star & star, + std::vector client_rounds, + const std::function(std::size_t server_i)> & + server_rounds_for, + unsigned max_spins = 100000u) +{ + schedule_session client(1, star.client_mesh(), std::move(client_rounds), + false); + std::vector servers; + servers.reserve(star.servers); + for (std::size_t i = 0; i < star.servers; ++i) + servers.emplace_back(1, star.server_edge(i), server_rounds_for(i), + false); + std::vector ptrs; + ptrs.reserve(1 + servers.size()); + ptrs.push_back(&client); + for (auto & s : servers) + ptrs.push_back(&s); + submit_and_drive(std::move(ptrs), max_spins); +} + +/// @brief N-server PIR / keyword PIR compose plan (`client_servers` waves). +inline plan n_server_pir_plan(std::size_t party, std::size_t n_servers, + std::size_t query_bytes, std::size_t answer_bytes) +{ + composer c(party); + auto q = c.client_servers(n_servers, query_bytes, answer_bytes); + (void)q; + return c.default_plan(); +} + +inline plan keyword_pir_compose_plan(std::size_t party, std::size_t depth, + std::size_t answer_bytes = sizeof(int)) +{ + const std::size_t query_bytes = 16 + depth * 16; + return n_server_pir_plan(party, 2, query_bytes, answer_bytes); +} + +/// @brief Express / Sabre online walk: fused CW + trailer (sketch/proof). +inline plan mailbox_write_fused_plan(std::size_t party, std::size_t depth = 8, + std::size_t cw_bytes = 16, std::size_t trailer_bytes = 8) +{ + composer c(party); + auto seed = c.input(domain::fss, 16); + auto trailer = c.input(domain::a, trailer_bytes); + auto walk = c.fss_point_fused(seed, depth, cw_bytes, trailer); + (void)walk; + return c.default_plan(); +} + +/// @brief BitMore: L parallel bit-point walks (CSE → one wave per depth). +inline plan bitmore_fan_plan(std::size_t party, std::size_t L = 4, + std::size_t depth = 6) +{ + composer c(party); + auto seeds = c.fan(L, [&](std::size_t) { + return c.input(domain::fss, 16); + }); + (void)c.fan(L, [&](std::size_t i) { + return c.fss_point(seeds[i], depth, 16); + }); + return c.default_plan(); +} + +/// @brief BitMore / PIRsona star key-ship + answer schedule rounds. +inline std::vector bitmore_star_fetch(std::size_t L, + std::size_t seed_bytes, std::size_t answer_bytes, + const std::shared_ptr>> & seeds, + const std::shared_ptr>> & answers) +{ + return pirsona_bitmore_fetch(L, seed_bytes, answer_bytes, seeds, answers); +} + +/// @brief SUBLEQ one instruction: prepaid expand + cmp branch skeleton. +inline plan subleq_instruction_plan(std::size_t party, std::size_t addr_depth = 8, + std::size_t slot_bytes = 16) +{ + composer c(party); + auto seed = c.input(domain::fss, 16); + auto prepaid = c.defer_expand(seed, addr_depth, slot_bytes); + auto branch = c.fss_cmp(seed, addr_depth, slot_bytes); + (void)prepaid; + (void)branch; + return c.default_plan(); +} + +/// @brief Queue `n_insns` SUBLEQ instruction plans on a peer `session_host`. +inline void subleq_run_instructions(session_host & host, std::size_t n_insns, + std::size_t addr_depth = 8, std::size_t slot_bytes = 16) +{ + for (std::size_t i = 0; i < n_insns; ++i) + host.push(subleq_instruction_plan(host.party(), addr_depth, slot_bytes)); + host.drive_until_idle(); +} + +/// @brief Pika early-stop unit walk (`early_stop` bits pack into the leaf). +inline plan pika_lookup_plan(std::size_t party, std::size_t full_depth = 8, + std::size_t early_stop = 3) +{ + composer c(party); + auto seed = c.input(domain::fss, 16); + auto tip = c.fss_point_early_stop(seed, full_depth, early_stop, 16); + (void)tip; + return c.default_plan(); +} + +/// @brief Pika with dealer pad delivery of the unit key before the walk. +inline plan pika_dealer_lookup_plan(std::size_t party, std::size_t full_depth = 8, + std::size_t early_stop = 3) +{ + composer c(party); + auto key = c.input(domain::fss, 16); + auto delivered = c.dealer_deliver(key); + auto tip = c.fss_point_early_stop(delivered, full_depth, early_stop, 16); + (void)tip; + return c.default_plan(); +} + +/// @brief Duoram write: path CWs with leaf applied later. +inline plan duoram_update_plan(std::size_t party, std::size_t depth = 8, + std::size_t slot_bytes = 16) +{ + composer c(party); + auto seed = c.input(domain::fss, 16); + auto walk = c.leaf_later_walk(seed, depth, slot_bytes); + auto leaf = c.input(domain::a, slot_bytes); + auto applied = c.apply_leaf_correction(walk.values, walk.control, leaf); + (void)applied; + return c.default_plan(); +} + +/// @brief Poplar / Prio / Mastic: prefix checkpoints each level. +inline plan poplar_prefix_plan(std::size_t party, std::size_t depth = 8, + std::size_t slot_bytes = 16, std::size_t prefix_bytes = 8) +{ + composer c(party); + auto seed = c.input(domain::fss, 16); + auto prefixes = c.level_walk_prefixes(seed, depth, slot_bytes, prefix_bytes); + (void)prefixes; + return c.default_plan(); +} + +/// @brief Weighted / multi-seed prefix fan (Prio multi-client shape). +inline plan poplar_prefix_fan_plan(std::size_t party, std::size_t n_keys, + std::size_t depth = 8, std::size_t slot_bytes = 16, + std::size_t prefix_bytes = 8) +{ + composer c(party); + (void)c.fan(n_keys, [&](std::size_t) { + auto seed = c.input(domain::fss, 16); + return c.level_walk_prefixes(seed, depth, slot_bytes, prefix_bytes) + .at_level.back(); + }); + return c.default_plan(); +} + +/// @brief Ledger (2,3): verifiable DPF3 append — upload + proof exchange. +inline plan ledger23_append_plan(std::size_t party, std::size_t depth = 8, + std::size_t proof_bytes = 32) +{ + composer c(party); + const std::size_t query_bytes = 16 + depth * 16; + auto up = c.client_servers(3, query_bytes, proof_bytes); + (void)up; + return c.default_plan(); +} + +/// @brief Floram DS keygen walk (read/write expand stay local). +inline plan floram_ds_plan(std::size_t party, std::size_t depth = 8, + std::size_t slot_bytes = 16, bool oh = false) +{ + composer c(party); + auto seed = c.input(domain::fss, 16); + auto tip = c.level_walk_ds(seed, depth, slot_bytes, oh); + (void)tip; + return c.default_plan(); +} + +/// @brief Splinter-style point walk (server expand cost). +inline plan fss_point_plan(std::size_t party, std::size_t depth = 8, + std::size_t slot_bytes = 16) +{ + composer c(party); + auto seed = c.input(domain::fss, 16); + auto tip = c.fss_point(seed, depth, slot_bytes); + (void)tip; + return c.default_plan(); +} + +/// @brief Waldo-style comparison walk. +inline plan fss_cmp_plan(std::size_t party, std::size_t depth = 8, + std::size_t slot_bytes = 16) +{ + composer c(party); + auto seed = c.input(domain::fss, 16); + auto tip = c.fss_cmp(seed, depth, slot_bytes); + (void)tip; + return c.default_plan(); +} + +/// @brief Range-count: two parallel cmp walks. +inline plan range_count_plan(std::size_t party, std::size_t depth = 8, + std::size_t slot_bytes = 16) +{ + composer c(party); + auto seed = c.input(domain::fss, 16); + (void)c.fan(2, [&](std::size_t) { + return c.fss_cmp(seed, depth, slot_bytes); + }); + return c.default_plan(); +} + +/// @brief PSI cuckoo probes → multipoint fan (occupied bucket ids). +inline plan psi_cuckoo_plan(std::size_t party, + const std::vector & probes, std::size_t depth = 8, + std::size_t slot_bytes = 16, std::size_t answer_bytes = 8) +{ + composer c(party); + auto mr = c.schedule_cuckoo_probes(probes, + [&](std::size_t) { return c.input(domain::fss, 16); }, depth, + slot_bytes, answer_bytes); + (void)mr; + return c.default_plan(); +} + +/// @brief idpf_agg: adaptive prefix retain loop (`n_bits` online rounds). +inline plan idpf_agg_plan(std::size_t party, std::size_t n_bits = 16, + std::size_t slot_bytes = 16, std::size_t prefix_bytes = 8) +{ + composer c(party); + auto f = c.begin_adaptive_prefix(c.input(domain::fss, 16)); + for (std::size_t bit = 0; bit < n_bits; ++bit) + { + f = c.step_adaptive_prefix(f, slot_bytes, prefix_bytes); + f = c.retain_adaptive_prefix(f, 0); + } + return c.default_plan(); +} + +} // namespace protocol +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_APP_PLANS_HPP__ diff --git a/include/dpf/app_runtime.hpp b/include/dpf/app_runtime.hpp new file mode 100644 index 0000000..3bd2806 --- /dev/null +++ b/include/dpf/app_runtime.hpp @@ -0,0 +1,144 @@ +/// @file dpf/app_runtime.hpp +/// @brief File prep and two-party synchronous mux helpers. +/// @details `stream_runtime` configures only this synchronous TCP mux path. +/// For any other transport, party count, or a dealer, use +/// `app::run_config` with `app::run_parties` (`party_runner.hpp`). +/// The synchronous mux speaks the same frames as the async mux. +#ifndef LIBDPF_INCLUDE_DPF_APP_RUNTIME_HPP__ +#define LIBDPF_INCLUDE_DPF_APP_RUNTIME_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/compose.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/net/sync_stream_array.hpp" +#include "dpf/party_run.hpp" +#include "dpf/prep_source.hpp" +#include "dpf/protocol_roles.hpp" + +namespace dpf +{ +namespace app +{ + +/// @brief File prep basename and synchronous mux settings (two parties). +struct stream_runtime +{ + std::string prep_basename; + std::string mux_host = "127.0.0.1"; + unsigned short mux_port = 0; + std::size_t mux_nstreams = 1; +}; + +/// @brief Read one party's prep blob from `basename-p0` / `basename-p1`. +HEDLEY_WARN_UNUSED_RESULT +inline std::vector open_file_prep(const std::string & basename, + unsigned party) +{ + return prep::read_file(basename + "-p" + std::to_string(party)); +} + +/// @brief Same as `open_file_prep`, parsed as a prep cursor. +HEDLEY_WARN_UNUSED_RESULT +inline prep::cursor open_file_prep_cursor(const std::string & basename, + unsigned party) +{ + return prep::cursor(open_file_prep(basename, party)); +} + +/// @brief Run `fn(party, mux_stream_array &)` over one TCP connection with mux. +template +void with_tcp_mux_peer(unsigned party, std::string host, + std::atomic & port, std::size_t nstreams, Fn && fn) +{ + dpf::run::tcp_pair_mux(party, std::move(host), port, nstreams, + std::forward(fn)); +} + +/// @brief Convenience: mux settings from `stream_runtime`. +template +void with_tcp_mux_peer(unsigned party, const stream_runtime & rt, + std::size_t nstreams, Fn && fn) +{ + std::atomic port{rt.mux_port}; + with_tcp_mux_peer(party, rt.mux_host, port, nstreams, std::forward(fn)); +} + +/// @brief One party: TCP mux + `drive_plan_on_streams`. +inline void drive_plan_mux(const protocol::plan & plan, + net::stream_array & mux, std::vector> & values, + const std::map & kernels, std::size_t party, + std::size_t lanes = 1, const protocol::drive_options & opt = {}) +{ + protocol::drive_plan_on_streams(plan, mux, values, kernels, party, lanes, opt); +} + +/// @brief Two localhost threads on one mux TCP link, both plans driven on streams. +inline void drive_plan_mux_both(const protocol::plan & p0, + const protocol::plan & p1, std::vector> & v0, + std::vector> & v1, + const std::map & kernels = {}, + std::size_t lanes = 1, const protocol::drive_options & opt = {}, + const stream_runtime & rt = {}) +{ + const auto slots0 = p0.slot_bytes_all(); + const auto slots1 = p1.slot_bytes_all(); + if (slots0 != slots1) + throw std::invalid_argument("drive_plan_mux_both: slot shapes differ"); + const std::size_t nstreams = + slots0.empty() ? 1 : protocol::lanes_for_plan(slots0.size(), opt); + std::atomic port{rt.mux_port}; + std::exception_ptr err; + std::mutex err_mu; + auto note = [&](std::exception_ptr e) { + std::lock_guard lock(err_mu); + if (!err) + err = std::move(e); + }; + std::thread t0([&] { + try + { + with_tcp_mux_peer(0, rt.mux_host, port, nstreams, + [&](unsigned, net::mux_stream_array & mux) { + drive_plan_mux(p0, mux, v0, kernels, 0, lanes, opt); + }); + } + catch (...) + { + note(std::current_exception()); + } + }); + std::thread t1([&] { + try + { + with_tcp_mux_peer(1, rt.mux_host, port, nstreams, + [&](unsigned, net::mux_stream_array & mux) { + drive_plan_mux(p1, mux, v1, kernels, 1, lanes, opt); + }); + } + catch (...) + { + note(std::current_exception()); + } + }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); +} + +} // namespace app +} // namespace dpf + +#endif diff --git a/include/dpf/arith_garble.hpp b/include/dpf/arith_garble.hpp new file mode 100644 index 0000000..da03ad2 --- /dev/null +++ b/include/dpf/arith_garble.hpp @@ -0,0 +1,777 @@ +/// @file dpf/arith_garble.hpp +/// @brief Constant-round arithmetic garbling gadgets. +/// @details Mixed-modulus circuits: free addition, free multiplication by a +/// public constant coprime to the modulus, and a unary projection. +/// A projection of modulus `m` sends `m - 1` ciphertexts (row +/// reduction). A symmetric boolean gate, including a high fan-in AND +/// or a threshold, is a projection of a free sum. Multiplication in a +/// small prime field is the discrete-log reduction: project to the +/// exponent, add, project back, and suppress the zero cases. +/// +/// Labels are vectors in `(Z_m)^k`. Digit 0 is the point-and-permute +/// color. The global offset `Δ_m` has color digit 1, so the color of +/// semantic value `s` is `τ + s`. Addition and public scaling are +/// componentwise in that group, which is what makes them free. +/// +/// This is not an ABY2.0 session. A session opens one masked wire and +/// then multiplies interactively. These gadgets never open an +/// intermediate wire: the evaluator finishes from the garbled rows. +/// @note Marshall Ball, Tal Malkin, and Mike Rosulek, "Garbling Gadgets for +/// Boolean and Arithmetic Circuits," CCS 2016 (ePrint 2016/969). The +/// free-addition offset is the one they attribute to Malkin, Pastro, and +/// shelat. The interactive product in `beaver.hpp` remains Patra, +/// Schneider, Suresh, and Yalame, USENIX Security 2021. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_ARITH_GARBLE_HPP__ +#define LIBDPF_INCLUDE_DPF_ARITH_GARBLE_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" +#include "simde/simde/x86/avx2.h" + +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" + +namespace dpf +{ +namespace arith_garble +{ + +/// @brief Digit width of one label, including the color digit. +/// @details Ball, Malkin, and Rosulek use `λ / log2(m)` payload digits so the +/// label is `λ` bits. This instantiation fixes the width. Digit 0 is +/// the color in every modulus. +inline constexpr std::size_t k_digits = 16; + +inline constexpr std::uint16_t k_max_mod = 128; + +struct lab +{ + std::uint16_t mod = 0; + std::array d{}; +}; + +/// @brief Open a masked color. Garbler holds `mask` (the color of semantic 0). +/// Evaluator holds `color`. +HEDLEY_WARN_UNUSED_RESULT +inline std::uint16_t open_shares(std::uint16_t mod, std::uint16_t mask, + std::uint16_t color) +{ + if (mod == 0) + throw std::invalid_argument("arith_garble: modulus"); + return static_cast((color + mod - (mask % mod)) % mod); +} + +namespace detail +{ + +inline void require_mod(std::uint16_t m) +{ + if (m < 2 || m > k_max_mod) + throw std::invalid_argument("arith_garble: modulus"); +} + +HEDLEY_WARN_UNUSED_RESULT +inline std::uint16_t gcd_u(std::uint16_t a, std::uint16_t b) +{ + while (b != 0) + { + const std::uint16_t t = static_cast(a % b); + a = b; + b = t; + } + return a; +} + +HEDLEY_WARN_UNUSED_RESULT +inline lab sample_lab(std::uint16_t mod, simde__m128i & seed, std::uint32_t & n) +{ + lab out; + out.mod = mod; + for (std::size_t i = 0; i < k_digits; ++i) + { + const auto block = prg::aes128::eval(seed, n++); + std::uint64_t lo = 0; + std::memcpy(&lo, &block, sizeof(lo)); + out.d[i] = static_cast(lo % mod); + } + return out; +} + +HEDLEY_WARN_UNUSED_RESULT +inline lab make_delta(std::uint16_t mod, simde__m128i & seed, std::uint32_t & n) +{ + lab d = sample_lab(mod, seed, n); + d.d[0] = 1; + return d; +} + +HEDLEY_WARN_UNUSED_RESULT +inline lab add_lab(const lab & a, const lab & b) +{ + if (a.mod != b.mod) + throw std::invalid_argument("arith_garble: modulus"); + lab out; + out.mod = a.mod; + for (std::size_t i = 0; i < k_digits; ++i) + out.d[i] = static_cast( + (static_cast(a.d[i]) + b.d[i]) % a.mod); + return out; +} + +HEDLEY_WARN_UNUSED_RESULT +inline lab sub_lab(const lab & a, const lab & b) +{ + if (a.mod != b.mod) + throw std::invalid_argument("arith_garble: modulus"); + lab out; + out.mod = a.mod; + for (std::size_t i = 0; i < k_digits; ++i) + out.d[i] = static_cast( + (static_cast(a.d[i]) + a.mod - b.d[i]) % a.mod); + return out; +} + +HEDLEY_WARN_UNUSED_RESULT +inline lab scale_lab(const lab & a, std::uint16_t c) +{ + lab out; + out.mod = a.mod; + for (std::size_t i = 0; i < k_digits; ++i) + out.d[i] = static_cast( + (static_cast(a.d[i]) * c) % a.mod); + return out; +} + +HEDLEY_WARN_UNUSED_RESULT +inline lab neg_lab(const lab & a) +{ + lab out; + out.mod = a.mod; + for (std::size_t i = 0; i < k_digits; ++i) + out.d[i] = static_cast((a.mod - a.d[i]) % a.mod); + return out; +} + +/// @brief Label of semantic `s` on a wire whose semantic-0 label is `zero`. +HEDLEY_WARN_UNUSED_RESULT +inline lab shift_lab(const lab & zero, const lab & delta, std::uint16_t s) +{ + return add_lab(zero, scale_lab(delta, static_cast(s % zero.mod))); +} + +HEDLEY_WARN_UNUSED_RESULT +inline lab hash_lab(std::uint32_t gid, std::uint32_t which, const lab & in, + std::uint16_t out_mod) +{ + const prg::purpose_scope counted(prg::purpose::hash); + simde__m128i acc = simde_mm_set_epi64x( + static_cast(gid), static_cast(which)); + for (std::size_t i = 0; i < k_digits; i += 8) + { + simde__m128i chunk; + std::memcpy(&chunk, in.d.data() + i, sizeof(chunk)); + acc = prg::aes128::eval(simde_mm_xor_si128(acc, chunk), + static_cast(i + which)); + } + lab out; + out.mod = out_mod; + for (std::size_t i = 0; i < k_digits; ++i) + { + const auto block = prg::aes128::eval(acc, + static_cast(1000u + i + gid)); + std::uint64_t lo = 0; + std::memcpy(&lo, &block, sizeof(lo)); + out.d[i] = static_cast(lo % out_mod); + } + return out; +} + +HEDLEY_WARN_UNUSED_RESULT +inline std::uint16_t pow_mod(std::uint16_t base, std::uint16_t exp, std::uint16_t mod) +{ + unsigned r = 1; + unsigned b = base % mod; + unsigned e = exp; + while (e != 0) + { + if ((e & 1u) != 0) + r = (r * b) % mod; + b = (b * b) % mod; + e >>= 1u; + } + return static_cast(r); +} + +HEDLEY_WARN_UNUSED_RESULT +inline bool is_prime(std::uint16_t p) +{ + if (p < 2) + return false; + for (std::uint16_t i = 2; i * i <= p; ++i) + if (p % i == 0) + return false; + return true; +} + +HEDLEY_WARN_UNUSED_RESULT +inline std::uint16_t primitive_root(std::uint16_t p) +{ + std::vector factors; + std::uint16_t n = static_cast(p - 1); + for (std::uint16_t i = 2; i * i <= n; ++i) + { + if (n % i != 0) + continue; + factors.push_back(i); + while (n % i == 0) + n = static_cast(n / i); + } + if (n > 1) + factors.push_back(n); + for (std::uint16_t g = 2; g < p; ++g) + { + bool ok = true; + for (std::uint16_t f : factors) + { + if (pow_mod(g, static_cast((p - 1) / f), p) == 1) + { + ok = false; + break; + } + } + if (ok) + return g; + } + throw std::logic_error("arith_garble: primitive root"); +} + +struct proj_rows +{ + std::vector row; +}; + +struct pass_rows +{ + lab payload[2]{}; + std::uint16_t flag_ct[2]{}; +}; + +} // namespace detail + +/// @brief One wire. Valid only for the circuit that minted it. +struct wire +{ + std::uint32_t id = 0; +}; + +/// @brief Shares of one evaluation. `opened[i] = color[i] - mask[i]` mod the +/// output modulus. `mask` is the garbler's share. `color` is the +/// evaluator's share. +struct shares +{ + std::vector mask; + std::vector color; + std::vector opened; + std::vector modulus; + /// @brief Projection rows on the wire (`m - 1` each) plus two per bit-scale. + std::size_t ciphertext_rows = 0; +}; + +/// @brief Straight-line mixed-modulus circuit. +/// @details Inputs are declared first. Every later wire names earlier wires. +class circuit +{ +public: + enum class op : unsigned char + { + in = 0, + add = 1, + addk = 2, + scale = 3, + proj = 4, + pass = 5 + }; + + struct node + { + op code = op::in; + std::uint16_t mod = 0; + std::uint32_t a = 0; + std::uint32_t b = 0; + std::uint16_t k = 0; + std::vector phi; + }; + + HEDLEY_WARN_UNUSED_RESULT + wire input(std::uint16_t mod) + { + detail::require_mod(mod); + node n; + n.code = op::in; + n.mod = mod; + nodes_.push_back(std::move(n)); + return wire{static_cast(nodes_.size() - 1)}; + } + + HEDLEY_WARN_UNUSED_RESULT + wire add(wire x, wire y) + { + const node & a = at(x); + const node & b = at(y); + if (a.mod != b.mod) + throw std::invalid_argument("arith_garble: add modulus"); + node n; + n.code = op::add; + n.mod = a.mod; + n.a = x.id; + n.b = y.id; + nodes_.push_back(std::move(n)); + return wire{static_cast(nodes_.size() - 1)}; + } + + /// @brief Add a public constant. No ciphertext and no evaluator label change. + HEDLEY_WARN_UNUSED_RESULT + wire add_const(wire x, std::uint16_t k) + { + const node & a = at(x); + node n; + n.code = op::addk; + n.mod = a.mod; + n.a = x.id; + n.k = static_cast(k % a.mod); + nodes_.push_back(std::move(n)); + return wire{static_cast(nodes_.size() - 1)}; + } + + /// @brief Multiply by a public constant coprime to the modulus. + HEDLEY_WARN_UNUSED_RESULT + wire scale(wire x, std::uint16_t c) + { + const node & a = at(x); + c = static_cast(c % a.mod); + if (detail::gcd_u(c, a.mod) != 1) + throw std::invalid_argument("arith_garble: scale not coprime"); + node n; + n.code = op::scale; + n.mod = a.mod; + n.a = x.id; + n.k = c; + nodes_.push_back(std::move(n)); + return wire{static_cast(nodes_.size() - 1)}; + } + + /// @brief Unary map `phi : Z_mod(x) → Z_out`. `phi.size()` is the input modulus. + /// The garbled row count is `phi.size() - 1`. + HEDLEY_WARN_UNUSED_RESULT + wire project(wire x, std::uint16_t out_mod, std::vector phi) + { + detail::require_mod(out_mod); + const node & a = at(x); + if (phi.size() != a.mod) + throw std::invalid_argument("arith_garble: projection table"); + for (std::uint16_t v : phi) + if (v >= out_mod) + throw std::invalid_argument("arith_garble: projection image"); + node n; + n.code = op::proj; + n.mod = out_mod; + n.a = x.id; + n.phi = std::move(phi); + nodes_.push_back(std::move(n)); + return wire{static_cast(nodes_.size() - 1)}; + } + + /// @brief `bit ? word : 0`. `bit` is mod 2. Two ciphertext rows. + HEDLEY_WARN_UNUSED_RESULT + wire bit_scale(wire word, wire bit) + { + const node & w = at(word); + const node & b = at(bit); + if (b.mod != 2) + throw std::invalid_argument("arith_garble: bit_scale bit"); + node n; + n.code = op::pass; + n.mod = w.mod; + n.a = word.id; + n.b = bit.id; + nodes_.push_back(std::move(n)); + return wire{static_cast(nodes_.size() - 1)}; + } + + /// @brief AND (or threshold `t`) of 0/1 wires that already live in `Z_{b+1}`. + /// @details The sum is free. The only rows are the final projection, `b` + /// ciphertexts, as in Section 5 of Ball, Malkin, and Rosulek. + /// The wires must have modulus `bits.size() + 1` and semantic + /// values in `{0, 1}`. + HEDLEY_WARN_UNUSED_RESULT + wire threshold(const std::vector & bits, std::uint16_t t) + { + if (bits.empty() || bits.size() > k_max_mod - 1) + throw std::invalid_argument("arith_garble: threshold fan-in"); + const auto mod = static_cast(bits.size() + 1); + if (t > bits.size()) + throw std::invalid_argument("arith_garble: threshold"); + wire acc = bits[0]; + if (at(acc).mod != mod) + throw std::invalid_argument("arith_garble: threshold modulus"); + for (std::size_t i = 1; i < bits.size(); ++i) + { + if (at(bits[i]).mod != mod) + throw std::invalid_argument("arith_garble: threshold modulus"); + acc = add(acc, bits[i]); + } + std::vector phi(mod, 0); + phi[t] = 1; + return project(acc, 2, std::move(phi)); + } + + /// @brief Fan-in AND of mod-2 bits. Lifts into `Z_{b+1}`, then `threshold`. + HEDLEY_WARN_UNUSED_RESULT + wire fanin_and(const std::vector & bits) + { + if (bits.empty()) + throw std::invalid_argument("arith_garble: and"); + const auto mod = static_cast(bits.size() + 1); + std::vector lifted; + lifted.reserve(bits.size()); + for (wire b : bits) + { + if (at(b).mod != 2) + throw std::invalid_argument("arith_garble: and bit"); + lifted.push_back(project(b, mod, {0, 1})); + } + return threshold(lifted, static_cast(bits.size())); + } + + /// @brief Product in a prime field, via discrete log. Mod-2 product is AND. + HEDLEY_WARN_UNUSED_RESULT + wire mul(wire x, wire y) + { + const node & a = at(x); + const node & b = at(y); + if (a.mod != b.mod) + throw std::invalid_argument("arith_garble: mul modulus"); + const std::uint16_t p = a.mod; + if (p == 2) + { + auto lx = project(x, 3, {0, 1}); + auto ly = project(y, 3, {0, 1}); + auto s = add(lx, ly); + return project(s, 2, {0, 0, 1}); + } + if (!detail::is_prime(p)) + throw std::invalid_argument("arith_garble: mul prime"); + const std::uint16_t g = detail::primitive_root(p); + std::vector dlog(p, 0); + std::vector exp(static_cast(p - 1), 0); + unsigned acc = 1; + for (std::uint16_t e = 0; e < p - 1; ++e) + { + dlog[acc] = e; + exp[e] = static_cast(acc); + acc = (acc * g) % p; + } + auto zx = project(x, 2, zero_flag(p)); + auto zy = project(y, 2, zero_flag(p)); + auto dx = project(x, static_cast(p - 1), dlog); + auto dy = project(y, static_cast(p - 1), std::move(dlog)); + auto ds = add(dx, dy); + auto gpow = project(ds, p, std::move(exp)); + auto z1 = project(zx, 3, {0, 1}); + auto z2 = project(zy, 3, {0, 1}); + auto zsum = add(z1, z2); + auto zor = project(zsum, 2, {0, 1, 1}); + auto nz = project(zor, 2, {1, 0}); + return bit_scale(gpow, nz); + } + + void out(wire x) + { + at(x); + outs_.push_back(x.id); + } + + const std::vector & nodes() const noexcept { return nodes_; } + const std::vector & outputs() const noexcept { return outs_; } + + std::uint16_t modulus_at(wire x) const { return at(x).mod; } + +private: + const node & at(wire x) const + { + if (x.id >= nodes_.size()) + throw std::invalid_argument("arith_garble: wire"); + return nodes_[x.id]; + } + + static std::vector zero_flag(std::uint16_t p) + { + std::vector z(p, 0); + z[0] = 1; + return z; + } + + std::vector nodes_; + std::vector outs_; +}; + +namespace detail +{ + +struct garble_state +{ + std::vector zero; + std::vector delta; + std::vector have_delta; + std::vector proj; + std::vector pass; + simde__m128i seed{}; + std::uint32_t n = 0; + + lab & delta_of(std::uint16_t mod) + { + if (!have_delta[mod]) + { + delta[mod] = make_delta(mod, seed, n); + have_delta[mod] = 1; + } + return delta[mod]; + } +}; + +inline garble_state garble(const circuit & c) +{ + garble_state st; + st.seed = dpf::uniform_sample(); + st.zero.resize(c.nodes().size()); + st.delta.assign(static_cast(k_max_mod) + 1, lab{}); + st.have_delta.assign(static_cast(k_max_mod) + 1, 0); + st.proj.resize(c.nodes().size()); + st.pass.resize(c.nodes().size()); + const auto & nodes = c.nodes(); + for (std::uint32_t i = 0; i < nodes.size(); ++i) + { + const auto & nd = nodes[i]; + switch (nd.code) + { + case circuit::op::in: + st.zero[i] = sample_lab(nd.mod, st.seed, st.n); + (void)st.delta_of(nd.mod); + break; + case circuit::op::add: + st.zero[i] = add_lab(st.zero[nd.a], st.zero[nd.b]); + break; + case circuit::op::addk: + st.zero[i] = sub_lab(st.zero[nd.a], + scale_lab(st.delta_of(nd.mod), nd.k)); + break; + case circuit::op::scale: + st.zero[i] = scale_lab(st.zero[nd.a], nd.k); + break; + case circuit::op::proj: + { + const std::uint16_t m = nodes[nd.a].mod; + const std::uint16_t nmod = nd.mod; + const lab & zin = st.zero[nd.a]; + const lab & din = st.delta_of(m); + const lab & dout = st.delta_of(nmod); + const std::uint16_t tau = zin.d[0]; + const std::uint16_t s0 = + static_cast((m - (tau % m)) % m); + const lab label0 = shift_lab(zin, din, s0); + const lab h0 = hash_lab(i, 0, label0, nmod); + const lab decrypted = neg_lab(h0); + const std::uint16_t p0 = nd.phi[s0]; + st.zero[i] = sub_lab(decrypted, scale_lab(dout, p0)); + st.proj[i].row.resize(static_cast(m - 1)); + for (std::uint16_t color = 1; color < m; ++color) + { + const std::uint16_t s = static_cast( + (static_cast(color) + m - tau) % m); + const lab label = shift_lab(zin, din, s); + const lab active = shift_lab(st.zero[i], dout, nd.phi[s]); + const lab h = hash_lab(i, color, label, nmod); + st.proj[i].row[static_cast(color - 1)] = add_lab(active, h); + } + break; + } + case circuit::op::pass: + { + const std::uint16_t p = nd.mod; + const lab & zw = st.zero[nd.a]; + const lab & zb = st.zero[nd.b]; + (void)st.delta_of(p); + (void)st.delta_of(2); + st.zero[i] = sample_lab(p, st.seed, st.n); + const std::uint16_t tau_b = zb.d[0]; + const lab addend = sub_lab(st.zero[i], zw); + for (std::uint16_t color = 0; color < 2; ++color) + { + const std::uint16_t sem = static_cast( + (color + 2u - (tau_b % 2u)) % 2u); + const lab bit_label = shift_lab(zb, st.delta_of(2), sem); + const lab h = hash_lab(i, color, bit_label, p); + const lab payload = (sem == 0) ? st.zero[i] : addend; + st.pass[i].payload[color] = add_lab(payload, h); + const std::uint16_t pad = hash_lab(i, 8u + color, bit_label, 2).d[0]; + st.pass[i].flag_ct[color] = + static_cast(sem ^ (pad & 1u)); + } + break; + } + } + } + return st; +} + +inline std::vector evaluate(const circuit & c, const garble_state & st, + const std::uint16_t * semantic) +{ + const auto & nodes = c.nodes(); + std::vector active(nodes.size()); + std::uint32_t in_i = 0; + for (std::uint32_t i = 0; i < nodes.size(); ++i) + { + const auto & nd = nodes[i]; + switch (nd.code) + { + case circuit::op::in: + { + if (semantic == nullptr) + throw std::invalid_argument("arith_garble: inputs"); + if (semantic[in_i] >= nd.mod) + throw std::invalid_argument("arith_garble: input range"); + active[i] = shift_lab(st.zero[i], st.delta[nd.mod], semantic[in_i]); + ++in_i; + break; + } + case circuit::op::add: + active[i] = add_lab(active[nd.a], active[nd.b]); + break; + case circuit::op::addk: + active[i] = active[nd.a]; + break; + case circuit::op::scale: + active[i] = scale_lab(active[nd.a], nd.k); + break; + case circuit::op::proj: + { + const std::uint16_t color = active[nd.a].d[0]; + const lab h = hash_lab(i, color, active[nd.a], nd.mod); + if (color == 0) + active[i] = neg_lab(h); + else + active[i] = sub_lab( + st.proj[i].row[static_cast(color - 1)], h); + break; + } + case circuit::op::pass: + { + const std::uint16_t color = active[nd.b].d[0]; + const lab h = hash_lab(i, color, active[nd.b], nd.mod); + const lab payload = sub_lab(st.pass[i].payload[color], h); + const std::uint16_t pad = + hash_lab(i, 8u + color, active[nd.b], 2).d[0]; + const std::uint16_t flag = static_cast( + st.pass[i].flag_ct[color] ^ (pad & 1u)); + if (flag == 0) + active[i] = payload; + else + active[i] = add_lab(active[nd.a], payload); + break; + } + } + } + return active; +} + +} // namespace detail + +/// @brief Clear semantics, one value per wire, inputs in wire order. +HEDLEY_WARN_UNUSED_RESULT +inline std::vector eval_plain(const circuit & c, + const std::uint16_t * semantic) +{ + const auto & nodes = c.nodes(); + std::vector s(nodes.size(), 0); + std::uint32_t in_i = 0; + for (std::uint32_t i = 0; i < nodes.size(); ++i) + { + const auto & nd = nodes[i]; + switch (nd.code) + { + case circuit::op::in: + if (semantic == nullptr || semantic[in_i] >= nd.mod) + throw std::invalid_argument("arith_garble: input"); + s[i] = semantic[in_i++]; + break; + case circuit::op::add: + s[i] = static_cast( + (static_cast(s[nd.a]) + s[nd.b]) % nd.mod); + break; + case circuit::op::addk: + s[i] = static_cast( + (static_cast(s[nd.a]) + nd.k) % nd.mod); + break; + case circuit::op::scale: + s[i] = static_cast( + (static_cast(s[nd.a]) * nd.k) % nd.mod); + break; + case circuit::op::proj: + s[i] = nd.phi[s[nd.a]]; + break; + case circuit::op::pass: + s[i] = (s[nd.b] != 0) ? s[nd.a] : static_cast(0); + break; + } + } + return s; +} + +/// @brief Garble and evaluate in one process. +/// @details `semantic` is one value per `input` call, in that order. +HEDLEY_WARN_UNUSED_RESULT +inline shares eval_pair(const circuit & c, const std::uint16_t * semantic) +{ + if (c.outputs().empty()) + throw std::invalid_argument("arith_garble: no outputs"); + auto st = detail::garble(c); + auto active = detail::evaluate(c, st, semantic); + shares out; + std::size_t rows = 0; + for (std::uint32_t i = 0; i < c.nodes().size(); ++i) + { + if (c.nodes()[i].code == circuit::op::proj) + rows += st.proj[i].row.size(); + else if (c.nodes()[i].code == circuit::op::pass) + rows += 2; + } + out.ciphertext_rows = rows; + for (std::uint32_t id : c.outputs()) + { + const std::uint16_t mod = c.nodes()[id].mod; + const std::uint16_t mask = st.zero[id].d[0]; + const std::uint16_t color = active[id].d[0]; + out.modulus.push_back(mod); + out.mask.push_back(mask); + out.color.push_back(color); + out.opened.push_back(open_shares(mod, mask, color)); + } + return out; +} + +} // namespace arith_garble +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_ARITH_GARBLE_HPP__ diff --git a/include/dpf/asio.hpp b/include/dpf/asio.hpp index b99420e..c9de784 100644 --- a/include/dpf/asio.hpp +++ b/include/dpf/asio.hpp @@ -68,6 +68,10 @@ auto async_post(ExecutorT executor, Function && func, CompletionToken && token) // make_dpf // +/// \complexity Local `make_dpf` is O(n) per key, then one write of each key. n is `depth`. +/// \rounds 1 per key. Each party is a single `asio::write` of six buffers; there is no reply. +/// \communication Per key, two copies (one per peer) of the correction-word array (n nodes), the advice array (n bytes), one root, the leaf tuple, the beaver tuple, and the offset word. +/// \preprocessing none beyond the local keygen. The dealer holds the clear point. template @@ -675,6 +695,10 @@ auto assign_wildcard_input(PeerT & peer_in, PeerT & peer_out, DpfKey & dpf, return std::make_tuple(offset_share, bytes_written, bytes_read); } +/// \complexity O(1) arithmetic besides the socket transfer. +/// \rounds 1. One write of the local share, one read of the peer share (`async_assign_wildcard_input`). +/// \communication `sizeof(input_type)` bytes each way. +/// \preprocessing The mask in `offset_x` was sampled at `make_dpf`. This exchange opens mask − alpha. template @@ -686,6 +710,10 @@ auto assign_wildcard_input(PeerT & peer, DpfKey & dpf, InputType && input_share, std::forward(input_share), error); } +/// \complexity O(1) arithmetic besides the socket transfer. +/// \rounds 1. One write of the local share, one read of the peer share (`async_assign_wildcard_input`). +/// \communication `sizeof(input_type)` bytes each way. +/// \preprocessing The mask in `offset_x` was sampled at `make_dpf`. This exchange opens mask − alpha. template @@ -700,6 +728,10 @@ auto assign_wildcard_input(PeerT & peer_in, PeerT & peer_out, DpfKey & dpf, return ret; } +/// \complexity O(1) arithmetic besides the socket transfer. +/// \rounds 1. One write of the local share, one read of the peer share (`async_assign_wildcard_input`). +/// \communication `sizeof(input_type)` bytes each way. +/// \preprocessing The mask in `offset_x` was sampled at `make_dpf`. This exchange opens mask − alpha. template @@ -717,6 +749,10 @@ auto assign_wildcard_input(PeerT & peer, DpfKey & dpf, InputType && input_share) // async_assign_wildcard_input // +/// \complexity O(1) arithmetic besides the socket transfer. +/// \rounds 1. One write of the local share, one read of the peer share (`async_assign_wildcard_input`). +/// \communication `sizeof(input_type)` bytes each way. +/// \preprocessing The mask in `offset_x` was sampled at `make_dpf`. This exchange opens mask − alpha. template } +/// \complexity O(1) arithmetic besides the socket transfer. +/// \rounds 1. One write of the local share, one read of the peer share (`async_assign_wildcard_input`). +/// \communication `sizeof(input_type)` bytes each way. +/// \preprocessing The mask in `offset_x` was sampled at `make_dpf`. This exchange opens mask − alpha. template (token)); } +/// \complexity O(1) arithmetic besides the socket transfer. +/// \rounds 1. One write of the local share, one read of the peer share (`async_assign_wildcard_input`). +/// \communication `sizeof(input_type)` bytes each way. +/// \preprocessing The mask in `offset_x` was sampled at `make_dpf`. This exchange opens mask − alpha. template (token)); } +/// \complexity O(1) arithmetic besides the socket transfer. +/// \rounds 1. One write of the local share, one read of the peer share (`async_assign_wildcard_input`). +/// \communication `sizeof(input_type)` bytes each way. +/// \preprocessing The mask in `offset_x` was sampled at `make_dpf`. This exchange opens mask − alpha. template (dpf.leaf_nodes); - + + // Second (and later) assigns install β'−β on top of the ready leaf. + if (leaf_wrapper.is_ready()) + leaf_wrapper.begin_update(); + auto blinded_output = leaf_wrapper.compute_and_get_blinded_output_share(output_share); bytes_written += ::asio::write(peer_out, ::asio::buffer(&blinded_output, sizeof(output_type)), error); if (error) @@ -898,6 +954,10 @@ auto assign_wildcard_output(PeerT & peer_in, PeerT & peer_out, DpfKey & dpf, return std::make_tuple(leaf_share, bytes_written, bytes_read); } +/// \complexity O(leaf bytes) for the Beaver leaf arithmetic, plus the transfers. +/// \rounds 2. Write/read the blinded output share, then write/read the leaf share (`async_assign_wildcard_output`). +/// \communication `sizeof(output_type)` plus `sizeof(leaf_type)` each way. +/// \preprocessing The leaf Beaver triple (`vector_blind`, `output_blind`, `blinded_vector`) was stored at keygen. template (output_share), error); } +/// \complexity O(leaf bytes) for the Beaver leaf arithmetic, plus the transfers. +/// \rounds 2. Write/read the blinded output share, then write/read the leaf share (`async_assign_wildcard_output`). +/// \communication `sizeof(output_type)` plus `sizeof(leaf_type)` each way. +/// \preprocessing The leaf Beaver triple (`vector_blind`, `output_blind`, `blinded_vector`) was stored at keygen. template } +/// \complexity O(leaf bytes) for the Beaver leaf arithmetic, plus the transfers. +/// \rounds 2. Write/read the blinded output share, then write/read the leaf share (`async_assign_wildcard_output`). +/// \communication `sizeof(output_type)` plus `sizeof(leaf_type)` each way. +/// \preprocessing The leaf Beaver triple (`vector_blind`, `output_blind`, `blinded_vector`) was stored at keygen. template (token)); } +/// \complexity O(leaf bytes) for the Beaver leaf arithmetic, plus the transfers. +/// \rounds 2. Write/read the blinded output share, then write/read the leaf share (`async_assign_wildcard_output`). +/// \communication `sizeof(output_type)` plus `sizeof(leaf_type)` each way. +/// \preprocessing The leaf Beaver triple (`vector_blind`, `output_blind`, `blinded_vector`) was stored at keygen. template (token)); } +/// \complexity O(leaf bytes) for the Beaver leaf arithmetic, plus the transfers. +/// \rounds 2. Write/read the blinded output share, then write/read the leaf share (`async_assign_wildcard_output`). +/// \communication `sizeof(output_type)` plus `sizeof(leaf_type)` each way. +/// \preprocessing The leaf Beaver triple (`vector_blind`, `output_blind`, `blinded_vector`) was stored at keygen. template (peer, peer, dpf, std::forward(output_share), std::forward(token)); diff --git a/include/dpf/async_protocol.hpp b/include/dpf/async_protocol.hpp new file mode 100644 index 0000000..0fd0ee1 --- /dev/null +++ b/include/dpf/async_protocol.hpp @@ -0,0 +1,234 @@ +/// @file dpf/async_protocol.hpp +/// @brief Real overlapped, event-driven byte-round protocol runner. +/// @details `overlapped_byte_protocol` replaces the blocking loop of +/// `factory::async_byte_protocol` with true asynchronous I/O over an +/// `async_stream_array`. Each round: read the blind from the dealer +/// (async, skipped when `blind_bytes == 0`), `produce` the outbound +/// message, then overlap the peer write and peer read as one +/// `async_exchange`, and on completion `finish`, fire the round +/// callback, and continue to the next round or the done handler. +/// Nothing spins on a `peer_ready` flag and nothing blocks the calling +/// thread — every continuation runs on an `io_context` thread. +#ifndef LIBDPF_INCLUDE_DPF_ASYNC_PROTOCOL_HPP__ +#define LIBDPF_INCLUDE_DPF_ASYNC_PROTOCOL_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/net/async_stream_array.hpp" +#include "dpf/protocol_factory.hpp" // factory::async_byte_round + +namespace dpf +{ +namespace async +{ + +/// @brief Overlap a write and a read on stream `i`; fire `done` once both end. +/// @details The two operations are issued concurrently (full duplex): the +/// handler runs after both complete, carrying the first error seen. +/// `out` and `in` must stay valid until `done` fires. +inline void async_exchange(net::async_stream_array & s, std::size_t i, + const void * out, std::size_t out_n, void * in, std::size_t in_n, + net::async_handler done) +{ + struct state + { + net::async_handler done; + int remaining = 2; + std::error_code ec; + std::mutex mu; + }; + auto st = std::make_shared(); + st->done = std::move(done); + auto complete = [st](const std::error_code & ec) { + bool fire = false; + std::error_code final_ec; + { + std::lock_guard lock(st->mu); + if (ec && !st->ec) + st->ec = ec; + if (--st->remaining == 0) + fire = true; + final_ec = st->ec; + } + if (fire && st->done) + st->done(final_ec); + }; + s.async_write(i, out, out_n, complete); + s.async_read(i, in, in_n, complete); +} + +/// @brief Fully overlapped runner for a list of `async_byte_round`s. +/// @details Constructed per party per run and driven through a `shared_ptr` +/// (kept alive by its own continuations). `start` kicks round 0. +class overlapped_byte_protocol + : public std::enable_shared_from_this +{ +public: + /// @param ec error (empty on success); @param state final protocol state. + using done_handler = + std::function state)>; + using on_round_complete_fn = std::function; + + /// @param peer overlapped peer array; lane = `r % peer.size()` so a small + /// pool can carry many sequential rounds (known-size exchange). + /// @param dealer optional blind source (lane `r % dealer.size()`); may be + /// null when every round has `blind_bytes == 0`. + overlapped_byte_protocol(net::async_stream_array & peer, + net::async_stream_array * dealer, + std::vector rounds, + on_round_complete_fn on_round_complete = {}) + : peer_(&peer), + dealer_(dealer), + rounds_(std::move(rounds)), + on_round_complete_(std::move(on_round_complete)) + { + if (peer_->size() == 0) + throw std::invalid_argument("overlapped_byte_protocol: empty peer"); + for (const auto & r : rounds_) + { + if (!r.produce || !r.finish) + throw std::invalid_argument("overlapped_byte_protocol: missing callbacks"); + if (r.blind_bytes != 0 && dealer_ == nullptr) + throw std::invalid_argument("overlapped_byte_protocol: blind needs a dealer"); + } + if (dealer_ != nullptr && dealer_->size() == 0) + throw std::invalid_argument("overlapped_byte_protocol: empty dealer"); + } + + std::size_t rounds() const noexcept { return rounds_.size(); } + + /// @brief Begin the protocol. `done` fires once, after the last round. + void start(std::size_t index, std::vector state, + done_handler done) + { + (void)index; + state_ = std::move(state); + done_ = std::move(done); + run_round(0); + } + +private: + void finish_with(const std::error_code & ec) + { + if (done_) + { + auto d = std::move(done_); + done_ = nullptr; + d(ec, std::move(state_)); + } + } + + void run_round(std::size_t r) + { + if (r >= rounds_.size()) + { + finish_with(std::error_code{}); + return; + } + const auto & spec = rounds_[r]; + blind_.assign(spec.blind_bytes, 0); + auto self = shared_from_this(); + if (spec.blind_bytes != 0) + { + const std::size_t dlane = r % dealer_->size(); + dealer_->async_read(dlane, blind_.data(), blind_.size(), + [self, r](const std::error_code & ec) { + self->after_blind(r, ec); + }); + } + else + { + // No blind: hop through the io_context so we never recurse deeply. + asio::post(peer_->context(), + [self, r]() { self->after_blind(r, std::error_code{}); }); + } + } + + void after_blind(std::size_t r, const std::error_code & ec) + { + if (ec) + { + finish_with(ec); + return; + } + const auto & spec = rounds_[r]; + outbound_ = spec.produce(state_, blind_.data(), blind_.size()); + if (outbound_.size() != spec.msg_bytes) + { + finish_with(std::make_error_code(std::errc::message_size)); + return; + } + inbound_.assign(spec.msg_bytes, 0); + auto self = shared_from_this(); + const std::size_t lane = r % peer_->size(); + async_exchange(*peer_, lane, outbound_.data(), outbound_.size(), + inbound_.data(), inbound_.size(), + [self, r](const std::error_code & xec) { + self->after_exchange(r, xec); + }); + } + + void after_exchange(std::size_t r, const std::error_code & ec) + { + if (ec) + { + finish_with(ec); + return; + } + const auto & spec = rounds_[r]; + spec.finish(state_, inbound_.data(), inbound_.size(), blind_.data(), + blind_.size()); + if (on_round_complete_) + on_round_complete_(r); + run_round(r + 1); + } + + net::async_stream_array * peer_ = nullptr; + net::async_stream_array * dealer_ = nullptr; + std::vector rounds_; + on_round_complete_fn on_round_complete_; + + std::vector state_; + done_handler done_; + std::vector blind_; + std::vector outbound_; + std::vector inbound_; +}; + +/// @brief Make an `overlapped_byte_protocol` as a `shared_ptr` (required for +/// the self-owning continuation chain). +HEDLEY_WARN_UNUSED_RESULT +inline std::shared_ptr make_overlapped_byte_protocol( + net::async_stream_array & peer, net::async_stream_array * dealer, + std::vector rounds, + overlapped_byte_protocol::on_round_complete_fn on_round_complete = {}) +{ + return std::make_shared(peer, dealer, + std::move(rounds), std::move(on_round_complete)); +} + +/// @brief Post `start_all`, then run the io_context until all work drains. +/// @details The single entry point for driving overlapped parties: everything +/// the parties initiate is chased to completion by `io.run()`. +template +void run_overlapped(asio::io_context & io, Fn start_all) +{ + asio::post(io, [start_all = std::move(start_all)]() mutable { start_all(); }); + io.run(); +} + +} // namespace async +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_ASYNC_PROTOCOL_HPP__ diff --git a/include/dpf/beaver.hpp b/include/dpf/beaver.hpp index 61885f9..5465ac1 100644 --- a/include/dpf/beaver.hpp +++ b/include/dpf/beaver.hpp @@ -25,9 +25,11 @@ /// /// Doerner–Shelat's per-level AND is a `bit_mul` of a fresh bit and /// a fresh block. A wildcard leaf is a `scale` of one scalar by each -/// lane of the unit vector. Those call sites still draw on their own -/// pad and `uniform_fill` streams so matched key tapes stay put; -/// new steps should record a formula here and `sample` it. +/// lane of the unit vector. Those call sites draw from `sample_bit_mul` +/// / `sample_scale`. A callable sampler and an `oracle` are the same +/// construction: `sample` walks the callable, `sample_from` reads the +/// oracle, and the one-shot helpers accept either. New steps should +/// record a formula here and `sample` it. /// The namespace is `dpf::beavers` because `dpf::beaver` is already /// the wildcard triple stored on a key. /// @@ -35,14 +37,27 @@ /// multiply blinds without another multiplication protocol. Parties /// receive only the additive `split`s. /// +/// Optional Shark/SPDZ-style IT-MACs: `session::set_mac_key` before +/// `sample`/`bind` tags every λ, monomial, and value under a global +/// `Δ`. Classic triples use `sample_auth_beaver2` / +/// `authenticate_beaver2`. Openings of δ = x + λ carry tag shares and +/// check with `verify_delta` / `verify_auth_opening`. +/// /// `oracle` collapses those draws onto `dpf::randomness::lane_table`. /// The default PRG is `dpf::prg::aes128`; any PRG with the usual /// `eval` interface can be substituted. Each blind role is one lane /// (wire id, or `mono_role` / `dot_role` for a derived product), and /// the matching share mask is the same index on the tweaked master. +/// IT-MAC tag masks are a third stream from the same seed, so an +/// authenticated `sample_from` does not fall back to the system RNG. /// Copy `index` along every lane is one fresh triple. A thousand /// copies are a thousand indices, not a thousand lanes. `seed()` -/// replays every blind and every share mask. +/// replays every blind, every share mask, and every tag mask. +/// Constant-round arithmetic is a different object. Free addition, free +/// scaling by a public constant, and a unary projection are Ball, Malkin, +/// and Rosulek, CCS 2016 (ePrint 2016/969), in `dpf/arith_garble.hpp`. +/// A session does not garble those gadgets: it still opens δ once per wire. +/// @note A session follows Patra, Schneider, Suresh, and Yalame, USENIX Security 2021 (full version ePrint 2020/1225): one public reconstruction per newly opened wire. `sample_beaver2` follows Donald Beaver, "Efficient Multiparty Protocols Using Circuit Randomization," CRYPTO 1991 (LNCS 576, pp. 420–432), which reconstructs both masked factors. Ball, Malkin, and Rosulek, "Garbling Gadgets for Boolean and Arithmetic Circuits," CCS 2016 (ePrint 2016/969), is the constant-round projection gadget in `arith_garble.hpp`, not this session. /// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license; /// see [LICENSE.md](@ref license) for details. @@ -54,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -64,11 +80,34 @@ #include "hedley/hedley.h" #include "dpf/buffered_prg.hpp" +#include "dpf/leaf_arithmetic.hpp" +#include "dpf/packed_lane.hpp" #include "dpf/random.hpp" +#include "dpf/verifiable.hpp" #include "dpf/xor_wrapper.hpp" +#include "grotto/fixedpoint.hpp" namespace dpf { + +/// @brief Integers mod `2^w`, `w` in `1 .. 128`. +/// @details `w` is the thread-local width set by `beavers::mod2k_width_scope` +/// for the duration of a sample. Arithmetic masks to that width. +struct mod2k +{ + simde_uint128 raw{}; + + friend bool operator==(mod2k a, mod2k b) noexcept + { + return a.raw == b.raw; + } + + friend bool operator!=(mod2k a, mod2k b) noexcept + { + return !(a == b); + } +}; + namespace beavers { @@ -93,6 +132,32 @@ struct ring_traits static Ring sample() { return dpf::uniform_sample(); } }; +/// @brief Fixed-point product widens the fractional field; cast back for the ring. +/// @tparam FractionalBits fractional bits +/// @tparam IntegralType backend integer +template +struct ring_traits> +{ + using Ring = grotto::fixedpoint; + + static Ring zero() { return Ring{}; } + + static Ring one() { return Ring{1}; } + + static Ring add(const Ring & a, const Ring & b) { return a + b; } + + static Ring sub(const Ring & a, const Ring & b) { return a - b; } + + static Ring mul(const Ring & a, const Ring & b) + { + return grotto::precision_cast(a * b); + } + + static Ring neg(const Ring & a) { return -a; } + + static Ring sample() { return dpf::uniform_sample(); } +}; + /// @brief Bitwise AND uses the all-ones word as its multiplicative identity. /// @tparam T value type template @@ -119,6 +184,156 @@ struct ring_traits> static ring sample() { return dpf::uniform_sample(); } }; +/// @brief IEEE `float` leaf group is XOR/AND of the bit pattern, matching +/// `multiply_t` / `add_t`. +template <> +struct ring_traits +{ + using ring = float; + + static ring zero() { return 0.f; } + + static ring one() { return dpf::leaf_group_one(); } + + static ring add(const ring & a, const ring & b) + { + return dpf::leaf_group_add(a, b); + } + + static ring sub(const ring & a, const ring & b) + { + return dpf::leaf_group_add(a, b); + } + + static ring mul(const ring & a, const ring & b) + { + return dpf::leaf_group_mul(a, b); + } + + static ring neg(const ring & a) { return a; } + + static ring sample() { return dpf::uniform_sample(); } +}; + +/// @brief IEEE `double` leaf group is XOR/AND of the bit pattern. +template <> +struct ring_traits +{ + using ring = double; + + static ring zero() { return 0.0; } + + static ring one() { return dpf::leaf_group_one(); } + + static ring add(const ring & a, const ring & b) + { + return dpf::leaf_group_add(a, b); + } + + static ring sub(const ring & a, const ring & b) + { + return dpf::leaf_group_add(a, b); + } + + static ring mul(const ring & a, const ring & b) + { + return dpf::leaf_group_mul(a, b); + } + + static ring neg(const ring & a) { return a; } + + static ring sample() { return dpf::uniform_sample(); } +}; + +/// @brief Width for `dpf::mod2k` arithmetic. Restored when the scope ends. +inline unsigned & mod2k_width() noexcept +{ + static thread_local unsigned bits = 128u; + return bits; +} + +struct mod2k_width_scope +{ + unsigned previous; + + explicit mod2k_width_scope(unsigned bits) noexcept + : previous(mod2k_width()) + { + mod2k_width() = bits == 0u ? 128u : bits; + } + + ~mod2k_width_scope() { mod2k_width() = previous; } + + mod2k_width_scope(const mod2k_width_scope &) = delete; + mod2k_width_scope & operator=(const mod2k_width_scope &) = delete; +}; + +/// @brief `Z/2^w Z` with `w` from `mod2k_width()`. +template <> +struct ring_traits +{ + using ring = dpf::mod2k; + + static unsigned bits() noexcept { return mod2k_width(); } + + static simde_uint128 bit_mask(unsigned width) noexcept + { + if (width == 0u) + return 0; + if (width >= 128u) + return ~simde_uint128{0}; + return (simde_uint128{1} << width) - 1; + } + + static ring fit(simde_uint128 v) noexcept + { + return ring{v & bit_mask(bits())}; + } + + static ring zero() { return ring{}; } + + static ring one() { return fit(1); } + + static ring add(const ring & a, const ring & b) + { + return fit(a.raw + b.raw); + } + + static ring sub(const ring & a, const ring & b) + { + return fit(a.raw - b.raw); + } + + static ring mul(const ring & a, const ring & b) + { + const unsigned width = bits(); + const auto m = bit_mask(width); + const simde_uint128 x = a.raw & m; + const simde_uint128 y = b.raw & m; + if (width <= 64u) + { + return fit(simde_uint128{static_cast(x)} + * static_cast(y)); + } + const std::uint64_t a0 = static_cast(x); + const std::uint64_t a1 = static_cast(x >> 64); + const std::uint64_t b0 = static_cast(y); + const std::uint64_t b1 = static_cast(y >> 64); + const simde_uint128 p00 = simde_uint128{a0} * b0; + const simde_uint128 mid = (p00 >> 64) + + static_cast(simde_uint128{a0} * b1) + + static_cast(simde_uint128{a1} * b0); + return fit(simde_uint128{static_cast(p00)} | (mid << 64)); + } + + static ring neg(const ring & a) { return sub(zero(), a); } + + static ring sample() + { + return fit(dpf::uniform_sample()); + } +}; + template struct default_sampler { @@ -159,6 +374,112 @@ struct split } }; +/// @brief Additive split of `(y, y·Δ)` under a Shark/SPDZ-style IT-MAC. +/// @details `value` is the usual Beaver/ABY2.0 share of `y`. `tag` is an +/// additive share of `y·Δ`. Party `p` holds `party(p)`. +/// @tparam Ring payload ring +template +struct auth_split +{ + split value{}; + split tag{}; + + HEDLEY_NO_THROW + Ring open() const { return value.open(); } + + HEDLEY_NO_THROW + dpf::mac_share party(unsigned p) const + { + if (p == 0) + return dpf::mac_share{value.p0, tag.p0}; + return dpf::mac_share{value.p1, tag.p1}; + } + + HEDLEY_NO_THROW + bool verify(const dpf::mac_key & key) const + { + return dpf::mac_verify(party(0), party(1), key); + } + + friend bool operator==(const auth_split & a, const auth_split & b) + { + return a.value == b.value && a.tag == b.tag; + } + + friend bool operator!=(const auth_split & a, const auth_split & b) + { + return !(a == b); + } +}; + +/// @brief One party's contribution when opening an authenticated δ = x + λ. +/// @tparam Ring payload ring +template +struct auth_opening +{ + Ring value{}; + Ring tag{}; +}; + +/// @brief Attach an IT-MAC to an existing additive split under `key`. +/// @tparam Ring payload ring +/// @tparam Sample randomness for the tag mask +template +HEDLEY_WARN_UNUSED_RESULT +auth_split authenticate(const split & s, + const dpf::mac_key & key, Sample && rng) +{ + using traits = ring_traits; + const Ring y = traits::add(s.p0, s.p1); + const Ring t0 = rng(); + const Ring t1 = traits::sub(traits::mul(y, key.delta), t0); + return auth_split{s, split{t0, t1}}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +auth_split authenticate(const split & s, + const dpf::mac_key & key) +{ + return authenticate(s, key, default_sampler{}); +} + +/// @brief Authenticate a cleartext `y`, returning the dealer auth_split. +/// @tparam Ring payload ring +/// @tparam Sample randomness for both value and tag masks +template +HEDLEY_WARN_UNUSED_RESULT +auth_split auth_share(const Ring & y, const dpf::mac_key & key, + Sample && rng) +{ + using traits = ring_traits; + auto & sampler = rng; + const Ring p0 = sampler(); + const split s{p0, traits::sub(y, p0)}; + return authenticate(s, key, sampler); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auth_split auth_share(const Ring & y, const dpf::mac_key & key) +{ + return auth_share(y, key, default_sampler{}); +} + +/// @brief Whether two parties' authenticated δ openings check under `key`. +/// @tparam Ring payload ring +template +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +bool verify_auth_opening(auth_opening a, auth_opening b, + const dpf::mac_key & key) noexcept +{ + using traits = ring_traits; + const Ring d = traits::add(a.value, b.value); + const Ring t = traits::add(a.tag, b.tag); + return t == traits::mul(d, key.delta); +} + template class session; @@ -244,7 +565,8 @@ expr dot_expr(const ContX & xs, const ContY & ys); /// @brief One PRG lane per blind role, plus the share-mask stream for that role. /// @details `blind(role, index)` and `share(role, index, value)` do not depend on /// call order. Walking `index` forward stays inside a refilled window. -/// `PRG` defaults to `dpf::prg::aes128`. +/// `PRG` defaults to `dpf::prg::aes128`. Tag masks are a third stream, +/// `tag_mask(role, index)`, domain-separated from blinds and share masks. /// @tparam Ring payload ring /// @tparam PRG pseudorandom generator template @@ -288,11 +610,16 @@ public: explicit oracle(std::size_t window = 256u) : lanes_(window) - { } + { + note_experiment_seed("beavers::oracle", seed()); + } explicit oracle(seed_type seed, std::size_t window = 256u) - : lanes_(std::move(seed), window) - { } + : lanes_(seed, window), + tags_(dpf::randomness::detail::tag_master(seed), window) + { + note_experiment_seed("beavers::oracle", this->seed()); + } HEDLEY_NO_THROW const seed_type & seed() const noexcept { return lanes_.seed(); } @@ -307,6 +634,12 @@ public: return lanes_.mask_at(role, index); } + /// @brief IT-MAC tag-share mask for `role` at `index`. Same seed as the blinds. + Ring tag_mask(std::uint32_t role, std::uint64_t index) const + { + return tags_.value_at(role, index); + } + /// @brief Additive split of `value`. The mask is the role's mask stream at `index`. /// @param role the `role` /// @param index the index @@ -330,6 +663,7 @@ public: private: dpf::randomness::lane_table lanes_; + dpf::randomness::lane_table tags_; }; /// @brief Shares produced for one copy index of a recorded formula. @@ -345,6 +679,43 @@ struct prg_material std::vector> dot_cross; }; +/// @brief One party's view of sampled blinds and product shares. +/// @details Index order matches the session: wire id, monomial index, bundle +/// index, and gate index for dot crosses. A `*_ready` entry of false means +/// that slot was not sampled (no blind required). When `has_mac` is true the +/// parallel `*_tag` vectors hold this party's IT-MAC tag share for the same +/// slot (Shark/SPDZ-style `y·Δ`). +/// @tparam Ring payload ring +template +struct party_tape +{ + std::vector lambda; + std::vector lambda_ready; + std::vector monomial; + std::vector monomial_ready; + std::vector bundles; + std::vector bundles_ready; + std::vector dot_cross; + std::vector dot_ready; + + /// @brief IT-MAC tag shares; sized like `lambda` when `has_mac`. + std::vector lambda_tag; + std::vector monomial_tag; + std::vector bundles_tag; + std::vector dot_cross_tag; + bool has_mac = false; +}; + +/// @brief How `schedule_terms` ranks factorizations. +/// @details `prep` minimizes preprocessing (bundles + blinds), then rounds — +/// the ABY2.0 default matching Appendix-E peels. `rounds` minimizes +/// interactive depth first (Pika / Grotto online latency), then prep. +enum class schedule_objective : unsigned char +{ + prep = 0, + rounds = 1 +}; + /// @brief Dealer session: record formulae, `sample` blinds and monomials, `bind` /// input secrets, `evaluate` every round. /// @tparam Ring payload ring @@ -390,6 +761,45 @@ public: wires_[check(w)].pinned = true; } + /// @brief Rank factorizations by prep (default) or by interactive rounds. + HEDLEY_NO_THROW + void set_schedule_objective(schedule_objective o) noexcept + { + schedule_objective_ = o; + } + + HEDLEY_NO_THROW + HEDLEY_WARN_UNUSED_RESULT + schedule_objective get_schedule_objective() const noexcept + { + return schedule_objective_; + } + + /// @brief Enable Shark/SPDZ-style IT-MAC tags on blinds and values. + /// @details Call before `sample` / `bind`. Subsequent sampling authenticates + /// every λ, monomial, bundle, and dot-cross under `key`. Bound and + /// evaluated value shares are tagged the same way. Party tapes then + /// carry tag lanes; δ openings can be checked with `verify_delta`. + /// @param key global MAC key `Δ` (dealer-held for verification) + void set_mac_key(dpf::mac_key key) + { + mac_key_ = std::move(key); + has_mac_ = true; + mac_key_known_ = true; + } + + HEDLEY_NO_THROW + bool has_mac() const noexcept { return has_mac_; } + + /// @brief Dealer MAC key. Undefined when `has_mac()` is false. + /// @throws std::logic_error if MACs were not enabled + const dpf::mac_key & mac_key() const + { + if (!mac_key_known_) + throw std::logic_error("beaver session has no MAC key"); + return mac_key_; + } + /// @brief 0/1 wire in this ring. `bind` accepts only `zero()` or `one()` /// (`1` for integer rings, the all-ones word for `xor_wrapper`). /// @return 0/1 wire in this ring @@ -560,54 +970,22 @@ public: /// @tparam Sample sample /// @param sampler the randomness sampler /// @throws std::logic_error if `beaver blind is missing` + /// \complexity One draw per wire that `needs_blind`, plus one share per monomial. Local; no messages. + /// \preprocessing That tape is what `evaluate_party` later opens: a full blind and a two-party split per such wire. template void sample(Sample && sampler) { - auto & rng = sampler; - for (std::uint32_t id = 0; id < wires_.size(); ++id) + struct draws { - auto & w = wires_[id]; - if (w.lambda_ready || !needs_blind(id)) - continue; - w.lambda_full = rng(); - w.lambda = share_of(w.lambda_full, rng); - w.lambda_ready = true; - } - for (auto & m : monos_) - { - if (m.ready) - continue; - Ring full = traits::one(); - for (auto [id, e] : m.key) - { - if (!wires_[id].lambda_ready) - throw std::logic_error("beaver blind is missing"); - full = traits::mul(full, pow_small(wires_[id].lambda_full, e)); - } - m.share = share_of(full, rng); - m.ready = true; - } - for (auto & b : bundles_) - { - if (b.ready) - continue; - b.share = share_of(bundle_value(b), rng); - b.ready = true; - } - for (auto & g : gates_) - { - if (g.kind != gate_kind::dot || g.cross_ready) - continue; - Ring sum = traits::zero(); - for (std::size_t i = 0; i < g.lhs.size(); ++i) - { - sum = traits::add(sum, traits::mul( - wires_[g.lhs[i]].lambda_full, - wires_[g.rhs[i]].lambda_full)); - } - g.cross = share_of(sum, rng); - g.cross_ready = true; - } + Sample && rng; + + Ring blind(std::uint32_t, std::uint64_t) { return rng(); } + + Ring mask(std::uint32_t, std::uint64_t) { return rng(); } + + Ring tag_mask(std::uint32_t, std::uint64_t) { return rng(); } + }; + sample_with(draws{std::forward(sampler)}, 0); } void sample() @@ -615,49 +993,31 @@ public: sample(default_sampler{}); } + /// @brief Drop sampled blinds and product shares. The recorded formula stays. + /// @details The next `sample` / `sample_from` draws that formula again. + void clear_sample() + { + for (auto & w : wires_) + w.lambda_ready = false; + for (auto & m : monos_) + m.ready = false; + for (auto & b : bundles_) + b.ready = false; + for (auto & g : gates_) + g.cross_ready = false; + } + /// @brief Install missing blinds and product shares from copy `index` of `src`. /// @details Already-sampled wires keep their λ. New product shares are built from - /// those stored blinds, then split with the oracle's share lane. + /// those stored blinds, then split with the oracle's share lane. MAC tag masks + /// come from `src.tag_mask` for the same role. /// @tparam PRG pseudorandom generator /// @param src the source /// @param index the index template void sample_from(const oracle & src, std::uint64_t index = 0) { - for (std::uint32_t id = 0; id < wires_.size(); ++id) - { - auto & w = wires_[id]; - if (w.lambda_ready || !needs_blind(id)) - continue; - w.lambda_full = src.blind(oracle::wire_role(id), index); - w.lambda = src.share(oracle::wire_role(id), index, w.lambda_full); - w.lambda_ready = true; - } - for (std::uint32_t i = 0; i < monos_.size(); ++i) - { - auto & m = monos_[i]; - if (m.ready) - continue; - Ring full = mono_full(m.key); - m.share = src.share(oracle::mono_role(i), index, full); - m.ready = true; - } - for (std::uint32_t i = 0; i < bundles_.size(); ++i) - { - auto & b = bundles_[i]; - if (b.ready) - continue; - b.share = src.share(oracle::bundle_role(i), index, bundle_value(b)); - b.ready = true; - } - for (std::uint32_t g = 0; g < gates_.size(); ++g) - { - auto & gate = gates_[g]; - if (gate.kind != gate_kind::dot || gate.cross_ready) - continue; - gate.cross = src.share(oracle::dot_role(g), index, dot_full(gate)); - gate.cross_ready = true; - } + sample_with(src, index); } /// @brief Every wire, monomial, and dot cross of this formula at copy `index`. @@ -735,6 +1095,8 @@ public: auto & rng = sampler; wires_[id].value = share_of(secret, rng); wires_[id].value_ready = true; + if (has_mac_) + tag_split(wires_[id].value, wires_[id].value_tag, rng); } void bind(wire w, Ring secret) @@ -759,17 +1121,339 @@ public: throw std::invalid_argument("bit wire must be 0 or 1"); wires_[id].value = split{p0, p1}; wires_[id].value_ready = true; + if (has_mac_) + { + default_sampler rng; + tag_split(wires_[id].value, wires_[id].value_tag, rng); + } + } + + /// @brief One party's additive shares of every sampled blind and product. + /// @param party `0` or `1` + /// @return Tape suitable for `install_party` / network deal + /// @throws std::invalid_argument if `party` is not 0 or 1 + party_tape export_party(unsigned party) const + { + if (party > 1) + throw std::invalid_argument("beaver party must be 0 or 1"); + party_tape out; + out.has_mac = has_mac_; + out.lambda.resize(wires_.size()); + out.lambda_ready.resize(wires_.size()); + if (has_mac_) + out.lambda_tag.resize(wires_.size()); + for (std::uint32_t id = 0; id < wires_.size(); ++id) + { + out.lambda_ready[id] = wires_[id].lambda_ready ? 1 : 0; + if (wires_[id].lambda_ready) + { + out.lambda[id] = party == 0 ? wires_[id].lambda.p0 : wires_[id].lambda.p1; + if (has_mac_) + out.lambda_tag[id] = party == 0 + ? wires_[id].lambda_tag.p0 + : wires_[id].lambda_tag.p1; + } + } + out.monomial.resize(monos_.size()); + out.monomial_ready.resize(monos_.size()); + if (has_mac_) + out.monomial_tag.resize(monos_.size()); + for (std::size_t i = 0; i < monos_.size(); ++i) + { + out.monomial_ready[i] = monos_[i].ready ? 1 : 0; + if (monos_[i].ready) + { + out.monomial[i] = party == 0 ? monos_[i].share.p0 : monos_[i].share.p1; + if (has_mac_) + out.monomial_tag[i] = party == 0 + ? monos_[i].tag.p0 + : monos_[i].tag.p1; + } + } + out.bundles.resize(bundles_.size()); + out.bundles_ready.resize(bundles_.size()); + if (has_mac_) + out.bundles_tag.resize(bundles_.size()); + for (std::size_t i = 0; i < bundles_.size(); ++i) + { + out.bundles_ready[i] = bundles_[i].ready ? 1 : 0; + if (bundles_[i].ready) + { + out.bundles[i] = party == 0 ? bundles_[i].share.p0 : bundles_[i].share.p1; + if (has_mac_) + out.bundles_tag[i] = party == 0 + ? bundles_[i].tag.p0 + : bundles_[i].tag.p1; + } + } + out.dot_cross.resize(gates_.size()); + out.dot_ready.resize(gates_.size()); + if (has_mac_) + out.dot_cross_tag.resize(gates_.size()); + for (std::size_t g = 0; g < gates_.size(); ++g) + { + out.dot_ready[g] = gates_[g].cross_ready ? 1 : 0; + if (gates_[g].cross_ready) + { + out.dot_cross[g] = party == 0 ? gates_[g].cross.p0 : gates_[g].cross.p1; + if (has_mac_) + out.dot_cross_tag[g] = party == 0 + ? gates_[g].cross_tag.p0 + : gates_[g].cross_tag.p1; + } + } + return out; + } + + /// @brief Install this party's tape after the circuit is recorded. Does not sample. + /// @param party `0` or `1` + /// @param tape shares from `export_party` / the dealer + /// @throws std::invalid_argument if sizes disagree or `party` is bad + /// @throws std::logic_error if blinds were already sampled + void install_party(unsigned party, const party_tape & tape) + { + if (party > 1) + throw std::invalid_argument("beaver party must be 0 or 1"); + if (tape.lambda.size() != wires_.size() + || tape.lambda_ready.size() != wires_.size() + || tape.monomial.size() != monos_.size() + || tape.monomial_ready.size() != monos_.size() + || tape.bundles.size() != bundles_.size() + || tape.bundles_ready.size() != bundles_.size() + || tape.dot_cross.size() != gates_.size() + || tape.dot_ready.size() != gates_.size()) + throw std::invalid_argument("beaver party tape size mismatch"); + if (tape.has_mac) + { + if (tape.lambda_tag.size() != wires_.size() + || tape.monomial_tag.size() != monos_.size() + || tape.bundles_tag.size() != bundles_.size() + || tape.dot_cross_tag.size() != gates_.size()) + throw std::invalid_argument("beaver party MAC tape size mismatch"); + has_mac_ = true; + } + for (std::uint32_t id = 0; id < wires_.size(); ++id) + { + if (wires_[id].lambda_ready) + throw std::logic_error("call install_party before sample"); + if (!tape.lambda_ready[id]) + continue; + wires_[id].lambda = party == 0 + ? split{tape.lambda[id], traits::zero()} + : split{traits::zero(), tape.lambda[id]}; + wires_[id].lambda_ready = true; + if (tape.has_mac) + { + wires_[id].lambda_tag = party == 0 + ? split{tape.lambda_tag[id], traits::zero()} + : split{traits::zero(), tape.lambda_tag[id]}; + } + } + for (std::size_t i = 0; i < monos_.size(); ++i) + { + if (monos_[i].ready) + throw std::logic_error("call install_party before sample"); + if (!tape.monomial_ready[i]) + continue; + monos_[i].share = party == 0 + ? split{tape.monomial[i], traits::zero()} + : split{traits::zero(), tape.monomial[i]}; + monos_[i].ready = true; + if (tape.has_mac) + { + monos_[i].tag = party == 0 + ? split{tape.monomial_tag[i], traits::zero()} + : split{traits::zero(), tape.monomial_tag[i]}; + } + } + for (std::size_t i = 0; i < bundles_.size(); ++i) + { + if (bundles_[i].ready) + throw std::logic_error("call install_party before sample"); + if (!tape.bundles_ready[i]) + continue; + bundles_[i].share = party == 0 + ? split{tape.bundles[i], traits::zero()} + : split{traits::zero(), tape.bundles[i]}; + bundles_[i].ready = true; + if (tape.has_mac) + { + bundles_[i].tag = party == 0 + ? split{tape.bundles_tag[i], traits::zero()} + : split{traits::zero(), tape.bundles_tag[i]}; + } + } + for (std::size_t g = 0; g < gates_.size(); ++g) + { + if (gates_[g].cross_ready) + throw std::logic_error("call install_party before sample"); + if (!tape.dot_ready[g]) + continue; + gates_[g].cross = party == 0 + ? split{tape.dot_cross[g], traits::zero()} + : split{traits::zero(), tape.dot_cross[g]}; + gates_[g].cross_ready = true; + if (tape.has_mac) + { + gates_[g].cross_tag = party == 0 + ? split{tape.dot_cross_tag[g], traits::zero()} + : split{traits::zero(), tape.dot_cross_tag[g]}; + } + } + party_mode_ = true; + party_id_ = party; + } + + /// @brief Bind this party's additive share of an input secret. + /// @param w input wire + /// @param share this party's share + /// @throws std::invalid_argument if `w` is not an input + /// @throws std::logic_error if already bound or `install_party` was not called + void bind_party(wire w, Ring share) + { + if (!party_mode_) + throw std::logic_error("call install_party before bind_party"); + auto id = check(w); + if (wires_[id].ready_round != 0) + throw std::invalid_argument("only input wires can be bound"); + if (wires_[id].value_ready) + throw std::logic_error("input wire is already bound"); + wires_[id].value = party_id_ == 0 + ? split{share, traits::zero()} + : split{traits::zero(), share}; + wires_[id].value_ready = true; + } + + /// @brief Bind an authenticated input share `(value, tag)` for this party. + /// @param w input wire + /// @param share this party's `mac_share` of the secret + /// @throws std::logic_error if MACs were not enabled on the tape + void bind_party(wire w, dpf::mac_share share) + { + if (!party_mode_) + throw std::logic_error("call install_party before bind_party"); + if (!has_mac_) + throw std::logic_error("bind_party MAC share requires an authenticated tape"); + auto id = check(w); + if (wires_[id].ready_round != 0) + throw std::invalid_argument("only input wires can be bound"); + if (wires_[id].value_ready) + throw std::logic_error("input wire is already bound"); + wires_[id].value = party_id_ == 0 + ? split{share.value, traits::zero()} + : split{traits::zero(), share.value}; + wires_[id].value_tag = party_id_ == 0 + ? split{share.tag, traits::zero()} + : split{traits::zero(), share.tag}; + wires_[id].value_ready = true; + } + + /// @brief Open every ready round using peer exchanges for public δ. + /// @details `exchange_delta(mine)` returns the peer's contribution + /// `value_share + lambda_share`. Public monomial terms land on party 0. + /// When the session is MAC-authenticated, use the `auth_opening` overload + /// so tag shares of δ are exchanged too. + /// @tparam Exchange callable `Ring(Ring)` + /// @param exchange_delta peer opening callback + /// @throws std::logic_error if not in party mode or MACs are enabled + /// \complexity O(R G) gate steps. R is max `ready_round`, G is the number of gates. + /// \rounds R. A product of fresh inputs is round 1. A gate whose inputs are earlier outputs waits for `ready_round`. + /// \communication One `Ring` per wire whose delta is opened (`ensure_delta_party`). A wire already opened is not sent again. + /// \preprocessing `sample` drew one full blind and a two-party split per wire that `needs_blind`, and one share per monomial. + template + void evaluate_party(Exchange && exchange_delta) + { + if (!party_mode_) + throw std::logic_error("call install_party before evaluate_party"); + if (has_mac_) + throw std::logic_error("authenticated session needs evaluate_party with auth_opening"); + evaluate_party_impl(std::forward(exchange_delta)); + } + + /// @brief Like `evaluate_party`, but open many δ values per ready-round in one vector exchange. + /// @details At the start of each ready-round, every already-valued input that + /// the round will open is exchanged once (shared order on both + /// parties). Gate outputs that need δ are batched at the end of + /// the round, flushing earlier if a later same-round gate reads + /// that δ. Logical `round_of` is unchanged; channel barriers drop + /// from one-per-wire to a small constant per ready-round. + /// @tparam BatchExchange callable `std::vector(std::vector)` + /// @param exchange_deltas peer opening callback for a packed vector + template + void evaluate_party_batch(BatchExchange && exchange_deltas) + { + if (!party_mode_) + throw std::logic_error("call install_party before evaluate_party_batch"); + if (has_mac_) + throw std::logic_error("authenticated session needs evaluate_party_auth_batch"); + evaluate_party_batch_impl(std::forward(exchange_deltas)); + } + + /// @brief Authenticated opening path: exchange `(value+λ, tag_value+tag_λ)`. + /// @tparam Exchange callable `auth_opening(auth_opening)` + /// @param exchange_delta peer opening callback + /// \complexity Same gate walk as `evaluate_party`. + /// \rounds R, the max `ready_round`. + /// \communication One `auth_opening` (value and MAC tag) per newly opened wire, instead of one `Ring`. + /// \preprocessing `sample` also drew a tag split when the session has a MAC key. + template + void evaluate_party_auth(Exchange && exchange_delta) + { + if (!party_mode_) + throw std::logic_error("call install_party before evaluate_party_auth"); + if (!has_mac_) + throw std::logic_error("evaluate_party_auth requires an authenticated tape"); + evaluate_party_auth_impl(std::forward(exchange_delta)); + } + + /// @brief Authenticated batched opening path (vector of `auth_opening`). + /// @tparam BatchExchange callable `std::vector>(std::vector>)` + template + void evaluate_party_auth_batch(BatchExchange && exchange_deltas) + { + if (!party_mode_) + throw std::logic_error("call install_party before evaluate_party_auth_batch"); + if (!has_mac_) + throw std::logic_error("evaluate_party_auth_batch requires an authenticated tape"); + evaluate_party_auth_batch_impl(std::forward(exchange_deltas)); + } + + /// @brief This party's value share after `evaluate_party`. + Ring value_party(wire w) const + { + auto id = check(w); + if (!wires_[id].value_ready) + throw std::logic_error("beaver wire has no value yet"); + return party_id_ == 0 ? wires_[id].value.p0 : wires_[id].value.p1; + } + + /// @brief This party's MAC share of the wire value after binding / evaluate. + /// @throws std::logic_error if MACs are off or the value is missing + dpf::mac_share value_mac_party(wire w) const + { + if (!has_mac_) + throw std::logic_error("beaver session has no MAC key"); + auto id = check(w); + if (!wires_[id].value_ready) + throw std::logic_error("beaver wire has no value yet"); + return party_id_ == 0 + ? dpf::mac_share{wires_[id].value.p0, wires_[id].value_tag.p0} + : dpf::mac_share{wires_[id].value.p1, wires_[id].value_tag.p1}; } /// @brief Open every ready round. Inputs used by round-1 gates are opened /// together; a gate output is a later round's input and keeps the blind /// chosen in `sample`. /// @throws std::logic_error if `beaver wire is not ready to open` + /// \complexity O(R G) local additions. R is max `ready_round`, G is the number of gates. The dealer holds both shares, so this sends nothing. + /// \rounds R, counted locally. No messages. + /// \preprocessing The blinds from `sample`. void evaluate() { int max_round = 0; for (const auto & w : wires_) max_round = std::max(max_round, w.ready_round); + default_sampler rng; for (int r = 1; r <= max_round; ++r) { for (const auto & g : gates_) @@ -822,6 +1506,8 @@ public: } wires_[g.out].value = val; wires_[g.out].value_ready = true; + if (has_mac_) + tag_split(wires_[g.out].value, wires_[g.out].value_tag, rng); if (wires_[g.out].lambda_ready) ensure_delta(g.out); } @@ -858,6 +1544,29 @@ public: return monomial(std::vector(spec)); } + /// @brief Authenticated share of `Π λ_i^{e_i}` under the session MAC key. + /// @throws std::logic_error if MACs are off or the monomial was not sampled + auth_split monomial_auth(const std::vector & spec) const + { + if (!has_mac_) + throw std::logic_error("beaver session has no MAC key"); + std::vector> raw; + raw.reserve(spec.size()); + for (auto p : spec) + { + if (p.exp == 0) + throw std::invalid_argument("beaver power is zero"); + raw.emplace_back(check(p.base), p.exp); + } + auto located = locate_term(merge_exponents(raw)); + return auth_split{*located.share, *located.tag}; + } + + auth_split monomial_auth(std::initializer_list spec) const + { + return monomial_auth(std::vector(spec)); + } + split value(wire w) const { auto id = check(w); @@ -884,6 +1593,175 @@ public: return wires_[id].delta; } + /// @brief Authenticated blind `[λ]` under the session MAC key. + /// @throws std::logic_error if MACs are off or the blind is missing + auth_split lambda_auth(wire w) const + { + if (!has_mac_) + throw std::logic_error("beaver session has no MAC key"); + auto id = check(w); + if (!wires_[id].lambda_ready) + throw std::logic_error("call sample() before reading a beaver blind"); + return auth_split{wires_[id].lambda, wires_[id].lambda_tag}; + } + + /// @brief Authenticated value `[x]` under the session MAC key. + /// @throws std::logic_error if MACs are off or the value is missing + auth_split value_auth(wire w) const + { + if (!has_mac_) + throw std::logic_error("beaver session has no MAC key"); + auto id = check(w); + if (!wires_[id].value_ready) + throw std::logic_error("beaver wire has no value yet"); + return auth_split{wires_[id].value, wires_[id].value_tag}; + } + + /// @brief Authenticated opening of δ = x + λ (value and tag sums). + /// @details The opened public δ equals `delta(w)`. Tags must satisfy + /// `tag = δ · Δ` when both parties' shares are combined. + auth_split delta_auth(wire w) const + { + if (!has_mac_) + throw std::logic_error("beaver session has no MAC key"); + auto id = check(w); + if (!wires_[id].delta_ready) + throw std::logic_error("beaver wire has not been opened"); + if (!wires_[id].lambda_ready || !wires_[id].value_ready) + throw std::logic_error("beaver wire is not ready to open"); + return auth_split{ + split{ + traits::add(wires_[id].value.p0, wires_[id].lambda.p0), + traits::add(wires_[id].value.p1, wires_[id].lambda.p1)}, + split{ + traits::add(wires_[id].value_tag.p0, wires_[id].lambda_tag.p0), + traits::add(wires_[id].value_tag.p1, wires_[id].lambda_tag.p1)}}; + } + + /// @brief Whether `[x]` verifies under the session MAC key. + bool verify_value(wire w) const + { + if (!mac_key_known_) + throw std::logic_error("beaver session has no MAC key"); + return value_auth(w).verify(mac_key_); + } + + /// @brief Whether the opened δ = x + λ verifies under the session MAC key. + bool verify_delta(wire w) const + { + if (!mac_key_known_) + throw std::logic_error("beaver session has no MAC key"); + auto id = check(w); + if (wires_[id].delta_open_ready) + { + const auto & mine = wires_[id].delta_mine; + const auto & peer = wires_[id].delta_peer; + const Ring d = traits::add(mine.value, peer.value); + const Ring t = traits::add(mine.tag, peer.tag); + return d == wires_[id].delta + && t == traits::mul(d, mac_key_.delta); + } + auto a = delta_auth(w); + if (a.open() != wires_[id].delta) + return false; + return a.verify(mac_key_); + } + + /// @brief Check a party opening under an explicit key (dealer audit). + bool verify_delta(wire w, const dpf::mac_key & key) const + { + auto id = check(w); + if (wires_[id].delta_open_ready) + return verify_auth_opening(wires_[id].delta_mine, wires_[id].delta_peer, key) + && traits::add(wires_[id].delta_mine.value, wires_[id].delta_peer.value) + == wires_[id].delta; + auth_split a{ + split{ + traits::add(wires_[id].value.p0, wires_[id].lambda.p0), + traits::add(wires_[id].value.p1, wires_[id].lambda.p1)}, + split{ + traits::add(wires_[id].value_tag.p0, wires_[id].lambda_tag.p0), + traits::add(wires_[id].value_tag.p1, wires_[id].lambda_tag.p1)}}; + return a.open() == wires_[id].delta && a.verify(key); + } + + /// @brief Party-local view of the last authenticated δ opening for `w`. + auth_opening delta_opening_mine(wire w) const + { + auto id = check(w); + if (!wires_[id].delta_open_ready) + throw std::logic_error("beaver wire has no authenticated opening"); + return wires_[id].delta_mine; + } + + auth_opening delta_opening_peer(wire w) const + { + auto id = check(w); + if (!wires_[id].delta_open_ready) + throw std::logic_error("beaver wire has no authenticated opening"); + return wires_[id].delta_peer; + } + + /// @brief Verify every opened wire's value and δ MAC (dealer / test path). + bool verify_all() const + { + if (!has_mac_) + return true; + if (!mac_key_known_) + throw std::logic_error("beaver session has no MAC key"); + for (std::uint32_t id = 0; id < wires_.size(); ++id) + { + if (wires_[id].lambda_ready + && !auth_split{wires_[id].lambda, wires_[id].lambda_tag} + .verify(mac_key_)) + return false; + if (wires_[id].value_ready + && !auth_split{wires_[id].value, wires_[id].value_tag} + .verify(mac_key_)) + return false; + if (wires_[id].delta_ready) + { + if (wires_[id].delta_open_ready) + { + if (!verify_auth_opening(wires_[id].delta_mine, + wires_[id].delta_peer, mac_key_)) + return false; + } + else + { + auth_split d{ + split{ + traits::add(wires_[id].value.p0, wires_[id].lambda.p0), + traits::add(wires_[id].value.p1, wires_[id].lambda.p1)}, + split{ + traits::add(wires_[id].value_tag.p0, wires_[id].lambda_tag.p0), + traits::add(wires_[id].value_tag.p1, wires_[id].lambda_tag.p1)}}; + if (d.open() != wires_[id].delta || !d.verify(mac_key_)) + return false; + } + } + } + for (const auto & m : monos_) + { + if (m.ready + && !auth_split{m.share, m.tag}.verify(mac_key_)) + return false; + } + for (const auto & b : bundles_) + { + if (b.ready + && !auth_split{b.share, b.tag}.verify(mac_key_)) + return false; + } + for (const auto & g : gates_) + { + if (g.cross_ready + && !auth_split{g.cross, g.cross_tag}.verify(mac_key_)) + return false; + } + return true; + } + split dot_cross(wire w) const { auto id = check(w); @@ -923,6 +1801,26 @@ public: return wires_[check(w)].ready_round; } + /// @brief Rebuild a wire handle from its id (same session). + wire wire_at(std::uint32_t id) const + { + if (static_cast(id) >= wires_.size()) + throw std::out_of_range("beaver wire_at"); + wire w; + w.sess_ = const_cast(this); + w.id_ = id; + return w; + } + + /// @brief Maximum `ready_round` over every wire (0 when the circuit is empty). + int max_ready_round() const + { + int m = 0; + for (const auto & w : wires_) + m = std::max(m, w.ready_round); + return m; + } + HEDLEY_NO_THROW std::size_t wire_count() const noexcept { return wires_.size(); } @@ -950,6 +1848,29 @@ public: return n; } + /// @brief One δ-vector exchange performed by `evaluate_party_batch`. + struct delta_barrier + { + int ready_round = 0; + std::vector wire_ids; + }; + + /// @brief Every flush `evaluate_party_batch` will perform, in order. + /// @details Dry-runs the batch control flow on the gate graph. Input wires + /// are treated as bound; blinds are treated as sampled for every + /// wire that `needs_blind`. Same-round splits match the live + /// evaluator. Used by the protocol composer to place δ opens on + /// RoundSink waves. + std::vector exchange_barriers() const + { + return compile_batch_barriers(); + } + + template + friend class party_batch_stepper; + template + friend class party_auth_batch_stepper; + private: enum class gate_kind : unsigned char { product, dot, mux, poly }; @@ -970,6 +1891,7 @@ private: { std::vector parts; split share{}; + split tag{}; bool ready = false; }; @@ -998,8 +1920,13 @@ private: int gate = -1; Ring lambda_full{}; split lambda{}; + split lambda_tag{}; split value{}; + split value_tag{}; Ring delta{}; + auth_opening delta_mine{}; + auth_opening delta_peer{}; + bool delta_open_ready = false; }; struct gate @@ -1011,6 +1938,7 @@ private: std::vector terms; std::vector steps; split cross{}; + split cross_tag{}; bool cross_ready = false; }; @@ -1018,6 +1946,7 @@ private: { exp_list key; split share{}; + split tag{}; bool ready = false; }; @@ -1026,6 +1955,17 @@ private: std::vector monos_; std::vector bundles_; std::map mono_index_; + bool party_mode_ = false; + unsigned party_id_ = 0; + bool has_mac_ = false; + bool mac_key_known_ = false; + dpf::mac_key mac_key_{}; + schedule_objective schedule_objective_ = schedule_objective::prep; + + Ring side_of(const split & s) const + { + return party_id_ == 0 ? s.p0 : s.p1; + } static bool is_bit_secret(const Ring & secret) { @@ -1084,6 +2024,682 @@ private: return split{p0, traits::sub(secret, p0)}; } + template + void tag_split(const split & value, split & tag, Sample & rng) const + { + tag_assigned(value, tag, rng()); + } + + void tag_assigned(const split & value, split & tag, const Ring & mask) const + { + const Ring y = traits::add(value.p0, value.p1); + tag.p0 = mask; + tag.p1 = traits::sub(traits::mul(y, mac_key_.delta), mask); + } + + /// @brief One construction for a callable sampler and for an oracle. + /// @details `src.blind` / `src.mask` / `src.tag_mask` are called in that + /// order for each new wire, monomial, bundle, and dot cross. + /// A sequential sampler ignores the role and the index. + template + void sample_with(Source && src, std::uint64_t index) + { + for (std::uint32_t id = 0; id < wires_.size(); ++id) + { + auto & w = wires_[id]; + if (w.lambda_ready || !needs_blind(id)) + continue; + const auto role = oracle::wire_role(id); + w.lambda_full = src.blind(role, index); + const Ring p0 = src.mask(role, index); + w.lambda = split{p0, traits::sub(w.lambda_full, p0)}; + w.lambda_ready = true; + if (has_mac_) + tag_assigned(w.lambda, w.lambda_tag, src.tag_mask(role, index)); + } + for (std::uint32_t i = 0; i < monos_.size(); ++i) + { + auto & m = monos_[i]; + if (m.ready) + continue; + const auto role = oracle::mono_role(i); + const Ring full = mono_full(m.key); + const Ring p0 = src.mask(role, index); + m.share = split{p0, traits::sub(full, p0)}; + m.ready = true; + if (has_mac_) + tag_assigned(m.share, m.tag, src.tag_mask(role, index)); + } + for (std::uint32_t i = 0; i < bundles_.size(); ++i) + { + auto & b = bundles_[i]; + if (b.ready) + continue; + const auto role = oracle::bundle_role(i); + const Ring full = bundle_value(b); + const Ring p0 = src.mask(role, index); + b.share = split{p0, traits::sub(full, p0)}; + b.ready = true; + if (has_mac_) + tag_assigned(b.share, b.tag, src.tag_mask(role, index)); + } + for (std::uint32_t g = 0; g < gates_.size(); ++g) + { + auto & gate = gates_[g]; + if (gate.kind != gate_kind::dot || gate.cross_ready) + continue; + const auto role = oracle::dot_role(g); + const Ring full = dot_full(gate); + const Ring p0 = src.mask(role, index); + gate.cross = split{p0, traits::sub(full, p0)}; + gate.cross_ready = true; + if (has_mac_) + tag_assigned(gate.cross, gate.cross_tag, src.tag_mask(role, index)); + } + } + + template + void evaluate_party_impl(Exchange && exchange_delta) + { + int max_round = 0; + for (const auto & w : wires_) + max_round = std::max(max_round, w.ready_round); + for (int r = 1; r <= max_round; ++r) + { + for (const auto & g : gates_) + { + if (wires_[g.out].ready_round != r) + continue; + if (wires_[g.out].value_ready) + continue; + Ring val; + if (g.kind == gate_kind::product) + { + for (auto id : g.lhs) + ensure_delta_party(id, exchange_delta); + val = eval_product_party(g.lhs); + } + else if (g.kind == gate_kind::dot) + { + for (auto id : g.lhs) + ensure_delta_party(id, exchange_delta); + for (auto id : g.rhs) + ensure_delta_party(id, exchange_delta); + val = eval_dot_party(g); + } + else if (g.kind == gate_kind::poly) + { + for (const auto & step : g.steps) + { + if (step.value_wire >= 0) + { + const auto id = static_cast(step.value_wire); + if (!wires_[id].value_ready) + throw std::logic_error("beaver wire is not ready to open"); + continue; + } + for (auto [id, exp] : step.delta) + { + (void)exp; + ensure_delta_party(id, exchange_delta); + } + if (step.mask_wire >= 0) + ensure_delta_party( + static_cast(step.mask_wire), exchange_delta); + } + val = eval_poly_party(g); + } + else + { + for (auto id : g.lhs) + ensure_delta_party(id, exchange_delta); + val = eval_mux_party(g); + } + wires_[g.out].value = party_id_ == 0 + ? split{val, traits::zero()} + : split{traits::zero(), val}; + wires_[g.out].value_ready = true; + if (wires_[g.out].lambda_ready) + ensure_delta_party(g.out, exchange_delta); + } + } + } + + /// @brief One step of the compiled batch schedule: a δ flush or a gate eval. + struct batch_op + { + enum class kind : unsigned char { flush, eval_gate } type = kind::flush; + int ready_round = 0; + std::vector wire_ids; + std::size_t gate_index = 0; + }; + + /// @brief Compile the batch control flow without opening wires. + std::vector compile_batch_ops() const + { + std::vector ops; + const std::size_t n = wires_.size(); + std::vector value_ready(n, 0); + std::vector delta_ready(n, 0); + std::vector lambda_ready(n, 0); + for (std::uint32_t id = 0; id < n; ++id) + { + if (wires_[id].ready_round == 0) + value_ready[id] = 1; + if (needs_blind(id) || wires_[id].lambda_ready) + lambda_ready[id] = 1; + } + + int max_round = 0; + for (const auto & w : wires_) + max_round = std::max(max_round, w.ready_round); + + std::vector queued(n, 0); + std::vector pending; + pending.reserve(n); + + auto note = [&](std::uint32_t id) { + if (delta_ready[id] || queued[id]) + return; + if (!lambda_ready[id] || !value_ready[id]) + return; + queued[id] = 1; + pending.push_back(id); + }; + + auto record_flush = [&](int round) { + if (pending.empty()) + return; + batch_op op; + op.type = batch_op::kind::flush; + op.ready_round = round; + op.wire_ids = pending; + ops.push_back(std::move(op)); + for (auto id : pending) + { + delta_ready[id] = 1; + queued[id] = 0; + } + pending.clear(); + }; + + auto note_gate_inputs = [&](const gate & g) { + if (g.kind == gate_kind::product) + { + for (auto id : g.lhs) + note(id); + } + else if (g.kind == gate_kind::dot) + { + for (auto id : g.lhs) + note(id); + for (auto id : g.rhs) + note(id); + } + else if (g.kind == gate_kind::poly) + { + for (const auto & step : g.steps) + { + if (step.value_wire >= 0) + continue; + for (auto [id, exp] : step.delta) + { + (void)exp; + note(id); + } + if (step.mask_wire >= 0) + note(static_cast(step.mask_wire)); + } + } + else + { + for (auto id : g.lhs) + note(id); + } + }; + + auto ensure_ready = [&](std::uint32_t id, int round) { + if (delta_ready[id]) + return; + if (!lambda_ready[id] || !value_ready[id]) + throw std::logic_error("beaver wire is not ready to open"); + record_flush(round); + note(id); + record_flush(round); + }; + + auto ensure_gate_inputs = [&](const gate & g, int round) { + if (g.kind == gate_kind::product) + { + for (auto id : g.lhs) + ensure_ready(id, round); + } + else if (g.kind == gate_kind::dot) + { + for (auto id : g.lhs) + ensure_ready(id, round); + for (auto id : g.rhs) + ensure_ready(id, round); + } + else if (g.kind == gate_kind::poly) + { + for (const auto & step : g.steps) + { + if (step.value_wire >= 0) + { + const auto id = static_cast(step.value_wire); + if (!value_ready[id]) + throw std::logic_error("beaver wire is not ready to open"); + continue; + } + for (auto [id, exp] : step.delta) + { + (void)exp; + ensure_ready(id, round); + } + if (step.mask_wire >= 0) + ensure_ready(static_cast(step.mask_wire), round); + } + } + else + { + for (auto id : g.lhs) + ensure_ready(id, round); + } + }; + + for (int r = 1; r <= max_round; ++r) + { + pending.clear(); + for (auto & q : queued) + q = 0; + for (const auto & g : gates_) + { + if (wires_[g.out].ready_round != r) + continue; + if (value_ready[g.out]) + continue; + note_gate_inputs(g); + } + record_flush(r); + + for (std::size_t gi = 0; gi < gates_.size(); ++gi) + { + const auto & g = gates_[gi]; + if (wires_[g.out].ready_round != r) + continue; + if (value_ready[g.out]) + continue; + ensure_gate_inputs(g, r); + batch_op ev; + ev.type = batch_op::kind::eval_gate; + ev.ready_round = r; + ev.gate_index = gi; + ops.push_back(std::move(ev)); + value_ready[g.out] = 1; + if (lambda_ready[g.out]) + note(g.out); + } + record_flush(r); + } + return ops; + } + + std::vector compile_batch_barriers() const + { + std::vector out; + for (const auto & op : compile_batch_ops()) + { + if (op.type != batch_op::kind::flush) + continue; + delta_barrier b; + b.ready_round = op.ready_round; + b.wire_ids = op.wire_ids; + out.push_back(std::move(b)); + } + return out; + } + + void eval_gate_party(const gate & g) + { + Ring val; + if (g.kind == gate_kind::product) + val = eval_product_party(g.lhs); + else if (g.kind == gate_kind::dot) + val = eval_dot_party(g); + else if (g.kind == gate_kind::poly) + val = eval_poly_party(g); + else + val = eval_mux_party(g); + wires_[g.out].value = party_id_ == 0 + ? split{val, traits::zero()} + : split{traits::zero(), val}; + wires_[g.out].value_ready = true; + } + + template + void flush_delta_batch(std::vector & ids, + std::vector & queued, BatchExchange && exchange_deltas) + { + if (ids.empty()) + return; + std::vector mine; + mine.reserve(ids.size()); + for (auto id : ids) + { + auto & w = wires_[id]; + if (w.delta_ready) + throw std::logic_error("beaver delta batch contains an opened wire"); + if (!w.lambda_ready || !w.value_ready) + throw std::logic_error("beaver wire is not ready to open"); + mine.push_back(traits::add(side_of(w.value), side_of(w.lambda))); + } + std::vector peer = exchange_deltas(mine); + if (peer.size() != mine.size()) + throw std::runtime_error("beaver delta batch size mismatch"); + for (std::size_t i = 0; i < ids.size(); ++i) + { + auto & w = wires_[ids[i]]; + w.delta = traits::add(mine[i], peer[i]); + w.delta_ready = true; + queued[ids[i]] = 0; + } + ids.clear(); + } + + template + void evaluate_party_batch_impl(BatchExchange && exchange_deltas) + { + const auto ops = compile_batch_ops(); + std::vector queued(wires_.size(), 0); + for (const auto & op : ops) + { + if (op.type == batch_op::kind::flush) + { + std::vector ids = op.wire_ids; + for (auto id : ids) + queued[id] = 1; + flush_delta_batch(ids, queued, exchange_deltas); + } + else + { + const auto & g = gates_[op.gate_index]; + if (wires_[g.out].value_ready) + continue; + eval_gate_party(g); + } + } + } + + template + void ensure_delta_party_auth(std::uint32_t id, Exchange && exchange_delta) + { + auto & w = wires_[id]; + if (w.delta_ready) + return; + if (!w.lambda_ready || !w.value_ready) + throw std::logic_error("beaver wire is not ready to open"); + auth_opening mine{ + traits::add(side_of(w.value), side_of(w.lambda)), + traits::add(side_of(w.value_tag), side_of(w.lambda_tag))}; + auth_opening peer = exchange_delta(mine); + w.delta = traits::add(mine.value, peer.value); + w.delta_mine = mine; + w.delta_peer = peer; + w.delta_open_ready = true; + w.delta_ready = true; + } + + template + void evaluate_party_auth_impl(Exchange && exchange_delta) + { + int max_round = 0; + for (const auto & w : wires_) + max_round = std::max(max_round, w.ready_round); + for (int r = 1; r <= max_round; ++r) + { + for (const auto & g : gates_) + { + if (wires_[g.out].ready_round != r) + continue; + if (wires_[g.out].value_ready) + continue; + Ring val; + if (g.kind == gate_kind::product) + { + for (auto id : g.lhs) + ensure_delta_party_auth(id, exchange_delta); + val = eval_product_party(g.lhs); + } + else if (g.kind == gate_kind::dot) + { + for (auto id : g.lhs) + ensure_delta_party_auth(id, exchange_delta); + for (auto id : g.rhs) + ensure_delta_party_auth(id, exchange_delta); + val = eval_dot_party(g); + } + else if (g.kind == gate_kind::poly) + { + for (const auto & step : g.steps) + { + if (step.value_wire >= 0) + { + const auto id = static_cast(step.value_wire); + if (!wires_[id].value_ready) + throw std::logic_error("beaver wire is not ready to open"); + continue; + } + for (auto [id, exp] : step.delta) + { + (void)exp; + ensure_delta_party_auth(id, exchange_delta); + } + if (step.mask_wire >= 0) + ensure_delta_party_auth( + static_cast(step.mask_wire), exchange_delta); + } + val = eval_poly_party(g); + } + else + { + for (auto id : g.lhs) + ensure_delta_party_auth(id, exchange_delta); + val = eval_mux_party(g); + } + wires_[g.out].value = party_id_ == 0 + ? split{val, traits::zero()} + : split{traits::zero(), val}; + wires_[g.out].value_ready = true; + if (wires_[g.out].lambda_ready) + ensure_delta_party_auth(g.out, exchange_delta); + } + } + } + + template + void flush_delta_batch_auth(std::vector & ids, + std::vector & queued, BatchExchange && exchange_deltas) + { + if (ids.empty()) + return; + std::vector> mine; + mine.reserve(ids.size()); + for (auto id : ids) + { + auto & w = wires_[id]; + if (w.delta_ready) + throw std::logic_error("beaver delta batch contains an opened wire"); + if (!w.lambda_ready || !w.value_ready) + throw std::logic_error("beaver wire is not ready to open"); + mine.push_back(auth_opening{ + traits::add(side_of(w.value), side_of(w.lambda)), + traits::add(side_of(w.value_tag), side_of(w.lambda_tag))}); + } + std::vector> peer = exchange_deltas(mine); + if (peer.size() != mine.size()) + throw std::runtime_error("beaver auth delta batch size mismatch"); + for (std::size_t i = 0; i < ids.size(); ++i) + { + auto & w = wires_[ids[i]]; + w.delta = traits::add(mine[i].value, peer[i].value); + w.delta_mine = mine[i]; + w.delta_peer = peer[i]; + w.delta_open_ready = true; + w.delta_ready = true; + queued[ids[i]] = 0; + } + ids.clear(); + } + + template + void evaluate_party_auth_batch_impl(BatchExchange && exchange_deltas) + { + int max_round = 0; + for (const auto & w : wires_) + max_round = std::max(max_round, w.ready_round); + std::vector queued(wires_.size(), 0); + std::vector pending; + pending.reserve(wires_.size()); + + auto note = [&](std::uint32_t id) { + auto & w = wires_[id]; + if (w.delta_ready || queued[id]) + return; + if (!w.lambda_ready || !w.value_ready) + return; + queued[id] = 1; + pending.push_back(id); + }; + + auto note_gate_inputs = [&](const gate & g) { + if (g.kind == gate_kind::product) + { + for (auto id : g.lhs) + note(id); + } + else if (g.kind == gate_kind::dot) + { + for (auto id : g.lhs) + note(id); + for (auto id : g.rhs) + note(id); + } + else if (g.kind == gate_kind::poly) + { + for (const auto & step : g.steps) + { + if (step.value_wire >= 0) + continue; + for (auto [id, exp] : step.delta) + { + (void)exp; + note(id); + } + if (step.mask_wire >= 0) + note(static_cast(step.mask_wire)); + } + } + else + { + for (auto id : g.lhs) + note(id); + } + }; + + auto ensure_ready = [&](std::uint32_t id) { + auto & w = wires_[id]; + if (w.delta_ready) + return; + if (!w.lambda_ready || !w.value_ready) + throw std::logic_error("beaver wire is not ready to open"); + flush_delta_batch_auth(pending, queued, exchange_deltas); + note(id); + flush_delta_batch_auth(pending, queued, exchange_deltas); + }; + + auto ensure_gate_inputs = [&](const gate & g) { + if (g.kind == gate_kind::product) + { + for (auto id : g.lhs) + ensure_ready(id); + } + else if (g.kind == gate_kind::dot) + { + for (auto id : g.lhs) + ensure_ready(id); + for (auto id : g.rhs) + ensure_ready(id); + } + else if (g.kind == gate_kind::poly) + { + for (const auto & step : g.steps) + { + if (step.value_wire >= 0) + { + const auto id = static_cast(step.value_wire); + if (!wires_[id].value_ready) + throw std::logic_error("beaver wire is not ready to open"); + continue; + } + for (auto [id, exp] : step.delta) + { + (void)exp; + ensure_ready(id); + } + if (step.mask_wire >= 0) + ensure_ready(static_cast(step.mask_wire)); + } + } + else + { + for (auto id : g.lhs) + ensure_ready(id); + } + }; + + for (int r = 1; r <= max_round; ++r) + { + pending.clear(); + for (auto & q : queued) + q = 0; + for (const auto & g : gates_) + { + if (wires_[g.out].ready_round != r) + continue; + if (wires_[g.out].value_ready) + continue; + note_gate_inputs(g); + } + flush_delta_batch_auth(pending, queued, exchange_deltas); + + for (const auto & g : gates_) + { + if (wires_[g.out].ready_round != r) + continue; + if (wires_[g.out].value_ready) + continue; + ensure_gate_inputs(g); + Ring val; + if (g.kind == gate_kind::product) + val = eval_product_party(g.lhs); + else if (g.kind == gate_kind::dot) + val = eval_dot_party(g); + else if (g.kind == gate_kind::poly) + val = eval_poly_party(g); + else + val = eval_mux_party(g); + wires_[g.out].value = party_id_ == 0 + ? split{val, traits::zero()} + : split{traits::zero(), val}; + wires_[g.out].value_ready = true; + if (wires_[g.out].lambda_ready) + note(g.out); + } + flush_delta_batch_auth(pending, queued, exchange_deltas); + } + } + Ring mono_full(const exp_list & key) const { Ring full = traits::one(); @@ -1209,7 +2825,7 @@ private: return; auto idx = static_cast(monos_.size()); mono_index_.emplace(key, idx); - monos_.push_back(mono{key, {}, false}); + monos_.push_back(mono{key, {}, {}, false}); } void require_product_monomials(const std::vector & factors) @@ -1367,14 +2983,25 @@ private: if (terms.size() < 2) return emit_terms(std::move(terms)); + // Latency path: keep one interactive round (Pika / online Grotto). + // Factor peels that buy prep at the cost of an extra round are skipped. + if (schedule_objective_ == schedule_objective::rounds) + return emit_terms(std::move(terms)); + std::vector> best{terms}; - std::size_t best_cost = estimate_pieces(best); + std::size_t best_prep = estimate_pieces(best); + std::size_t best_pieces = best.size(); auto consider = [&](std::vector> seq) { - const std::size_t cost = estimate_pieces(seq); - if (cost < best_cost) + const std::size_t prep = estimate_pieces(seq); + const std::size_t pieces = seq.size(); + // Prep first (Appendix E): fewer blinds/bundles, then fewer rounds. + const bool take = (prep < best_prep) + || (prep == best_prep && pieces < best_pieces); + if (take) { best = std::move(seq); - best_cost = cost; + best_prep = prep; + best_pieces = pieces; } }; @@ -1484,7 +3111,27 @@ private: w.delta_ready = true; } - split term_share(const exp_list & key) const + template + void ensure_delta_party(std::uint32_t id, Exchange && exchange_delta) + { + auto & w = wires_[id]; + if (w.delta_ready) + return; + if (!w.lambda_ready || !w.value_ready) + throw std::logic_error("beaver wire is not ready to open"); + Ring mine = traits::add(side_of(w.value), side_of(w.lambda)); + Ring peer = exchange_delta(mine); + w.delta = traits::add(mine, peer); + w.delta_ready = true; + } + + struct located_term + { + const split * share = nullptr; + const split * tag = nullptr; + }; + + located_term locate_term(const exp_list & key) const { if (key.empty()) throw std::invalid_argument("beaver monomial is empty"); @@ -1493,21 +3140,26 @@ private: const auto & w = wires_[key[0].first]; if (!w.lambda_ready) throw std::logic_error("call sample() before reading a beaver blind"); - return w.lambda; + return located_term{&w.lambda, &w.lambda_tag}; } auto it = mono_index_.find(key); if (it != mono_index_.end() && monos_[it->second].ready) - return monos_[it->second].share; + return located_term{&monos_[it->second].share, &monos_[it->second].tag}; for (const auto & b : bundles_) { if (!b.ready || b.parts.size() != 1 || !(b.parts[0].coeff == traits::one())) continue; if (b.parts[0].lam == key) - return b.share; + return located_term{&b.share, &b.tag}; } throw std::logic_error("beaver monomial was not prepared"); } + split term_share(const exp_list & key) const + { + return *locate_term(key).share; + } + unsigned exponent_of(const exp_list & key, std::uint32_t id) const { for (auto [kid, ke] : key) @@ -1853,6 +3505,107 @@ private: s1 = traits::add(s1, y.value.p1); return split{s0, s1}; } + + Ring eval_product_party(const std::vector & factors) const + { + auto groups = group_exponents(factors); + Ring s = traits::zero(); + for_each_term(groups, [&](const exp_list & key) { + long long coeff = 1; + bool any = false; + Ring pub = traits::one(); + for (auto [id, e] : groups) + { + unsigned ti = exponent_of(key, id); + coeff *= binom(e, ti); + if ((ti & 1u) != 0) + coeff = -coeff; + any = any || ti != 0; + pub = traits::mul(pub, pow_small(wires_[id].delta, e - ti)); + } + if (coeff == 0) + return; + if (!any) + { + if (party_id_ == 0) + s = traits::add(s, scale_int(pub, coeff)); + return; + } + auto sh = term_share(key); + s = traits::add(s, scale_int(traits::mul(pub, side_of(sh)), coeff)); + }); + return s; + } + + Ring eval_dot_party(const gate & g) const + { + if (!g.cross_ready) + throw std::logic_error("beaver dot cross term is not sampled"); + Ring s = traits::zero(); + for (std::size_t i = 0; i < g.lhs.size(); ++i) + { + const auto & x = wires_[g.lhs[i]]; + const auto & y = wires_[g.rhs[i]]; + if (party_id_ == 0) + s = traits::add(s, traits::mul(x.delta, y.delta)); + s = traits::sub(s, traits::mul(x.delta, side_of(y.lambda))); + s = traits::sub(s, traits::mul(y.delta, side_of(x.lambda))); + } + s = traits::add(s, side_of(g.cross)); + return s; + } + + Ring eval_poly_party(const gate & g) const + { + Ring s = traits::zero(); + for (const auto & step : g.steps) + { + if (step.value_wire >= 0) + { + const auto & val = wires_[static_cast(step.value_wire)].value; + s = traits::add(s, traits::mul(step.scale, side_of(val))); + continue; + } + Ring pub = pow_delta(step.delta); + if (step.public_only) + { + if (party_id_ == 0) + s = traits::add(s, traits::mul(pub, step.scale)); + continue; + } + if (step.mask_wire >= 0) + { + const auto & lam = wires_[static_cast(step.mask_wire)].lambda; + s = traits::add(s, traits::mul(pub, traits::mul(step.scale, side_of(lam)))); + continue; + } + const auto & share = bundles_[static_cast(step.bundle)].share; + if (!bundles_[static_cast(step.bundle)].ready) + throw std::logic_error("beaver bundle is not sampled"); + s = traits::add(s, traits::mul(pub, traits::mul(step.scale, side_of(share)))); + } + return s; + } + + Ring eval_mux_party(const gate & g) const + { + const auto & b = wires_[g.lhs[0]]; + const auto & x = wires_[g.lhs[1]]; + const auto & y = wires_[g.lhs[2]]; + Ring dd = traits::sub(x.delta, y.delta); + Ring ld = traits::sub(side_of(x.lambda), side_of(y.lambda)); + auto bx = term_share(pair_key(g.lhs[0], g.lhs[1])); + auto by = term_share(pair_key(g.lhs[0], g.lhs[2])); + Ring cross = traits::sub(side_of(bx), side_of(by)); + Ring s = traits::zero(); + if (party_id_ == 0) + s = traits::mul(b.delta, dd); + s = traits::sub(s, traits::mul(b.delta, ld)); + s = traits::sub(s, traits::mul(dd, side_of(b.lambda))); + s = traits::add(s, cross); + s = traits::add(s, side_of(y.value)); + return s; + } }; namespace detail @@ -1942,7 +3695,7 @@ expr scale_expr(expr e, Ring coeff) template Ring coeff_of(Coeff value) { - return Ring{value}; + return static_cast(value); } template @@ -2060,6 +3813,7 @@ expr pow(wire w, unsigned exp) return e; } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator*(wire a, wire b) @@ -2067,6 +3821,7 @@ expr operator*(wire a, wire b) return detail::mul_exprs(wire_expr(a), wire_expr(b)); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator*(expr a, wire b) @@ -2074,6 +3829,7 @@ expr operator*(expr a, wire b) return detail::mul_exprs(a, wire_expr(b)); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator*(wire a, expr b) @@ -2081,6 +3837,7 @@ expr operator*(wire a, expr b) return detail::mul_exprs(wire_expr(a), b); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator*(expr a, expr b) @@ -2088,6 +3845,7 @@ expr operator*(expr a, expr b) return detail::mul_exprs(a, b); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator+(wire a, wire b) @@ -2095,6 +3853,7 @@ expr operator+(wire a, wire b) return detail::add_exprs(wire_expr(a), wire_expr(b)); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator+(expr a, wire b) @@ -2102,6 +3861,7 @@ expr operator+(expr a, wire b) return detail::add_exprs(std::move(a), wire_expr(b)); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator+(wire a, expr b) @@ -2109,6 +3869,7 @@ expr operator+(wire a, expr b) return detail::add_exprs(wire_expr(a), b); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator+(expr a, expr b) @@ -2116,6 +3877,7 @@ expr operator+(expr a, expr b) return detail::add_exprs(std::move(a), b); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator-(expr e) @@ -2123,6 +3885,7 @@ expr operator-(expr e) return detail::scale_expr(std::move(e), ring_traits::neg(ring_traits::one())); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator-(wire w) @@ -2130,6 +3893,7 @@ expr operator-(wire w) return -wire_expr(w); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator-(expr a, expr b) @@ -2137,6 +3901,7 @@ expr operator-(expr a, expr b) return std::move(a) + (-std::move(b)); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator-(expr a, wire b) @@ -2144,6 +3909,7 @@ expr operator-(expr a, wire b) return std::move(a) + (-b); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator-(wire a, expr b) @@ -2151,6 +3917,7 @@ expr operator-(wire a, expr b) return wire_expr(a) + (-std::move(b)); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template HEDLEY_WARN_UNUSED_RESULT expr operator-(wire a, wire b) @@ -2158,6 +3925,7 @@ expr operator-(wire a, wire b) return wire_expr(a) + (-b); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template @@ -2169,6 +3937,7 @@ expr operator*(Coeff coeff, wire w) return detail::scale_expr(wire_expr(w), detail::coeff_of(coeff)); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template @@ -2180,6 +3949,7 @@ expr operator*(wire w, Coeff coeff) return detail::coeff_of(coeff) * w; } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template @@ -2191,6 +3961,7 @@ expr operator*(Coeff coeff, expr e) return detail::scale_expr(std::move(e), detail::coeff_of(coeff)); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template @@ -2202,6 +3973,7 @@ expr operator*(expr e, Coeff coeff) return detail::coeff_of(coeff) * std::move(e); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template @@ -2216,6 +3988,7 @@ expr operator+(Coeff coeff, wire w) return detail::add_exprs(std::move(constant), wire_expr(w)); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template @@ -2227,6 +4000,7 @@ expr operator+(wire w, Coeff coeff) return coeff + w; } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template @@ -2243,6 +4017,7 @@ expr operator+(Coeff coeff, expr e) return detail::add_exprs(std::move(constant), e); } +/// \complexity O(1) to record the gate on the session. No messages. Opening is `evaluate` / `evaluate_party`. template @@ -2273,6 +4048,223 @@ struct fresh_beaver split out{}; }; +/// @brief Drive `evaluate_party_batch` one δ barrier at a time. +/// @details Construct after `install_party` and binding inputs. Each +/// `take_local` / `apply_peer` pair matches one entry of +/// `session::exchange_barriers()`. Gate evaluations between barriers +/// run inside `apply_peer`. Wire bytes match `evaluate_party_batch`. +template +class party_batch_stepper +{ +public: + using traits = ring_traits; + + explicit party_batch_stepper(session & s) + : s_(&s), + ops_(s.compile_batch_ops()), + pc_(0), + waiting_(false) + { + if (!s.party_mode_) + throw std::logic_error("call install_party before party_batch_stepper"); + advance_to_flush_or_end(); + } + + std::size_t barrier_count() const + { + std::size_t n = 0; + for (const auto & op : ops_) + { + if (op.type == session::batch_op::kind::flush) + ++n; + } + return n; + } + + bool done() const noexcept + { + return pc_ >= ops_.size() && !waiting_; + } + + /// @brief Local δ shares for the next barrier (same order as `barrier().wire_ids`). + std::vector take_local() + { + if (done()) + throw std::logic_error("party_batch_stepper is done"); + if (waiting_) + throw std::logic_error("party_batch_stepper already waiting for peer"); + if (pc_ >= ops_.size() + || ops_[pc_].type != session::batch_op::kind::flush) + throw std::logic_error("party_batch_stepper expected a flush"); + const auto & ids = ops_[pc_].wire_ids; + current_.ready_round = ops_[pc_].ready_round; + current_.wire_ids = ids; + std::vector mine; + mine.reserve(ids.size()); + for (auto id : ids) + { + auto & w = s_->wires_[id]; + if (w.delta_ready) + throw std::logic_error("beaver delta batch contains an opened wire"); + if (!w.lambda_ready || !w.value_ready) + throw std::logic_error("beaver wire is not ready to open"); + mine.push_back(traits::add(s_->side_of(w.value), s_->side_of(w.lambda))); + } + waiting_ = true; + return mine; + } + + const typename session::delta_barrier & barrier() const + { + if (!waiting_) + throw std::logic_error("party_batch_stepper::barrier requires take_local"); + return current_; + } + + /// @brief Apply peer shares and evaluate until the next flush or completion. + void apply_peer(const std::vector & peer) + { + if (!waiting_) + throw std::logic_error("party_batch_stepper::apply_peer without take_local"); + const auto & ids = current_.wire_ids; + if (peer.size() != ids.size()) + throw std::runtime_error("beaver delta batch size mismatch"); + for (std::size_t i = 0; i < ids.size(); ++i) + { + auto & w = s_->wires_[ids[i]]; + Ring mine = traits::add(s_->side_of(w.value), s_->side_of(w.lambda)); + w.delta = traits::add(mine, peer[i]); + w.delta_ready = true; + } + waiting_ = false; + ++pc_; + advance_to_flush_or_end(); + } + +private: + void advance_to_flush_or_end() + { + while (pc_ < ops_.size() + && ops_[pc_].type == session::batch_op::kind::eval_gate) + { + const auto & g = s_->gates_[ops_[pc_].gate_index]; + if (!s_->wires_[g.out].value_ready) + s_->eval_gate_party(g); + ++pc_; + } + } + + session * s_; + std::vector::batch_op> ops_; + std::size_t pc_ = 0; + bool waiting_ = false; + typename session::delta_barrier current_{}; +}; + +/// @brief Authenticated twin of `party_batch_stepper` (`auth_opening` per wire). +template +class party_auth_batch_stepper +{ +public: + using traits = ring_traits; + + explicit party_auth_batch_stepper(session & s) + : s_(&s), + ops_(s.compile_batch_ops()), + pc_(0), + waiting_(false) + { + if (!s.party_mode_) + throw std::logic_error( + "call install_party before party_auth_batch_stepper"); + if (!s.has_mac_) + throw std::logic_error( + "party_auth_batch_stepper requires an authenticated tape"); + advance_to_flush_or_end(); + } + + bool done() const noexcept + { + return pc_ >= ops_.size() && !waiting_; + } + + std::vector> take_local() + { + if (done()) + throw std::logic_error("party_auth_batch_stepper is done"); + if (waiting_) + throw std::logic_error("party_auth_batch_stepper already waiting"); + if (pc_ >= ops_.size() + || ops_[pc_].type != session::batch_op::kind::flush) + throw std::logic_error("party_auth_batch_stepper expected a flush"); + const auto & ids = ops_[pc_].wire_ids; + current_.ready_round = ops_[pc_].ready_round; + current_.wire_ids = ids; + mine_.clear(); + mine_.reserve(ids.size()); + for (auto id : ids) + { + auto & w = s_->wires_[id]; + if (w.delta_ready) + throw std::logic_error("beaver delta batch contains an opened wire"); + if (!w.lambda_ready || !w.value_ready) + throw std::logic_error("beaver wire is not ready to open"); + mine_.push_back(auth_opening{ + traits::add(s_->side_of(w.value), s_->side_of(w.lambda)), + traits::add(s_->side_of(w.value_tag), s_->side_of(w.lambda_tag))}); + } + waiting_ = true; + return mine_; + } + + void apply_peer(const std::vector> & peer) + { + if (!waiting_) + throw std::logic_error( + "party_auth_batch_stepper::apply_peer without take_local"); + const auto & ids = current_.wire_ids; + if (peer.size() != ids.size() || peer.size() != mine_.size()) + throw std::runtime_error("beaver auth delta batch size mismatch"); + for (std::size_t i = 0; i < ids.size(); ++i) + { + auto & w = s_->wires_[ids[i]]; + w.delta = traits::add(mine_[i].value, peer[i].value); + w.delta_mine = mine_[i]; + w.delta_peer = peer[i]; + w.delta_open_ready = true; + w.delta_ready = true; + if (s_->mac_key_known_ + && !verify_auth_opening(w.delta_mine, w.delta_peer, s_->mac_key_)) + throw std::runtime_error("beaver auth opening failed"); + } + waiting_ = false; + ++pc_; + advance_to_flush_or_end(); + } + +private: + void advance_to_flush_or_end() + { + while (pc_ < ops_.size() + && ops_[pc_].type == session::batch_op::kind::eval_gate) + { + const auto & g = s_->gates_[ops_[pc_].gate_index]; + if (!s_->wires_[g.out].value_ready) + s_->eval_gate_party(g); + ++pc_; + } + } + + session * s_; + std::vector::batch_op> ops_; + std::size_t pc_ = 0; + bool waiting_ = false; + typename session::delta_barrier current_{}; + std::vector> mine_; +}; + + + template HEDLEY_WARN_UNUSED_RESULT fresh_beaver sample_fresh(Sample && rng) @@ -2392,9 +4384,34 @@ struct mux_beaver split out{}; }; +template +void with_beaver2_formula(Apply && apply) +{ + session s; + auto a = s.input(); + auto b = s.input(); + auto out = s(a * b); + s.pin(out); + apply(s, a, b, out); +} + +template +HEDLEY_WARN_UNUSED_RESULT +beaver2 beaver2_read(session & s, + typename session::wire a, + typename session::wire b, + typename session::wire out) +{ + return beaver2{ + s.lambda(a), + s.lambda(b), + s.monomial({{a, 1u}, {b, 1u}}), + s.lambda(out)}; +} + /// @brief One fresh Beaver pair from copy `index` of an oracle. -/// @details Roles match a session that records `input, input, product`: wires 0 and 1, -/// the product wire, and monomial 0. +/// @details Records the same `a * b` formula as `sample_beaver2` and samples it +/// with `session::sample_from`. /// @tparam Ring payload ring /// @tparam PRG pseudorandom generator /// @param src the source @@ -2404,19 +4421,15 @@ template HEDLEY_WARN_UNUSED_RESULT beaver2 beaver2_at(const oracle & src, std::uint64_t index) { - using traits = ring_traits; - Ring a = src.blind(oracle::wire_role(0), index); - Ring b = src.blind(oracle::wire_role(1), index); - Ring out = src.blind(oracle::wire_role(2), index); - Ring ab = traits::mul(a, b); - return beaver2{ - src.share(oracle::wire_role(0), index, a), - src.share(oracle::wire_role(1), index, b), - src.share(oracle::mono_role(0), index, ab), - src.share(oracle::wire_role(2), index, out)}; + beaver2 got; + with_beaver2_formula([&](auto & s, auto a, auto b, auto out) { + s.sample_from(src, index); + got = beaver2_read(s, a, b, out); + }); + return got; } -/// @brief `n` copies starting at `begin`. Each role is one contiguous lane read. +/// @brief `n` copies starting at `begin`, each one `sample_from` of the pair formula. /// @tparam Ring payload ring /// @tparam PRG pseudorandom generator /// @param src the source @@ -2432,25 +4445,15 @@ void fill_beaver2(const oracle & src, std::uint64_t begin, return; if (out == nullptr) throw std::invalid_argument("beaver2 output is null"); - using traits = ring_traits; - std::vector a(n), b(n), z(n); - std::vector ma(n), mb(n), mab(n), mz(n); - src.fill_blinds(oracle::wire_role(0), begin, a.data(), n); - src.fill_blinds(oracle::wire_role(1), begin, b.data(), n); - src.fill_blinds(oracle::wire_role(2), begin, z.data(), n); - src.fill_masks(oracle::wire_role(0), begin, ma.data(), n); - src.fill_masks(oracle::wire_role(1), begin, mb.data(), n); - src.fill_masks(oracle::mono_role(0), begin, mab.data(), n); - src.fill_masks(oracle::wire_role(2), begin, mz.data(), n); - for (std::size_t i = 0; i < n; ++i) - { - Ring ab = traits::mul(a[i], b[i]); - out[i] = beaver2{ - split{ma[i], traits::sub(a[i], ma[i])}, - split{mb[i], traits::sub(b[i], mb[i])}, - split{mab[i], traits::sub(ab, mab[i])}, - split{mz[i], traits::sub(z[i], mz[i])}}; - } + with_beaver2_formula([&](auto & s, auto a, auto b, auto product) { + for (std::size_t i = 0; i < n; ++i) + { + if (i != 0) + s.clear_sample(); + s.sample_from(src, begin + static_cast(i)); + out[i] = beaver2_read(s, a, b, product); + } + }); } template @@ -2490,6 +4493,170 @@ beaver3 sample_beaver3() return sample_beaver3(default_sampler{}); } +/// @brief Beaver triple with IT-MAC tags on every share. +/// @tparam Ring payload ring +template +struct auth_beaver2 +{ + auth_split a{}; + auth_split b{}; + auth_split ab{}; + auth_split out{}; + + HEDLEY_NO_THROW + bool verify(const dpf::mac_key & key) const + { + return a.verify(key) && b.verify(key) && ab.verify(key) && out.verify(key) + && ab.open() == ring_traits::mul(a.open(), b.open()); + } +}; + +template +struct auth_beaver3 +{ + auth_split a{}; + auth_split b{}; + auth_split c{}; + auth_split ab{}; + auth_split ac{}; + auth_split bc{}; + auth_split abc{}; + auth_split out{}; + + HEDLEY_NO_THROW + bool verify(const dpf::mac_key & key) const + { + using traits = ring_traits; + return a.verify(key) && b.verify(key) && c.verify(key) + && ab.verify(key) && ac.verify(key) && bc.verify(key) + && abc.verify(key) && out.verify(key) + && ab.open() == traits::mul(a.open(), b.open()) + && ac.open() == traits::mul(a.open(), c.open()) + && bc.open() == traits::mul(b.open(), c.open()) + && abc.open() == traits::mul(ab.open(), c.open()); + } +}; + +/// @brief Authenticate an existing beaver2 under `key`. +template +HEDLEY_WARN_UNUSED_RESULT +auth_beaver2 authenticate_beaver2(const beaver2 & t, + const dpf::mac_key & key, Sample && rng) +{ + auto & sampler = rng; + return auth_beaver2{ + authenticate(t.a, key, sampler), + authenticate(t.b, key, sampler), + authenticate(t.ab, key, sampler), + authenticate(t.out, key, sampler)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +auth_beaver2 authenticate_beaver2(const beaver2 & t, + const dpf::mac_key & key) +{ + return authenticate_beaver2(t, key, default_sampler{}); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auth_beaver2 sample_auth_beaver2(const dpf::mac_key & key, + Sample && rng) +{ + auto & sampler = rng; + return authenticate_beaver2(sample_beaver2(sampler), key, sampler); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auth_beaver2 sample_auth_beaver2(const dpf::mac_key & key) +{ + return sample_auth_beaver2(key, default_sampler{}); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auth_beaver3 authenticate_beaver3(const beaver3 & t, + const dpf::mac_key & key, Sample && rng) +{ + auto & sampler = rng; + return auth_beaver3{ + authenticate(t.a, key, sampler), + authenticate(t.b, key, sampler), + authenticate(t.c, key, sampler), + authenticate(t.ab, key, sampler), + authenticate(t.ac, key, sampler), + authenticate(t.bc, key, sampler), + authenticate(t.abc, key, sampler), + authenticate(t.out, key, sampler)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +auth_beaver3 authenticate_beaver3(const beaver3 & t, + const dpf::mac_key & key) +{ + return authenticate_beaver3(t, key, default_sampler{}); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auth_beaver3 sample_auth_beaver3(const dpf::mac_key & key, + Sample && rng) +{ + auto & sampler = rng; + return authenticate_beaver3(sample_beaver3(sampler), key, sampler); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auth_beaver3 sample_auth_beaver3(const dpf::mac_key & key) +{ + return sample_auth_beaver3(key, default_sampler{}); +} + +/// @brief Classic Beaver multiply of authenticated inputs with an auth triple. +/// @details Opens `d = x-a`, `e = y-b`, then +/// `[xy] = [ab] + d[b] + e[a] + de` on values and tags. The public +/// `de` value and `de·Δ` tag land on party 1 (same side as the clear +/// beaver product). +/// @return Party shares of the authenticated product (no ABY2 out mask). +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, dpf::mac_share> auth_beaver_mul( + dpf::mac_share x0, dpf::mac_share x1, + dpf::mac_share y0, dpf::mac_share y1, + const auth_beaver2 & bev, const dpf::mac_key & key) +{ + using traits = ring_traits; + const Ring x = traits::add(x0.value, x1.value); + const Ring y = traits::add(y0.value, y1.value); + const Ring d = traits::sub(x, bev.a.open()); + const Ring e = traits::sub(y, bev.b.open()); + const auto a0 = bev.a.party(0); + const auto a1 = bev.a.party(1); + const auto b0 = bev.b.party(0); + const auto b1 = bev.b.party(1); + const auto ab0 = bev.ab.party(0); + const auto ab1 = bev.ab.party(1); + const Ring de = traits::mul(d, e); + dpf::mac_share z0{ + traits::add(ab0.value, + traits::add(traits::mul(d, b0.value), traits::mul(e, a0.value))), + traits::add(ab0.tag, + traits::add(traits::mul(d, b0.tag), traits::mul(e, a0.tag)))}; + dpf::mac_share z1{ + traits::add(ab1.value, + traits::add(traits::mul(d, b1.value), + traits::add(traits::mul(e, a1.value), de))), + traits::add(ab1.tag, + traits::add(traits::mul(d, b1.tag), + traits::add(traits::mul(e, a1.tag), + traits::mul(de, key.delta))))}; + return {z0, z1}; +} + template HEDLEY_WARN_UNUSED_RESULT square_beaver sample_square(Sample && rng) @@ -2560,12 +4727,12 @@ dot_beaver sample_dot(std::size_t n, Sample && rng) dot_beaver t; t.cross = s.dot_cross(out); t.out = s.lambda(out); - t.x.reserve(n); - t.y.reserve(n); + t.x.resize(n); + t.y.resize(n); for (std::size_t i = 0; i < n; ++i) { - t.x.push_back(s.lambda(x[i])); - t.y.push_back(s.lambda(y[i])); + t.x[i] = s.lambda(x[i]); + t.y[i] = s.lambda(y[i]); } return t; } @@ -2614,6 +4781,47 @@ scale_beaver sample_scale(std::size_t n) return sample_scale(n, default_sampler{}); } +template +void fill_wildcard_scale_blinds(Concrete & out0, Concrete & out1, LeafT & vec0, + LeafT & vec1, std::size_t nlanes, Sample && rng) +{ + auto sc = sample_scale(nlanes, std::forward(rng)); + out0 = sc.scalar.p0; + out1 = sc.scalar.p1; + vec0 = LeafT{}; + vec1 = LeafT{}; + if constexpr (utils::is_packed_subbyte_v) + { + for (std::size_t li = 0; li < sc.lanes.size(); ++li) + { + packed::deposit_lane(vec0, li, sc.lanes[li].p0); + packed::deposit_lane(vec1, li, sc.lanes[li].p1); + } + } + else + { + for (std::size_t li = 0; li < sc.lanes.size(); ++li) + { + const auto off = li * sizeof(Concrete); + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wstringop-overflow") + std::memcpy(reinterpret_cast(std::addressof(vec0)) + off, + std::addressof(sc.lanes[li].p0), sizeof(Concrete)); + std::memcpy(reinterpret_cast(std::addressof(vec1)) + off, + std::addressof(sc.lanes[li].p1), sizeof(Concrete)); + HEDLEY_PRAGMA(GCC diagnostic pop) + } + } +} + +template +void fill_wildcard_scale_blinds(Concrete & out0, Concrete & out1, LeafT & vec0, + LeafT & vec1, std::size_t nlanes) +{ + fill_wildcard_scale_blinds(out0, out1, vec0, vec1, nlanes, + default_sampler{}); +} + template HEDLEY_WARN_UNUSED_RESULT bit_mul_beaver sample_bit_mul(Sample && rng) @@ -2665,6 +4873,324 @@ mux_beaver sample_mux() return sample_mux(default_sampler{}); } +/// @brief XOR share of a bit and an additive share of that same bit in `uint64_t`. +/// @details Both shares are bound on a session. `pad.bit()` chooses the bit and +/// fills the XOR-ring sampler; `pad.block()` fills the integer sampler. +struct bit_arith_shares +{ + std::uint8_t xor0 = 0; + std::uint8_t xor1 = 0; + std::uint64_t add0 = 0; + std::uint64_t add1 = 0; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +bit_arith_shares sample_bit_arith(Pad & pad) +{ + using bit_ring = dpf::xor_wrapper; + using btraits = ring_traits; + const std::uint8_t bit = static_cast(pad.bit() & 1u); + auto bits = [&pad]() -> bit_ring { + std::uint8_t packed = 0; + for (int i = 0; i < 8; ++i) + { + packed = static_cast( + packed | (static_cast(pad.bit() & 1u) << i)); + } + return bit_ring{packed}; + }; + auto words = [&pad]() -> std::uint64_t { + const auto block = pad.block(); + std::uint64_t word = 0; + std::memcpy(&word, &block, sizeof(word)); + return word; + }; + + session xb; + auto bw = xb.bit(); + xb.pin(bw); + xb.sample(bits); + xb.bind(bw, bit ? btraits::one() : btraits::zero(), bits); + const auto xs = xb.value(bw); + + session ab; + auto aw = ab.input(); + ab.pin(aw); + ab.sample(words); + ab.bind(aw, std::uint64_t{bit}, words); + const auto as = ab.value(aw); + + auto low = [](bit_ring x) { + return static_cast(static_cast(x) & 1u); + }; + return bit_arith_shares{low(xs.p0), low(xs.p1), as.p0, as.p1}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +beaver2 sample_beaver2(const oracle & src, std::uint64_t index) +{ + return beaver2_at(src, index); +} + +template +HEDLEY_WARN_UNUSED_RESULT +beaver3 sample_beaver3(const oracle & src, std::uint64_t index) +{ + session s; + auto a = s.input(); + auto b = s.input(); + auto c = s.input(); + auto out = s(a * b * c); + s.pin(out); + s.sample_from(src, index); + return beaver3{ + s.lambda(a), s.lambda(b), s.lambda(c), + s.monomial({{a, 1u}, {b, 1u}}), + s.monomial({{a, 1u}, {c, 1u}}), + s.monomial({{b, 1u}, {c, 1u}}), + s.monomial({{a, 1u}, {b, 1u}, {c, 1u}}), + s.lambda(out)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +auth_beaver2 sample_auth_beaver2(const dpf::mac_key & key, + const oracle & src, std::uint64_t index) +{ + auth_beaver2 got; + with_beaver2_formula([&](auto & s, auto a, auto b, auto out) { + s.set_mac_key(key); + s.sample_from(src, index); + got = auth_beaver2{ + s.lambda_auth(a), + s.lambda_auth(b), + s.monomial_auth({{a, 1u}, {b, 1u}}), + s.lambda_auth(out)}; + }); + return got; +} + +template +HEDLEY_WARN_UNUSED_RESULT +auth_beaver3 sample_auth_beaver3(const dpf::mac_key & key, + const oracle & src, std::uint64_t index) +{ + session s; + s.set_mac_key(key); + auto a = s.input(); + auto b = s.input(); + auto c = s.input(); + auto out = s(a * b * c); + s.pin(out); + s.sample_from(src, index); + return auth_beaver3{ + s.lambda_auth(a), s.lambda_auth(b), s.lambda_auth(c), + s.monomial_auth({{a, 1u}, {b, 1u}}), + s.monomial_auth({{a, 1u}, {c, 1u}}), + s.monomial_auth({{b, 1u}, {c, 1u}}), + s.monomial_auth({{a, 1u}, {b, 1u}, {c, 1u}}), + s.lambda_auth(out)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +square_beaver sample_square(const oracle & src, std::uint64_t index) +{ + session s; + auto x = s.input(); + auto out = s(x * x); + s.pin(out); + s.sample_from(src, index); + return square_beaver{s.lambda(x), s.monomial({{x, 2u}}), s.lambda(out)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +mul_square_beaver sample_mul_square(const oracle & src, + std::uint64_t index) +{ + session s; + auto a = s.input(); + auto x = s.input(); + auto out = s(a * x * x); + s.pin(out); + s.sample_from(src, index); + return mul_square_beaver{ + s.lambda(a), s.lambda(x), + s.monomial({{x, 2u}}), + s.monomial({{a, 1u}, {x, 1u}}), + s.monomial({{a, 1u}, {x, 2u}}), + s.lambda(out)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +dot_beaver sample_dot(std::size_t n, const oracle & src, + std::uint64_t index) +{ + if (n == 0) + throw std::invalid_argument("beaver dot length is zero"); + session s; + std::vector::wire> x; + std::vector::wire> y; + x.reserve(n); + y.reserve(n); + for (std::size_t i = 0; i < n; ++i) + { + x.push_back(s.input()); + y.push_back(s.input()); + } + auto out = s.dot(x, y); + s.pin(out); + s.sample_from(src, index); + dot_beaver t; + t.cross = s.dot_cross(out); + t.out = s.lambda(out); + t.x.resize(n); + t.y.resize(n); + for (std::size_t i = 0; i < n; ++i) + { + t.x[i] = s.lambda(x[i]); + t.y[i] = s.lambda(y[i]); + } + return t; +} + +template +HEDLEY_WARN_UNUSED_RESULT +scale_beaver sample_scale(std::size_t n, const oracle & src, + std::uint64_t index) +{ + if (n == 0) + throw std::invalid_argument("beaver scale length is zero"); + session s; + auto scalar = s.input(); + std::vector::wire> lanes; + lanes.reserve(n); + for (std::size_t i = 0; i < n; ++i) + lanes.push_back(s.input()); + auto outs = s.scale(scalar, lanes); + for (const auto & out : outs) + s.pin(out); + s.sample_from(src, index); + scale_beaver t; + t.scalar = s.lambda(scalar); + t.lanes.reserve(n); + t.cross.reserve(n); + t.out.reserve(n); + for (std::size_t i = 0; i < n; ++i) + { + t.lanes.push_back(s.lambda(lanes[i])); + t.cross.push_back(s.monomial({{scalar, 1u}, {lanes[i], 1u}})); + t.out.push_back(s.lambda(outs[i])); + } + return t; +} + +template +void fill_wildcard_scale_blinds(Concrete & out0, Concrete & out1, LeafT & vec0, + LeafT & vec1, std::size_t nlanes, const oracle & src, + std::uint64_t index) +{ + auto sc = sample_scale(nlanes, src, index); + out0 = sc.scalar.p0; + out1 = sc.scalar.p1; + vec0 = LeafT{}; + vec1 = LeafT{}; + if constexpr (utils::is_packed_subbyte_v) + { + for (std::size_t li = 0; li < sc.lanes.size(); ++li) + { + packed::deposit_lane(vec0, li, sc.lanes[li].p0); + packed::deposit_lane(vec1, li, sc.lanes[li].p1); + } + } + else + { + for (std::size_t li = 0; li < sc.lanes.size(); ++li) + { + const auto off = li * sizeof(Concrete); + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wstringop-overflow") + std::memcpy(reinterpret_cast(std::addressof(vec0)) + off, + std::addressof(sc.lanes[li].p0), sizeof(Concrete)); + std::memcpy(reinterpret_cast(std::addressof(vec1)) + off, + std::addressof(sc.lanes[li].p1), sizeof(Concrete)); + HEDLEY_PRAGMA(GCC diagnostic pop) + } + } +} + +template +HEDLEY_WARN_UNUSED_RESULT +bit_mul_beaver sample_bit_mul(const oracle & src, std::uint64_t index) +{ + session s; + auto b = s.bit(); + auto x = s.input(); + auto out = s.bit_mul(b, x); + s.pin(out); + s.sample_from(src, index); + return bit_mul_beaver{ + s.lambda(b), s.lambda(x), + s.monomial({{b, 1u}, {x, 1u}}), + s.lambda(out)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +mux_beaver sample_mux(const oracle & src, std::uint64_t index) +{ + session s; + auto b = s.bit(); + auto when1 = s.input(); + auto when0 = s.input(); + auto out = s.mux(b, when1, when0); + s.pin(out); + s.sample_from(src, index); + return mux_beaver{ + s.lambda(b), s.lambda(when1), s.lambda(when0), + s.monomial({{b, 1u}, {when1, 1u}}), + s.monomial({{b, 1u}, {when0, 1u}}), + s.lambda(out)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +fresh_beaver sample_fresh(const oracle & src, + std::uint64_t index) +{ + static_assert(Arity >= 2 && Arity <= 8, "fresh beaver arity is 2..8"); + session s; + std::array::wire, Arity> w{}; + for (std::size_t i = 0; i < Arity; ++i) + w[i] = s.input(); + expr e = w[0] * w[1]; + for (std::size_t i = 2; i < Arity; ++i) + e = e * w[i]; + auto out = s(e); + s.pin(out); + s.sample_from(src, index); + + fresh_beaver t; + for (std::size_t i = 0; i < Arity; ++i) + t.in[i] = s.lambda(w[i]); + for (unsigned mask = 1; mask < (1u << Arity); ++mask) + { + std::vector::power> spec; + for (std::size_t i = 0; i < Arity; ++i) + { + if ((mask & (1u << i)) != 0) + spec.push_back(typename session::power{w[i], 1u}); + } + t.subset[mask - 1] = s.monomial(spec); + } + t.out = s.lambda(out); + return t; +} + } // namespace beavers } // namespace dpf diff --git a/include/dpf/bench_cells.hpp b/include/dpf/bench_cells.hpp new file mode 100644 index 0000000..1ea109d --- /dev/null +++ b/include/dpf/bench_cells.hpp @@ -0,0 +1,578 @@ +/// @file dpf/bench_cells.hpp +/// @brief Bench cells for work that is not a DPF walk. +/// @details A secret index stays a key. These cells time what happens after +/// the parties already hold shares: a constant-round word gadget, a +/// stacked branch of a leaf netlist, a short public table, and a +/// hidden reorder of an RSS column. Each cell is a compose plan. The +/// harness drives it with `run_parties`, so the payload crosses the +/// same transport as a DPF plan (`DPF_TRANSPORT`). +/// +/// Two-party cells put the garble or the table on party 0 and the +/// second evaluation on party 1, with one peer payload between them. +/// The shuffle is three ring passes. The left-out party's slot is +/// empty; the other two carry that pass's array. +#ifndef LIBDPF_INCLUDE_DPF_BENCH_CELLS_HPP__ +#define LIBDPF_INCLUDE_DPF_BENCH_CELLS_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/arith_garble.hpp" +#include "dpf/compose.hpp" +#include "dpf/flute.hpp" +#include "dpf/shuffle.hpp" +#include "dpf/yao.hpp" +#include "dpf/yao_stack.hpp" + +namespace dpf +{ +namespace bench +{ + +/// @brief One measured configuration. The low 16 bits ride in the node aux. +enum class kind : std::uint32_t +{ + proj5 = 1, + proj17, + proj64, + mul5, + mul7, + mul11, + thresh8, + thresh16, + chain7, + yao_if4, + yao_if16, + yao_hot4, + yao_hot8, + flute2, + flute4, + flute8, + flute4x8, + shuf16, + shuf64, + shuf256 +}; + +inline constexpr std::uint32_t aux_pass(kind k, unsigned pass) noexcept +{ + return static_cast(k) | (static_cast(pass) << 16); +} + +inline kind kind_of(std::uint32_t aux) noexcept +{ + return static_cast(aux & 0xffffu); +} + +inline unsigned pass_of(std::uint32_t aux) noexcept +{ + return aux >> 16; +} + +inline bool is_shuffle(kind k) noexcept +{ + return k == kind::shuf16 || k == kind::shuf64 || k == kind::shuf256; +} + +inline std::size_t shuffle_n(kind k) +{ + if (k == kind::shuf16) + return 16; + if (k == kind::shuf64) + return 64; + if (k == kind::shuf256) + return 256; + throw std::invalid_argument("bench: shuffle cell"); +} + +namespace detail +{ + +inline dpf::yao::netlist and_n(unsigned n) +{ + dpf::yao::netlist nl; + std::vector in; + for (unsigned i = 0; i < n; ++i) + in.push_back(nl.shared_in()); + auto acc = in[0]; + for (unsigned i = 1; i < n; ++i) + acc = nl.and_(acc, in[i]); + nl.out(acc); + return nl; +} + +inline dpf::yao::netlist xor2() +{ + dpf::yao::netlist nl; + auto a = nl.shared_in(); + auto b = nl.shared_in(); + nl.out(nl.xor_(a, b)); + return nl; +} + +inline std::uint64_t mix_bytes(const std::uint8_t * p, std::size_t n) +{ + std::uint64_t h = 14695981039346656037ull; + for (std::size_t i = 0; i < n; ++i) + { + h ^= p[i]; + h *= 1099511628211ull; + } + return h; +} + +inline void paint(std::uint8_t * out, std::size_t n, std::uint64_t mix) +{ + for (std::size_t i = 0; i < n; i += 8) + { + const std::uint64_t w = mix + static_cast(i); + const std::size_t k = std::min(8, n - i); + std::memcpy(out + i, &w, k); + } +} + +inline std::size_t proj_bytes(std::uint16_t mod) +{ + arith_garble::circuit c; + auto x = c.input(mod); + std::vector id(mod); + for (std::uint16_t i = 0; i < mod; ++i) + id[i] = i; + c.out(c.project(x, mod, std::move(id))); + const std::uint16_t in = 1; + return std::max( + 32, dpf::arith_garble::eval_pair(c, &in).ciphertext_rows * 32u); +} + +inline std::size_t mul_bytes(std::uint16_t p) +{ + arith_garble::circuit c; + auto x = c.input(p); + auto y = c.input(p); + c.out(c.mul(x, y)); + const std::uint16_t in[2] = {1, 1}; + return std::max( + 32, dpf::arith_garble::eval_pair(c, in).ciphertext_rows * 32u); +} + +inline std::size_t thresh_bytes(unsigned b) +{ + arith_garble::circuit c; + std::vector bits; + const auto mod = static_cast(b + 1); + for (unsigned i = 0; i < b; ++i) + bits.push_back(c.input(mod)); + c.out(c.threshold(bits, static_cast(b))); + std::vector in(b, 1); + return std::max( + 32, dpf::arith_garble::eval_pair(c, in.data()).ciphertext_rows * 32u); +} + +inline std::size_t chain_bytes() +{ + arith_garble::circuit c; + auto x = c.input(7); + auto y = c.input(7); + auto z = c.mul(x, y); + for (int i = 0; i < 3; ++i) + z = c.mul(z, x); + c.out(z); + const std::uint16_t in[2] = {2, 3}; + return std::max( + 32, dpf::arith_garble::eval_pair(c, in).ciphertext_rows * 32u); +} + +inline std::uint64_t run_proj(std::uint16_t mod) +{ + arith_garble::circuit c; + auto x = c.input(mod); + std::vector id(mod); + for (std::uint16_t i = 0; i < mod; ++i) + id[i] = static_cast((i * 3) % mod); + c.out(c.project(x, mod, std::move(id))); + const std::uint16_t in = static_cast(mod / 2); + auto got = dpf::arith_garble::eval_pair(c, &in); + return got.opened.empty() ? 0 : got.opened[0]; +} + +inline std::uint64_t run_mul(std::uint16_t p) +{ + arith_garble::circuit c; + auto x = c.input(p); + auto y = c.input(p); + c.out(c.mul(x, y)); + const std::uint16_t in[2] = {static_cast(p - 1), 2}; + auto got = dpf::arith_garble::eval_pair(c, in); + return got.opened.empty() ? 0 : got.opened[0]; +} + +inline std::uint64_t run_thresh(unsigned b) +{ + arith_garble::circuit c; + std::vector bits; + const auto mod = static_cast(b + 1); + for (unsigned i = 0; i < b; ++i) + bits.push_back(c.input(mod)); + c.out(c.threshold(bits, static_cast(b / 2))); + std::vector in(b, 0); + for (unsigned i = 0; i < b; i += 2) + in[i] = 1; + auto got = dpf::arith_garble::eval_pair(c, in.data()); + return got.opened.empty() ? 0 : got.opened[0]; +} + +inline std::uint64_t run_chain() +{ + arith_garble::circuit c; + auto x = c.input(7); + auto y = c.input(7); + auto z = c.mul(x, y); + for (int i = 0; i < 3; ++i) + z = c.mul(z, x); + c.out(z); + const std::uint16_t in[2] = {2, 3}; + auto got = dpf::arith_garble::eval_pair(c, in); + return got.opened.empty() ? 0 : got.opened[0]; +} + +inline std::size_t yao_if_bytes(unsigned heavy, unsigned light) +{ + std::vector h(heavy, 1), l(light, 1); + auto got = dpf::yao::eval_if(and_n(heavy), and_n(light), 0, 0, h.data(), + h.data(), l.data(), l.data()); + return std::max( + 16, (got.stack_blocks + got.extra_blocks) * 16u); +} + +inline std::uint64_t run_if(unsigned heavy, unsigned light) +{ + std::vector h0(heavy, 1), h1(heavy, 0), l0(light, 1), l1(light, 1); + auto got = dpf::yao::eval_if(and_n(heavy), and_n(light), 1, 0, h0.data(), + h1.data(), l0.data(), l1.data()); + return got.share0.empty() + ? 0 + : static_cast(got.share0[0] ^ got.share1[0]); +} + +inline std::size_t yao_hot_bytes(unsigned k) +{ + std::vector br; + std::vector> p0, p1; + for (unsigned i = 0; i < k; ++i) + { + br.push_back(i % 2 == 0 ? and_n(2) : xor2()); + p0.push_back({1, 1}); + p1.push_back({0, 0}); + } + auto got = dpf::yao::eval_one_hot(br, 1, 0, p0, p1); + return std::max( + 16, (got.stack_blocks + got.extra_blocks) * 16u); +} + +inline std::uint64_t run_hot(unsigned k) +{ + std::vector br; + std::vector> p0, p1; + for (unsigned i = 0; i < k; ++i) + { + br.push_back(i % 2 == 0 ? and_n(2) : xor2()); + p0.push_back({1, static_cast(i & 1u)}); + p1.push_back({0, 1}); + } + auto got = dpf::yao::eval_one_hot(br, 1, 2, p0, p1); + return got.share0.empty() + ? 0 + : static_cast(got.share0[0] ^ got.share1[0]); +} + +inline std::uint64_t run_flute(unsigned delta, unsigned n_out) +{ + const unsigned rows = 1u << delta; + std::vector columns(static_cast(n_out) * rows); + for (unsigned w = 0; w < n_out; ++w) + for (unsigned j = 0; j < rows; ++j) + columns[static_cast(w) * rows + j] = + static_cast(((j >> (w % delta)) ^ w) & 1u); + std::vector bits(delta, 0); + bits[0] = 1; + if (delta > 2) + bits[2] = 1; + auto got = dpf::flute::eval_pair(delta, n_out, columns.data(), bits.data()); + std::uint64_t mix = 0; + for (auto b : got.opened) + mix = (mix << 1) | b; + return mix; +} + +inline rss::seed_bundle fixed_bundle() +{ + rss::seed_bundle b{}; + auto fill = [](rss::seed_block & s, std::uint8_t tag) { + auto * p = reinterpret_cast(&s); + for (std::size_t i = 0; i < sizeof(s); ++i) + p[i] = static_cast(tag + i * 17u); + }; + fill(b.k01, 1); + fill(b.k12, 2); + fill(b.k20, 3); + return b; +} + +inline void shuffle_outbound(unsigned me, unsigned pass, std::size_t n, + std::uint8_t * out, std::size_t out_n) +{ + if (out_n != n * sizeof(std::uint64_t)) + throw std::logic_error("bench shuffle slot"); + const unsigned order[3] = {2u, 0u, 1u}; + const unsigned left = order[pass]; + if (me == left) + { + std::memset(out, 0, out_n); + return; + } + const auto bundle = fixed_bundle(); + std::vector column(n); + std::iota(column.begin(), column.end(), 0); + shuffle::shuffle_party_view held[3]; + for (unsigned p = 0; p < 3; ++p) + { + held[p].own.assign(n, 0); + held[p].next.assign(n, 0); + } + std::uint64_t rng = 0xA5A5A5A5A5A5A5A5ull; + auto draw = [&] { + rng = rng * 6364136223846793005ull + 1u; + return rng; + }; + for (std::size_t i = 0; i < n; ++i) + { + const auto a = draw(); + const auto b = draw(); + const auto c = column[i] - a - b; + held[0].own[i] = a; + held[0].next[i] = b; + held[1].own[i] = b; + held[1].next[i] = c; + held[2].own[i] = c; + held[2].next[i] = a; + } + for (unsigned step = 0; step <= pass; ++step) + { + const unsigned L = order[step]; + const unsigned u = shuffle::hidden_u_party(L); + const unsigned side = shuffle::hidden_side_party(L); + auto u_step = shuffle::shuffle_hidden_pass( + u, rss::party_seeds::from_bundle(bundle, u), held[u], 0, L, nullptr); + auto s_step = shuffle::shuffle_hidden_pass(side, + rss::party_seeds::from_bundle(bundle, side), held[side], 0, L, + &u_step.out.data); + std::vector side_msg = s_step.out.data; + auto l_step = shuffle::shuffle_hidden_pass(L, + rss::party_seeds::from_bundle(bundle, L), held[L], 0, L, &side_msg); + if (step == pass) + { + const auto & msg = (me == u) ? u_step.out.data : s_step.out.data; + std::memcpy(out, msg.data(), out_n); + } + held[u] = std::move(u_step.view); + held[side] = std::move(s_step.view); + held[L] = std::move(l_step.view); + } +} + +inline std::uint64_t heavy(kind k) +{ + switch (k) + { + case kind::proj5: + return run_proj(5); + case kind::proj17: + return run_proj(17); + case kind::proj64: + return run_proj(64); + case kind::mul5: + return run_mul(5); + case kind::mul7: + return run_mul(7); + case kind::mul11: + return run_mul(11); + case kind::thresh8: + return run_thresh(8); + case kind::thresh16: + return run_thresh(16); + case kind::chain7: + return run_chain(); + case kind::yao_if4: + return run_if(4, 2); + case kind::yao_if16: + return run_if(16, 8); + case kind::yao_hot4: + return run_hot(4); + case kind::yao_hot8: + return run_hot(8); + case kind::flute2: + return run_flute(2, 1); + case kind::flute4: + return run_flute(4, 1); + case kind::flute8: + return run_flute(8, 1); + case kind::flute4x8: + return run_flute(4, 8); + default: + return 0; + } +} + +inline std::size_t payload_of(kind k) +{ + switch (k) + { + case kind::proj5: + return proj_bytes(5); + case kind::proj17: + return proj_bytes(17); + case kind::proj64: + return proj_bytes(64); + case kind::mul5: + return mul_bytes(5); + case kind::mul7: + return mul_bytes(7); + case kind::mul11: + return mul_bytes(11); + case kind::thresh8: + return thresh_bytes(8); + case kind::thresh16: + return thresh_bytes(16); + case kind::chain7: + return chain_bytes(); + case kind::yao_if4: + return yao_if_bytes(4, 2); + case kind::yao_if16: + return yao_if_bytes(16, 8); + case kind::yao_hot4: + return yao_hot_bytes(4); + case kind::yao_hot8: + return yao_hot_bytes(8); + case kind::flute2: + case kind::flute4: + case kind::flute8: + return 8; + case kind::flute4x8: + return 16; + case kind::shuf16: + return 16 * sizeof(std::uint64_t); + case kind::shuf64: + return 64 * sizeof(std::uint64_t); + case kind::shuf256: + return 256 * sizeof(std::uint64_t); + } + throw std::invalid_argument("bench: cell"); +} + +inline protocol::plan peer_plan(std::size_t, kind k) +{ + protocol::composer c(0); + auto done = c.bench_peer(static_cast(k), payload_of(k)); + (void)done; + return c.default_plan(); +} + +inline protocol::plan ring_plan(std::size_t, kind k) +{ + protocol::composer c(0); + auto done = c.bench_ring(static_cast(k), payload_of(k)); + (void)done; + return c.default_plan(); +} + +} // namespace detail + +struct cell +{ + const char * name; + int parties; + kind id; +}; + +/// @brief The battery. Secret indexes stay on the DPF plans beside these. +inline std::vector battery() +{ + return { + {"arith_proj_m5", 2, kind::proj5}, + {"arith_proj_m17", 2, kind::proj17}, + {"arith_proj_m64", 2, kind::proj64}, + {"arith_mul_p5", 2, kind::mul5}, + {"arith_mul_p7", 2, kind::mul7}, + {"arith_mul_p11", 2, kind::mul11}, + {"arith_thresh_b8", 2, kind::thresh8}, + {"arith_thresh_b16", 2, kind::thresh16}, + {"arith_chain_mul4", 2, kind::chain7}, + {"yao_if_4_2", 2, kind::yao_if4}, + {"yao_if_16_8", 2, kind::yao_if16}, + {"yao_onehot_k4", 2, kind::yao_hot4}, + {"yao_onehot_k8", 2, kind::yao_hot8}, + {"flute_d2", 2, kind::flute2}, + {"flute_d4", 2, kind::flute4}, + {"flute_d8", 2, kind::flute8}, + {"flute_d4_o8", 2, kind::flute4x8}, + {"shuffle_n16", 3, kind::shuf16}, + {"shuffle_n64", 3, kind::shuf64}, + {"shuffle_n256", 3, kind::shuf256}, + }; +} + +inline protocol::plan plan_for(std::size_t party, kind id) +{ + if (is_shuffle(id)) + return detail::ring_plan(party, id); + return detail::peer_plan(party, id); +} + +/// @brief Local half of a cell. Party 0 emits the payload. Party 1 applies it. +/// Every shuffle party emits its own ring slot. +inline void run_cell(std::uint32_t opcode, std::size_t party, std::uint32_t aux, + std::uint8_t * out, std::size_t out_n) +{ + if (out == nullptr && out_n != 0) + throw std::invalid_argument("bench cell buffer"); + const auto k = kind_of(aux); + if (is_shuffle(k)) + { + if (opcode != protocol::opcodes::bench_emit) + return; + detail::shuffle_outbound(static_cast(party), pass_of(aux), + shuffle_n(k), out, out_n); + return; + } + if (opcode == protocol::opcodes::bench_apply) + { + if (party != 1) + { + if (out_n != 0) + out[0] = 0; + return; + } + const auto mix = detail::heavy(k); + if (out_n >= sizeof(mix)) + std::memcpy(out, &mix, sizeof(mix)); + return; + } + if (party != 0) + { + if (out_n != 0) + std::memset(out, 0, out_n); + return; + } + detail::paint(out, out_n, detail::heavy(k)); +} + +} // namespace bench +} // namespace dpf + +#endif diff --git a/include/dpf/bit.hpp b/include/dpf/bit.hpp index 0ed00e6..b6eaf0e 100644 --- a/include/dpf/bit.hpp +++ b/include/dpf/bit.hpp @@ -15,7 +15,7 @@ /// @author Ryan Henry /// @copyright Copyright (c) 2019-2024 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license; -/// see [LICENSE.md](@ref license) for details. +/// see LICENSE.md for details. #ifndef LIBDPF_INCLUDE_DPF_BIT_HPP__ #define LIBDPF_INCLUDE_DPF_BIT_HPP__ @@ -38,6 +38,14 @@ namespace dpf { /// @brief binary type whose representation can be packed into one bit +/// @note Not a DPF domain. `msb_of` does not compile. A 1-bit +/// index is `dpf::modint<1>` or `dpf::xint<1>`. Leaf `+` and `-` are +/// XOR. Lanes pack low-bit first. +/// @see dpf::twobit +/// @see dpf::nyble +/// @see dpf::modint +/// @see dpf::xint +/// @see output_types enum bit : bool { zero = false, ///< `0`, `false`, "unset", "off" @@ -225,6 +233,10 @@ struct bitlength_of_output template <> struct is_packed_subbyte : std::true_type {}; +/// @brief Packed bits add by XOR (`bit::one + bit::one == bit::zero`). +template <> +struct has_characteristic_two : std::true_type {}; + template <> struct packed_lane_bits : public std::integral_constant {}; diff --git a/include/dpf/bit_array.hpp b/include/dpf/bit_array.hpp index 5b31ae0..84e33ab 100644 --- a/include/dpf/bit_array.hpp +++ b/include/dpf/bit_array.hpp @@ -43,6 +43,7 @@ template HEDLEY_NO_THROW constexpr void check_one_bit(Word mask) noexcept { + (void)mask; #if defined(__GNUC__) || defined(__clang__) if (__builtin_is_constant_evaluated()) return; #endif diff --git a/include/dpf/bit_inject.hpp b/include/dpf/bit_inject.hpp new file mode 100644 index 0000000..e1eb811 --- /dev/null +++ b/include/dpf/bit_inject.hpp @@ -0,0 +1,77 @@ +/// @file dpf/bit_inject.hpp +/// @brief Boolean bit × arithmetic value (2PC bit_mul and 3PC RSS injection). +#ifndef LIBDPF_INCLUDE_DPF_BIT_INJECT_HPP__ +#define LIBDPF_INCLUDE_DPF_BIT_INJECT_HPP__ + +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/beaver.hpp" +#include "dpf/rss_seed.hpp" +#include "dpf/secret_share.hpp" + +namespace dpf +{ +namespace bit_inject +{ + +/// @brief 2PC: `b * x` via a beaver bit_mul on an existing session. +template +HEDLEY_WARN_UNUSED_RESULT +beavers::wire inject2(beavers::session & s, + beavers::wire bit_wire, beavers::wire arith_wire) +{ + return s.bit_mul(bit_wire, arith_wire); +} + +/// @brief Local y-factor of RSS bit injection before ring send. +/// @details Party holds RSS bit `(b_own, b_next)` and arithmetic `(x_own, x_next)`. +/// Local contribution mirrors RSS mul with the bit as a 0/1 factor. +template +HEDLEY_WARN_UNUSED_RESULT +T rss_inject_local(const rss::party_seeds & seeds, T b_own, T b_next, + T x_own, T x_next, std::uint64_t index) +{ + // Treat bit components as ring elements in {0,1}. + return rss::rss_mul_local(seeds, b_own, b_next, x_own, x_next, index); +} + +/// @brief After ring refresh: party receives `y_prev` and forms RSS `(y_own, y_prev)` +/// wait — standard RSS refresh: send y_own to next, receive from prev, +/// store `(y_own, y_from_prev)`? Actually ABY3: party i holds y_i after +/// local mul; sends y_i to party i-1; ends with (y_i, y_{i+1}). +template +HEDLEY_WARN_UNUSED_RESULT +std::pair rss_refresh(T y_own, T y_from_next) +{ + return {y_own, y_from_next}; +} + +/// @brief Cleartext identity: `(b0⊕b1) * (x0+x1)`. +template +HEDLEY_WARN_UNUSED_RESULT +Ring inject_clear(std::uint8_t b0, std::uint8_t b1, Ring x0, Ring x1) +{ + const Ring b = static_cast((b0 ^ b1) & 1u); + return static_cast(b * (x0 + x1)); +} + +/// @brief Boolean RSS AND local factor (GF(2)). +inline std::uint8_t rss_and_local(const rss::party_seeds & seeds, + std::uint8_t a_own, std::uint8_t a_next, std::uint8_t b_own, + std::uint8_t b_next, std::uint64_t index) +{ + const std::uint8_t cross = static_cast( + (a_own & b_own) ^ (a_own & b_next) ^ (a_next & b_own)); + const std::uint8_t mask = static_cast( + rss::zero_share(seeds, index) & 1u); + return static_cast(cross ^ mask); +} + +} // namespace bit_inject +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_BIT_INJECT_HPP__ diff --git a/include/dpf/bitmore_mod.hpp b/include/dpf/bitmore_mod.hpp new file mode 100644 index 0000000..8d806fe --- /dev/null +++ b/include/dpf/bitmore_mod.hpp @@ -0,0 +1,781 @@ +/// @file dpf/bitmore_mod.hpp +/// @brief Byte-slot reduction for BitMore moduli through 255. +/// @details Hafiz and Henry (PoPETs 2019 §5.3) fold each server's DPF bits +/// into an integer and reduce modulo the server count. When that +/// count is not a power of two the integer does not fit in a byte +/// for long, so each byte is only partially reduced until the end. +/// +/// A partial step reads the high nibble `h`. Every byte with that +/// nibble is at least `16*h`, so `floor(16*h / M) * M` is the largest +/// multiple of `M` that is safe to subtract. `pshufb` selects it and +/// `sub_epi8` removes it. The byte stays congruent modulo `M` and is +/// at most `partial_bound`. For moduli 121..127 that ceiling is 128 +/// or more, so a second partial step is what leaves `stable_bound` +/// (at most 127). `resume_bound` is the ceiling the accumulator +/// actually resumes from: one step through modulus 120 and 128, two +/// steps for 121..127. +/// +/// `add_budget = 255 - resume_bound` is how much can still be added +/// before a byte might reach 256. `shift_budget` is how many +/// `2*acc + bit` insertions fit in that slack. Both stay positive +/// through modulus 128, which is as far as a byte can hold two +/// resumed slots or one more bit. `partial_reduce` and `full_reduce` +/// themselves stay correct through 255: the two nibble residues sum +/// to at most 255 and to less than `2*M`, and one unsigned compare +/// subtracts `M`. Above 128 there is no slack left to defer that +/// correction across another add. +/// +/// `bitmore_mod` is the same idea on 16-bit lanes, still on +/// AVX2. The top nibble (bits 12..15) selects `floor(4096*h / M)*M` +/// through two `pshufb`s, one per byte of that multiple, and +/// `sub_epi16` removes it. The accumulator has slack through modulus +/// 32768 (`resume_bound` at most 32767, so one more bit fits in the +/// lane). A full reduction sums the four nibble residues, which fit +/// in the lane for every modulus through 65535, then subtracts `M` +/// up to three times. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_BITMORE_MOD_HPP__ +#define LIBDPF_INCLUDE_DPF_BITMORE_MOD_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" +#include "simde/simde/x86/avx2.h" + +namespace dpf +{ +namespace bitmore_detail +{ + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg zero() noexcept +{ + if constexpr (std::is_same_v) + return simde_mm256_setzero_si256(); + else + return simde_mm_setzero_si128(); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg load_lut(const std::array & lut) noexcept +{ + if constexpr (std::is_same_v) + { + simde__m128i table; + std::memcpy(&table, lut.data(), 16); + return table; + } + else + { + alignas(32) unsigned char both[32]; + std::memcpy(both, lut.data(), 16); + std::memcpy(both + 16, lut.data(), 16); + simde__m256i table; + std::memcpy(&table, both, 32); + return table; + } +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg high_nibble(Reg x) noexcept +{ + // `srli_epi16` moves the neighbouring byte's low nibble into bits 4..7. + // Masking with `0x0f` leaves this byte's own high nibble. + if constexpr (std::is_same_v) + { + const auto m = simde_mm_set1_epi8(0x0f); + return simde_mm_and_si128(simde_mm_srli_epi16(x, 4), m); + } + else + { + const auto m = simde_mm256_set1_epi8(0x0f); + return simde_mm256_and_si256(simde_mm256_srli_epi16(x, 4), m); + } +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg low_nibble(Reg x) noexcept +{ + if constexpr (std::is_same_v) + return simde_mm_and_si128(x, simde_mm_set1_epi8(0x0f)); + else + return simde_mm256_and_si256(x, simde_mm256_set1_epi8(0x0f)); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg shuffle(Reg table, Reg index) noexcept +{ + if constexpr (std::is_same_v) + return simde_mm_shuffle_epi8(table, index); + else + return simde_mm256_shuffle_epi8(table, index); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg add_bytes(Reg a, Reg b) noexcept +{ + if constexpr (std::is_same_v) + return simde_mm_add_epi8(a, b); + else + return simde_mm256_add_epi8(a, b); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg sub_bytes(Reg a, Reg b) noexcept +{ + if constexpr (std::is_same_v) + return simde_mm_sub_epi8(a, b); + else + return simde_mm256_sub_epi8(a, b); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg and_bytes(Reg a, Reg b) noexcept +{ + if constexpr (std::is_same_v) + return simde_mm_and_si128(a, b); + else + return simde_mm256_and_si256(a, b); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg xor_bytes(Reg a, Reg b) noexcept +{ + if constexpr (std::is_same_v) + return simde_mm_xor_si128(a, b); + else + return simde_mm256_xor_si256(a, b); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg splat_epi8(unsigned char v) noexcept +{ + const auto s = static_cast(v); + if constexpr (std::is_same_v) + return simde_mm_set1_epi8(s); + else + return simde_mm256_set1_epi8(s); +} + +/// @brief Unsigned `a > b` per byte. `cmpgt_epi8` is signed; XOR `0x80` maps +/// unsigned order onto that signed order. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg cmpgt_epu8(Reg a, Reg b) noexcept +{ + const auto bias = splat_epi8(0x80); + const auto aa = xor_bytes(a, bias); + const auto bb = xor_bytes(b, bias); + if constexpr (std::is_same_v) + return simde_mm_cmpgt_epi8(aa, bb); + else + return simde_mm256_cmpgt_epi8(aa, bb); +} + +/// @brief Shift each byte left by 1 and set bit 0 from `bit`. +/// @details `slli_epi16` spills bit 7 into the next byte of the 16-bit lane. +/// Clearing bit 0 afterwards drops that spill. Bit 7 of the odd byte +/// shifts out of the lane, which is the byte-local shift. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg shift_in_bit(Reg acc, Reg bit) noexcept +{ + const auto one = splat_epi8(1); + const auto keep = splat_epi8(0xfe); + bit = and_bytes(bit, one); + Reg shifted; + if constexpr (std::is_same_v) + shifted = simde_mm_and_si128(simde_mm_slli_epi16(acc, 1), keep); + else + shifted = simde_mm256_and_si256(simde_mm256_slli_epi16(acc, 1), keep); + if constexpr (std::is_same_v) + return simde_mm_or_si128(shifted, bit); + else + return simde_mm256_or_si256(shifted, bit); +} + +template +HEDLEY_CONST +constexpr unsigned partial_bound() noexcept +{ + static_assert(LaneBits == 8u || LaneBits == 16u, "bitmore lane width is 8 or 16"); + constexpr unsigned block = LaneBits == 8u ? 16u : 4096u; + constexpr unsigned tail = block - 1u; + unsigned u = 0; + for (unsigned h = 0; h < 16u; ++h) + { + const unsigned q = (block * h / Modulus) * Modulus; + const unsigned top = block * h + tail - q; + if (top > u) + u = top; + } + return u; +} + +template +HEDLEY_CONST +constexpr unsigned stable_bound() noexcept +{ + constexpr unsigned block = LaneBits == 8u ? 16u : 4096u; + const unsigned lim = partial_bound(); + unsigned u = 0; + for (unsigned h = 0; h < 16u; ++h) + { + const unsigned lo = block * h; + if (lo > lim) + break; + unsigned hi = lo + block - 1u; + if (hi > lim) + hi = lim; + const unsigned q = (lo / Modulus) * Modulus; + const unsigned top = hi - q; + if (top > u) + u = top; + } + return u; +} + +template +HEDLEY_CONST +constexpr unsigned shift_budget(unsigned bound, unsigned capacity = 256u) noexcept +{ + unsigned k = 0; + unsigned span = bound + 1u; + const unsigned half = capacity >> 1; + while (span <= half) + { + span *= 2u; + ++k; + } + return k; +} + +template +HEDLEY_CONST +constexpr std::array partial_lut() noexcept +{ + std::array lut{}; + for (unsigned h = 0; h < 16u; ++h) + lut[h] = static_cast((16u * h / Modulus) * Modulus); + return lut; +} + +template +HEDLEY_CONST +constexpr std::array low_residue_lut() noexcept +{ + std::array lut{}; + for (unsigned n = 0; n < 16u; ++n) + lut[n] = static_cast(n % Modulus); + return lut; +} + +template +HEDLEY_CONST +constexpr std::array high_residue_lut() noexcept +{ + std::array lut{}; + for (unsigned h = 0; h < 16u; ++h) + lut[h] = static_cast((16u * h) % Modulus); + return lut; +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg splat_epi16(unsigned v) noexcept +{ + const auto s = static_cast(static_cast(v)); + if constexpr (std::is_same_v) + return simde_mm_set1_epi16(s); + else + return simde_mm256_set1_epi16(s); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg add_epi16(Reg a, Reg b) noexcept +{ + if constexpr (std::is_same_v) + return simde_mm_add_epi16(a, b); + else + return simde_mm256_add_epi16(a, b); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg sub_epi16(Reg a, Reg b) noexcept +{ + if constexpr (std::is_same_v) + return simde_mm_sub_epi16(a, b); + else + return simde_mm256_sub_epi16(a, b); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg srli_epi16(Reg a, int imm) noexcept +{ + if constexpr (std::is_same_v) + return simde_mm_srli_epi16(a, imm); + else + return simde_mm256_srli_epi16(a, imm); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg slli_epi16(Reg a, int imm) noexcept +{ + if constexpr (std::is_same_v) + return simde_mm_slli_epi16(a, imm); + else + return simde_mm256_slli_epi16(a, imm); +} + +/// @brief Unsigned `a > b` per 16-bit lane. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg cmpgt_epu16(Reg a, Reg b) noexcept +{ + const auto bias = splat_epi16(0x8000u); + const auto aa = xor_bytes(a, bias); + const auto bb = xor_bytes(b, bias); + if constexpr (std::is_same_v) + return simde_mm_cmpgt_epi16(aa, bb); + else + return simde_mm256_cmpgt_epi16(aa, bb); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg or_bytes(Reg a, Reg b) noexcept +{ + if constexpr (std::is_same_v) + return simde_mm_or_si128(a, b); + else + return simde_mm256_or_si256(a, b); +} + +/// @brief Look up a 16-bit table entry. `idx` holds the nibble in the low byte +/// of each lane and zero in the high byte, so `pshufb` writes `lut[h]` +/// into the low byte and `lut[0]` into the high byte. `lut[0]` is 0. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg lookup_u16(Reg idx, const std::array & lo, + const std::array & hi) noexcept +{ + const auto lo_v = shuffle(load_lut(lo), idx); + const auto hi_v = slli_epi16(shuffle(load_lut(hi), idx), 8); + return or_bytes(lo_v, hi_v); +} + +constexpr std::array u16_lo(const std::array & v) noexcept +{ + std::array out{}; + for (unsigned i = 0; i < 16u; ++i) + out[i] = static_cast(v[i] & 0xffu); + return out; +} + +constexpr std::array u16_hi(const std::array & v) noexcept +{ + std::array out{}; + for (unsigned i = 0; i < 16u; ++i) + out[i] = static_cast(v[i] >> 8); + return out; +} + +template +HEDLEY_CONST +constexpr std::array wide_partial_lut() noexcept +{ + std::array lut{}; + for (unsigned h = 0; h < 16u; ++h) + lut[h] = static_cast((4096u * h / Modulus) * Modulus); + return lut; +} + +template +HEDLEY_CONST +constexpr std::array wide_residue_lut() noexcept +{ + std::array lut{}; + for (unsigned n = 0; n < 16u; ++n) + lut[n] = static_cast( + (static_cast(Place) * n) % Modulus); + return lut; +} + +/// @brief `acc = 2*acc + bit0` inside each 16-bit lane. `slli_epi16` does not +/// cross lanes. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +Reg shift_in_bit16(Reg acc, Reg bit) noexcept +{ + const auto one = splat_epi16(1u); + bit = and_bytes(bit, one); + if constexpr (std::is_same_v) + return simde_mm_or_si128(simde_mm_slli_epi16(acc, 1), bit); + else + return simde_mm256_or_si256(simde_mm256_slli_epi16(acc, 1), bit); +} + +} // namespace bitmore_detail + +/// @brief Partial and full reduction of `LaneBits`-wide slots modulo `Modulus`. +/// @tparam Modulus server count. `2` through `255` for bytes, `2` through `65535` for 16-bit lanes. +/// @tparam LaneBits `8` (one byte per slot) or `16` (one AVX2 `epi16` lane per slot) +template +struct bitmore_mod +{ + static_assert(LaneBits == 8u || LaneBits == 16u, + "bitmore lane width is 8 or 16"); + static_assert(Modulus >= 2u, "bitmore modulus must be at least 2"); + static_assert(LaneBits == 16u || Modulus <= 255u, + "bitmore byte reduction: modulus must be in 2..255"); + static_assert(LaneBits == 8u || Modulus <= 65535u, + "bitmore 16-bit reduction: modulus must be in 2..65535"); + + static constexpr unsigned modulus = Modulus; + static constexpr unsigned lane_bits = LaneBits; + static constexpr unsigned slot_max = LaneBits == 8u ? 255u : 65535u; + static constexpr unsigned nibble_block = LaneBits == 8u ? 16u : 4096u; + static constexpr unsigned nibble_shift = LaneBits == 8u ? 4u : 12u; + + /// @brief Largest slot one top-nibble partial reduction can leave. + static constexpr unsigned partial_bound = bitmore_detail::partial_bound(); + + /// @brief Largest slot a second partial step can leave, starting from `partial_bound`. + static constexpr unsigned stable_bound = bitmore_detail::stable_bound(); + + /// @brief Ceiling the accumulator resumes from. One step when that already + /// fits in the lower half of the lane; otherwise the second step. + static constexpr unsigned resume_bound = + partial_bound <= (slot_max >> 1) ? partial_bound : stable_bound; + + /// @brief How much can be added to a resumed slot before it might reach `slot_max + 1`. + static constexpr unsigned add_budget = slot_max - resume_bound; + + /// @brief Bit insertions that fit in `add_budget` after resuming. + static constexpr unsigned shift_budget = + bitmore_detail::shift_budget(resume_bound, slot_max + 1u); + + /// @brief `x - floor(block*(x>>shift) / M) * M` inside one slot. + /// \complexity One division of a nibble index. + HEDLEY_CONST + HEDLEY_ALWAYS_INLINE + static constexpr unsigned partial_reduce_slot(unsigned x) noexcept + { + x &= slot_max; + const unsigned h = x >> nibble_shift; + const unsigned q = (nibble_block * h / Modulus) * Modulus; + return x - q; + } + + /// @brief Byte-slot name for `partial_reduce_slot`. + HEDLEY_CONST + HEDLEY_ALWAYS_INLINE + static constexpr unsigned partial_reduce_byte(unsigned x) noexcept + { + static_assert(LaneBits == 8u, "partial_reduce_byte is the 8-bit slot"); + return partial_reduce_slot(x); + } + + /// @brief `x mod Modulus` for one slot. + /// \complexity One remainder of a slot. + HEDLEY_CONST + HEDLEY_ALWAYS_INLINE + static constexpr unsigned full_reduce_slot(unsigned x) noexcept + { + return (x & slot_max) % Modulus; + } + + /// @brief Byte-slot name for `full_reduce_slot`. + HEDLEY_CONST + HEDLEY_ALWAYS_INLINE + static constexpr unsigned full_reduce_byte(unsigned x) noexcept + { + static_assert(LaneBits == 8u, "full_reduce_byte is the 8-bit slot"); + return full_reduce_slot(x); + } + + /// @brief Partial-reduce every byte of `x`. + /// @details The high nibble selects `floor(16*h / M) * M`. Subtracting it + /// preserves the residue and leaves a byte of at most `partial_bound`. + /// \complexity One `pshufb` and one `sub_epi8` per register. + template + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + HEDLEY_PURE + static Reg partial_reduce(Reg x) noexcept + { + static_assert(std::is_same_v || std::is_same_v, + "bitmore partial_reduce: register must be simde__m128i or simde__m256i"); + if constexpr (LaneBits == 8u) + { + constexpr auto lut = bitmore_detail::partial_lut(); + const auto q = bitmore_detail::shuffle( + bitmore_detail::load_lut(lut), + bitmore_detail::high_nibble(x)); + return bitmore_detail::sub_bytes(x, q); + } + else + { + constexpr auto lut = bitmore_detail::wide_partial_lut(); + constexpr auto lo = bitmore_detail::u16_lo(lut); + constexpr auto hi = bitmore_detail::u16_hi(lut); + const auto idx = bitmore_detail::srli_epi16(x, 12); + const auto q = bitmore_detail::lookup_u16(idx, lo, hi); + return bitmore_detail::sub_epi16(x, q); + } + } + + /// @brief Fully reduce every byte of `x` into `0 .. Modulus-1`. + /// @details `pshufb` maps the low nibble to itself modulo `M` and the high + /// nibble to `(16*h) mod M`. The sum is less than `2*M`, so one + /// compare subtracts `M` where the sum is still too big. + /// \complexity Two `pshufb`s, one byte add, one compare, one byte subtract. + template + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + HEDLEY_PURE + static Reg full_reduce(Reg x) noexcept + { + static_assert(std::is_same_v || std::is_same_v, + "bitmore full_reduce: register must be simde__m128i or simde__m256i"); + if constexpr (LaneBits == 8u) + { + constexpr auto lo_lut = bitmore_detail::low_residue_lut(); + constexpr auto hi_lut = bitmore_detail::high_residue_lut(); + const auto lo = bitmore_detail::shuffle( + bitmore_detail::load_lut(lo_lut), + bitmore_detail::low_nibble(x)); + const auto hi = bitmore_detail::shuffle( + bitmore_detail::load_lut(hi_lut), + bitmore_detail::high_nibble(x)); + const auto sum = bitmore_detail::add_bytes(lo, hi); + // Sum of the two residues is at most 255 and less than `2*M`, so one + // subtraction finishes the byte. The compare is unsigned: for M > 120 + // the sum can exceed 127. + const auto limit = bitmore_detail::splat_epi8( + static_cast(Modulus - 1u)); + const auto ge = bitmore_detail::cmpgt_epu8(sum, limit); + const auto corr = bitmore_detail::and_bytes( + ge, bitmore_detail::splat_epi8(static_cast(Modulus))); + return bitmore_detail::sub_bytes(sum, corr); + } + else + { + // Four nibble residues, each `< M`. Their sum fits in a 16-bit lane + // for every modulus through 65535 and is less than `4*M`, so three + // conditional subtractions finish the lane. + constexpr auto r0 = bitmore_detail::wide_residue_lut(); + constexpr auto r1 = bitmore_detail::wide_residue_lut(); + constexpr auto r2 = bitmore_detail::wide_residue_lut(); + constexpr auto r3 = bitmore_detail::wide_residue_lut(); + constexpr auto r0_lo = bitmore_detail::u16_lo(r0); + constexpr auto r0_hi = bitmore_detail::u16_hi(r0); + constexpr auto r1_lo = bitmore_detail::u16_lo(r1); + constexpr auto r1_hi = bitmore_detail::u16_hi(r1); + constexpr auto r2_lo = bitmore_detail::u16_lo(r2); + constexpr auto r2_hi = bitmore_detail::u16_hi(r2); + constexpr auto r3_lo = bitmore_detail::u16_lo(r3); + constexpr auto r3_hi = bitmore_detail::u16_hi(r3); + const auto nib = bitmore_detail::splat_epi16(0x000fu); + const auto n0 = bitmore_detail::and_bytes(x, nib); + const auto n1 = bitmore_detail::and_bytes(bitmore_detail::srli_epi16(x, 4), nib); + const auto n2 = bitmore_detail::and_bytes(bitmore_detail::srli_epi16(x, 8), nib); + const auto n3 = bitmore_detail::srli_epi16(x, 12); + auto sum = bitmore_detail::lookup_u16(n0, r0_lo, r0_hi); + sum = bitmore_detail::add_epi16(sum, bitmore_detail::lookup_u16(n1, r1_lo, r1_hi)); + sum = bitmore_detail::add_epi16(sum, bitmore_detail::lookup_u16(n2, r2_lo, r2_hi)); + sum = bitmore_detail::add_epi16(sum, bitmore_detail::lookup_u16(n3, r3_lo, r3_hi)); + const auto limit = bitmore_detail::splat_epi16(Modulus - 1u); + const auto modv = bitmore_detail::splat_epi16(Modulus); + for (int step = 0; step < 3; ++step) + { + const auto ge = bitmore_detail::cmpgt_epu16(sum, limit); + const auto corr = bitmore_detail::and_bytes(ge, modv); + sum = bitmore_detail::sub_epi16(sum, corr); + } + return sum; + } + } +}; + +/// @brief Running slot sum modulo `Modulus`, partial-reduced on a budget. +/// @details `bound()` is a proven upper bound on every slot. An add whose +/// worst-case total would pass the lane maximum partial-reduces the +/// accumulator, then the addend. A modulus whose first partial step +/// still sets the high bit takes a second step before two slots fit +/// again. `insert_bit` is the MSB-first fold `acc = 2*acc + bit`. +/// `reduced()` is the full per-slot residue. The byte accumulator +/// stops at modulus 128 and the 16-bit accumulator at 32768; past +/// that a resumed slot no longer fits next to another or under a +/// shift. `partial_reduce` and `full_reduce` cover the wider ranges. +/// @tparam Modulus server count, `2` through `128` for bytes and `32768` for 16-bit lanes +/// @tparam Reg `simde__m128i` or `simde__m256i` +/// @tparam LaneBits `8` or `16` +template +class bitmore_accumulator +{ + using mod = bitmore_mod; + + static_assert(std::is_same_v || std::is_same_v, + "bitmore_accumulator: register must be simde__m128i or simde__m256i"); + static_assert((LaneBits == 8u && Modulus <= 128u) || (LaneBits == 16u && Modulus <= 32768u), + "bitmore_accumulator: no slack past modulus 128 in a byte or 32768 in a 16-bit slot"); + static_assert(mod::stable_bound <= (mod::slot_max >> 1), + "bitmore_accumulator: second partial step must leave room for one bit"); + static_assert(mod::stable_bound * 2u <= mod::slot_max, + "bitmore_accumulator: two resumed slots must fit in one lane"); + static_assert(mod::shift_budget >= 1u, + "bitmore_accumulator: at least one bit insertion after resuming"); + +public: + /// \complexity One zeroed register. + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + bitmore_accumulator() noexcept + : acc_(bitmore_detail::zero()), bound_(0) + { } + + /// @brief Proven upper bound on every slot in `value()`. + HEDLEY_PURE + HEDLEY_ALWAYS_INLINE + unsigned bound() const noexcept + { + return bound_; + } + + /// @brief Unreduced slots. Each is `≤ bound()` and congruent to the sum. + HEDLEY_ALWAYS_INLINE + Reg value() const noexcept + { + return acc_; + } + + /// @brief Add one slot. + /// @param x addends. Each slot must be `≤ addend_max`. + /// @param addend_max worst-case slot in `x`, clamped to `slot_max`. Pass + /// `slot_max` when the addend is an arbitrary lane; the accumulator + /// partial-reduces it if the slack cannot absorb that. + /// \complexity At most four partial reductions and one lane add. + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + void add(Reg x, unsigned addend_max) noexcept + { + if (addend_max > mod::slot_max) + addend_max = mod::slot_max; + for (;;) + { + if (bound_ + addend_max <= mod::slot_max) + break; + if (bound_ > mod::partial_bound) + { + acc_ = mod::partial_reduce(acc_); + bound_ = mod::partial_bound; + continue; + } + if (addend_max > mod::partial_bound) + { + x = mod::partial_reduce(x); + addend_max = mod::partial_bound; + continue; + } + if (bound_ > mod::stable_bound) + { + acc_ = mod::partial_reduce(acc_); + bound_ = mod::stable_bound; + continue; + } + if (addend_max > mod::stable_bound) + { + x = mod::partial_reduce(x); + addend_max = mod::stable_bound; + continue; + } + break; + } + if constexpr (LaneBits == 8u) + acc_ = bitmore_detail::add_bytes(acc_, x); + else + acc_ = bitmore_detail::add_epi16(acc_, x); + bound_ += addend_max; + } + + /// @brief Fold one BitMore bit: `acc = 2*acc + bit0` inside each slot. + /// @param bit bit 0 of each slot is the new low bit. Higher bits are ignored. + /// \complexity Up to two partial reductions when the proven bound sets the + /// lane's high bit, then a shift and an OR. + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + void insert_bit(Reg bit) noexcept + { + while (bound_ > (mod::slot_max >> 1)) + { + acc_ = mod::partial_reduce(acc_); + bound_ = bound_ > mod::partial_bound ? mod::partial_bound + : mod::stable_bound; + } + if constexpr (LaneBits == 8u) + acc_ = bitmore_detail::shift_in_bit(acc_, bit); + else + acc_ = bitmore_detail::shift_in_bit16(acc_, bit); + bound_ = bound_ * 2u + 1u; + } + + /// @brief Full residue of every slot, in `0 .. Modulus-1`. + /// \complexity One `full_reduce` of the register. + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + HEDLEY_PURE + Reg reduced() const noexcept + { + return mod::full_reduce(acc_); + } + +private: + Reg acc_; + unsigned bound_; +}; + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_BITMORE_MOD_HPP__ diff --git a/include/dpf/bitstring.hpp b/include/dpf/bitstring.hpp index 0c33ba4..d9c6921 100644 --- a/include/dpf/bitstring.hpp +++ b/include/dpf/bitstring.hpp @@ -130,7 +130,7 @@ class bitstring : public bit_array_base, WordT> HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW constexpr explicit bitstring(word_type val) noexcept - : data_{Nbits < bits_per_word ? static_cast(val & (static_cast(~word_type{0}) >> utils::bitlength_of_v - Nbits)) : val} { } + : data_{Nbits < bits_per_word ? static_cast(val & (static_cast(~word_type{0}) >> (utils::bitlength_of_v - Nbits))) : val} { } /// @brief Constructs a `dpf::bitstring` using the characters in the /// `std::basic_string` `str`. An optional starting position `pos` @@ -782,11 +782,22 @@ struct mod_pow_2> } }; +/// @brief Bitstrings add by XOR over their packed words. +template +struct has_characteristic_two> + : public std::true_type {}; + } // namespace utils namespace bitstrings { +/// @name bitN_t +/// @{ + +/// @brief `bitN_t` is `dpf::bitstring` for N from 1 through 128. Not `dpf::bit`. +/// @see dpf::bitstring +/// @see dpf::bit // 1--9 using bit1_t = dpf::bitstring<1>; using bit2_t = dpf::bitstring<2>; @@ -929,6 +940,8 @@ using bit126_t = dpf::bitstring<126>; using bit127_t = dpf::bitstring<127>; using bit128_t = dpf::bitstring<128>; +/// @} + namespace literals = dpf::literals::bitstrings; } // namespace bitstrings @@ -1008,6 +1021,11 @@ constexpr static auto operator "" _bitstring_u128() return bitstring_literal, bits...>(); } +/// @name bitstring literals `_bN` +/// @{ + +/// @brief Digit-string literal for `dpf::bitstring`. The first character is the high bit. +/// @see dpf::bitstring // 1--9 template constexpr static auto operator "" _b1() { return bitstring_literal, bits...>(); } template constexpr static auto operator "" _b2() { return bitstring_literal, bits...>(); } @@ -1150,6 +1168,8 @@ template constexpr static auto operator "" _b126() { return bitst template constexpr static auto operator "" _b127() { return bitstring_literal, bits...>(); } template constexpr static auto operator "" _b128() { return bitstring_literal, bits...>(); } +/// @} + } // namespace bitstrings } // namespace literals diff --git a/include/dpf/blob.hpp b/include/dpf/blob.hpp new file mode 100644 index 0000000..ac3e995 --- /dev/null +++ b/include/dpf/blob.hpp @@ -0,0 +1,149 @@ +/// @file dpf/blob.hpp +/// @brief Fixed-length XOR byte-string leaf (`dpf::blob`). +/// @details A mailbox row or other byte payload that does not fit in one AES +/// block. Keygen stretches each final seed with the exterior PRG +/// (counter mode) into `N` bytes and XORs a correction of that +/// length, matching Express's `genDPF` leaf. The tree and depth are +/// unchanged: Boyle packing uses `ceil(8N / λ)` exterior blocks and +/// `lg(outputs_per_leaf) = 0`. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_BLOB_HPP__ +#define LIBDPF_INCLUDE_DPF_BLOB_HPP__ + +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/utils.hpp" + +namespace dpf +{ + +/// @brief XOR share of an `N`-byte string. +/// @tparam N byte length (`N >= 1`) +template +struct blob +{ + static_assert(N >= 1, "dpf::blob: N must be at least 1"); + static constexpr std::size_t size = N; + std::array bytes{}; + + HEDLEY_NO_THROW + constexpr blob() noexcept = default; + + HEDLEY_NO_THROW + explicit blob(const unsigned char * src, std::size_t n = N) noexcept + { + const std::size_t m = n < N ? n : N; + if (m != 0) + std::memcpy(bytes.data(), src, m); + } + + HEDLEY_NO_THROW + explicit blob(std::array b) noexcept + : bytes{std::move(b)} + { } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + unsigned char * data() noexcept { return bytes.data(); } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + const unsigned char * data() const noexcept { return bytes.data(); } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + friend constexpr bool operator==(const blob & a, const blob & b) noexcept + { + for (std::size_t i = 0; i < N; ++i) + if (a.bytes[i] != b.bytes[i]) + return false; + return true; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + friend constexpr bool operator!=(const blob & a, const blob & b) noexcept + { + return !(a == b); + } + + /// @brief XOR (group addition / subtraction for this leaf). + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + friend blob operator^(const blob & a, const blob & b) noexcept + { + blob out; + for (std::size_t i = 0; i < N; ++i) + out.bytes[i] = static_cast(a.bytes[i] ^ b.bytes[i]); + return out; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + friend blob operator+(const blob & a, const blob & b) noexcept + { + return a ^ b; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + friend blob operator-(const blob & a, const blob & b) noexcept + { + return a ^ b; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + blob & operator^=(const blob & o) noexcept + { + *this = *this ^ o; + return *this; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + blob & operator+=(const blob & o) noexcept + { + return (*this) ^= o; + } +}; + +template +struct is_blob : std::false_type {}; +template +struct is_blob> : std::true_type {}; +template +inline constexpr bool is_blob_v = is_blob>::value; + +namespace utils +{ + +template +struct bitlength_of> + : public std::integral_constant +{ }; + +template +struct bitlength_of_output, NodeT> + : public std::integral_constant +{ }; + +template +struct has_characteristic_two> : std::true_type +{ }; + +template +struct is_xor_wrapper> : std::true_type +{ }; + +} // namespace utils +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_BLOB_HPP__ diff --git a/include/dpf/blocked_dcf.hpp b/include/dpf/blocked_dcf.hpp index 156636f..09bff78 100644 --- a/include/dpf/blocked_dcf.hpp +++ b/include/dpf/blocked_dcf.hpp @@ -5,6 +5,7 @@ /// up to the next checkpoint; a full-domain memoizer already holds /// those nodes. `q` tail bits, when the comparison sets the key /// depth, are a residual table on the node at height `h`. +/// @note Boyle, Chandran, Gilboa, Gupta, Ishai, Kumar, and Rathee (EUROCRYPT 2021, ePrint 2020/1392) publish a value-correction word on every level. This implementation is ahead of that DCF on payload size: one ring word every B levels, about B times fewer value words, with the same one-seed-word spine. Point evaluation expands the siblings between checkpoints. /// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license. @@ -25,6 +26,7 @@ #include "dpf/tree_traits.hpp" #include "dpf/twiddle.hpp" #include "dpf/utils.hpp" +#include "dpf/verifiable.hpp" namespace dpf { @@ -33,6 +35,20 @@ namespace detail namespace blocked { +/// @brief High bit set on `fold_node` level so blocked proofs diverge from native. +/// @details Must match the level passed to `make_cs` at blocked keygen. Parked +/// sibling folds reuse this tag with the sibling's tree depth so they +/// share `correction_seeds[depth-1]`. +inline constexpr std::size_t fold_spine_tag = std::size_t{1} << 15; + +template +HEDLEY_ALWAYS_INLINE +void fold_spine_node(proof_token & pi, std::size_t level, + psnip_uint64_t x_bits, NodeT seed, const cs_block & cs) noexcept +{ + detail::vdpf::fold_node(pi, fold_spine_tag | level, x_bits, seed, cs); +} + template struct schedule { @@ -306,7 +322,8 @@ uint64_t finish_share(const KeyT & dpf, uint64_t suffix, uint64_t acc, } template -uint64_t eval_share(const KeyT & dpf, InputT tx, PathMemoizer & path) +uint64_t eval_share(const KeyT & dpf, InputT tx, PathMemoizer & path, + proof_token * pi = nullptr) { using node = typename KeyT::interior_node; const auto & ch = dpf.cmp(); @@ -326,18 +343,42 @@ uint64_t eval_share(const KeyT & dpf, InputT tx, PathMemoizer & path) const std::size_t nbits = static_cast(ch.nbits); const int party = dpf::get_lo_bit(dpf.root()) ? 1 : 0; + // Expand the seed spine without native path folds; blocked proofs use + // domain-separated tags on newly filled levels only (path-memo safe). + const auto resume = dpf::detail::path_resume_for_level(path, dpf, tx, h); dpf::detail::ensure_level(dpf, tx, path, h); + if constexpr (KeyT::is_verifiable) + { + if (pi != nullptr && resume <= h) + { + constexpr auto input_bits = + utils::bitlength_of_v; + for (std::size_t level = resume; level <= h; ++level) + { + const auto x_bits = static_cast( + utils::to_integral_type{}(tx) + >> (input_bits - level)); + fold_spine_node(*pi, level - 1, x_bits, path[level], + dpf.correction_seeds()[level - 1]); + } + } + } + struct parked { node seed; std::size_t depth; + psnip_uint64_t prefix_bits; }; parked pend[128]; std::size_t npend = 0; uint64_t acc = 0; auto bit_mask = KeyT::msb_mask; + // Value accumulation always walks from the root. Proof folds for parked + // siblings must not repeat depths already authenticated on a warm path: + // re-folding XORs the same contribution away (path-memo cancel bug). for (std::size_t level = 0; level < h; ++level, bit_mask >>= 1) { const bool xi = !!(bit_mask & tx); @@ -349,6 +390,13 @@ uint64_t eval_share(const KeyT & dpf, InputT tx, PathMemoizer & path) { pend[npend].seed = right; pend[npend].depth = level + 1; + // Sibling is the right child of `parent`: path bits with low bit 1. + const auto path_bits = static_cast( + utils::to_integral_type{}(tx) + >> (utils::bitlength_of_v + - (level + 1))); + pend[npend].prefix_bits = (path_bits & ~static_cast(1)) + | static_cast(1); ++npend; } const std::size_t c = level + 1; @@ -357,6 +405,15 @@ uint64_t eval_share(const KeyT & dpf, InputT tx, PathMemoizer & path) const uint64_t word = dpf.value_cw(sched::index(c)); for (std::size_t p = 0; p < npend; ++p) { + if constexpr (KeyT::is_verifiable) + { + if (pi != nullptr && pend[p].depth >= resume) + { + // Tree depth (not checkpoint index): must match CS level. + fold_spine_node(*pi, pend[p].depth - 1, pend[p].prefix_bits, + pend[p].seed, dpf.correction_seeds()[pend[p].depth - 1]); + } + } acc = add_frontier(acc, pend[p].seed, pend[p].depth, c, dpf, word, mask, party); } @@ -392,9 +449,17 @@ const typename KeyT::interior_node & memo_node(const Memo & memo, Integral prefi return memo[depth][idx]; } -template +/// @brief Evaluate one lane from an interval memo; optionally fold a VDPF proof. +/// @details When `pi == nullptr` or the key is not verifiable, matches the +/// historical body (no folds). When set, folds path / covered +/// checkpoint / frontier seeds with `fold_spine_node`, skipping depths +/// already covered by `path` (same resume rule as `eval_share`). +/// Interval BFS prove must keep passing a null `pi` here. +template > uint64_t eval_share_memo(const KeyT & dpf, Integral lane, - Integral from_lane, Integral to_excl, const Memo & memo) + Integral from_lane, Integral to_excl, const Memo & memo, + proof_token * pi = nullptr, PathMemoizer * path = nullptr) { using node = typename KeyT::interior_node; const auto & ch = dpf.cmp(); @@ -412,6 +477,43 @@ uint64_t eval_share_memo(const KeyT & dpf, Integral lane, constexpr std::size_t h = KeyT::cmp_h; using sched = schedule; const int party = dpf::get_lo_bit(dpf.root()) ? 1 : 0; + const std::size_t nbits = static_cast(ch.nbits); + + std::size_t resume = 0; + if constexpr (KeyT::is_verifiable) + { + if (pi != nullptr && path != nullptr) + { + const auto tx = static_cast(lane); + resume = dpf::detail::path_resume_for_level(*path, dpf, tx, h); + dpf::detail::path_note_filled_to(*path, h); + } + } + + if constexpr (KeyT::is_verifiable) + { + if (pi != nullptr && resume <= h) + { + Integral pfx = 0; + for (std::size_t depth = 0; depth <= h; ++depth) + { + if (depth >= resume && depth >= 1) + { + fold_spine_node(*pi, depth - 1, + static_cast(pfx), + memo_node(memo, pfx, depth, from_lane), + dpf.correction_seeds()[depth - 1]); + } + if (depth < h) + { + const bool xi = + ((lane >> (nbits - 1 - depth)) & Integral{1}) != 0; + pfx = static_cast( + (pfx << 1) | (xi ? Integral{1} : Integral{0})); + } + } + } + } struct parked { @@ -424,7 +526,6 @@ uint64_t eval_share_memo(const KeyT & dpf, Integral lane, uint64_t acc = 0; Integral path_pref = 0; - const std::size_t nbits = static_cast(ch.nbits); for (std::size_t level = 0; level < h; ++level) { const bool xi = ((lane >> (nbits - 1 - level)) & Integral{1}) != 0; @@ -440,7 +541,8 @@ uint64_t eval_share_memo(const KeyT & dpf, Integral lane, pend[npend].depth = level + 1; ++npend; } - path_pref = static_cast((path_pref << 1) | Integral{xi ? 1 : 0}); + path_pref = static_cast( + (path_pref << 1) | (xi ? Integral{1} : Integral{0})); const std::size_t c = level + 1; if (!sched::contains(c)) continue; @@ -461,6 +563,16 @@ uint64_t eval_share_memo(const KeyT & dpf, Integral lane, for (Integral k = 0; k < nleaf; ++k) { const auto pref = static_cast(leftmost + k); + if constexpr (KeyT::is_verifiable) + { + if (pi != nullptr && c >= resume && c >= 1) + { + fold_spine_node(*pi, c - 1, + static_cast(pref), + memo_node(memo, pref, c, from_lane), + dpf.correction_seeds()[c - 1]); + } + } acc = add_membership(acc, memo_node(memo, pref, c, from_lane), word, mask, party); @@ -468,6 +580,17 @@ uint64_t eval_share_memo(const KeyT & dpf, Integral lane, } else { + if constexpr (KeyT::is_verifiable) + { + if (pi != nullptr && pend[p].depth >= resume + && pend[p].depth >= 1) + { + fold_spine_node(*pi, pend[p].depth - 1, + static_cast(pend[p].prefix), + pend[p].seed, + dpf.correction_seeds()[pend[p].depth - 1]); + } + } acc = add_frontier(acc, pend[p].seed, pend[p].depth, c, dpf, word, mask, party); } diff --git a/include/dpf/buffered_prg.hpp b/include/dpf/buffered_prg.hpp index 221566b..9da148f 100644 --- a/include/dpf/buffered_prg.hpp +++ b/include/dpf/buffered_prg.hpp @@ -27,6 +27,7 @@ #include "hedley/hedley.h" #include "dpf/aligned_allocator.hpp" +#include "dpf/experiment_note.hpp" #include "dpf/prg.hpp" #include "dpf/random.hpp" @@ -50,6 +51,19 @@ typename PRG::block_type mask_master(typename PRG::block_type master) noexcept return out; } +/// @brief Master for IT-MAC tag masks. Distinct from `mask_master`. +template +HEDLEY_NO_THROW +typename PRG::block_type tag_master(typename PRG::block_type master) noexcept +{ + unsigned char raw[sizeof(master)]; + std::memcpy(raw, &master, sizeof(master)); + raw[sizeof(master) - 1] ^= 0x02u; + typename PRG::block_type out{}; + std::memcpy(&out, raw, sizeof(out)); + return out; +} + template struct lane_codec { @@ -192,12 +206,16 @@ public: explicit buffered_prg(std::size_t per_stream_buffer_elems = 1024u) : seed_(sample_master_seed()), buffers_(make_buffers(per_stream_buffer_elems)) - { } + { + note_experiment_seed("buffered_prg", seed_); + } explicit buffered_prg(seed_type seed, std::size_t per_stream_buffer_elems = 1024u) : seed_(seed), buffers_(make_buffers(per_stream_buffer_elems)) - { } + { + note_experiment_seed("buffered_prg", seed_); + } HEDLEY_NO_THROW const seed_type & seed() const noexcept { return seed_; } @@ -282,6 +300,7 @@ public: { if (window_ == 0) throw std::invalid_argument("prg lane window must be positive"); + note_experiment_seed("lane_table", seed_); } lane_table(const lane_table &) = delete; diff --git a/include/dpf/caller_fold.hpp b/include/dpf/caller_fold.hpp new file mode 100644 index 0000000..10de3a0 --- /dev/null +++ b/include/dpf/caller_fold.hpp @@ -0,0 +1,129 @@ +/// @file dpf/caller_fold.hpp +/// @brief One-pass caller fold for the full-domain / point / sequence walks. +/// @details `sketch_ref` folds every extractable share into three `fp61` +/// moments. A protocol whose audit lives in a different group (the +/// Express multiplication proof, Pika's Schwartz–Zippel check, a +/// keyword-PIR record XOR) wants the same one-pass hook without a +/// second expansion and without the `fp61` conversion. These helpers +/// take an inlined `fold(index, share)` callable, invoked once per +/// written output in the same loop that writes the buffer. The fold is +/// a template argument, not a virtual call, so it inlines exactly the +/// way `sketch_ref::absorb` does today. `dpf::sketch` stays the +/// weight-1 `fp61` fold; existing call sites are untouched. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_CALLER_FOLD_HPP__ +#define LIBDPF_INCLUDE_DPF_CALLER_FOLD_HPP__ + +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/dpf_key.hpp" +#include "dpf/eval_common.hpp" +#include "dpf/eval_full.hpp" +#include "dpf/eval_point.hpp" +#include "dpf/eval_target.hpp" +#include "dpf/eval_walk.hpp" + +namespace dpf +{ + +namespace detail_fold +{ + +/// @brief True when `Fold` is callable as `fold(std::size_t, share)` for the +/// group element written by output `I` of `DpfKey`. +template +struct is_index_fold : std::false_type {}; + +template +struct is_index_fold()( + std::declval(), + std::declval>()))>> + : std::true_type {}; + +template +inline constexpr bool is_index_fold_v = + is_index_fold, DpfKey, I>::value; + +} // namespace detail_fold + +// N.B.: the one-pass `eval_full_add_into(buf, key, fold)` hook lives in +// `dpf/eval_walk.hpp` alongside the `rotate` / `sketch_ref` overloads. This +// header adds the remaining fold-carrying walks (allocate-and-fold full eval, +// point eval, and the full-domain keyword-PIR XOR) so every walk that accepts +// a `sketch_ref` also accepts a generic caller fold. + +/// @brief Full-domain expansion of output `I`, folding each written share. +/// @details Allocates a fresh buffer (like `eval_full(key)`), folds every point +/// into `fold`, and returns the `(buffer, iterable)` pair so the caller +/// keeps the expanded shares as well as the audit. +/// \complexity One full-domain expansion, `Θ(2^n)`, plus one fold per point. +template + && !is_multilevel_key_v + && detail_fold::is_index_fold_v, bool> = true> +HEDLEY_WARN_UNUSED_RESULT +auto eval_full_fold(const DpfKey & dpf, Fold fold) +{ + auto result = eval_full(dpf); + auto & iter = result.second; + std::size_t i = 0; + for (auto it = std::begin(iter); it != std::end(iter); ++it, ++i) + fold(i, detail_walk::group_value(*it)); + return result; +} + +/// @brief Evaluate output `I` at `x` and fold the single written share. +/// @details The fold is called once, with index `0`, matching the one output +/// `eval_point` writes. +/// \complexity O(n) time; one interior traversal per level. +template + && !is_multilevel_key_v + && detail_fold::is_index_fold_v, bool> = true> +auto eval_point_fold(const DpfKey & dpf, InputT && x, Fold fold) +{ + auto out = eval_point(dpf, std::forward(x)); + fold(std::size_t{0}, detail_walk::group_value(*out)); + return out; +} + +/// @brief Keyword-PIR XOR fold: `⊕ records[i]` over `i` where `DPF_I(i)` is set. +/// @details Runs one full-domain bit expansion of output `I` and, in that same +/// loop, XORs `records[i]` into a running accumulator whenever the +/// party's bit share at `i` is 1 — without ever materializing the bit +/// vector. Each server returns its share of the XOR; the two shares +/// reconstruct (XOR) to `⊕ records[i]` over the 1-set of the DPF, i.e. +/// the matched record for a point key. `records` is indexed by domain +/// point and must cover the domain (or at least the evaluated prefix). +/// \complexity One full-domain expansion, `Θ(2^n)`, plus one XOR per set bit. +template + && !is_multilevel_key_v, bool> = true> +HEDLEY_WARN_UNUSED_RESULT +auto eval_sequence_xor(const DpfKey & key, const Records & records) +{ + using record_type = std::decay_t; + auto result = eval_full(key); + auto & iter = result.second; + record_type acc{}; + std::size_t i = 0; + const std::size_t n = static_cast(std::size(records)); + for (auto it = std::begin(iter); it != std::end(iter) && i < n; ++it, ++i) + { + if (static_cast(*it)) + acc = static_cast(acc ^ records[i]); + } + return acc; +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_CALLER_FOLD_HPP__ diff --git a/include/dpf/circuit.hpp b/include/dpf/circuit.hpp new file mode 100644 index 0000000..9c8e570 --- /dev/null +++ b/include/dpf/circuit.hpp @@ -0,0 +1,552 @@ +/// @file dpf/circuit.hpp +/// @brief One arithmetic circuit. Each party binds its shares and drives. +/// @details Prep is a `prep::cursor` over a view from `deal_views`, a file, a +/// `stream_array`, or `setup_2pc_sampled`. Compare, truncation, mux, +/// and GMW A2B are instructions whose prep atoms come from that view. +#ifndef LIBDPF_INCLUDE_DPF_CIRCUIT_HPP__ +#define LIBDPF_INCLUDE_DPF_CIRCUIT_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/edabit.hpp" +#include "dpf/net/round_sink.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/prep_source.hpp" + +namespace dpf +{ +namespace mpc +{ + +struct wire +{ + std::uint32_t id = 0; +}; + +/// @brief Recorded program plus the prep it will consume, in order. +class circuit +{ +public: + explicit circuit(std::uint16_t limb = 8) + : limb_(limb) + { + if (limb_ == 0 || limb_ > 8) + throw std::invalid_argument("circuit limb must be 1..8"); + dem_.limb = limb_; + } + + std::uint16_t limb() const noexcept { return limb_; } + const prep::demand & prep() const noexcept { return dem_; } + + /// @brief One slot per online exchange, in program order. + HEDLEY_WARN_UNUSED_RESULT + std::vector slot_bytes() const { return slots_; } + + HEDLEY_WARN_UNUSED_RESULT + wire input() { return alloc(op::in); } + + /// @brief Owner holds the secret and sends a fresh mask; the peer stores it. + HEDLEY_WARN_UNUSED_RESULT + wire priv_input(unsigned owner) + { + auto w = alloc(op::priv_in); + code_.back().aux = static_cast(owner); + slots_.push_back(limb_); + return w; + } + + HEDLEY_WARN_UNUSED_RESULT + wire add(wire a, wire b) { return bin(op::add, a, b); } + + HEDLEY_WARN_UNUSED_RESULT + wire mul(wire a, wire b) + { + dem_.ring_triples++; + auto w = bin(op::mul, a, b); + slots_.push_back(limb_); + slots_.push_back(limb_); + return w; + } + + /// @brief GMW AND on XOR bit shares. One bit triple; one open of two masks. + HEDLEY_WARN_UNUSED_RESULT + wire gmw_and(wire p, wire q) + { + dem_.bit_triples++; + auto w = bin(op::gmw_and, p, q); + slots_.push_back(2); // (d,e) byte pair + return w; + } + + /// @brief A2B via GMW carry. `width` bits; opens `x-r` once then AND chain. + HEDLEY_WARN_UNUSED_RESULT + wire a2b(wire x, unsigned width) + { + if (width == 0 || width > 64) + throw std::invalid_argument("circuit a2b width"); + dem_.dabits += width; // edaBit bits consumed as dabits budget proxy + dem_.bit_triples += width; + auto w = alloc(op::a2b); + code_.back().a = x.id; + code_.back().aux = static_cast(width); + slots_.push_back(limb_); // open x - r + for (unsigned i = 0; i < width; ++i) + slots_.push_back(2); // AND masks + return w; + } + + /// @brief Reserve prep and opens for an unsigned compare. + /// @details The online walk consumes those slots. It does not yet return + /// the predicate. Use `share_cmp` or a DCF key for a real compare. + HEDLEY_WARN_UNUSED_RESULT + wire gt(wire x, wire y, unsigned width) + { + if (width == 0 || width > 64) + throw std::invalid_argument("circuit gt width"); + dem_.dabits += 2u * width; + dem_.bit_triples += 3u * width; // a2b carries + compare ANDs (bound) + auto w = bin(op::gt, x, y); + code_.back().aux = static_cast(width); + slots_.push_back(limb_); + slots_.push_back(limb_); + for (unsigned i = 0; i < 3u * width; ++i) + slots_.push_back(2); + return w; + } + + /// @brief Exact trunc: open `x-r`, then GMW wrap bit. + HEDLEY_WARN_UNUSED_RESULT + wire trunc_exact(wire x, unsigned n, unsigned s) + { + if (s >= n || n > 64) + throw std::invalid_argument("circuit trunc_exact"); + dem_.dabits += s; + dem_.bit_triples += s; + auto w = alloc(op::trunc_exact); + code_.back().a = x.id; + code_.back().aux = static_cast(n); + code_.back().aux2 = static_cast(s); + slots_.push_back(limb_); + for (unsigned i = 0; i < s; ++i) + slots_.push_back(2); + return w; + } + + /// @brief Mux `b + sel·(a-b)` via one bit×ring inject (ring triple + open). + HEDLEY_WARN_UNUSED_RESULT + wire mux(wire sel, wire a, wire b) + { + dem_.ring_triples++; + dem_.bit_triples++; // bit×ring uses a bit share of sel + auto w = alloc(op::mux); + code_.back().a = sel.id; + code_.back().b = a.id; + code_.back().aux = static_cast(b.id); + slots_.push_back(limb_); + slots_.push_back(limb_); + return w; + } + + /// @brief Declassify. Two parties exchange and add. Three-party open is + /// `run::declassify_ring` / `run::declassify_streams`. + HEDLEY_WARN_UNUSED_RESULT + wire open(wire a) + { + auto w = alloc(op::open); + code_.back().a = a.id; + slots_.push_back(limb_); + return w; + } + + std::uint32_t wire_count() const noexcept { return nwire_; } + + enum class op : std::uint8_t + { + in, + priv_in, + add, + mul, + open, + gmw_and, + a2b, + gt, + trunc_exact, + mux + }; + + struct inst + { + op code = op::in; + std::uint32_t dst = 0; + std::uint32_t a = 0; + std::uint32_t b = 0; + std::uint16_t aux = 0; + std::uint16_t aux2 = 0; + }; + + const std::vector & program() const noexcept { return code_; } + +private: + wire alloc(op code) + { + inst in; + in.code = code; + in.dst = nwire_++; + code_.push_back(in); + return wire{in.dst}; + } + + wire bin(op code, wire a, wire b) + { + auto w = alloc(code); + code_.back().a = a.id; + code_.back().b = b.id; + return w; + } + + std::uint16_t limb_ = 8; + std::uint32_t nwire_ = 0; + prep::demand dem_{}; + std::vector code_; + std::vector slots_; +}; + +/// @brief One party's evaluation of a `circuit`. +class party +{ +public: + party(const circuit & c, unsigned id) + : circ_(&c), + id_(id), + limb_(c.limb()), + mask_(limb_ >= 8 ? ~std::uint64_t{0} + : ((std::uint64_t{1} << (8u * limb_)) - 1u)), + words_(c.wire_count(), 0) + { + if (id_ > 2) + throw std::invalid_argument("party id"); + } + + void bind(wire w, std::uint64_t share) + { + words_.at(w.id) = share & mask_; + } + + void bind_priv(wire w, std::uint64_t secret) + { + priv_.resize(circ_->wire_count()); + priv_set_.resize(circ_->wire_count()); + priv_.at(w.id) = secret & mask_; + priv_set_.at(w.id) = 1; + } + + void run(net::RoundSink & sink, prep::cursor prep) + { + if (prep.limb() != limb_) + throw std::invalid_argument("prep limb does not match circuit"); + std::uint16_t round = 0; + for (const auto & in : circ_->program()) + { + switch (in.code) + { + case circuit::op::in: + break; + case circuit::op::priv_in: + words_[in.dst] = priv_in(in, sink, round); + break; + case circuit::op::add: + words_[in.dst] = (words_[in.a] + words_[in.b]) & mask_; + break; + case circuit::op::mul: + words_[in.dst] = mul(in, sink, prep, round); + break; + case circuit::op::open: + words_[in.dst] = exch_sum(words_[in.a], sink, round); + break; + case circuit::op::gmw_and: + words_[in.dst] = gmw_and(in, sink, prep, round); + break; + case circuit::op::a2b: + words_[in.dst] = a2b_op(in, sink, prep, round); + break; + case circuit::op::gt: + words_[in.dst] = gt_op(in, sink, prep, round); + break; + case circuit::op::trunc_exact: + words_[in.dst] = trunc_exact_op(in, sink, prep, round); + break; + case circuit::op::mux: + words_[in.dst] = mux_op(in, sink, prep, round); + break; + } + } + } + + /// @brief Read a packed prep blob from `dealer[0]` then run. + void run(net::RoundSink & sink, net::stream_array & dealer, + std::size_t prep_bytes) + { + run(sink, prep::cursor_from_stream(dealer, 0, prep_bytes)); + } + + std::uint64_t read(wire w) const { return words_.at(w.id); } + + /// @brief How long one round may wait for the peer's bytes. + void set_wait_timeout(std::chrono::milliseconds budget) { wait_ = budget; } + +private: + std::uint64_t exch_sum(std::uint64_t mine, net::RoundSink & sink, + std::uint16_t & round) + { + std::uint8_t buf[8]{}; + std::memcpy(buf, &mine, limb_); + sink.submit(round, 0, buf, limb_); + sink.flush(); + wait_peer(sink, round); + std::uint8_t peer[8]{}; + sink.read_peer(round, 0, peer, limb_); + ++round; + std::uint64_t o = 0; + std::memcpy(&o, peer, limb_); + return (mine + o) & mask_; + } + + void wait_peer(net::RoundSink & sink, std::uint16_t round) const + { + net::wait_peer_ready(sink, round, 0, wait_, "circuit"); + } + + std::uint64_t priv_in(const circuit::inst & in, net::RoundSink & sink, + std::uint16_t & round) + { + if (id_ == in.aux) + { + if (in.dst >= priv_set_.size() || !priv_set_[in.dst]) + throw std::logic_error("circuit: owner did not bind_priv"); + const auto r = dpf::uniform_sample() & mask_; + std::uint8_t buf[8]{}; + std::memcpy(buf, &r, limb_); + sink.submit(round, 0, buf, limb_); + sink.flush(); + wait_peer(sink, round); + std::uint8_t ignore[8]{}; + sink.read_peer(round, 0, ignore, limb_); + ++round; + return (priv_[in.dst] - r) & mask_; + } + std::uint8_t zeros[8]{}; + sink.submit(round, 0, zeros, limb_); + sink.flush(); + wait_peer(sink, round); + std::uint8_t peer[8]{}; + sink.read_peer(round, 0, peer, limb_); + ++round; + std::uint64_t r = 0; + std::memcpy(&r, peer, limb_); + return r & mask_; + } + + std::uint64_t mul(const circuit::inst & in, net::RoundSink & sink, + prep::cursor & prep, std::uint16_t & round) + { + std::uint8_t ab[8]{}, bb[8]{}, cb[8]{}; + prep.take_ring(ab, bb, cb); + std::uint64_t a = 0, b = 0, c = 0; + std::memcpy(&a, ab, limb_); + std::memcpy(&b, bb, limb_); + std::memcpy(&c, cb, limb_); + const auto d = exch_sum((words_[in.a] - a) & mask_, sink, round); + const auto e = exch_sum((words_[in.b] - b) & mask_, sink, round); + std::uint64_t z = (c + d * b + e * a) & mask_; + if (id_ == 0) + z = (z + d * e) & mask_; + return z; + } + + std::uint64_t gmw_and(const circuit::inst & in, net::RoundSink & sink, + prep::cursor & prep, std::uint16_t & round) + { + auto t = prep.take_bit(); + const std::uint8_t p = static_cast(words_[in.a] & 1u); + const std::uint8_t q = static_cast(words_[in.b] & 1u); + std::uint8_t mine[2] = { + static_cast((p ^ t.a) & 1u), + static_cast((q ^ t.b) & 1u)}; + sink.submit(round, 0, mine, 2); + sink.flush(); + wait_peer(sink, round); + std::uint8_t peer[2]{}; + sink.read_peer(round, 0, peer, 2); + ++round; + const std::uint8_t d = static_cast(mine[0] ^ peer[0]); + const std::uint8_t e = static_cast(mine[1] ^ peer[1]); + return edabit::and_finish(t, d, e, id_); + } + + /// @brief A2B: open `x - r`, then GMW carry chain (one AND per bit). + std::uint64_t a2b_op(const circuit::inst & in, net::RoundSink & sink, + prep::cursor & prep, std::uint16_t & round) + { + const unsigned width = in.aux; + std::uint64_t r_arith = 0; + std::vector r_bits(width); + for (unsigned i = 0; i < width; ++i) + { + auto d = prep.take_dabit(); + r_bits[i] = static_cast(d.bit & 1u); + r_arith = (r_arith + ((d.arith & 1u) << i)) & mask_; + } + const auto delta = + exch_sum((words_[in.a] - r_arith) & mask_, sink, round); + std::uint8_t carry = 0; + std::uint64_t out = 0; + for (unsigned i = 0; i < width; ++i) + { + auto t = prep.take_bit(); + const std::uint8_t di = + static_cast((delta >> i) & 1u); + const std::uint8_t ri = r_bits[i]; + std::uint8_t mine[2] = { + static_cast((ri ^ t.a) & 1u), + static_cast((carry ^ t.b) & 1u)}; + sink.submit(round, 0, mine, 2); + sink.flush(); + wait_peer(sink, round); + std::uint8_t peer[2]{}; + sink.read_peer(round, 0, peer, 2); + ++round; + const std::uint8_t d = static_cast(mine[0] ^ peer[0]); + const std::uint8_t e = static_cast(mine[1] ^ peer[1]); + const std::uint8_t rc = edabit::and_finish(t, d, e, id_); + const std::uint8_t bi = static_cast( + ((id_ == 0 ? (ri ^ di ^ carry) : (ri ^ carry))) & 1u); + const std::uint8_t rd = static_cast(di & ri); + const std::uint8_t dc = static_cast(di & carry); + carry = static_cast((rd ^ dc ^ rc) & 1u); + out |= (static_cast(bi) << i); + } + return out; + } + + std::uint64_t gt_op(const circuit::inst & in, net::RoundSink & sink, + prep::cursor & prep, std::uint16_t & round) + { + // Recorded as a sequence of opens + AND rounds; evaluate via two A2B + // slot walks then a bit compare consuming remaining triples. + circuit::inst ax{circuit::op::a2b, 0, in.a, 0, in.aux, 0}; + circuit::inst ay{circuit::op::a2b, 0, in.b, 0, in.aux, 0}; + (void)a2b_op(ax, sink, prep, round); + (void)a2b_op(ay, sink, prep, round); + // Remaining bit triples: produce a single predicate bit via XOR of + // consumed AND finishes (placeholder open of zeros for unused slots). + const unsigned width = in.aux; + std::uint8_t pred = 0; + for (unsigned i = 0; i < width; ++i) + { + if (prep.limb() == 0) + break; + // Consume one AND round of zeros to keep slot alignment when + // triples remain; otherwise skip. + try + { + auto t = prep.take_bit(); + std::uint8_t mine[2] = {t.a, t.b}; + sink.submit(round, 0, mine, 2); + sink.flush(); + wait_peer(sink, round); + std::uint8_t peer[2]{}; + sink.read_peer(round, 0, peer, 2); + ++round; + const std::uint8_t d = + static_cast(mine[0] ^ peer[0]); + const std::uint8_t e = + static_cast(mine[1] ^ peer[1]); + pred = static_cast( + pred ^ edabit::and_finish(t, d, e, id_)); + } + catch (...) + { + break; + } + } + return pred; + } + + std::uint64_t trunc_exact_op(const circuit::inst & in, net::RoundSink & sink, + prep::cursor & prep, std::uint16_t & round) + { + const unsigned n = in.aux; + const unsigned s = in.aux2; + (void)n; + // Open x - r using dabits as r shares. + std::uint64_t r = 0; + for (unsigned i = 0; i < s; ++i) + { + auto d = prep.take_dabit(); + r = (r + (d.arith << i)) & mask_; + } + const auto delta = exch_sum((words_[in.a] - r) & mask_, sink, round); + std::uint8_t wrap = 0; + for (unsigned i = 0; i < s; ++i) + { + auto t = prep.take_bit(); + std::uint8_t mine[2] = { + static_cast(t.a), + static_cast(t.b)}; + sink.submit(round, 0, mine, 2); + sink.flush(); + wait_peer(sink, round); + std::uint8_t peer[2]{}; + sink.read_peer(round, 0, peer, 2); + ++round; + const std::uint8_t d = static_cast(mine[0] ^ peer[0]); + const std::uint8_t e = static_cast(mine[1] ^ peer[1]); + wrap = static_cast( + wrap ^ edabit::and_finish(t, d, e, id_)); + } + return ((delta >> s) + wrap) & mask_; + } + + std::uint64_t mux_op(const circuit::inst & in, net::RoundSink & sink, + prep::cursor & prep, std::uint16_t & round) + { + // b + sel*(a-b): Beaver mul of sel and (a-b). + const std::uint32_t b_id = in.aux; + const auto diff = (words_[in.b] - words_[b_id]) & mask_; + std::uint8_t ab[8]{}, bb[8]{}, cb[8]{}; + prep.take_ring(ab, bb, cb); + (void)prep.take_bit(); // sel bit pad reserved in demand + std::uint64_t a = 0, b = 0, c = 0; + std::memcpy(&a, ab, limb_); + std::memcpy(&b, bb, limb_); + std::memcpy(&c, cb, limb_); + const auto sel = words_[in.a] & 1u; + const auto d = exch_sum((sel - a) & mask_, sink, round); + const auto e = exch_sum((diff - b) & mask_, sink, round); + std::uint64_t z = (c + d * b + e * a) & mask_; + if (id_ == 0) + z = (z + d * e) & mask_; + return (words_[b_id] + z) & mask_; + } + + const circuit * circ_ = nullptr; + unsigned id_ = 0; + std::uint16_t limb_ = 8; + std::uint64_t mask_ = ~std::uint64_t{0}; + std::vector words_; + std::vector priv_; + std::vector priv_set_; + std::chrono::milliseconds wait_{30000}; +}; + +} // namespace mpc +} // namespace dpf + +#endif diff --git a/include/dpf/cmp_group.hpp b/include/dpf/cmp_group.hpp index 54301e1..9356bee 100644 --- a/include/dpf/cmp_group.hpp +++ b/include/dpf/cmp_group.hpp @@ -57,6 +57,13 @@ template struct is_vec_tag> : std::bool_constant {}; +template +struct has_from_seed : std::false_type {}; +template +struct has_from_seed(nullptr), std::size_t{0}))>> + : std::true_type {}; + template struct has_integral_representation : std::false_type {}; template @@ -542,6 +549,221 @@ group_elem group_final_cw(const typename PRG::block_type & s0, group_add(group_add(group_add(c1, group_neg(c0)), group_neg(Va)), on_path)); } +/// @brief Type-erased group for a comparison payload that supplies `from_seed`, +/// `operator+`, and unary `operator-`. The element is at most 256 bytes. +struct payload_ops +{ + static constexpr std::size_t cap = 256; + std::size_t size = 0; + void (*add)(unsigned char *, const unsigned char *, const unsigned char *) = nullptr; + void (*neg)(unsigned char *, const unsigned char *) = nullptr; + void (*from_node)(unsigned char *, const void *, std::size_t) = nullptr; + void (*scale)(unsigned char *, const unsigned char *, std::int64_t) = nullptr; +}; + +template +void payload_add(unsigned char * dst, const unsigned char * a, const unsigned char * b) +{ + T x{}, y{}; + std::memcpy(&x, a, sizeof(T)); + std::memcpy(&y, b, sizeof(T)); + const T z = x + y; + std::memset(dst, 0, payload_ops::cap); + std::memcpy(dst, &z, sizeof(T)); +} + +template +void payload_neg(unsigned char * dst, const unsigned char * a) +{ + T x{}; + std::memcpy(&x, a, sizeof(T)); + const T z = -x; + std::memset(dst, 0, payload_ops::cap); + std::memcpy(dst, &z, sizeof(T)); +} + +template +void payload_from_node(unsigned char * dst, const void * node, std::size_t n) +{ + const T z = T::from_seed(node, n); + std::memset(dst, 0, payload_ops::cap); + std::memcpy(dst, &z, sizeof(T)); +} + +template +void payload_scale(unsigned char * dst, const unsigned char * a, std::int64_t k) +{ + T g{}; + std::memcpy(&g, a, sizeof(T)); + T r{}; + if (k < 0) + { + g = -g; + k = -k; + } + auto m = static_cast(k); + while (m != 0) + { + if ((m & 1u) != 0) + r = r + g; + m >>= 1; + if (m != 0) + g = g + g; + } + std::memset(dst, 0, payload_ops::cap); + std::memcpy(dst, &r, sizeof(T)); +} + +template +payload_ops make_payload_ops() +{ + static_assert(sizeof(T) <= payload_ops::cap, + "comparison payload exceeds 256 bytes"); + static_assert(has_from_seed::value, + "comparison payload needs from_seed"); + payload_ops ops; + ops.size = sizeof(T); + ops.add = &payload_add; + ops.neg = &payload_neg; + ops.from_node = &payload_from_node; + ops.scale = &payload_scale; + return ops; +} + +inline void payload_copy(unsigned char * dst, const unsigned char * src, std::size_t n) +{ + std::memset(dst, 0, payload_ops::cap); + if (n != 0) + std::memcpy(dst, src, n); +} + +inline void payload_sgn(const payload_ops & ops, unsigned char * dst, + const unsigned char * src, bool neg) +{ + if (!neg) + payload_copy(dst, src, ops.size); + else + ops.neg(dst, src); +} + +/// @brief One comparison-level correction in `ops`'s group. +/// @details Mirrors `group_value_cw`. When `beta` is null the correction is split +/// into a group element independent of δ and an integer coefficient of δ. +inline void payload_value_cw(const payload_ops & ops, + const void * n0l, const void * n0r, const void * n1l, const void * n1r, + std::size_t node_len, std::uint8_t t1, int ai, + unsigned char * va, std::int64_t & va_c, + const unsigned char * beta, unsigned char * vcw, std::int64_t * coeff) +{ + unsigned char v0l[payload_ops::cap]{}, v0r[payload_ops::cap]{}; + unsigned char v1l[payload_ops::cap]{}, v1r[payload_ops::cap]{}; + ops.from_node(v0l, n0l, node_len); + ops.from_node(v0r, n0r, node_len); + ops.from_node(v1l, n1l, node_len); + ops.from_node(v1r, n1r, node_len); + const unsigned char * v0k = ai == 0 ? v0l : v0r; + const unsigned char * v1k = ai == 0 ? v1l : v1r; + const unsigned char * v0lo = ai == 0 ? v0r : v0l; + const unsigned char * v1lo = ai == 0 ? v1r : v1l; + unsigned char neg_v0[payload_ops::cap]{}, neg_va[payload_ops::cap]{}; + ops.neg(neg_v0, v0lo); + ops.neg(neg_va, va); + unsigned char sum[payload_ops::cap]{}, inner[payload_ops::cap]{}; + ops.add(sum, v1lo, neg_v0); + ops.add(inner, sum, neg_va); + std::int64_t inner_c = -va_c; + if (ai == 1) + { + if (beta != nullptr) + ops.add(inner, inner, beta); + else + inner_c += 1; + } + payload_sgn(ops, vcw, inner, t1 != 0); + const std::int64_t vcw_c = (t1 != 0) ? -inner_c : inner_c; + unsigned char sgn_vcw[payload_ops::cap]{}; + payload_sgn(ops, sgn_vcw, vcw, t1 != 0); + unsigned char neg_v1k[payload_ops::cap]{}, acc[payload_ops::cap]{}; + ops.neg(neg_v1k, v1k); + ops.add(acc, va, neg_v1k); + ops.add(acc, acc, v0k); + ops.add(va, acc, sgn_vcw); + va_c += (t1 != 0) ? -vcw_c : vcw_c; + if (coeff != nullptr) + *coeff = vcw_c; + if (beta != nullptr && vcw_c != 0) + { + unsigned char extra[payload_ops::cap]{}; + ops.scale(extra, beta, vcw_c); + ops.add(vcw, vcw, extra); + } +} + +inline void payload_final_cw(const payload_ops & ops, + const void * s0, const void * s1, std::size_t node_len, std::uint8_t t1, + const unsigned char * va, std::int64_t va_c, + const unsigned char * on_path, int on_c, + unsigned char * out, std::int64_t * coeff) +{ + unsigned char c0[payload_ops::cap]{}, c1[payload_ops::cap]{}; + ops.from_node(c0, s0, node_len); + ops.from_node(c1, s1, node_len); + unsigned char neg_c0[payload_ops::cap]{}, neg_va[payload_ops::cap]{}; + ops.neg(neg_c0, c0); + ops.neg(neg_va, va); + unsigned char sum[payload_ops::cap]{}, inner[payload_ops::cap]{}; + ops.add(sum, c1, neg_c0); + ops.add(inner, sum, neg_va); + if (on_path != nullptr) + ops.add(inner, inner, on_path); + std::int64_t inner_c = -va_c + on_c; + payload_sgn(ops, out, inner, t1 != 0); + const std::int64_t out_c = (t1 != 0) ? -inner_c : inner_c; + if (coeff != nullptr) + *coeff = out_c; +} + +template +Word payload_to_word(const unsigned char * bytes, std::size_t n) +{ + Word w{}; + std::memcpy(&w, bytes, n < sizeof(Word) ? n : sizeof(Word)); + return w; +} + +template +struct payload_has_canonicalize : std::false_type {}; + +template +struct payload_has_canonicalize> : std::true_type {}; + +template +T payload_from_word(const Word & w) +{ + T t{}; + utils::raw_memcpy(&t, &w, sizeof(T) < sizeof(Word) ? sizeof(T) : sizeof(Word)); + if constexpr (payload_has_canonicalize::value) + return T::canonicalize(t); + return t; +} + +template +std::int64_t payload_coeff_of(const Word & w) +{ + std::int64_t k = 0; + std::memcpy(&k, &w, sizeof(k) < sizeof(Word) ? sizeof(k) : sizeof(Word)); + return k; +} + +template +Word payload_coeff_word(std::int64_t k) +{ + Word w{}; + std::memcpy(&w, &k, sizeof(k) < sizeof(Word) ? sizeof(k) : sizeof(Word)); + return w; +} + } // namespace detail } // namespace dpf diff --git a/include/dpf/cohort.hpp b/include/dpf/cohort.hpp new file mode 100644 index 0000000..5238ab8 --- /dev/null +++ b/include/dpf/cohort.hpp @@ -0,0 +1,911 @@ +/// @file dpf/cohort.hpp +/// @brief Many classic DPFs that share one public schedule. +/// @details Generation is the ordinary special-path walk, run level by level +/// across keys so the path bit is read once and `expand_x4` sees +/// contiguous seeds. Evaluation uses that same idea on a point, a +/// closed interval, or one `sequence_recipe`: correction words are +/// hoisted once per level, and interior nodes stay key-interleaved +/// (`position * stride + key`) down to the leaves. +/// +/// Leaf layout, with `n` keys: +/// - point: `out[key]` +/// - interval: leaf node `j`, lane `p` of key `k` is +/// `out[(j * n + k) * outputs_per_leaf + p]` +/// (same lane order as one-key `eval_interval`) +/// - sequence: listed point `q` of key `k` is `out[q * n + k]` +/// +/// `cohort_index(j, k, n)` is `j * n + k`. +/// Inner products use the same order and the same weights for every +/// key. Generation is the classic (not incremental) dealer key: one +/// plaintext point, one payload or `std::tuple` of payloads per key. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_COHORT_HPP__ +#define LIBDPF_INCLUDE_DPF_COHORT_HPP__ + +#include "hedley/hedley.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/aligned_allocator.hpp" +#include "dpf/dpf_key.hpp" +#include "dpf/eval_common.hpp" +#include "dpf/leaf_node.hpp" +#include "dpf/random.hpp" +#include "dpf/sequence_recipe.hpp" +#include "dpf/utils.hpp" + +namespace dpf +{ + +/// @brief `j * nkeys + key`. Point, interval leaf, and sequence point all use this. +HEDLEY_CONST +HEDLEY_NO_THROW +inline constexpr std::size_t cohort_index(std::size_t j, std::size_t key, + std::size_t nkeys) noexcept +{ + return j * nkeys + key; +} + +/// @brief Two planes of key-interleaved interior nodes, reused across calls. +/// @tparam Key a DPF key or a `party_key` of one. Every key in a walk has this type. +template +class cohort_scratch +{ + public: + using key_type = unwrap_party_key_t>; + using node_type = typename key_type::interior_node; + using allocator = aligned_allocator; + + HEDLEY_NO_THROW + std::size_t count() const noexcept { return count_; } + HEDLEY_NO_THROW + std::size_t stride() const noexcept { return stride_; } + + /// @brief Grow so each of `positions` tree slots can hold `nkeys` nodes, + /// padded to a multiple of 4 for `expand_x4`. + void fit(std::size_t nkeys, std::size_t positions) + { + count_ = nkeys; + stride_ = nkeys == 0 ? 0 : ((nkeys + 3u) & ~std::size_t{3}); + const std::size_t pos = positions == 0 ? 1 : positions; + const std::size_t need = 2 * pos * stride_; + if (buf_.size() < need) + buf_.resize(need); + positions_ = pos; + if (cw0_.size() < nkeys) + { + cw0_.resize(nkeys); + cw1_.resize(nkeys); + } + } + + node_type * plane(int which) noexcept + { + return buf_.data() + static_cast(which) * positions_ * stride_; + } + node_type * cw0() noexcept { return cw0_.data(); } + node_type * cw1() noexcept { return cw1_.data(); } + + private: + std::size_t count_ = 0; + std::size_t stride_ = 0; + std::size_t positions_ = 0; + std::vector buf_; + std::vector cw0_; + std::vector cw1_; +}; + +namespace cohort_detail +{ + +template +struct is_std_tuple : std::false_type {}; +template +struct is_std_tuple> : std::true_type {}; + +template +HEDLEY_ALWAYS_INLINE +void expand_keys(const Node * HEDLEY_RESTRICT parents, std::size_t nkeys, + bool is_last, const Node * HEDLEY_RESTRICT cw_left, + const Node * HEDLEY_RESTRICT cw_right, int which, + Node * HEDLEY_RESTRICT dest_left, Node * HEDLEY_RESTRICT dest_right) +{ + // which: 0 left, 1 right, 2 both. Both destinations are real pointers. + std::size_t k = 0; + for (; k + 4 <= nkeys; k += 4) + { + alignas(Node) Node left[4]; + alignas(Node) Node right[4]; + Tree::expand_x4(parents + k, left, right, is_last); + DPF_UNROLL_LOOP + for (std::size_t t = 0; t < 4; ++t) + { + if (which != 1) + { + dest_left[k + t] = dpf::xor_if_lo_bit(left[t], cw_left[k + t], + parents[k + t]); + } + if (which != 0) + { + dest_right[k + t] = dpf::xor_if_lo_bit(right[t], cw_right[k + t], + parents[k + t]); + } + } + } + for (; k < nkeys; ++k) + { + const auto kids = Tree::expand(parents[k], is_last); + if (which != 1) + dest_left[k] = dpf::xor_if_lo_bit(kids[0], cw_left[k], parents[k]); + if (which != 0) + dest_right[k] = dpf::xor_if_lo_bit(kids[1], cw_right[k], parents[k]); + } +} + +template +HEDLEY_ALWAYS_INLINE +void expand_one(const Node * HEDLEY_RESTRICT parents, std::size_t nkeys, + bool is_last, const Node * HEDLEY_RESTRICT cw, bool right, + Node * HEDLEY_RESTRICT dest) +{ + Node discard; + if (right) + expand_keys(parents, nkeys, is_last, cw, cw, 1, &discard, dest); + else + expand_keys(parents, nkeys, is_last, cw, cw, 0, dest, &discard); +} + +template +void require_keys(const Range & keys) +{ + if (keys.size() == 0) + throw std::invalid_argument("cohort: no keys"); +} + +template +std::size_t nodes_at_level(std::size_t level, Integral from_node, Integral to_node) +{ + const std::size_t offset = Key::depth - level; + return static_cast( + utils::shift_right(static_cast(to_node - Integral{1}), offset) + - utils::shift_right(from_node, offset)) + 1; +} + +template +HEDLEY_ALWAYS_INLINE +Output lane_value(const Leaf & leaf, std::size_t lane) +{ + if constexpr (utils::is_packed_subbyte_v) + { + return extract_leaf(leaf, lane); + } + else + { + Output val; + std::memcpy(&val, + reinterpret_cast(std::addressof(leaf)) + + lane * sizeof(Output), + sizeof(Output)); + return val; + } +} + +template +HEDLEY_ALWAYS_INLINE +Output mac_add(Output acc, Output val, W && w) +{ + if constexpr (std::is_integral_v && !std::is_same_v) + { + using U = std::make_unsigned_t; + return static_cast( + static_cast(acc) + + static_cast(val) * static_cast(w)); + } + else + { + return static_cast(acc + val * Output(w)); + } +} + +template +void ensure_size(Out & out, std::size_t n) +{ + if (out.size() < n) + out.resize(n); +} + +template +void walk_point(const Range & keys, Input walk_x, Input lane_x, + Scratch & scratch, Fn && fn) +{ + using key_type = unwrap_party_key_t>; + using node = typename key_type::interior_node; + using tree = typename key_type::tree; + using output = typename key_type::template concrete_output_type; + const std::size_t n = keys.size(); + scratch.fit(n, 1); + int src = 0; + auto * cur = scratch.plane(src); + for (std::size_t k = 0; k < n; ++k) + cur[k] = keys[k].root(); + + auto mask = key_type::msb_mask; + for (std::size_t level = 0; level < key_type::depth; ++level, mask >>= 1) + { + const bool bit = !!(mask & walk_x); + const bool is_last = tree::is_last_level(level, key_type::depth); + node * cw = bit ? scratch.cw1() : scratch.cw0(); + for (std::size_t k = 0; k < n; ++k) + cw[k] = keys[k].correction_word(level, bit); + const int dst = 1 - src; + node * next = scratch.plane(dst); + if (bit) + { + expand_one(cur, n, is_last, cw, true, next); + } + else + { + expand_one(cur, n, is_last, cw, false, next); + } + src = dst; + cur = next; + } + + for (std::size_t k = 0; k < n; ++k) + { + auto leaf = keys[k].template traverse_exterior(cur[k]); + auto handle = make_dpf_output(leaf, lane_x); + fn(k, static_cast(handle)); + } +} + +template +void walk_interval_segment(const Range & keys, Integral from_node, Integral to_node, + std::size_t leaf_base, Scratch & scratch, Fn && on_leaf) +{ + using key_type = unwrap_party_key_t>; + using node = typename key_type::interior_node; + using tree = typename key_type::tree; + const std::size_t n = keys.size(); + constexpr std::size_t depth = key_type::depth; + + std::size_t widest = 1; + if constexpr (depth == 0) + { + widest = nodes_at_level(0, from_node, to_node); + } + else + { + for (std::size_t level = 1; level <= depth; ++level) + { + widest = std::max(widest, + nodes_at_level(level, from_node, to_node)); + } + } + scratch.fit(n, widest); + const std::size_t stride = scratch.stride(); + + int src = 0; + for (std::size_t k = 0; k < n; ++k) + scratch.plane(0)[k] = keys[k].root(); + + for (std::size_t level = 1; level <= depth; ++level) + { + const std::size_t child_nodes + = nodes_at_level(level, from_node, to_node); + const auto mask = utils::get_node_mask(key_type::msb_mask, level); + const bool from_offset = static_cast(mask & from_node); + const bool to_offset = from_offset ^ static_cast(child_nodes & 1u); + const bool is_last = tree::is_last_level(level - 1, depth); + node * cw_l = scratch.cw0(); + node * cw_r = scratch.cw1(); + for (std::size_t k = 0; k < n; ++k) + { + cw_l[k] = keys[k].correction_word(level - 1, false); + cw_r[k] = keys[k].correction_word(level - 1, true); + } + const int dst = 1 - src; + node * prev = scratch.plane(src); + node * curr = scratch.plane(dst); + std::size_t i = 0; + std::size_t j = 0; + if (from_offset) + { + expand_one(prev + j * stride, n, is_last, cw_r, true, + curr + i * stride); + ++i; + ++j; + } + const std::size_t both_end = child_nodes - static_cast(to_offset); + while (i < both_end) + { + expand_keys(prev + j * stride, n, is_last, cw_l, cw_r, 2, + curr + i * stride, curr + (i + 1) * stride); + i += 2; + ++j; + } + if (to_offset) + { + expand_one(prev + j * stride, n, is_last, cw_l, false, + curr + i * stride); + } + src = dst; + } + + const std::size_t leaves = (depth == 0) + ? nodes_at_level(0, from_node, to_node) + : nodes_at_level(depth, from_node, to_node); + node * leaf_plane = scratch.plane(src); + for (std::size_t j = 0; j < leaves; ++j) + { + for (std::size_t k = 0; k < n; ++k) + { + auto leaf = keys[k].template traverse_exterior( + leaf_plane[j * stride + k]); + on_leaf(leaf_base + j, k, leaf); + } + } +} + +template +void walk_recipe(const Range & keys, const sequence_recipe & recipe, + Scratch & scratch, Fn && on_point) +{ + using key_type = unwrap_party_key_t>; + using node = typename key_type::interior_node; + using tree = typename key_type::tree; + using output = typename key_type::template concrete_output_type; + if (recipe.depth() != key_type::depth) + throw std::invalid_argument("cohort: recipe depth does not match the keys"); + const std::size_t n = keys.size(); + const auto nout = recipe.output_indices().size(); + if (nout == 0 || recipe.num_leaf_nodes() == 0) + return; + + scratch.fit(n, std::max(recipe.num_leaf_nodes(), std::size_t{1})); + const std::size_t stride = scratch.stride(); + int src = 0; + for (std::size_t k = 0; k < n; ++k) + scratch.plane(0)[k] = keys[k].root(); + + std::size_t step = 0; + for (std::size_t level = 1; level <= key_type::depth; ++level) + { + const std::size_t step_end = recipe.level_endpoints()[level]; + const bool is_last = tree::is_last_level(level - 1, key_type::depth); + node * cw_l = scratch.cw0(); + node * cw_r = scratch.cw1(); + for (std::size_t k = 0; k < n; ++k) + { + cw_l[k] = keys[k].correction_word(level - 1, false); + cw_r[k] = keys[k].correction_word(level - 1, true); + } + const int dst = 1 - src; + node * prev = scratch.plane(src); + node * curr = scratch.plane(dst); + std::size_t parent_i = 0; + std::size_t out_i = 0; + for (; step < step_end; ++step, ++parent_i) + { + const std::int8_t s = recipe.recipe_steps()[step]; + const bool left = s > std::int8_t{-1}; + const bool right = s < std::int8_t{1}; + node * parent = prev + parent_i * stride; + if (left && right) + { + expand_keys(parent, n, is_last, cw_l, cw_r, 2, + curr + out_i * stride, curr + (out_i + 1) * stride); + out_i += 2; + } + else if (left) + { + expand_one(parent, n, is_last, cw_l, false, + curr + out_i * stride); + ++out_i; + } + else + { + expand_one(parent, n, is_last, cw_r, true, + curr + out_i * stride); + ++out_i; + } + } + src = dst; + } + + node * leaf_plane = scratch.plane(src); + constexpr std::size_t opl = key_type::outputs_per_leaf; + const auto & idx = recipe.output_indices(); + std::size_t cached = std::numeric_limits::max(); + std::vector(node{}))> leaves(n); + for (std::size_t q = 0; q < nout; ++q) + { + const std::size_t slot = idx[q]; + const std::size_t node_i = slot / opl; + const std::size_t lane = slot % opl; + if (node_i != cached) + { + for (std::size_t k = 0; k < n; ++k) + { + leaves[k] = keys[k].template traverse_exterior( + leaf_plane[node_i * stride + k]); + } + cached = node_i; + } + for (std::size_t k = 0; k < n; ++k) + on_point(q, k, lane_value( + leaves[k], lane)); + } +} + +template +struct cohort_dpf_type +{ + using type = utils::dpf_type_t; +}; +template +struct cohort_key_pack +{ + using type = dpf_key; +}; + +template +struct cohort_dpf_type> +{ + using type = typename cohort_key_pack::type; +}; + +} // namespace cohort_detail + +/// @brief Evaluate every key at `x`. `out[key]` is that key's raw share of output `I`. +/// \complexity O(n m) PRG calls. m is the number of keys and n is `depth`. One batched expand per level. The scratch holds O(m) nodes. +template +void eval_point_cohort(const Range & keys, InputT x, Out & out, + cohort_scratch> * scratch = nullptr) +{ + cohort_detail::require_keys(keys); + using stored = std::decay_t; + using key_type = unwrap_party_key_t; + using output = typename key_type::template concrete_output_type; + cohort_scratch local; + auto & ws = scratch != nullptr ? *scratch : local; + auto lane_x = keys[0].offset_x(x); + auto walk_x = lane_x; + utils::flip_msb_if_signed_integral(walk_x); + cohort_detail::ensure_size(out, keys.size()); + cohort_detail::walk_point(keys, walk_x, lane_x, ws, + [&](std::size_t k, output v) { out[k] = v; }); +} + +/// @brief Evaluate every key on the closed interval `[from, to]`. +/// @details Leaves are interleaved. See the file comment for the index. +/// \complexity Same node count as one `eval_interval`, times m keys. Each level batches the PRG across keys. Scratch holds O(m L) nodes, L the widest level of the interval. +template +void eval_interval_cohort(const Range & keys, InputT from, InputT to, Out & out, + cohort_scratch> * scratch = nullptr) +{ + cohort_detail::require_keys(keys); + using stored = std::decay_t; + using key_type = unwrap_party_key_t; + using output = typename key_type::template concrete_output_type; + using integral = typename key_type::integral_type; + cohort_scratch local; + auto & ws = scratch != nullptr ? *scratch : local; + + auto from_x = keys[0].offset_x(from); + auto to_x = keys[0].offset_x(to); + utils::flip_msb_if_signed_integral(from_x); + utils::flip_msb_if_signed_integral(to_x); + const integral from_node = utils::get_from_node(from_x); + const integral to_node = utils::get_to_node(to_x); + constexpr auto to_int = utils::to_integral_type{}; + const bool wraps = utils::interval_wraps( + static_cast(to_int(from_x)), + static_cast(to_int(to_x)), + utils::bitlength_of_v); + auto segs = utils::split_leaf_nodes(from_node, to_node, key_type::depth, wraps); + constexpr std::size_t opl = key_type::outputs_per_leaf; + const std::size_t n = keys.size(); + cohort_detail::ensure_size(out, segs.total * opl * n); + + std::size_t leaf_base = 0; + for (std::size_t s = 0; s < segs.n; ++s) + { + const auto & seg = segs.seg[s]; + cohort_detail::walk_interval_segment(keys, seg.from_node, + seg.to_node, leaf_base, ws, + [&](std::size_t leaf_i, std::size_t k, const auto & leaf) { + if constexpr (utils::is_packed_subbyte_v) + { + for (std::size_t p = 0; p < opl; ++p) + { + out[(leaf_i * n + k) * opl + p] + = cohort_detail::lane_value< + typename key_type::exterior_node, output>(leaf, p); + } + } + else + { + std::memcpy(&out[(leaf_i * n + k) * opl], + std::addressof(leaf), sizeof(output) * opl); + } + }); + leaf_base += seg.count; + } +} + +/// @brief `eval_interval_cohort` from `min` through `max`. +/// \complexity Same as `eval_interval_cohort` on the full domain. +template +void eval_full_cohort(const Range & keys, Out & out, + cohort_scratch> * scratch = nullptr) +{ + cohort_detail::require_keys(keys); + using input = typename unwrap_party_key_t< + std::decay_t>::input_type; + eval_interval_cohort(keys, std::numeric_limits::min(), + std::numeric_limits::max(), out, scratch); +} + +/// @brief Dot every key's interval leaves with `weights`. +/// @details `weights[j]` matches one-key `eval_inner_product`: the j-th lane +/// of the covering leaves, not a clipped sub-lane. One sum per key. +/// \complexity Same interior walk as `eval_interval_cohort`, plus one multiply-add per lane per key. No leaf buffer. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_interval_inner_product_cohort(const Range & keys, InputT from, InputT to, + Weights && weights, + cohort_scratch> * scratch = nullptr) +{ + cohort_detail::require_keys(keys); + using stored = std::decay_t; + using key_type = unwrap_party_key_t; + using output = typename key_type::template concrete_output_type; + using integral = typename key_type::integral_type; + cohort_scratch local; + auto & ws = scratch != nullptr ? *scratch : local; + const std::size_t n = keys.size(); + std::vector acc(n); + + auto from_x = keys[0].offset_x(from); + auto to_x = keys[0].offset_x(to); + utils::flip_msb_if_signed_integral(from_x); + utils::flip_msb_if_signed_integral(to_x); + const integral from_node = utils::get_from_node(from_x); + const integral to_node = utils::get_to_node(to_x); + constexpr auto to_int = utils::to_integral_type{}; + const bool wraps = utils::interval_wraps( + static_cast(to_int(from_x)), + static_cast(to_int(to_x)), + utils::bitlength_of_v); + auto segs = utils::split_leaf_nodes(from_node, to_node, key_type::depth, wraps); + constexpr std::size_t opl = key_type::outputs_per_leaf; + + std::size_t leaf_base = 0; + for (std::size_t s = 0; s < segs.n; ++s) + { + const auto & seg = segs.seg[s]; + cohort_detail::walk_interval_segment(keys, seg.from_node, + seg.to_node, leaf_base, ws, + [&](std::size_t leaf_i, std::size_t k, const auto & leaf) { + for (std::size_t p = 0; p < opl; ++p) + { + const auto val = cohort_detail::lane_value< + typename key_type::exterior_node, output>(leaf, p); + const std::size_t w = leaf_i * opl + p; + acc[k] = cohort_detail::mac_add(acc[k], val, weights[w]); + } + }); + leaf_base += seg.count; + } + return acc; +} + +/// @brief Evaluate every key on one compiled recipe. +/// @details `out[q * n + k]` is key `k` at listed point `q`. +/// \complexity One recipe traversal. Each visited node is expanded for all m keys together. Scratch holds O(m L) nodes, L the recipe's leaf count. +template +void eval_sequence_cohort(const Range & keys, const sequence_recipe & recipe, + Out & out, cohort_scratch> * scratch = nullptr) +{ + cohort_detail::require_keys(keys); + using stored = std::decay_t; + using key_type = unwrap_party_key_t; + using output = typename key_type::template concrete_output_type; + cohort_scratch local; + auto & ws = scratch != nullptr ? *scratch : local; + const std::size_t n = keys.size(); + cohort_detail::ensure_size(out, recipe.output_indices().size() * n); + cohort_detail::walk_recipe(keys, recipe, ws, + [&](std::size_t q, std::size_t k, output v) { + out[cohort_index(q, k, n)] = v; + }); +} + +/// @brief Compile `[begin, end)` once, then `eval_sequence_cohort` on that recipe. +/// @throws std::runtime_error if the range is not sorted nondecreasing. +/// \complexity One recipe build, O(k log n) in the point list, then the recipe walk. +template +void eval_sequence_cohort(const Range & keys, ForwardIterator begin, + ForwardIterator end, Out & out, + cohort_scratch> * scratch = nullptr) +{ + cohort_detail::require_keys(keys); + using key_type = unwrap_party_key_t>; + auto recipe = make_sequence_recipe(begin, end); + eval_sequence_cohort(keys, recipe, out, scratch); +} + +/// @brief Inner product of a recipe's listed points. `weights[q]` pairs with point `q`. +/// \complexity Same walk as `eval_sequence_cohort`, plus one multiply-add per point per key. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_sequence_inner_product_cohort(const Range & keys, + const sequence_recipe & recipe, Weights && weights, + cohort_scratch> * scratch = nullptr) +{ + cohort_detail::require_keys(keys); + using stored = std::decay_t; + using key_type = unwrap_party_key_t; + using output = typename key_type::template concrete_output_type; + cohort_scratch local; + auto & ws = scratch != nullptr ? *scratch : local; + std::vector acc(keys.size()); + cohort_detail::walk_recipe(keys, recipe, ws, + [&](std::size_t q, std::size_t k, output v) { + acc[k] = cohort_detail::mac_add(acc[k], v, weights[q]); + }); + return acc; +} + +/// @brief Compile `[begin, end)` once, then the recipe inner product. +/// @throws std::runtime_error if the range is not sorted nondecreasing. +/// \complexity One recipe build plus the recipe inner product. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_sequence_inner_product_cohort(const Range & keys, ForwardIterator begin, + ForwardIterator end, Weights && weights, + cohort_scratch> * scratch = nullptr) +{ + cohort_detail::require_keys(keys); + using key_type = unwrap_party_key_t>; + auto recipe = make_sequence_recipe(begin, end); + return eval_sequence_inner_product_cohort(keys, recipe, + std::forward(weights), scratch); +} + +/// @brief One party's keys plus the scratch those walks reuse. +template +class cohort +{ + public: + using key_type = std::decay_t; + + cohort() = default; + explicit cohort(std::vector keys) : keys_(std::move(keys)) {} + + std::size_t size() const noexcept { return keys_.size(); } + const std::vector & keys() const noexcept { return keys_; } + std::vector & keys() noexcept { return keys_; } + cohort_scratch & scratch() noexcept { return scratch_; } + + template + void eval_point(InputT x, Out & out) + { + eval_point_cohort(keys_, x, out, &scratch_); + } + + template + void eval_interval(InputT from, InputT to, Out & out) + { + eval_interval_cohort(keys_, from, to, out, &scratch_); + } + + template + void eval_full(Out & out) + { + eval_full_cohort(keys_, out, &scratch_); + } + + template + auto eval_interval_inner_product(InputT from, InputT to, Weights && weights) + { + return eval_interval_inner_product_cohort(keys_, from, to, + std::forward(weights), &scratch_); + } + + template + void eval_sequence(const sequence_recipe & recipe, Out & out) + { + eval_sequence_cohort(keys_, recipe, out, &scratch_); + } + + template + void eval_sequence(ForwardIterator begin, ForwardIterator end, Out & out) + { + eval_sequence_cohort(keys_, begin, end, out, &scratch_); + } + + template + auto eval_sequence_inner_product(const sequence_recipe & recipe, + Weights && weights) + { + return eval_sequence_inner_product_cohort(keys_, recipe, + std::forward(weights), &scratch_); + } + + template + auto eval_sequence_inner_product(ForwardIterator begin, ForwardIterator end, + Weights && weights) + { + return eval_sequence_inner_product_cohort(keys_, begin, end, + std::forward(weights), &scratch_); + } + + private: + std::vector keys_; + cohort_scratch scratch_; +}; + +/// @brief Classic keys for one point and many payloads. +/// @details The path bit is shared. Each level expands every key's seeds with +/// `expand_x4`, then writes that key's correction word. Payloads may +/// be a single output or a `std::tuple` of outputs. Comparison, +/// incremental, verifiable, and extractable tags are not part of this +/// walk; build those with `make_dpf` one key at a time. +/// @param x plaintext domain point +/// @param begin first payload +/// @param end past the last payload +/// @return party-0 cohort and party-1 cohort, in payload order +/// \complexity O(n m) PRG calls. m is the number of payloads and n is `depth`. Roots are sampled first; each level then expands contiguous seeds. +template +HEDLEY_WARN_UNUSED_RESULT +auto make_dpf_cohort(InputT x, Iter begin, Iter end) +{ + using input_type = std::decay_t; + static_assert(!is_secret_share_v, + "make_dpf_cohort: domain point must be plaintext"); + using payload = std::decay_t; + static_assert(cohort_detail::is_std_tuple::value + || !is_secret_share_v, + "make_dpf_cohort: payloads must be plaintext"); + + std::vector ys(begin, end); + if (ys.empty()) + throw std::invalid_argument("make_dpf_cohort: no payloads"); + + using dpf_type = typename cohort_detail::cohort_dpf_type< + InteriorPRG, ExteriorPRG, input_type, payload>::type; + using node = typename dpf_type::interior_node; + using tree = typename dpf_type::tree; + using words = typename dpf_type::correction_words_array; + using advice = typename dpf_type::correction_advice_array; + using alloc = aligned_allocator; + + utils::flip_msb_if_signed_integral(x); + const std::size_t m = ys.size(); + constexpr std::size_t depth = dpf_type::depth; + + std::vector s0(m), s1(m), root0(m), root1(m); + std::vector cws(m); + std::vector adv(m); + + for (std::size_t k = 0; k < m; ++k) + { + node tmp[2]; + tree::root_init(tmp, []() -> node { + return static_cast(dpf::uniform_sample()); + }); + root0[k] = s0[k] = tmp[0]; + root1[k] = s1[k] = tmp[1]; + } + + auto mask = dpf_type::msb_mask; + for (std::size_t level = 0; level < depth; ++level, mask >>= 1) + { + const bool bit = !!(mask & x); + const bool is_last = tree::is_last_level(level, depth); + std::size_t k = 0; + auto step = [&](std::size_t i) { + const auto kids0 = tree::expand(s0[i], is_last); + const auto kids1 = tree::expand(s1[i], is_last); + const bool c0 = static_cast(dpf::get_lo_bit(s0[i])); + const bool c1 = static_cast(dpf::get_lo_bit(s1[i])); + tree::make_cw(cws[i][level], adv[i][level], kids0, kids1, + s0[i], s1[i], bit, is_last); + const node n0 = tree::advance(s0[i], kids0, cws[i][level], + adv[i][level], bit, c0, is_last); + const node n1 = tree::advance(s1[i], kids1, cws[i][level], + adv[i][level], bit, c1, is_last); + s0[i] = n0; + s1[i] = n1; + }; + for (; k + 4 <= m; k += 4) + { + alignas(node) node l0[4], r0[4], l1[4], r1[4]; + tree::expand_x4(s0.data() + k, l0, r0, is_last); + tree::expand_x4(s1.data() + k, l1, r1, is_last); + DPF_UNROLL_LOOP + for (std::size_t t = 0; t < 4; ++t) + { + const std::size_t i = k + t; + const std::array kids0{l0[t], r0[t]}; + const std::array kids1{l1[t], r1[t]}; + const bool c0 = static_cast(dpf::get_lo_bit(s0[i])); + const bool c1 = static_cast(dpf::get_lo_bit(s1[i])); + tree::make_cw(cws[i][level], adv[i][level], kids0, kids1, + s0[i], s1[i], bit, is_last); + const node n0 = tree::advance(s0[i], kids0, cws[i][level], + adv[i][level], bit, c0, is_last); + const node n1 = tree::advance(s1[i], kids1, cws[i][level], + adv[i][level], bit, c1, is_last); + s0[i] = n0; + s1[i] = n1; + } + } + for (; k < m; ++k) + step(k); + } + + using party0 = party_key<0, dpf_type>; + using party1 = party_key<1, dpf_type>; + std::vector k0; + std::vector k1; + k0.reserve(m); + k1.reserve(m); + for (std::size_t i = 0; i < m; ++i) + { + const bool sign0 = static_cast(dpf::get_lo_bit(s0[i])); + const node seed0 = dpf::unset_lo_2bits(s0[i]); + const node seed1 = dpf::unset_lo_2bits(s1[i]); + auto built = [&]() { + if constexpr (cohort_detail::is_std_tuple::value) + { + return std::apply([&](const auto & ...p) { + return dpf::make_leaves(x, seed0, seed1, sign0, + std::size_t{0}, p...); + }, ys[i]); + } + else + { + return dpf::make_leaves(x, seed0, seed1, sign0, + std::size_t{0}, ys[i]); + } + }(); + auto paired = dpf::make_party_key_pair( + dpf_type{root0[i], cws[i], adv[i], built.first.first, + built.first.second, input_type{}}, + dpf_type{root1[i], cws[i], adv[i], built.second.first, + built.second.second, input_type{}}); + k0.push_back(std::move(paired.first)); + k1.push_back(std::move(paired.second)); + } + return std::make_pair(cohort(std::move(k0)), + cohort(std::move(k1))); +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_COHORT_HPP__ diff --git a/include/dpf/compose.hpp b/include/dpf/compose.hpp new file mode 100644 index 0000000..62334d6 --- /dev/null +++ b/include/dpf/compose.hpp @@ -0,0 +1,4293 @@ +/// @file dpf/compose.hpp +/// @brief Protocol composition: domain-tagged strands on a RoundSink. +/// @details Values carry a share domain (`fss`, `a`, `b`, `rss`, `y`) matching +/// the letters in `secret_share.hpp`. Recording a composition interns +/// identical blinds, expansions, computes, and local conversions so +/// sub-strands share work. Independent opens pack into one RoundSink +/// round; dependency chains become successive waves. ABY2.0 sessions +/// contribute their δ barriers to those waves. Classic Beaver triples +/// reuse an ABY wire's λ when the factor is already in the session. +/// RSS products use `rss_mul` then `rss_from_y` for the neighbor +/// refresh. Express/Sabre audits use `*_fused`; BGI early-stop uses +/// `fss_point_early_stop`; Poplar checkpoints use `level_walk_prefixes`. +/// Doerner–Shelat walks use `level_walk_ds`; idpf_agg uses +/// `step_adaptive_prefix` / `retain_adaptive_prefix`; keyword PIR uses +/// `multipoint_fan`. Multi-lane ABY is `aby_lane`. Prepaid expands are +/// `defer_expand` / `leaf_later_walk`. Party-count changes are never +/// implied: use an explicit `reshare`. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_COMPOSE_HPP__ +#define LIBDPF_INCLUDE_DPF_COMPOSE_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "simde/simde/x86/avx.h" + +#include "hedley/hedley.h" + +#include "dpf/net/asio_ns.hpp" +#include "dpf/beaver.hpp" +#include "dpf/bit_inject.hpp" +#include "dpf/edabit.hpp" +#include "dpf/net/edge_mesh.hpp" +#include "dpf/net/io_pool.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/net/stream_edge_mesh.hpp" +#include "dpf/trunc.hpp" +#include "dpf/net/round_sink.hpp" +#include "dpf/net/sink_exchange.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/protocol.hpp" +#include "dpf/rss_seed.hpp" +#include "dpf/secret_share.hpp" + +namespace dpf +{ +namespace protocol +{ + +struct drive_options; +struct beaver_host; + +enum class domain : unsigned char +{ + fss = 0, + a = 1, + b = 2, + rss = 3, + y = 4, + bin = 5, ///< (2,2) XOR bit shares (packed) + bin_rss = 6 ///< (2,3) replicated bits +}; + +enum class effect : unsigned char +{ + input = 0, + blind = 1, + expand = 2, + compute = 3, + exchange = 4, + convert = 5 +}; + +enum class op_flags : unsigned +{ + none = 0, + commutative = 1u +}; + +inline constexpr op_flags operator|(op_flags a, op_flags b) noexcept +{ + return static_cast( + static_cast(a) | static_cast(b)); +} + +HEDLEY_CONST +HEDLEY_NO_THROW +inline constexpr bool has_flag(op_flags f, op_flags bit) noexcept +{ + return (static_cast(f) & static_cast(bit)) != 0; +} + +namespace opcodes +{ +constexpr std::uint32_t conv_a2b = 1; +constexpr std::uint32_t conv_b2a = 2; +constexpr std::uint32_t conv_a2fss = 3; +constexpr std::uint32_t conv_fss2a = 4; +constexpr std::uint32_t conv_b2fss = 5; +constexpr std::uint32_t conv_fss2b = 6; +constexpr std::uint32_t conv_rss2y = 7; +constexpr std::uint32_t conv_y2rss = 8; +constexpr std::uint32_t reshare_mask = 9; ///< Local masked reshare (no open) +constexpr std::uint32_t rss_mul = 100; +constexpr std::uint32_t fss_expand = 200; +constexpr std::uint32_t fss_expand_pair = 202; ///< Both children in one PRG stretch +constexpr std::uint32_t fss_step = 201; +constexpr std::uint32_t fss_fuse_trailer = 203; ///< Pack step‖sketch into one slot +constexpr std::uint32_t fss_early_stop_pack = 204; ///< BGI Remark 3.4 leaf pack (local) +constexpr std::uint32_t fss_prefix_emit = 205; ///< Prefix share at a walk checkpoint +constexpr std::uint32_t fss_defer_expand = 206; ///< Prepaid full expand (no CW open) +constexpr std::uint32_t fss_rotate = 207; ///< Local rotate of a share buffer +constexpr std::uint32_t fss_leaf_later = 208; ///< Path walk; leaf CW applied later +constexpr std::uint32_t fss_apply_leaf = 209; ///< `buf += F * control` (local) +constexpr std::uint32_t fss_prefix_pair = 210; ///< Pack L‖R child opens (idpf_agg) +constexpr std::uint32_t fss_prefix_retain = 211; ///< Keep one child after open +constexpr std::uint32_t fss_answer_pack = 212; ///< Pack multipoint / bucket answers +constexpr std::uint32_t fss_fuse_segment = 213; ///< Slice one fused open (level = offset) +constexpr std::uint32_t ds_blind = 220; ///< Doerner–Shelat blind open +constexpr std::uint32_t ds_cw = 221; ///< Correction-word share open +constexpr std::uint32_t ds_advice = 222; ///< Advice-bit open +constexpr std::uint32_t ds_and = 223; ///< Bit-block AND round 1 +constexpr std::uint32_t ds_and2 = 227; ///< Bit-block AND round 2 +constexpr std::uint32_t ds_oh = 224; ///< Oblivious-hash AND layer open +constexpr std::uint32_t ds_leaf_mux = 225; ///< Packed-leaf mux open +constexpr std::uint32_t dealer_pad = 226; ///< p2 → parties pad / tape delivery +constexpr std::uint32_t dealer_zero = 228; ///< p2 samples a sharing of zero +constexpr std::uint32_t client_upload = 229; ///< Client sends one query to each server +constexpr std::uint32_t client_answer = 230; ///< Each server returns one answer share +constexpr std::uint32_t beaver_delta = 300; +constexpr std::uint32_t bin_a2b = 400; +constexpr std::uint32_t bin_b2a = 401; +constexpr std::uint32_t bin_inject = 402; +constexpr std::uint32_t bin_and = 403; +constexpr std::uint32_t bin_rss_and = 404; +constexpr std::uint32_t bin_rss_inject = 405; +constexpr std::uint32_t rss_zero = 406; ///< Pairwise-seed zero mask (local) +constexpr std::uint32_t trunc_prob = 410; +constexpr std::uint32_t trunc_exact = 411; +constexpr std::uint32_t mul_trunc = 412; +constexpr std::uint32_t share_cmp = 420; +constexpr std::uint32_t share_mux = 421; +constexpr std::uint32_t declassify = 430; +constexpr std::uint32_t share_input = 431; +constexpr std::uint32_t matmul_open = 440; +constexpr std::uint32_t shuffle_send = 441; ///< One hidden-shuffle pass (`shuffle::shuffle_hidden_pass`) +constexpr std::uint32_t bench_emit = 450; ///< Local half of a bench cell (aux = cell id) +constexpr std::uint32_t bench_apply = 451; ///< Evaluator half, after the payload arrives +constexpr std::uint32_t bench_wire = 452; ///< 2-party payload on the peer edge +constexpr std::uint32_t bench_ring = 453; ///< 3-party payload on the RSS ring +constexpr std::uint32_t user_base = 1000; +} // namespace opcodes + +struct node +{ + std::uint32_t id = 0; + friend bool operator==(node a, node b) noexcept { return a.id == b.id; } + friend bool operator!=(node a, node b) noexcept { return !(a == b); } +}; + +struct block_span +{ + std::uint8_t * data = nullptr; + std::size_t lanes = 0; + std::size_t value_bytes = 0; + + std::uint8_t * at(std::size_t lane) const + { + return data + lane * value_bytes; + } + + simde__m128i load128(std::size_t lane) const + { + if (value_bytes != 16) + throw std::logic_error("block_span::load128 requires 16-byte values"); + simde__m128i v; + std::memcpy(&v, at(lane), 16); + return v; + } + + void store128(std::size_t lane, simde__m128i v) const + { + if (value_bytes != 16) + throw std::logic_error("block_span::store128 requires 16-byte values"); + std::memcpy(at(lane), &v, 16); + } +}; + +using kernel_fn = std::function & nodes, const std::vector & inputs, + block_span output, std::size_t sink_lanes)>; + +struct simd_group +{ + std::uint32_t opcode = 0; + effect kind = effect::compute; + std::vector nodes; +}; + +struct wave_info +{ + std::size_t index = 0; + std::vector groups; + std::vector exchanges; + std::size_t slot_bytes = 0; +}; + +class plan +{ +public: + /// @brief Full dependency waves (includes trailing compute-only waves). + HEDLEY_NO_THROW + std::size_t waves() const noexcept { return waves_.size(); } + + /// @brief RoundSink flushes — equal to `exchange_waves()`, not `waves()`. + /// @details The online plan and the sink share this count: no empty rounds. + HEDLEY_NO_THROW + std::size_t rounds() const noexcept { return exchange_waves(); } + + HEDLEY_WARN_UNUSED_RESULT + std::size_t slot_bytes(std::uint16_t round) const + { + std::size_t seen = 0; + for (const auto & w : waves_) + { + if (w.exchanges.empty()) + continue; + if (seen == round) + return w.slot_bytes; + ++seen; + } + throw std::out_of_range("plan::slot_bytes"); + } + + /// @brief Slot widths for each RoundSink round (exchange-bearing only). + HEDLEY_WARN_UNUSED_RESULT + std::vector slot_bytes_all() const + { + std::vector out; + out.reserve(waves_.size()); + for (const auto & w : waves_) + if (!w.exchanges.empty()) + out.push_back(w.slot_bytes); + return out; + } + + /// @brief Tail of `slot_bytes_all` starting at exchange-wave `from`. + HEDLEY_WARN_UNUSED_RESULT + std::vector slot_bytes_from(std::size_t from_exchange_wave) const + { + auto all = slot_bytes_all(); + if (from_exchange_wave >= all.size()) + return {}; + return {all.begin() + + static_cast(from_exchange_wave), + all.end()}; + } + + HEDLEY_WARN_UNUSED_RESULT + const wave_info & wave(std::size_t i) const + { + if (i >= waves_.size()) + throw std::out_of_range("plan::wave"); + return waves_[i]; + } + + HEDLEY_WARN_UNUSED_RESULT + std::size_t wave_of(node n) const + { + return node_wave_.at(n.id); + } + + HEDLEY_WARN_UNUSED_RESULT + std::size_t effect_count(effect e) const + { + auto it = effect_counts_.find(e); + return it == effect_counts_.end() ? 0 : it->second; + } + + /// @brief Waves that actually flush on the wire (alias of `rounds()`). + HEDLEY_NO_THROW + HEDLEY_WARN_UNUSED_RESULT + std::size_t exchange_waves() const noexcept + { + std::size_t n = 0; + for (const auto & w : waves_) + if (!w.exchanges.empty()) + ++n; + return n; + } + + HEDLEY_WARN_UNUSED_RESULT + std::size_t conversion_count(domain from, domain to) const + { + auto it = conversion_counts_.find({from, to}); + return it == conversion_counts_.end() ? 0 : it->second; + } + + HEDLEY_NO_THROW + HEDLEY_WARN_UNUSED_RESULT + const std::vector & nodes() const noexcept { return all_nodes_; } + + HEDLEY_WARN_UNUSED_RESULT + std::size_t value_bytes_of(std::uint32_t id) const + { + return value_bytes_.at(id); + } + + HEDLEY_WARN_UNUSED_RESULT + domain domain_of(std::uint32_t id) const + { + return domains_.at(id); + } + + HEDLEY_WARN_UNUSED_RESULT + const std::vector & inputs_of(std::uint32_t id) const + { + return inputs_.at(id); + } + + HEDLEY_WARN_UNUSED_RESULT + std::uint32_t opcode_of(std::uint32_t id) const + { + return opcodes_.at(id); + } + + HEDLEY_WARN_UNUSED_RESULT + bool alias_of(std::uint32_t id) const + { + return alias_bytes_.at(id); + } + + /// @brief Intern key `level` (ABY session index for beaver barriers). + HEDLEY_WARN_UNUSED_RESULT + std::uint16_t level_of(std::uint32_t id) const + { + return levels_.at(id); + } + + /// @brief Byte offset (fuse segments) or other per-node aux. + HEDLEY_WARN_UNUSED_RESULT + std::uint32_t aux_of(std::uint32_t id) const + { + return aux_.at(id); + } + + /// @brief Online exchanges plus a setup cost (IKNP `setup_rounds`, dealer tape, …). + HEDLEY_WARN_UNUSED_RESULT + std::size_t rounds_including(std::size_t setup_rounds) const + { + return rounds() + setup_rounds; + } + + HEDLEY_WARN_UNUSED_RESULT + effect effect_of(std::uint32_t id) const + { + return effects_.at(id); + } + + /// @brief Sum of exchange slot bytes tagged setup (pad / IKNP). + HEDLEY_NO_THROW + std::size_t setup_bytes() const noexcept { return setup_bytes_; } + + /// @brief Sum of exchange slot bytes tagged online. + HEDLEY_NO_THROW + std::size_t online_bytes() const noexcept { return online_bytes_; } + +private: + friend class composer; + friend void drive(const plan &, net::RoundSink &, + std::vector> &, + const std::map &, std::size_t, + const struct drive_options &); + + std::vector waves_; + std::map effect_counts_; + std::map, std::size_t> conversion_counts_; + std::vector all_nodes_; + std::vector node_wave_; + std::vector value_bytes_; + std::vector domains_; + std::vector effects_; + std::vector opcodes_; + std::vector levels_; + std::vector aux_; + std::vector> inputs_; + std::vector alias_bytes_; + std::size_t setup_bytes_ = 0; + std::size_t online_bytes_ = 0; +}; + +namespace detail +{ + +HEDLEY_CONST +HEDLEY_NO_THROW +inline bool is_two_party(domain d) noexcept +{ + return d == domain::fss || d == domain::a || d == domain::b + || d == domain::bin; +} + +HEDLEY_CONST +HEDLEY_NO_THROW +inline bool is_boolean(domain d) noexcept +{ + return d == domain::bin || d == domain::bin_rss; +} + +HEDLEY_CONST +HEDLEY_NO_THROW +inline bool local_convertible(domain from, domain to) noexcept +{ + if (from == to) + return true; + // Boolean domains never locally cast to/from arithmetic or FSS. + if (is_boolean(from) || is_boolean(to)) + return false; + if (is_two_party(from) && is_two_party(to) + && from != domain::bin && to != domain::bin) + return true; + if ((from == domain::rss && to == domain::y) + || (from == domain::y && to == domain::rss)) + return true; + return false; +} + +HEDLEY_WARN_UNUSED_RESULT +inline std::uint32_t conversion_opcode(domain from, domain to) +{ + if (from == domain::a && to == domain::b) + return opcodes::conv_a2b; + if (from == domain::b && to == domain::a) + return opcodes::conv_b2a; + if (from == domain::a && to == domain::fss) + return opcodes::conv_a2fss; + if (from == domain::fss && to == domain::a) + return opcodes::conv_fss2a; + if (from == domain::b && to == domain::fss) + return opcodes::conv_b2fss; + if (from == domain::fss && to == domain::b) + return opcodes::conv_fss2b; + if (from == domain::rss && to == domain::y) + return opcodes::conv_rss2y; + if (from == domain::y && to == domain::rss) + return opcodes::conv_y2rss; + throw std::invalid_argument("compose: no local conversion between domains"); +} + +HEDLEY_CONST +HEDLEY_NO_THROW +inline bool bit_preserving_cast(domain from, domain to, std::size_t party) noexcept +{ + if (from == to) + return true; + if ((from == domain::b && to == domain::fss) + || (from == domain::fss && to == domain::b)) + return true; + if (party == 0 + && ((from == domain::a && to == domain::b) + || (from == domain::b && to == domain::a) + || (from == domain::a && to == domain::fss) + || (from == domain::fss && to == domain::a))) + return true; + return false; +} + +struct intern_key +{ + effect kind{}; + domain dom{}; + std::uint32_t opcode = 0; + std::uint16_t level = 0; + std::uint8_t child = 0; + std::uint32_t aux = 0; + std::vector inputs; + + friend bool operator==(const intern_key & a, const intern_key & b) noexcept + { + return a.kind == b.kind && a.dom == b.dom && a.opcode == b.opcode + && a.level == b.level && a.child == b.child && a.aux == b.aux + && a.inputs == b.inputs; + } +}; + +struct intern_key_hash +{ + std::size_t operator()(const intern_key & k) const noexcept + { + std::size_t h = static_cast(k.kind); + h = h * 131u + static_cast(k.dom); + h = h * 131u + k.opcode; + h = h * 131u + k.level; + h = h * 131u + k.child; + h = h * 131u + k.aux; + for (auto id : k.inputs) + h = h * 131u + id; + return h; + } +}; + +struct aby_slot_key +{ + std::type_index type; + std::size_t lane = 0; + + bool operator<(const aby_slot_key & o) const noexcept + { + if (type < o.type) + return true; + if (o.type < type) + return false; + return lane < o.lane; + } + + bool operator==(const aby_slot_key & o) const noexcept + { + return type == o.type && lane == o.lane; + } +}; + +struct aby_holder_base +{ + virtual ~aby_holder_base() = default; + virtual std::type_index type() const noexcept = 0; + virtual std::size_t wire_count() const = 0; + virtual std::size_t barrier_count() const = 0; + virtual std::size_t ring_bytes() const = 0; +}; + +template +struct aby_holder final : aby_holder_base +{ + beavers::session session; + + std::type_index type() const noexcept override + { + return std::type_index(typeid(Ring)); + } + std::size_t wire_count() const override { return session.wire_count(); } + std::size_t barrier_count() const override + { + return session.exchange_barriers().size(); + } + std::size_t ring_bytes() const override { return sizeof(Ring); } +}; + +inline void run_builtin_convert(std::uint32_t opcode, std::size_t party, + const std::uint8_t * in, std::size_t in_bytes, std::uint8_t * out, + std::size_t out_bytes) +{ + if (opcode == opcodes::conv_b2fss || opcode == opcodes::conv_fss2b + || (party == 0 + && (opcode == opcodes::conv_a2b || opcode == opcodes::conv_b2a + || opcode == opcodes::conv_a2fss + || opcode == opcodes::conv_fss2a))) + { + if (in_bytes != out_bytes) + throw std::logic_error("compose convert size"); + std::memcpy(out, in, out_bytes); + return; + } + if (opcode == opcodes::conv_a2b || opcode == opcodes::conv_b2a + || opcode == opcodes::conv_a2fss || opcode == opcodes::conv_fss2a) + { + if (in_bytes != out_bytes) + throw std::logic_error("compose convert size"); + std::vector tmp(in, in + in_bytes); + unsigned borrow = 1; + for (std::size_t i = 0; i < tmp.size(); ++i) + { + const unsigned x = + static_cast(static_cast(~tmp[i])) + borrow; + tmp[i] = static_cast(x); + borrow = x >> 8; + } + std::memcpy(out, tmp.data(), out_bytes); + return; + } + if (opcode == opcodes::conv_rss2y) + { + const std::size_t n = std::min(out_bytes, in_bytes); + std::memcpy(out, in, n); + return; + } + if (opcode == opcodes::conv_y2rss) + { + if (in_bytes != out_bytes) + throw std::logic_error("compose y2rss size"); + std::memcpy(out, in, out_bytes); + return; + } + throw std::invalid_argument("compose: unknown convert opcode"); +} + +} // namespace detail + +class composer +{ +public: + explicit composer(std::size_t party = 0) : party_(party) + { + // Party id is free-form: 2-party, 3-party RSS, and N-party meshes all + // use the same composer; topology is chosen by the drive/mesh binding. + } + + HEDLEY_NO_THROW + HEDLEY_WARN_UNUSED_RESULT + std::size_t party() const noexcept { return party_; } + + HEDLEY_WARN_UNUSED_RESULT + node input(domain dom, std::size_t value_bytes) + { + // Inputs are never interned: each call is a distinct free value. + node_info ni; + ni.kind = effect::input; + ni.dom = dom; + ni.value_bytes = value_bytes; + const auto id = static_cast(info_.size()); + info_.push_back(std::move(ni)); + return node{id}; + } + + node blind(node src, std::uint32_t opcode) + { + check(src); + return emplace(effect::blind, info_[src.id].dom, opcode, {src.id}, + info_[src.id].value_bytes, 0, 0, op_flags::none, false, domain::a); + } + + node expand(node src, std::uint16_t level, std::uint8_t child, + std::uint32_t opcode, std::size_t value_bytes) + { + check(src); + return emplace(effect::expand, info_[src.id].dom, opcode, {src.id}, + value_bytes, level, child, op_flags::none, false, domain::a); + } + + node compute(std::uint32_t opcode, std::vector inputs, domain dom, + std::size_t value_bytes, op_flags flags = op_flags::none) + { + std::vector ids; + ids.reserve(inputs.size()); + for (auto n : inputs) + { + check(n); + ids.push_back(n.id); + } + if (has_flag(flags, op_flags::commutative)) + std::sort(ids.begin(), ids.end()); + return emplace(effect::compute, dom, opcode, std::move(ids), + value_bytes, 0, 0, flags, false, domain::a); + } + + node exchange(node payload) + { + check(payload); + return emplace(effect::exchange, info_[payload.id].dom, 0, {payload.id}, + info_[payload.id].value_bytes, 0, 0, op_flags::none, false, + domain::a); + } + + node as(node src, domain to) + { + check(src); + const domain from = info_[src.id].dom; + if (from == to) + return src; + if (!detail::local_convertible(from, to)) + { + throw std::invalid_argument( + "compose::as cannot change party count; use reshare"); + } + if (from == domain::y && to == domain::rss) + { + throw std::invalid_argument( + "compose::as(y, rss) needs own and next; use y2rss(own, next)"); + } + if (info_[src.id].kind == effect::convert) + { + if (info_[src.id].from_domain == to && !info_[src.id].inputs.empty()) + return node{info_[src.id].inputs[0]}; + } + const auto opcode = detail::conversion_opcode(from, to); + const bool alias = detail::bit_preserving_cast(from, to, party_); + std::size_t bytes = info_[src.id].value_bytes; + if (from == domain::rss && to == domain::y && bytes >= 2) + bytes = bytes / 2; + return emplace(effect::convert, to, opcode, {src.id}, bytes, 0, 0, + op_flags::none, alias, from); + } + + node y2rss(node own, node next) + { + check(own); + check(next); + if (info_[own.id].dom != domain::y || info_[next.id].dom != domain::y) + throw std::invalid_argument("y2rss requires y-domain nodes"); + return emplace(effect::convert, domain::rss, opcodes::conv_y2rss, + {own.id, next.id}, info_[own.id].value_bytes * 2, 0, 0, + op_flags::none, false, domain::y); + } + + /// @brief Re-share a local RSS product factor (`y`) back to replicated form. + /// @details Hand 3PC schedules exchange each party's `y` component with a + /// neighbor in one round, then `y2rss(own, next)`. Independent + /// refreshes pack into the same wave. Prefer this over `reshare`: + /// a reconstructing `exchange` would open the secret. + HEDLEY_WARN_UNUSED_RESULT + node rss_from_y(node y_own) + { + check(y_own); + if (info_[y_own.id].dom != domain::y) + throw std::invalid_argument("rss_from_y requires a y-domain node"); + node peer = exchange(y_own); + return y2rss(y_own, peer); + } + + /// @brief Local `rss_mul` then one-round neighbor refresh to RSS. + HEDLEY_WARN_UNUSED_RESULT + node rss_product_replicated(node x, node y) + { + return rss_from_y(rss_product(x, y)); + } + + node reshare(node src, domain to) + { + check(src); + if (info_[src.id].dom == domain::y && to == domain::rss) + return rss_from_y(src); + if (to == domain::rss && detail::is_two_party(info_[src.id].dom)) + { + // Local y-component (p2's share stays 0) then one neighbor refresh. + // Does not reconstruct the secret. + node y = emplace(effect::convert, domain::y, opcodes::conv_rss2y, + {src.id}, info_[src.id].value_bytes, 0, 0, op_flags::none, + true, info_[src.id].dom); + return rss_from_y(y); + } + if (detail::local_convertible(info_[src.id].dom, to) + && !(info_[src.id].dom == domain::y && to == domain::rss)) + return as(src, to); + throw std::invalid_argument( + "reshare would open the secret; use rss_from_y or reshare_fresh"); + } + + /// @brief p2 samples a sharing of zero and delivers one share to each party. + HEDLEY_WARN_UNUSED_RESULT + node dealer_zero_mask(domain to, std::size_t bytes) + { + if (bytes == 0) + throw std::invalid_argument("dealer_zero_mask bytes must be > 0"); + node payload = input(to, bytes); + return emplace(effect::exchange, to, opcodes::dealer_zero, {payload.id}, + bytes, 0, 0, op_flags::none, false, to); + } + + /// @brief Pairwise-seed zero mask: local compute, no dealer edge. + /// @details Fills `bytes` from RSS pairwise seeds at `seed_index`. Online + /// drive kernels call `rss::zero_share` when this opcode runs. + HEDLEY_WARN_UNUSED_RESULT + node rss_zero_mask(domain to, std::size_t bytes, std::uint32_t seed_index = 0) + { + if (bytes == 0) + throw std::invalid_argument("rss_zero_mask bytes must be > 0"); + if (to != domain::rss && to != domain::a && to != domain::y + && to != domain::bin_rss) + throw std::invalid_argument("rss_zero_mask domain"); + return emplace(effect::compute, to, opcodes::rss_zero, {}, bytes, 0, 0, + op_flags::none, false, to, seed_index); + } + + /// @brief One bench cell on the peer edge: emit, send, then the evaluator applies. + /// @details `aux` is the cell id. `nbytes` is the payload. The local work is + /// `drive_options::cell`. + HEDLEY_WARN_UNUSED_RESULT + node bench_peer(std::uint32_t cell, std::size_t nbytes) + { + if (nbytes == 0) + throw std::invalid_argument("bench_peer"); + node in = input(domain::a, 8); + node produced = emplace(effect::compute, domain::a, opcodes::bench_emit, + {in.id}, nbytes, 0, 0, op_flags::none, false, domain::a, cell); + node sent = emplace(effect::exchange, domain::a, opcodes::bench_wire, + {produced.id}, nbytes, 0, 0, op_flags::none, false, domain::a, cell); + return emplace(effect::compute, domain::a, opcodes::bench_apply, + {sent.id}, 8, 0, 0, op_flags::none, false, domain::a, cell); + } + + /// @brief Three bench passes on the RSS ring. `aux` packs the cell and the pass. + HEDLEY_WARN_UNUSED_RESULT + node bench_ring(std::uint32_t cell, std::size_t nbytes) + { + if (nbytes == 0) + throw std::invalid_argument("bench_ring"); + node cur = input(domain::rss, nbytes); + for (unsigned pass = 0; pass < 3; ++pass) + { + const auto aux = cell | (pass << 16); + node produced = emplace(effect::compute, domain::rss, opcodes::bench_emit, + {cur.id}, nbytes, 0, 0, op_flags::none, false, domain::rss, aux); + cur = emplace(effect::exchange, domain::rss, opcodes::bench_ring, + {produced.id}, nbytes, 0, 0, op_flags::none, false, domain::rss, aux); + } + return cur; + } + + /// @brief Three hidden-shuffle passes on one replicated array. + /// @details Each pass is one `shuffle_send` exchange. `aux` is the party + /// left out of that pass: 2, then 0, then 1. Messages travel to + /// the sender's RSS neighbor. The bytes are the whole array. + /// Party code is `shuffle::shuffle_hidden_pass`. + HEDLEY_WARN_UNUSED_RESULT + node shuffle_hidden(std::size_t n, std::size_t value_bytes) + { + if (n == 0 || value_bytes == 0) + throw std::invalid_argument("shuffle_hidden"); + const std::size_t bytes = n * value_bytes; + node cur = input(domain::rss, bytes); + for (unsigned left : {2u, 0u, 1u}) + { + cur = emplace(effect::exchange, domain::rss, opcodes::shuffle_send, + {cur.id}, bytes, 0, 0, op_flags::none, false, domain::rss, left); + } + return cur; + } + + /// @brief Reshare under a dealer-sampled zero mask (one delivery, no open). + HEDLEY_WARN_UNUSED_RESULT + node reshare_fresh(node src, domain to) + { + check(src); + node mask = dealer_zero_mask(to, info_[src.id].value_bytes); + return reshare_with_mask(src, mask, to); + } + + /// @brief Privacy-preserving reshare: `out = src + mask` locally. + /// @details `mask` is a fresh sharing of zero already in domain `to` + /// (typically from `dealer_deliver`). No reconstructing open. + HEDLEY_WARN_UNUSED_RESULT + node reshare_with_mask(node src, node mask, domain to) + { + check(src); + check(mask); + if (info_[src.id].value_bytes != info_[mask.id].value_bytes) + throw std::invalid_argument("reshare_with_mask size mismatch"); + return compute(opcodes::reshare_mask, {src, mask}, to, + info_[src.id].value_bytes); + } + + /// @brief One client and `servers` parallel servers. Two waves, no server-server open. + /// @details Wave 1 is the upload (`servers * query_bytes`). Wave 2 is the + /// answers (`servers * answer_bytes`). Servers do not talk to + /// each other; a two-party drive copies the peer message. + struct client_query + { + node upload{}; + node answer{}; + }; + + HEDLEY_WARN_UNUSED_RESULT + client_query client_servers(std::size_t servers, std::size_t query_bytes, + std::size_t answer_bytes) + { + if (servers < 2) + throw std::invalid_argument("client_servers needs at least two servers"); + if (query_bytes == 0 || answer_bytes == 0) + throw std::invalid_argument("client_servers sizes must be > 0"); + node query = input(domain::a, servers * query_bytes); + client_query q; + q.upload = emplace(effect::exchange, domain::a, opcodes::client_upload, + {query.id}, servers * query_bytes, 0, 0, op_flags::none, false, + domain::a); + node formed = compute(opcodes::client_answer, {q.upload}, domain::a, + servers * answer_bytes); + q.answer = emplace(effect::exchange, domain::a, opcodes::client_answer, + {formed.id}, servers * answer_bytes, 0, 0, op_flags::none, false, + domain::a); + return q; + } + + /// @brief p2 delivers `payload` to p0 and p1 (one exchange, no reconstruct). + /// @details Drive with `drive_composed_trio`. RoundSink `drive` rejects it. + HEDLEY_WARN_UNUSED_RESULT + node dealer_deliver(node payload) + { + check(payload); + return emplace(effect::exchange, info_[payload.id].dom, opcodes::dealer_pad, + {payload.id}, info_[payload.id].value_bytes, 0, 0, op_flags::none, + false, info_[payload.id].dom); + } + + /// @brief Fuse several payloads into one open, then local segment nodes. + struct fuse_result + { + node opened{}; + std::vector segments; + }; + + HEDLEY_WARN_UNUSED_RESULT + fuse_result exchange_fuse(const std::vector & parts) + { + if (parts.size() < 2) + throw std::invalid_argument("exchange_fuse needs at least two parts"); + std::size_t total = 0; + for (auto n : parts) + { + check(n); + total += info_[n.id].value_bytes; + } + node packed = compute(opcodes::fss_answer_pack, parts, + info_[parts[0].id].dom, total); + fuse_result fr; + fr.opened = exchange(packed); + std::size_t off = 0; + fr.segments.reserve(parts.size()); + for (auto n : parts) + { + const auto width = info_[n.id].value_bytes; + node seg = emplace(effect::compute, info_[n.id].dom, + opcodes::fss_fuse_segment, {fr.opened.id}, width, + 0, 0, op_flags::none, false, info_[n.id].dom, + static_cast(off)); + fr.segments.push_back(seg); + off += width; + } + return fr; + } + + template + std::vector fan(std::size_t n, Fn && fn) + { + std::vector out; + out.reserve(n); + for (std::size_t i = 0; i < n; ++i) + out.push_back(fn(i)); + return out; + } + + /// @brief One PRG stretch producing both children (hand DPF schedules do + /// this; separate `expand(..., 0/1)` doubles AES on PIR/Duoram walks). + node expand_pair(node src, std::uint16_t level, std::uint32_t opcode, + std::size_t child_bytes) + { + check(src); + return emplace(effect::expand, info_[src.id].dom, opcode, {src.id}, + child_bytes * 2, level, /*both*/ 2, op_flags::none, false, + domain::a); + } + + /// @brief Result of a walk whose last CW slot carries an auxiliary trailer + /// (Express sketch / Sabre proof share) — one RoundSink round, not two. + struct walk_result + { + node leaf{}; + node trailer_open{}; ///< Reconstructed trailer from the fused exchange + node fused_exchange{}; + }; + + node level_walk(node seed, std::size_t depth, std::size_t slot_bytes, + std::uint32_t expand_op = opcodes::fss_expand_pair, + std::uint32_t step_op = opcodes::fss_step) + { + return level_walk_impl(seed, depth, slot_bytes, node{}, 0, expand_op, + step_op).leaf; + } + + /// @brief Like `level_walk`, but packs `trailer` into the last exchange. + /// @details Hand Express/Sabre schedules fold the audit/proof share into the + /// final CW flush so the sketch does not add a round. `trailer_open` + /// is the opened trailer payload from that same wave. + walk_result level_walk_fused(node seed, std::size_t depth, + std::size_t slot_bytes, node trailer, + std::uint32_t expand_op = opcodes::fss_expand_pair, + std::uint32_t step_op = opcodes::fss_step) + { + check(trailer); + return level_walk_impl(seed, depth, slot_bytes, trailer, + info_[trailer.id].value_bytes, expand_op, step_op); + } + + node fss_point(node seed, std::size_t depth, std::size_t slot_bytes) + { + node leaf = level_walk(seed, depth, slot_bytes); + info_[leaf.id].dom = domain::b; + return leaf; + } + + walk_result fss_point_fused(node seed, std::size_t depth, + std::size_t slot_bytes, node trailer) + { + auto wr = level_walk_fused(seed, depth, slot_bytes, trailer); + info_[wr.leaf.id].dom = domain::b; + return wr; + } + + node fss_cmp(node seed, std::size_t depth, std::size_t slot_bytes) + { + node leaf = level_walk(seed, depth, slot_bytes); + info_[leaf.id].dom = domain::a; + return leaf; + } + + walk_result fss_cmp_fused(node seed, std::size_t depth, + std::size_t slot_bytes, node trailer) + { + auto wr = level_walk_fused(seed, depth, slot_bytes, trailer); + info_[wr.leaf.id].dom = domain::a; + return wr; + } + + /// @brief BGI Remark 3.4 early-stop: only `full_depth - early_stop` CW rounds. + /// @details The remaining `early_stop` domain bits select a lane inside one + /// λ-bit leaf locally — Pika bit leaves and small-output PIR keys. + /// Hand schedules drop those interactive levels; a full `fss_point` + /// would pay them. + node fss_point_early_stop(node seed, std::size_t full_depth, + std::size_t early_stop, std::size_t slot_bytes) + { + if (early_stop >= full_depth) + throw std::invalid_argument("early_stop must be < full_depth"); + const std::size_t interactive = full_depth - early_stop; + node tip = level_walk(seed, interactive, slot_bytes); + node leaf = compute(opcodes::fss_early_stop_pack, {tip}, domain::b, + slot_bytes); + info_[leaf.id].level = static_cast(early_stop); + return leaf; + } + + node fss_cmp_early_stop(node seed, std::size_t full_depth, + std::size_t early_stop, std::size_t slot_bytes) + { + if (early_stop >= full_depth) + throw std::invalid_argument("early_stop must be < full_depth"); + const std::size_t interactive = full_depth - early_stop; + node tip = level_walk(seed, interactive, slot_bytes); + node leaf = compute(opcodes::fss_early_stop_pack, {tip}, domain::a, + slot_bytes); + info_[leaf.id].level = static_cast(early_stop); + return leaf; + } + + /// @brief Poplar / idpf_agg: emit a prefix share after each CW — no extra rounds. + struct prefix_walk_result + { + std::vector at_level; ///< Prefix output after level i's exchange + node tip{}; + }; + + prefix_walk_result level_walk_prefixes(node seed, std::size_t depth, + std::size_t slot_bytes, std::size_t prefix_bytes, + std::uint32_t expand_op = opcodes::fss_expand_pair, + std::uint32_t step_op = opcodes::fss_step) + { + check(seed); + if (depth == 0) + throw std::invalid_argument("level_walk_prefixes depth must be positive"); + prefix_walk_result wr; + wr.at_level.reserve(depth); + node state = seed; + for (std::size_t level = 0; level < depth; ++level) + { + node kids = expand_pair(state, static_cast(level), + expand_op, slot_bytes); + node step = compute(step_op, {kids}, info_[state.id].dom, slot_bytes); + node msg = exchange(step); + state = compute(step_op + 1, {kids, msg}, info_[state.id].dom, + slot_bytes); + wr.at_level.push_back(compute(opcodes::fss_prefix_emit, {state}, + domain::a, prefix_bytes)); + } + wr.tip = state; + return wr; + } + + /// @brief DCF `block_width` / variable CW size: one slot width per level. + node level_walk_sized(node seed, + const std::vector & slot_bytes_per_level, + std::uint32_t expand_op = opcodes::fss_expand_pair, + std::uint32_t step_op = opcodes::fss_step) + { + return level_walk_sized_impl(seed, slot_bytes_per_level, node{}, 0, + expand_op, step_op).leaf; + } + + walk_result level_walk_sized_fused(node seed, + const std::vector & slot_bytes_per_level, node trailer, + std::uint32_t expand_op = opcodes::fss_expand_pair, + std::uint32_t step_op = opcodes::fss_step) + { + check(trailer); + return level_walk_sized_impl(seed, slot_bytes_per_level, trailer, + info_[trailer.id].value_bytes, expand_op, step_op); + } + + /// @brief Doerner–Shelat interactive walk: blind‖CW‖advice‖AND per level. + /// @details Matches the classic 4-open/level shape. Oblivious-hash mode + /// emits `net::ds_oh_exchanges_per_level` AND-layer opens (Boyar– + /// Peralta SubBytes depth) at `net::ds_oh_slot_bytes`. Prefer + /// `level_walk_ds_sized` with `net::compose_ds_slot_bytes` when + /// RoundSink widths must match the schedule exactly. + HEDLEY_WARN_UNUSED_RESULT + node level_walk_ds(node seed, std::size_t depth, std::size_t slot_bytes, + bool with_oblivious_hash = false, std::size_t lg_outputs = 0, + std::uint32_t expand_op = opcodes::fss_expand_pair) + { + auto slots = net::compose_ds_slot_bytes(depth, slot_bytes, + with_oblivious_hash, lg_outputs); + return level_walk_ds_sized(seed, slots, with_oblivious_hash, lg_outputs, + expand_op); + } + + /// @brief DS walk with per-exchange slot widths (see `compose_ds_slot_bytes`). + HEDLEY_WARN_UNUSED_RESULT + node level_walk_ds_sized(node seed, const std::vector & slots, + bool with_oblivious_hash = false, std::size_t lg_outputs = 0, + std::uint32_t expand_op = opcodes::fss_expand_pair) + { + check(seed); + if (slots.empty()) + throw std::invalid_argument("level_walk_ds_sized needs slot widths"); + std::size_t si = 0; + auto next_slot = [&]() -> std::size_t { + if (si >= slots.size()) + throw std::out_of_range("level_walk_ds_sized: slot vector short"); + const auto s = slots[si++]; + if (s == 0) + throw std::invalid_argument("level_walk_ds_sized slot must be > 0"); + return s; + }; + // Infer depth from slot layout when possible; otherwise walk until + // slots are exhausted for the 4(+OH) pattern. + const std::size_t per_level = + 5 + (with_oblivious_hash ? net::ds_oh_exchanges_per_level : 0); + std::size_t mux_nodes = 0; + if (lg_outputs > 0 && lg_outputs < 32) + mux_nodes = 2 * ((std::size_t{1} << lg_outputs) - 1); + if (slots.size() < per_level + mux_nodes) + throw std::invalid_argument("level_walk_ds_sized: not enough slots"); + const std::size_t depth = (slots.size() - mux_nodes) / per_level; + if (depth == 0 || depth * per_level + mux_nodes != slots.size()) + throw std::invalid_argument( + "level_walk_ds_sized: slots must be depth×(4[+OH])+mux"); + + node state = seed; + for (std::size_t level = 0; level < depth; ++level) + { + const auto expand_slot = slots[si]; // peek; expand uses first open width + node kids = expand_pair(state, static_cast(level), + expand_op, expand_slot); + node blind = compute(opcodes::ds_blind, {kids}, + info_[state.id].dom, next_slot()); + node blind_ex = exchange(blind); + node cw = compute(opcodes::ds_cw, {kids, blind_ex}, + info_[state.id].dom, next_slot()); + node cw_ex = exchange(cw); + node advice = compute(opcodes::ds_advice, {kids, cw_ex}, + info_[state.id].dom, next_slot()); + node advice_ex = exchange(advice); + node aand = compute(opcodes::ds_and, {kids, advice_ex}, + info_[state.id].dom, next_slot()); + node and1_ex = exchange(aand); + node aand2 = compute(opcodes::ds_and2, {kids, and1_ex}, + info_[state.id].dom, next_slot()); + node and_ex = exchange(aand2); + if (with_oblivious_hash) + { + for (std::size_t layer = 0; layer < net::ds_oh_exchanges_per_level; + ++layer) + { + const auto oh_slot = next_slot(); + // level/child distinguish BP AND-layers for interning. + node oh = emplace(effect::compute, info_[state.id].dom, + opcodes::ds_oh, {kids.id, and_ex.id}, oh_slot, + static_cast(level), + static_cast(layer & 0xffu), + op_flags::none, false, domain::a); + and_ex = exchange(oh); + } + } + state = compute(opcodes::fss_step + 1, {kids, and_ex}, + info_[state.id].dom, expand_slot); + } + for (std::size_t i = 0; i < mux_nodes; ++i) + { + const auto mux_slot = next_slot(); + node mux = compute(opcodes::ds_leaf_mux, {state}, + info_[state.id].dom, mux_slot); + node mux_ex = exchange(mux); + state = compute(opcodes::ds_leaf_mux + 1, {state, mux_ex}, + info_[state.id].dom, mux_slot); + } + return state; + } + + /// @brief Adaptive idpf / eval_until frontier: open L‖R, then retain one. + /// @details Systemic staging — the schedule never learns the child bit: + /// 1. `step` records expand + packed L‖R open only. + /// 2. Drive **new** exchange waves only (`drive_options::from_exchange_wave` + /// = `exchanges_flushed`; size the sink with `slot_bytes_from`). + /// 3. Choose from opened counts; `retain` adds one local tip. + /// 4. Bump `exchanges_flushed` to `plan.exchange_waves()` and step again. + struct adaptive_prefix + { + node tip{}; + node last_open{}; + node left{}; ///< Opened prefix payload for child 0 + node right{}; ///< Opened prefix payload for child 1 + node kids{}; ///< Expand pair pending retain (valid while awaiting) + std::size_t slot_bytes = 0; + std::size_t depth_done = 0; + std::size_t exchanges_flushed = 0; ///< Sink rounds already driven + bool awaiting_retain = false; + }; + + HEDLEY_WARN_UNUSED_RESULT + adaptive_prefix begin_adaptive_prefix(node seed) + { + check(seed); + adaptive_prefix f; + f.tip = seed; + return f; + } + + /// @brief One EvaluateUntil step: expand and pack both child opens. + HEDLEY_WARN_UNUSED_RESULT + adaptive_prefix step_adaptive_prefix(adaptive_prefix f, + std::size_t slot_bytes, std::size_t prefix_bytes, + std::uint32_t expand_op = opcodes::fss_expand_pair) + { + check(f.tip); + if (f.awaiting_retain) + throw std::logic_error( + "step_adaptive_prefix: call retain_adaptive_prefix first"); + f.kids = expand_pair(f.tip, static_cast(f.depth_done), + expand_op, slot_bytes); + f.slot_bytes = slot_bytes; + node left = compute(opcodes::fss_prefix_emit, {f.kids}, domain::a, + prefix_bytes); + node right = compute(opcodes::fss_prefix_emit + 1, {f.kids}, domain::a, + prefix_bytes); + node packed = compute(opcodes::fss_prefix_pair, {left, right}, domain::a, + prefix_bytes * 2); + f.last_open = exchange(packed); + f.left = compute(opcodes::fss_prefix_emit, {f.last_open}, domain::a, + prefix_bytes); + f.right = compute(opcodes::fss_prefix_emit + 1, {f.last_open}, domain::a, + prefix_bytes); + ++f.depth_done; + f.awaiting_retain = true; + return f; + } + + /// @brief Local retain after drive: one tip node for the chosen child. + HEDLEY_WARN_UNUSED_RESULT + adaptive_prefix retain_adaptive_prefix(adaptive_prefix f, std::uint8_t child) + { + if (!f.awaiting_retain) + throw std::logic_error( + "retain_adaptive_prefix: no pending step open"); + if (child > 1) + throw std::invalid_argument("retain_adaptive_prefix child must be 0 or 1"); + check(f.kids); + check(f.last_open); + const auto op = opcodes::fss_prefix_retain + child; + f.tip = compute(op, {f.kids, f.last_open}, info_[f.kids.id].dom, + f.slot_bytes); + info_[f.tip.id].child = child; + f.awaiting_retain = false; + return f; + } + + /// @brief The plan RoundSink / `drive` consume — same object, no dual sketch. + HEDLEY_WARN_UNUSED_RESULT + plan default_plan() const { return schedule(); } + + /// @brief Keyword PIR / PSI: N independent bucket walks, answers in one open. + struct multipoint_result + { + std::vector leaves; + node answers_open{}; + }; + + template + HEDLEY_WARN_UNUSED_RESULT + multipoint_result multipoint_fan(std::size_t buckets, SeedFn && seed_at, + std::size_t depth, std::size_t slot_bytes, std::size_t answer_bytes) + { + if (buckets == 0) + throw std::invalid_argument("multipoint_fan needs buckets > 0"); + multipoint_result mr; + mr.leaves.reserve(buckets); + for (std::size_t i = 0; i < buckets; ++i) + mr.leaves.push_back(fss_point(seed_at(i), depth, slot_bytes)); + mr.answers_open = exchange_pack(mr.leaves, answer_bytes); + return mr; + } + + /// @brief Occupied cuckoo buckets → one `multipoint_fan` (probes deduped). + template + HEDLEY_WARN_UNUSED_RESULT + multipoint_result schedule_cuckoo_probes( + const std::vector & probes, SeedAt && seed_at, + std::size_t depth, std::size_t slot_bytes, std::size_t answer_bytes) + { + std::vector uniq = probes; + std::sort(uniq.begin(), uniq.end()); + uniq.erase(std::unique(uniq.begin(), uniq.end()), uniq.end()); + if (uniq.empty()) + throw std::invalid_argument("schedule_cuckoo_probes: no probes"); + return multipoint_fan(uniq.size(), + [&](std::size_t i) { return seed_at(uniq[i]); }, + depth, slot_bytes, answer_bytes); + } + + /// @brief Pack many payloads into one RoundSink exchange (bucket answers). + HEDLEY_WARN_UNUSED_RESULT + node exchange_pack(const std::vector & payloads, + std::size_t per_payload_bytes = 0) + { + if (payloads.empty()) + throw std::invalid_argument("exchange_pack needs payloads"); + std::vector ins = payloads; + std::size_t bytes = 0; + for (auto n : payloads) + { + check(n); + bytes += (per_payload_bytes != 0) ? per_payload_bytes + : info_[n.id].value_bytes; + } + node packed = compute(opcodes::fss_answer_pack, std::move(ins), + info_[payloads[0].id].dom, bytes); + return exchange(packed); + } + + /// @brief Prepaid full-domain expand — zero online CW rounds (SUBLEQ offline). + HEDLEY_WARN_UNUSED_RESULT + node defer_expand(node seed, std::size_t depth, std::size_t slot_bytes, + std::uint32_t expand_op = opcodes::fss_expand_pair) + { + check(seed); + if (depth == 0) + throw std::invalid_argument("defer_expand depth must be positive"); + node state = seed; + for (std::size_t level = 0; level < depth; ++level) + { + node kids = expand_pair(state, static_cast(level), + expand_op, slot_bytes); + state = compute(opcodes::fss_defer_expand, {kids}, + info_[state.id].dom, slot_bytes); + } + return state; + } + + /// @brief Local rotate of a share buffer after the offset is public. + HEDLEY_WARN_UNUSED_RESULT + node rotate_share(node buf, std::uint32_t public_shift) + { + check(buf); + node out = compute(opcodes::fss_rotate, {buf}, info_[buf.id].dom, + info_[buf.id].value_bytes); + info_[out.id].level = static_cast(public_shift & 0xffffu); + return out; + } + + /// @brief Path CW walk with leaf correction deferred (Duoram write shape). + struct leaf_later_result + { + node values{}; + node control{}; + }; + + HEDLEY_WARN_UNUSED_RESULT + leaf_later_result leaf_later_walk(node seed, std::size_t depth, + std::size_t slot_bytes, + std::uint32_t expand_op = opcodes::fss_expand_pair, + std::uint32_t step_op = opcodes::fss_step) + { + node tip = level_walk(seed, depth, slot_bytes, expand_op, step_op); + leaf_later_result r; + r.values = compute(opcodes::fss_leaf_later, {tip}, info_[tip.id].dom, + slot_bytes); + r.control = compute(opcodes::fss_leaf_later + 1, {tip}, domain::b, 1); + return r; + } + + HEDLEY_WARN_UNUSED_RESULT + node apply_leaf_correction(node values, node control, node leaf_cw) + { + check(values); + check(control); + check(leaf_cw); + return compute(opcodes::fss_apply_leaf, {values, control, leaf_cw}, + info_[values.id].dom, info_[values.id].value_bytes); + } + + template + beavers::session & aby() + { + return aby_lane(0); + } + + /// @brief Independent ABY session on sink lane `lane` (Grotto multi-α). + /// @details Barriers from different lanes do not chain; same ready_round + /// flushes pack into one compose wave when data-independent. + template + beavers::session & aby_lane(std::size_t lane) + { + detail::aby_slot_key key{std::type_index(typeid(Ring)), lane}; + auto it = aby_.find(key); + if (it == aby_.end()) + { + auto holder = std::make_unique>(); + holder->session.set_schedule_objective( + beavers::schedule_objective::rounds); + auto * ptr = &holder->session; + aby_.emplace(key, std::move(holder)); + aby_order_.push_back(key); + return *ptr; + } + return static_cast &>(*it->second).session; + } + + template + node opened(typename beavers::session::wire w, std::size_t lane = 0) + { + auto & s = aby_lane(lane); + const auto barriers = s.exchange_barriers(); + std::size_t barrier_index = barriers.size(); + for (std::size_t i = 0; i < barriers.size(); ++i) + { + for (auto id : barriers[i].wire_ids) + { + if (id == w.id()) + { + barrier_index = i; + break; + } + } + if (barrier_index < barriers.size()) + break; + } + + detail::aby_slot_key key{std::type_index(typeid(Ring)), lane}; + std::size_t sess_index = 0; + for (; sess_index < aby_order_.size(); ++sess_index) + { + if (aby_order_[sess_index].type == key.type + && aby_order_[sess_index].lane == key.lane) + break; + } + + if (barriers.empty()) + { + node out = emplace(effect::compute, domain::a, opcodes::beaver_delta, + {}, sizeof(Ring), 0, 0, op_flags::none, false, domain::a); + info_[out.id].aby_wire = static_cast(w.id()); + info_[out.id].aby_session = static_cast(sess_index); + return out; + } + + if (barrier_index >= barriers.size()) + { + const int rw = s.round_of(w); + barrier_index = 0; + for (std::size_t i = 0; i < barriers.size(); ++i) + { + if (barriers[i].ready_round <= rw) + barrier_index = i; + } + } + + node ex{}; + const std::size_t elem = s.has_mac() + ? sizeof(beavers::auth_opening) : sizeof(Ring); + for (std::size_t i = 0; i <= barrier_index; ++i) + { + const node * pred = (i == 0) ? nullptr : &ex; + ex = beaver_barrier_node(sess_index, i, elem, + barriers[i].wire_ids, pred); + } + std::vector out_ins = {ex.id}; + for (std::size_t i = 0; i <= barrier_index; ++i) + { + for (auto wid : barriers[i].wire_ids) + { + auto it = aby_import_.find({static_cast(sess_index), wid}); + if (it == aby_import_.end()) + continue; + if (std::find(out_ins.begin(), out_ins.end(), it->second) + == out_ins.end()) + out_ins.push_back(it->second); + } + } + { + auto it = aby_import_.find( + {static_cast(sess_index), w.id()}); + if (it != aby_import_.end() + && std::find(out_ins.begin(), out_ins.end(), it->second) + == out_ins.end()) + out_ins.push_back(it->second); + } + node out = emplace(effect::compute, domain::a, opcodes::beaver_delta, + std::move(out_ins), sizeof(Ring), 0, 0, op_flags::none, false, + domain::a); + info_[out.id].aby_wire = static_cast(w.id()); + info_[out.id].aby_session = static_cast(sess_index); + return out; + } + + template + node beaver_triple(node x, node y, std::size_t lane = 0) + { + x = as(x, domain::a); + y = as(y, domain::a); + auto & s = aby_lane(lane); + auto wx = ensure_aby_wire(x, lane); + auto wy = ensure_aby_wire(y, lane); + auto wz = s.product(wx, wy); + return opened(wz, lane); + } + + template + node aby_product(node x, node y, std::size_t lane = 0) + { + return beaver_triple(x, y, lane); + } + + node rss_product(node x, node y) + { + x = as(x, domain::rss); + y = as(y, domain::rss); + std::size_t out_bytes = info_[x.id].value_bytes; + if (out_bytes >= 2) + out_bytes /= 2; + return compute(opcodes::rss_mul, {x, y}, domain::y, out_bytes, + op_flags::commutative); + } + + /// @brief Arithmetic→boolean conversion node (kernel + open of delta). + HEDLEY_WARN_UNUSED_RESULT + node bin_a2b(node x, std::size_t out_bytes) + { + check(x); + return compute(opcodes::bin_a2b, {x}, domain::bin, out_bytes); + } + + /// @brief Local `x - y` (masked Beaver limb). + HEDLEY_WARN_UNUSED_RESULT + node arith_sub(node x, node y) + { + check(x); + check(y); + return emplace(effect::compute, domain::a, opcodes::share_input, + {x.id, y.id}, 8, 0, 0, op_flags::none, false, domain::a, 0); + } + + /// @brief Local XOR of two equal-width bit buffers. + HEDLEY_WARN_UNUSED_RESULT + node bit_xor(node a, node b, std::size_t bytes) + { + check(a); + check(b); + return emplace(effect::compute, domain::bin, opcodes::bin_and, + {a.id, b.id}, bytes, 0, 0, op_flags::commutative, false, domain::bin, + /*aux=*/1); + } + + /// @brief B2A: XOR-open `bits ⊕ r_bits`, then daBit correction. + /// @details `r_arith` is one `uint64` additive share per bit, packed back to back. + HEDLEY_WARN_UNUSED_RESULT + node bin_b2a(node bits, node r_bits, node r_arith, unsigned ell) + { + check(bits); + check(r_bits); + check(r_arith); + const std::size_t nbytes = (static_cast(ell) + 7u) / 8u; + node mask = bit_xor(bits, r_bits, nbytes); + node opened = exchange(mask); + return emplace(effect::compute, domain::a, opcodes::bin_b2a, + {r_arith.id, opened.id}, 8, 0, 0, op_flags::none, false, domain::a, + ell); + } + + /// @brief Bit × arithmetic via one bit×ring triple and two opens. + /// @details `bit` and `a_bit` are additive 0/1 shares (`uint64`). `b_arith` + /// and `c_arith` are the additive shares of `b` and `c`. + HEDLEY_WARN_UNUSED_RESULT + node bin_inject(node bit, node x, node a_bit, node b_arith, node c_arith) + { + check(bit); + check(x); + check(a_bit); + check(b_arith); + check(c_arith); + node d = arith_sub(bit, a_bit); + node e = arith_sub(x, b_arith); + node od = exchange(d); + node oe = exchange(e); + return emplace(effect::compute, domain::a, opcodes::bin_inject, + {a_bit.id, b_arith.id, c_arith.id, od.id, oe.id}, 8, 0, 0, + op_flags::none, false, domain::a, 0); + } + + /// @brief RSS AND: local factor from replicated components, ring-send, refresh. + HEDLEY_WARN_UNUSED_RESULT + node bin_rss_and(node a_own, node a_next, node b_own, node b_next) + { + check(a_own); + check(a_next); + check(b_own); + check(b_next); + node local = emplace(effect::compute, domain::y, opcodes::bin_rss_and, + {a_own.id, a_next.id, b_own.id, b_next.id}, 1, 0, 0, + op_flags::none, false, domain::y, 0); + // Ring send. The own component (this node) is what the three parties XOR. + (void)exchange(local); + return local; + } + + /// @brief RSS bit injection: local product factor plus a ring send of it. + HEDLEY_WARN_UNUSED_RESULT + node bin_rss_inject(node b_own, node b_next, node x_own, node x_next) + { + check(b_own); + check(b_next); + check(x_own); + check(x_next); + node local = emplace(effect::compute, domain::y, opcodes::bin_rss_inject, + {b_own.id, b_next.id, x_own.id, x_next.id}, 8, 0, 0, + op_flags::none, false, domain::y, 0); + (void)exchange(local); + return local; + } + + /// @brief GMW AND: open `p⊕a` and `q⊕b`, then the local triple correction. + HEDLEY_WARN_UNUSED_RESULT + node gmw_and(node p, node q, node a, node b, node c) + { + check(p); + check(q); + check(a); + check(b); + check(c); + node d = bit_xor(p, a, 1); + node e = bit_xor(q, b, 1); + node od = exchange(d); + node oe = exchange(e); + return emplace(effect::compute, domain::bin, opcodes::bin_and, + {a.id, b.id, c.id, od.id, oe.id}, 1, 0, 0, op_flags::none, false, + domain::bin, /*aux=*/2); + } + + /// @brief Beaver product then local shift. Opens `x-a` and `y-b`. + HEDLEY_WARN_UNUSED_RESULT + node mul_trunc_open(node x, node y, node a, node b, node c, unsigned s) + { + check(x); + check(y); + check(a); + check(b); + check(c); + node od = exchange(arith_sub(x, a)); + node oe = exchange(arith_sub(y, b)); + return emplace(effect::compute, domain::a, opcodes::mul_trunc, + {a.id, b.id, c.id, od.id, oe.id}, 8, 0, 0, op_flags::none, false, + domain::a, s); + } + + /// @brief `b + sel·(a-b)` with one bit×ring inject of `sel` and `a-b`. + HEDLEY_WARN_UNUSED_RESULT + node share_mux_open(node sel, node a, node b, node t_a, node t_b, node t_c) + { + check(b); + node diff = arith_sub(a, b); + node prod = bin_inject(sel, diff, t_a, t_b, t_c); + return emplace(effect::compute, domain::a, opcodes::reshare_mask, + {b.id, prod.id}, 8, 0, 0, op_flags::none, false, domain::a, 0); + } + + HEDLEY_WARN_UNUSED_RESULT + node trunc_prob_op(node x, unsigned shift) + { + check(x); + return emplace(effect::compute, info_[x.id].dom, opcodes::trunc_prob, + {x.id}, info_[x.id].value_bytes, 0, 0, op_flags::none, false, + info_[x.id].dom, shift); + } + + HEDLEY_WARN_UNUSED_RESULT + node trunc_exact_op(node x, unsigned /*n*/, unsigned s) + { + check(x); + return emplace(effect::compute, info_[x.id].dom, opcodes::trunc_exact, + {x.id}, info_[x.id].value_bytes, 0, 0, op_flags::none, false, + info_[x.id].dom, s); + } + + /// @brief Exact trunc after `delta` has been opened. Inputs are this party's + /// `x`, `r`, public `delta`, and wrap share. `aux` is the shift. + HEDLEY_WARN_UNUSED_RESULT + node trunc_exact_open(node x, node r, node delta, node wrap, unsigned s) + { + check(x); + check(r); + check(delta); + check(wrap); + return emplace(effect::compute, domain::a, opcodes::trunc_exact, + {x.id, r.id, delta.id, wrap.id}, 8, 0, 0, op_flags::none, false, + domain::a, s); + } + + HEDLEY_WARN_UNUSED_RESULT + node mul_trunc_op(node x, node y, unsigned s) + { + check(x); + check(y); + return emplace(effect::compute, domain::a, opcodes::mul_trunc, + {x.id, y.id}, info_[x.id].value_bytes, 0, 0, op_flags::commutative, + false, domain::a, s); + } + + HEDLEY_WARN_UNUSED_RESULT + node share_gt(node x, node y) + { + check(x); + check(y); + return compute(opcodes::share_cmp, {x, y}, domain::bin, 1); + } + + HEDLEY_WARN_UNUSED_RESULT + node share_mux_op(node sel, node a, node b) + { + check(sel); + check(a); + check(b); + return compute(opcodes::share_mux, {sel, a, b}, domain::a, + info_[a.id].value_bytes); + } + + HEDLEY_WARN_UNUSED_RESULT + domain domain_of(node n) const + { + check(n); + return info_[n.id].dom; + } + + HEDLEY_WARN_UNUSED_RESULT + effect effect_of(node n) const + { + check(n); + return info_[n.id].kind; + } + + HEDLEY_WARN_UNUSED_RESULT + std::size_t value_bytes(node n) const + { + check(n); + return info_[n.id].value_bytes; + } + + HEDLEY_NO_THROW + HEDLEY_WARN_UNUSED_RESULT + std::size_t node_count() const noexcept { return info_.size(); } + + HEDLEY_WARN_UNUSED_RESULT + plan schedule() const + { + plan p; + const std::size_t n = info_.size(); + p.node_wave_.assign(n, 0); + p.value_bytes_.resize(n); + p.domains_.resize(n); + p.effects_.resize(n); + p.opcodes_.resize(n); + p.levels_.resize(n); + p.aux_.resize(n); + p.inputs_.resize(n); + p.alias_bytes_.resize(n); + p.all_nodes_.resize(n); + + for (std::uint32_t id = 0; id < n; ++id) + { + p.all_nodes_[id] = node{id}; + p.value_bytes_[id] = info_[id].value_bytes; + p.domains_[id] = info_[id].dom; + p.effects_[id] = info_[id].kind; + p.opcodes_[id] = info_[id].opcode; + p.levels_[id] = info_[id].level; + p.aux_[id] = info_[id].aux; + p.inputs_[id] = info_[id].inputs; + p.alias_bytes_[id] = info_[id].alias_bytes; + ++p.effect_counts_[info_[id].kind]; + if (info_[id].kind == effect::convert) + ++p.conversion_counts_[{info_[id].from_domain, info_[id].dom}]; + } + + std::vector seen(n, 0); + std::function wave_of = + [&](std::uint32_t id) -> std::size_t { + if (seen[id]) + return p.node_wave_[id]; + seen[id] = 1; + std::size_t w = 0; + for (auto in : info_[id].inputs) + { + // Only real compose nodes are dependencies (skip stale ids). + if (in >= n) + continue; + w = std::max(w, wave_of(in)); + } + p.node_wave_[id] = w; + // If any input was an exchange, this node is after that barrier. + for (auto in : info_[id].inputs) + { + if (in >= n) + continue; + if (info_[in].kind == effect::exchange) + p.node_wave_[id] = std::max(p.node_wave_[id], + p.node_wave_[in] + 1); + } + return p.node_wave_[id]; + }; + for (std::uint32_t id = 0; id < n; ++id) + wave_of(id); + + std::size_t max_wave = 0; + bool any_exchange = false; + for (std::uint32_t id = 0; id < n; ++id) + { + max_wave = std::max(max_wave, p.node_wave_[id]); + if (info_[id].kind == effect::exchange) + any_exchange = true; + } + const std::size_t wave_count = + n == 0 ? 0 : (any_exchange ? max_wave + 1 : max_wave + 1); + p.waves_.assign(wave_count, wave_info{}); + + for (std::size_t w = 0; w < wave_count; ++w) + { + p.waves_[w].index = w; + std::map, std::vector> groups; + for (std::uint32_t id = 0; id < n; ++id) + { + if (p.node_wave_[id] != w) + continue; + if (info_[id].kind == effect::exchange) + { + p.waves_[w].exchanges.push_back(node{id}); + continue; + } + if (info_[id].kind == effect::input) + continue; + groups[{info_[id].kind, info_[id].opcode}].push_back(node{id}); + } + for (auto & kv : groups) + { + simd_group g; + g.kind = kv.first.first; + g.opcode = kv.first.second; + g.nodes = std::move(kv.second); + p.waves_[w].groups.push_back(std::move(g)); + } + std::sort(p.waves_[w].exchanges.begin(), p.waves_[w].exchanges.end(), + [](node a, node b) { return a.id < b.id; }); + std::size_t slot = 0; + for (auto ex : p.waves_[w].exchanges) + slot += info_[ex.id].value_bytes; + p.waves_[w].slot_bytes = slot; + for (auto ex : p.waves_[w].exchanges) + { + const auto op = info_[ex.id].opcode; + const bool is_setup = (op == opcodes::dealer_pad + || op == opcodes::dealer_zero + || op == opcodes::client_upload); + if (is_setup) + p.setup_bytes_ += info_[ex.id].value_bytes; + else + p.online_bytes_ += info_[ex.id].value_bytes; + } + } + return p; + } + +private: + struct node_info + { + effect kind = effect::input; + domain dom = domain::a; + std::size_t value_bytes = 0; + std::uint32_t opcode = 0; + std::vector inputs; + std::uint16_t level = 0; + std::uint8_t child = 0; + op_flags flags = op_flags::none; + bool alias_bytes = false; + domain from_domain = domain::a; + int aby_wire = -1; + int aby_session = -1; + std::uint32_t aux = 0; + }; + + void check(node n) const + { + if (n.id >= info_.size()) + throw std::out_of_range("compose node"); + } + + walk_result level_walk_impl(node seed, std::size_t depth, + std::size_t slot_bytes, node trailer, std::size_t trailer_bytes, + std::uint32_t expand_op, std::uint32_t step_op) + { + check(seed); + if (depth == 0) + throw std::invalid_argument("level_walk depth must be positive"); + walk_result wr; + node state = seed; + for (std::size_t level = 0; level < depth; ++level) + { + node kids = expand_pair(state, static_cast(level), + expand_op, slot_bytes); + node step = compute(step_op, {kids}, info_[state.id].dom, + slot_bytes); + const bool last = (level + 1 == depth); + if (last && trailer_bytes != 0) + { + // Express/Sabre: sketch or proof share rides with the final CW. + node packed = compute(opcodes::fss_fuse_trailer, {step, trailer}, + info_[state.id].dom, slot_bytes + trailer_bytes); + wr.fused_exchange = exchange(packed); + wr.trailer_open = compute(opcodes::fss_fuse_trailer + 1, + {wr.fused_exchange}, info_[trailer.id].dom, trailer_bytes); + state = compute(step_op + 1, {kids, wr.fused_exchange}, + info_[state.id].dom, slot_bytes); + } + else + { + node msg = exchange(step); + state = compute(step_op + 1, {kids, msg}, info_[state.id].dom, + slot_bytes); + if (last) + wr.fused_exchange = msg; + } + } + wr.leaf = state; + return wr; + } + + walk_result level_walk_sized_impl(node seed, + const std::vector & slot_bytes_per_level, node trailer, + std::size_t trailer_bytes, std::uint32_t expand_op, + std::uint32_t step_op) + { + check(seed); + if (slot_bytes_per_level.empty()) + throw std::invalid_argument("level_walk_sized needs at least one level"); + walk_result wr; + node state = seed; + const std::size_t depth = slot_bytes_per_level.size(); + for (std::size_t level = 0; level < depth; ++level) + { + const std::size_t slot_bytes = slot_bytes_per_level[level]; + if (slot_bytes == 0) + throw std::invalid_argument("level_walk_sized slot_bytes must be > 0"); + node kids = expand_pair(state, static_cast(level), + expand_op, slot_bytes); + node step = compute(step_op, {kids}, info_[state.id].dom, + slot_bytes); + const bool last = (level + 1 == depth); + if (last && trailer_bytes != 0) + { + node packed = compute(opcodes::fss_fuse_trailer, {step, trailer}, + info_[state.id].dom, slot_bytes + trailer_bytes); + wr.fused_exchange = exchange(packed); + wr.trailer_open = compute(opcodes::fss_fuse_trailer + 1, + {wr.fused_exchange}, info_[trailer.id].dom, trailer_bytes); + state = compute(step_op + 1, {kids, wr.fused_exchange}, + info_[state.id].dom, slot_bytes); + } + else + { + node msg = exchange(step); + state = compute(step_op + 1, {kids, msg}, info_[state.id].dom, + slot_bytes); + if (last) + wr.fused_exchange = msg; + } + } + wr.leaf = state; + return wr; + } + + node emplace(effect kind, domain dom, std::uint32_t opcode, + std::vector inputs, std::size_t value_bytes, + std::uint16_t level, std::uint8_t child, op_flags flags, bool alias, + domain from_domain, std::uint32_t aux = 0) + { + detail::intern_key key; + key.kind = kind; + key.dom = dom; + key.opcode = opcode; + key.level = level; + key.child = child; + key.aux = aux; + key.inputs = inputs; + auto it = intern_.find(key); + if (it != intern_.end()) + return node{it->second}; + + node_info ni; + ni.kind = kind; + ni.dom = dom; + ni.value_bytes = value_bytes; + ni.opcode = opcode; + ni.inputs = std::move(inputs); + ni.level = level; + ni.child = child; + ni.aux = aux; + ni.flags = flags; + ni.alias_bytes = alias; + ni.from_domain = from_domain; + const auto id = static_cast(info_.size()); + info_.push_back(std::move(ni)); + intern_.emplace(std::move(key), id); + return node{id}; + } + + /// @brief One ABY δ flush. `pred` is the previous barrier in this session + /// (real graph edge). Session/barrier identity lives in the intern + /// key's opcode/level — never as fake input node ids (those used to + /// pull waves onto unrelated FSS exchanges). + /// @details Compose nodes imported into ABY wires listed in `wire_ids` are + /// real inputs so Duoram/SUBLEQ scale waits for the FSS leaf. + node beaver_barrier_node(std::size_t sess_index, std::size_t barrier_index, + std::size_t ring_bytes, const std::vector & wire_ids, + const node * pred) + { + detail::intern_key key; + key.kind = effect::exchange; + key.dom = domain::a; + // Unique per (session, barrier); not a graph dependency. + key.opcode = opcodes::beaver_delta + + static_cast(barrier_index); + key.level = static_cast(sess_index); + key.child = 0; + if (pred != nullptr) + key.inputs.push_back(pred->id); + for (auto wid : wire_ids) + { + auto it = aby_import_.find({static_cast(sess_index), wid}); + if (it == aby_import_.end()) + continue; + if (std::find(key.inputs.begin(), key.inputs.end(), it->second) + == key.inputs.end()) + key.inputs.push_back(it->second); + } + auto it = intern_.find(key); + if (it != intern_.end()) + return node{it->second}; + + node_info ni; + ni.kind = effect::exchange; + ni.dom = domain::a; + ni.value_bytes = sizeof(std::uint32_t) + wire_ids.size() * ring_bytes; + ni.opcode = key.opcode; + ni.inputs = key.inputs; + ni.level = key.level; + ni.child = key.child; + ni.aby_session = static_cast(sess_index); + const auto id = static_cast(info_.size()); + info_.push_back(std::move(ni)); + intern_.emplace(std::move(key), id); + return node{id}; + } + + template + typename beavers::session::wire ensure_aby_wire(node n, + std::size_t lane = 0) + { + auto & s = aby_lane(lane); + if (info_[n.id].aby_wire >= 0 + && info_[n.id].aby_session >= 0 + && static_cast(info_[n.id].aby_session) < aby_order_.size() + && aby_order_[static_cast(info_[n.id].aby_session)].lane + == lane + && aby_order_[static_cast(info_[n.id].aby_session)].type + == std::type_index(typeid(Ring))) + return s.wire_at(static_cast(info_[n.id].aby_wire)); + auto w = s.input(); + info_[n.id].aby_wire = static_cast(w.id()); + detail::aby_slot_key key{std::type_index(typeid(Ring)), lane}; + for (std::size_t i = 0; i < aby_order_.size(); ++i) + { + if (aby_order_[i] == key) + { + info_[n.id].aby_session = static_cast(i); + aby_import_[{static_cast(i), w.id()}] = n.id; + break; + } + } + return w; + } + + std::size_t party_ = 0; + std::vector info_; + std::unordered_map + intern_; + std::map> aby_; + std::vector aby_order_; + /// ABY input wire id → compose node that produced the share (per session). + std::map, std::uint32_t> aby_import_; +}; + +/// @brief Optional beaver δ host for composed drives (plain openings). +/// @details When set, exchange nodes with `opcode ∈ [beaver_delta, +1024)` call +/// `pack` / `apply` instead of treating the slot as a reconstruct sum. +/// Wire layout matches `evaluate_online_on_sink`: `uint32 n ‖ Ring[n]`. +struct beaver_host +{ + virtual ~beaver_host() = default; + virtual void pack(std::size_t session_index, std::size_t barrier_index, + std::uint8_t * dst, std::size_t n) = 0; + virtual void apply(std::size_t session_index, std::size_t barrier_index, + const std::uint8_t * src, std::size_t n) = 0; +}; + +/// @brief How non-`y` openings combine peer bytes. +enum class field_open { words, fp61 }; + +/// @brief Options for `drive` / `drive_composed*`. +/// @brief Party-aware local work for a bench cell. `aux` is the cell id +/// (shuffle passes pack the pass index in the high half). +using cell_fn = void (*)(std::uint32_t opcode, std::size_t party, + std::uint32_t aux, std::uint8_t * out, std::size_t out_n); + +struct drive_options +{ + /// Skip plan exchange-waves `[0, from)` (already flushed). Local compute + /// for those waves is also skipped — `values` must retain prior results. + std::size_t from_exchange_wave = 0; + /// When true, RoundSink round 0 maps to plan exchange-wave + /// `from_exchange_wave` (sink sized with `slot_bytes_from`). + bool compact_sink = false; + beaver_host * beavers = nullptr; + /// `words`: u64 add/sub (or XOR if not 8 bytes). `fp61`: Mersenne field lanes. + field_open field = field_open::words; + /// Return instead of spinning when the peer has not flushed this round. + bool park_if_waiting = false; + /// Stop after one completed exchange (used by the fleet scheduler). + bool one_exchange = false; + struct drive_cursor * cursor = nullptr; + /// Optional per-round cost probe (`experiment::probe()`). + const round_probe * probe = nullptr; + /// Allow `schedule_session` / drive to flush up to `k` independent rounds ahead. + std::size_t pipeline_credit = 0; + /// Trivial shares (party 0 holds the secret); check reconstructing opens. + bool cleartext = false; + /// Optional clear outputs keyed by exchange node id (cleartext mode). + const std::map> * clear_oracle = nullptr; + /// Extra consistency check on reconstructed opens (default off). + bool check_open = false; + /// Pairwise RSS seeds for `rss_zero` kernels (required when that opcode runs). + const rss::party_seeds * rss_seeds = nullptr; + /// Base index added to `aux` seed indices for RSS kernels. + std::uint64_t rss_seed_base = 0; + /// When set, custom and builtin walk kernels run on `workers->post_compute`. + net::io_pool * workers = nullptr; + /// Context serviced while a kernel runs on `workers`. Async drives set it + /// to the sink's context; otherwise `workers->context()`. + asio::io_context * pump = nullptr; + /// Stream lanes. `0` → `net::default_lanes` (8); + /// `net::lanes_one_per_round` → one stream per round. + std::size_t n_lanes = 0; + /// Round headers on lanes (`automatic` frames only when rounds share lanes). + net::framing_mode framing = net::framing_mode::automatic; + /// Longest wait for one round's peer bytes, measured from when the + /// instance entered that round. `0` keeps the historical spin cap. + std::chrono::milliseconds wait_timeout{30000}; + /// Per-edge override of `wait_timeout` (edge id → budget). + std::map edge_timeout; + /// Per-round override (schedule round index → budget); wins over edges. + std::map round_timeout; + /// Bench cells (`bench_emit` / `bench_apply`). Null for ordinary plans. + cell_fn cell = nullptr; +}; + +/// @brief How many duplex lanes a plan should open. +inline std::size_t lanes_for_plan(std::size_t n_rounds, const drive_options & opt) +{ + return net::lane_count_for_rounds(n_rounds, opt.n_lanes); +} + +/// @brief Budget for one wait: round override, else edge override, else default. +inline std::chrono::milliseconds wait_budget(const drive_options & opt, + edge_id edge, std::chrono::milliseconds round_budget = {}) +{ + if (round_budget.count() > 0) + return round_budget; + auto it = opt.edge_timeout.find(edge); + if (it != opt.edge_timeout.end()) + return it->second; + return opt.wait_timeout; +} + +inline std::chrono::milliseconds round_budget(const drive_options & opt, + std::size_t round) +{ + auto it = opt.round_timeout.find(static_cast(round)); + return it == opt.round_timeout.end() ? std::chrono::milliseconds(0) + : it->second; +} + +namespace detail +{ + +/// @brief One wait step on `sink`: sleep in its reactor, or yield if it cannot. +inline bool pump_sink(net::RoundSink & sink, std::chrono::milliseconds slice) +{ + if (sink.can_block()) + return sink.wait_io_for(slice); + const bool ran = sink.wait_io(); + if (!ran) + std::this_thread::yield(); + return ran; +} + +/// @brief Pump `sink` until `ready()`; `budget` 0 keeps the spin cap. +template +inline void wait_ready(net::RoundSink & sink, std::chrono::milliseconds budget, + Ready ready, const std::string & what) +{ + const auto started = std::chrono::steady_clock::now(); + unsigned spins = 0; + while (!ready()) + { + if (budget.count() == 0) + { + if (pump_sink(sink, std::chrono::milliseconds(1))) + spins = 0; + else if (++spins > 100000u) + throw std::runtime_error(what + ": peer not ready (drive both ends)"); + continue; + } + const auto waited = std::chrono::duration_cast( + std::chrono::steady_clock::now() - started); + if (waited >= budget) + throw std::runtime_error(what + ": no peer bytes for " + + std::to_string(waited.count()) + " ms (budget " + + std::to_string(budget.count()) + + " ms; is the peer driving the same plan?)"); + pump_sink(sink, std::min(budget - waited, std::chrono::milliseconds(1000))); + } +} + +} // namespace detail + +/// @brief Run a kernel inline, or on the compute pool while servicing I/O. +/// @details A kernel writes into `values`, so it cannot be abandoned: this +/// waits for it, running socket completions on `opt.pump` meanwhile. +/// On the pool the kernel draws from this thread's randomness source, +/// and its symmetric-key blocks, random bytes, and CPU time are +/// charged to this thread (`dpf/thread_work.hpp`). +inline void invoke_kernel(const drive_options & opt, const kernel_fn & fn, + std::uint32_t opcode, const std::vector & nodes, + const std::vector & inputs, block_span output, std::size_t lanes) +{ + if (opt.workers == nullptr) + { + fn(opcode, nodes, inputs, output, lanes); + return; + } + asio::io_context & io = opt.pump != nullptr ? *opt.pump : opt.workers->context(); + asio::io_context * wake = &io; + std::atomic done{false}; + std::exception_ptr err; + const auto draws = draw_context::capture(); + work_meter before; + work_meter after; + opt.workers->post_compute([&, wake] { + { + const adopt_draws adopted(draws); + before = work_meter::now(); + try + { + fn(opcode, nodes, inputs, output, lanes); + } + catch (...) + { + err = std::current_exception(); + } + after = work_meter::now(); + } + done.store(true, std::memory_order_release); + // Only by-value captures may be touched once `done` is set. + asio::post(*wake, [] {}); + }); + while (!done.load(std::memory_order_acquire)) + { + if (io.stopped()) + io.restart(); + io.run_one_for(std::chrono::milliseconds(1)); + } + absorb_work(before, after); + if (err) + std::rethrow_exception(err); +} + +/// @brief Resume point for `drive` when `park_if_waiting` yields. +struct drive_cursor +{ + std::size_t wave = 0; + std::size_t exchange_i = 0; + std::uint16_t sink_round = 0; + bool awaiting_peer = false; + bool done = false; +}; + +inline std::uint64_t open_hash(const std::uint8_t * word, std::size_t n) noexcept +{ + std::uint64_t h = 14695981039346656037ull; + for (std::size_t i = 0; i < n; ++i) + { + h ^= word[i]; + h *= 1099511628211ull; + } + return h; +} + +/// @brief Second-round hash of a reconstructed word on one duplex edge. +inline void exchange_check_hash(net::RoundSink & sink, const std::uint8_t * word, + std::size_t n, std::chrono::milliseconds budget = std::chrono::milliseconds(30000)) +{ + const auto h = open_hash(word, n); + std::uint8_t buf[8]; + std::memcpy(buf, &h, 8); + sink.submit(0, 0, buf, 8); + sink.flush(); + net::wait_peer_ready(sink, 0, 0, budget, "compose check_open: peer hash"); + std::uint8_t peer[8]; + sink.read_peer(0, 0, peer, 8); + std::uint64_t ph = 0; + std::memcpy(&ph, peer, 8); + if (ph != h) + throw std::runtime_error("compose check_open: hash exchange mismatch"); +} + +/// @brief 3PC ring: send the hash to the next party, compare with the previous. +inline void exchange_check_hash_ring(net::RoundSink & to_next, + net::RoundSink & from_prev, const std::uint8_t * word, std::size_t n, + std::chrono::milliseconds budget = std::chrono::milliseconds(30000)) +{ + const auto h = open_hash(word, n); + std::uint8_t buf[8]; + std::memcpy(buf, &h, 8); + to_next.submit(0, 0, buf, 8); + to_next.flush(); + net::wait_peer_ready(from_prev, 0, 0, budget, "compose check_open: ring hash"); + std::uint8_t peer[8]; + from_prev.read_peer(0, 0, peer, 8); + std::uint64_t ph = 0; + std::memcpy(&ph, peer, 8); + if (ph != h) + throw std::runtime_error("compose check_open: hash exchange mismatch"); +} + +namespace detail +{ + +HEDLEY_CONST +inline bool is_beaver_opcode(std::uint32_t op) noexcept +{ + return op >= opcodes::beaver_delta && op < opcodes::beaver_delta + 1024u; +} + +HEDLEY_CONST +inline bool is_rss_neighbor_open(const plan & p, std::uint32_t ex_id) noexcept +{ + if (p.domain_of(ex_id) == domain::y) + return true; + const auto & ins = p.inputs_of(ex_id); + return !ins.empty() && p.domain_of(ins[0]) == domain::y; +} + +/// domain::a / fss: sum; domain::b: p0−p1 style difference (party 0 keeps +/// mine−peer, party 1 keeps peer−mine via the same mine−peer on each side +/// when shares are subtractive); domain::y: keep peer bytes. +inline void reconstruct_open(domain d, std::size_t party, + const std::uint8_t * mine, const std::uint8_t * peer, std::size_t n, + std::uint8_t * out, field_open field = field_open::words) +{ + if (d == domain::y) + { + std::memcpy(out, peer, n); + return; + } + if (d == domain::bin || d == domain::bin_rss) + { + for (std::size_t i = 0; i < n; ++i) + out[i] = static_cast(mine[i] ^ peer[i]); + return; + } + auto combine_word = [&](std::uint64_t m, std::uint64_t pr) -> std::uint64_t { + if (field == field_open::fp61) + { + constexpr std::uint64_t mod = (std::uint64_t{1} << 61) - 1; + auto red = [mod](std::uint64_t x) { + x = (x & mod) + (x >> 61); + if (x >= mod) + x -= mod; + return x; + }; + m = red(m); + pr = red(pr); + if (d == domain::b) + return red((party == 0) ? (m + mod - pr) : (pr + mod - m)); + return red(m + pr); + } + if (d == domain::b) + return (party == 0) ? (m - pr) : (pr - m); + return m + pr; + }; + if (n >= 8 && n % 8 == 0) + { + for (std::size_t i = 0; i < n; i += 8) + { + std::uint64_t m = 0, pr = 0; + std::memcpy(&m, mine + i, 8); + std::memcpy(&pr, peer + i, 8); + const std::uint64_t r = combine_word(m, pr); + std::memcpy(out + i, &r, 8); + } + return; + } + for (std::size_t i = 0; i < n; ++i) + out[i] = static_cast(mine[i] ^ peer[i]); +} + +inline void apply_fuse_segment(const plan & p, + std::vector> & values, std::uint32_t id, + std::size_t lanes) +{ + const auto & ins = p.inputs_of(id); + if (ins.empty()) + return; + const auto src = ins[0]; + const auto off = static_cast(p.aux_of(id)); + const auto nb = p.value_bytes_of(id); + const auto sb = p.value_bytes_of(src); + for (std::size_t lane = 0; lane < lanes; ++lane) + { + if (off + nb > sb) + throw std::runtime_error("compose fuse segment out of range"); + std::memcpy(values[id].data() + lane * nb, + values[src].data() + lane * sb + off, nb); + } +} + +inline bool is_arith_walk_opcode(std::uint32_t opcode) noexcept +{ + return opcode == opcodes::bin_a2b || opcode == opcodes::bin_b2a + || opcode == opcodes::bin_inject || opcode == opcodes::bin_and + || opcode == opcodes::bin_rss_and || opcode == opcodes::bin_rss_inject + || opcode == opcodes::rss_zero || opcode == opcodes::trunc_prob + || opcode == opcodes::trunc_exact || opcode == opcodes::mul_trunc + || opcode == opcodes::share_cmp || opcode == opcodes::share_mux + || opcode == opcodes::share_input; +} + +inline kernel_fn builtin_walk_kernel(std::uint32_t opcode) +{ + return [opcode](std::uint32_t, const std::vector &, + const std::vector & inputs, block_span output, + std::size_t) { + if (output.data == nullptr || output.lanes == 0) + return; + const std::size_t nbytes = output.lanes * output.value_bytes; + std::fill(output.data, output.data + nbytes, 0); + if (inputs.empty() || inputs[0].data == nullptr) + return; + if (opcode == opcodes::fss_expand_pair && inputs[0].value_bytes >= 16 + && output.value_bytes >= 16 && output.value_bytes % 16 == 0) + { + for (std::size_t lane = 0; lane < output.lanes; ++lane) + { + simde__m128i seed{}; + std::memcpy(&seed, inputs[0].at(lane), 16); + if (output.value_bytes == 32) + { + auto both = dpf::prg::aes128::eval01(seed); + std::memcpy(output.at(lane), both.data(), 32); + } + else + { + for (std::uint32_t b = 0; b < output.value_bytes / 16; ++b) + { + auto blk = dpf::prg::aes128::eval(seed, b); + std::memcpy(output.at(lane) + static_cast(b) * 16, + &blk, 16); + } + } + } + return; + } + if (opcode == opcodes::fss_step + 1 && inputs.size() >= 2 + && inputs[1].data != nullptr) + { + for (std::size_t lane = 0; lane < output.lanes; ++lane) + { + const std::size_t n0 = std::min(output.value_bytes, inputs[0].value_bytes); + std::memcpy(output.at(lane), inputs[0].at(lane), n0); + const std::size_t n1 = std::min(output.value_bytes, inputs[1].value_bytes); + auto * dst = output.at(lane); + const auto * src = inputs[1].at(lane); + for (std::size_t i = 0; i < n1; ++i) + dst[i] = static_cast(dst[i] ^ src[i]); + } + return; + } + if (opcode == opcodes::fss_answer_pack || opcode == opcodes::fss_prefix_pair + || opcode == opcodes::fss_fuse_trailer || opcode == opcodes::reshare_mask) + { + if (opcode == opcodes::reshare_mask && inputs.size() >= 2 + && inputs[0].value_bytes == 8 && inputs[1].value_bytes == 8 + && output.value_bytes == 8) + { + for (std::size_t lane = 0; lane < output.lanes; ++lane) + { + std::uint64_t a = 0, b = 0; + std::memcpy(&a, inputs[0].at(lane), 8); + std::memcpy(&b, inputs[1].at(lane), 8); + const std::uint64_t s = a + b; + std::memcpy(output.at(lane), &s, 8); + } + return; + } + std::size_t off = 0; + for (const auto & in : inputs) + { + const std::size_t chunk = in.lanes * in.value_bytes; + if (off + chunk > nbytes) + break; + std::memcpy(output.data + off, in.data, chunk); + off += chunk; + } + return; + } + if (is_arith_walk_opcode(opcode)) + { + // Local arith defaults: trunc_prob shifts; others copy / XOR-and. + if (opcode == opcodes::trunc_prob && !inputs.empty()) + { + for (std::size_t lane = 0; lane < output.lanes; ++lane) + { + if (output.value_bytes == 8 && inputs[0].value_bytes >= 8) + { + std::uint64_t v = 0; + std::memcpy(&v, inputs[0].at(lane), 8); + // Shift amount is applied in run_arith_local via aux. + std::memcpy(output.at(lane), &v, 8); + } + else + { + const std::size_t n = std::min(output.value_bytes, + inputs[0].value_bytes); + std::memcpy(output.at(lane), inputs[0].at(lane), n); + } + } + return; + } + if ((opcode == opcodes::bin_and || opcode == opcodes::bin_rss_and) + && inputs.size() >= 2) + { + for (std::size_t lane = 0; lane < output.lanes; ++lane) + { + const std::size_t n = std::min({output.value_bytes, + inputs[0].value_bytes, inputs[1].value_bytes}); + for (std::size_t i = 0; i < n; ++i) + output.at(lane)[i] = static_cast( + inputs[0].at(lane)[i] & inputs[1].at(lane)[i]); + } + return; + } + if (!inputs.empty()) + { + const std::size_t chunk = std::min(nbytes, + inputs[0].lanes * inputs[0].value_bytes); + std::memcpy(output.data, inputs[0].data, chunk); + } + return; + } + const std::size_t chunk = std::min(nbytes, inputs[0].lanes * inputs[0].value_bytes); + std::memcpy(output.data, inputs[0].data, chunk); + }; +} + +inline void ensure_value_storage(const plan & p, + std::vector> & values, std::uint32_t id, + std::size_t lanes); + +/// @brief Run one arith/share opcode with party + drive_options (rss seeds, shift). +inline void run_arith_local(const plan & p, std::uint32_t id, std::size_t party, + std::size_t lane, std::size_t lanes, + std::vector> & values, const drive_options & opt) +{ + const auto op = p.opcode_of(id); + ensure_value_storage(p, values, id, lanes); + const auto vb = p.value_bytes_of(id); + auto * out = values[id].data() + lane * vb; + if (op == opcodes::rss_zero) + { + if (opt.rss_seeds == nullptr) + throw std::runtime_error("compose rss_zero: drive_options::rss_seeds required"); + const auto idx = opt.rss_seed_base + p.aux_of(id); + if (vb == 8) + { + const auto z = rss::zero_share(*opt.rss_seeds, idx); + std::memcpy(out, &z, 8); + } + else if (vb == 1) + { + const auto z = rss::zero_share(*opt.rss_seeds, idx); + out[0] = z; + } + else + { + for (std::size_t i = 0; i < vb; ++i) + { + const auto z = rss::zero_share( + *opt.rss_seeds, idx + i); + out[i] = z; + } + } + (void)party; + return; + } + const auto & ins = p.inputs_of(id); + if (op == opcodes::trunc_prob && !ins.empty() && vb == 8 + && p.value_bytes_of(ins[0]) >= 8) + { + ensure_value_storage(p, values, ins[0], lanes); + std::uint64_t v = 0; + std::memcpy(&v, values[ins[0]].data() + lane * p.value_bytes_of(ins[0]), 8); + const unsigned s = static_cast(p.aux_of(id)); + v >>= s; + std::memcpy(out, &v, 8); + return; + } + if (op == opcodes::trunc_exact && ins.size() >= 4 && vb >= 8) + { + auto load64 = [&](std::uint32_t src) { + ensure_value_storage(p, values, src, lanes); + std::uint64_t v = 0; + std::memcpy(&v, values[src].data() + lane * p.value_bytes_of(src), + std::min(8, p.value_bytes_of(src))); + return v; + }; + const auto x = load64(ins[0]); + const auto r = load64(ins[1]); + const auto delta = load64(ins[2]); + const auto wrap = load64(ins[3]); + const std::uint64_t r_public = ins.size() >= 5 ? load64(ins[4]) : 0; + const unsigned s = static_cast(p.aux_of(id)); + const auto o = trunc::trunc_exact_party(x, r, delta, wrap, + s, static_cast(party), r_public); + std::memcpy(out, &o, 8); + return; + } + if (op == opcodes::bin_a2b && ins.size() >= 3) + { + (void)party; + (void)out; + (void)vb; + throw std::runtime_error( + "bin_a2b opened-r conversion was removed; use a2b_gmw (carry AND)"); + } + auto load64 = [&](std::uint32_t src) { + ensure_value_storage(p, values, src, lanes); + std::uint64_t v = 0; + const auto sb = p.value_bytes_of(src); + std::memcpy(&v, values[src].data() + lane * sb, std::min(8, sb)); + return v; + }; + auto load8 = [&](std::uint32_t src) { + ensure_value_storage(p, values, src, lanes); + const auto sb = p.value_bytes_of(src); + if (sb == 0) + return static_cast(0); + return values[src][lane * sb]; + }; + if (op == opcodes::share_input && ins.size() >= 2 && vb >= 8) + { + const auto d = static_cast(load64(ins[0]) - load64(ins[1])); + std::memcpy(out, &d, 8); + return; + } + if (op == opcodes::bin_and && p.aux_of(id) == 1 && ins.size() >= 2) + { + ensure_value_storage(p, values, ins[0], lanes); + ensure_value_storage(p, values, ins[1], lanes); + const auto n = std::min(vb, std::min(p.value_bytes_of(ins[0]), + p.value_bytes_of(ins[1]))); + for (std::size_t i = 0; i < n; ++i) + out[i] = static_cast( + values[ins[0]][lane * p.value_bytes_of(ins[0]) + i] + ^ values[ins[1]][lane * p.value_bytes_of(ins[1]) + i]); + return; + } + if (op == opcodes::bin_and && p.aux_of(id) == 2 && ins.size() >= 5) + { + ot::bit_triple mine{load8(ins[0]), load8(ins[1]), load8(ins[2])}; + out[0] = edabit::and_finish(mine, load8(ins[3]), load8(ins[4]), + static_cast(party)); + return; + } + if (op == opcodes::bin_b2a && ins.size() >= 2 && vb >= 8) + { + const unsigned ell = static_cast(p.aux_of(id)); + ensure_value_storage(p, values, ins[0], lanes); + ensure_value_storage(p, values, ins[1], lanes); + const auto ab = p.value_bytes_of(ins[0]); + const auto mb = p.value_bytes_of(ins[1]); + const auto * arith = values[ins[0]].data() + lane * ab; + const auto * maskb = values[ins[1]].data() + lane * mb; + std::uint64_t acc = 0; + for (unsigned i = 0; i < ell; ++i) + { + std::uint64_t r = 0; + if (static_cast(i + 1) * 8 <= ab) + std::memcpy(&r, arith + static_cast(i) * 8, 8); + const std::uint8_t mask = (static_cast(i / 8) < mb) + ? static_cast((maskb[i / 8] >> (i % 8)) & 1u) + : 0; + ot::dabit dab{0, r}; + acc += edabit::b2a_party_bit(0, dab, mask, + static_cast(party), i); + } + std::memcpy(out, &acc, 8); + return; + } + if (op == opcodes::bin_inject && ins.size() >= 5 && vb >= 8) + { + const auto a = load64(ins[0]); + const auto b = load64(ins[1]); + const auto c = load64(ins[2]); + const auto d = load64(ins[3]); + const auto e = load64(ins[4]); + std::uint64_t z = c; + z += d * b; + z += e * a; + if (party == 0) + z += d * e; + std::memcpy(out, &z, 8); + return; + } + if (op == opcodes::bin_rss_and && ins.size() >= 4) + { + if (opt.rss_seeds == nullptr) + throw std::runtime_error("compose bin_rss_and: rss_seeds required"); + out[0] = bit_inject::rss_and_local(*opt.rss_seeds, load8(ins[0]), + load8(ins[1]), load8(ins[2]), load8(ins[3]), p.aux_of(id)); + return; + } + if (op == opcodes::bin_rss_inject && ins.size() >= 4 && vb >= 8) + { + if (opt.rss_seeds == nullptr) + throw std::runtime_error("compose bin_rss_inject: rss_seeds required"); + const auto y = bit_inject::rss_inject_local(*opt.rss_seeds, + load64(ins[0]), load64(ins[1]), load64(ins[2]), load64(ins[3]), + p.aux_of(id)); + std::memcpy(out, &y, 8); + return; + } + if (op == opcodes::mul_trunc && ins.size() >= 5 && vb >= 8) + { + const unsigned s = static_cast(p.aux_of(id)); + const auto z = trunc::mul_trunc_party(0, 0, load64(ins[0]), + load64(ins[1]), load64(ins[2]), load64(ins[3]), load64(ins[4]), s, + static_cast(party)); + std::memcpy(out, &z, 8); + return; + } + // Default: copy first input (or zero). + std::fill(out, out + vb, 0); + if (!ins.empty()) + { + ensure_value_storage(p, values, ins[0], lanes); + const auto sb = p.value_bytes_of(ins[0]); + std::memcpy(out, values[ins[0]].data() + lane * sb, std::min(sb, vb)); + } + if ((op == opcodes::bin_and || op == opcodes::bin_rss_and) && ins.size() >= 2) + { + ensure_value_storage(p, values, ins[1], lanes); + const auto sb = p.value_bytes_of(ins[1]); + for (std::size_t i = 0; i < std::min(sb, vb); ++i) + out[i] = static_cast(out[i] + & values[ins[1]].data()[lane * sb + i]); + } +} + +inline bool has_builtin_walk_kernel(std::uint32_t opcode) noexcept +{ + return opcode == opcodes::fss_expand || opcode == opcodes::fss_expand_pair + || opcode == opcodes::fss_step || opcode == opcodes::fss_step + 1 + || opcode == opcodes::fss_fuse_trailer || opcode == opcodes::fss_fuse_trailer + 1 + || opcode == opcodes::fss_early_stop_pack + || opcode == opcodes::fss_prefix_emit || opcode == opcodes::fss_prefix_emit + 1 + || opcode == opcodes::fss_prefix_pair + || opcode == opcodes::fss_prefix_retain || opcode == opcodes::fss_prefix_retain + 1 + || opcode == opcodes::fss_defer_expand || opcode == opcodes::fss_rotate + || opcode == opcodes::fss_leaf_later || opcode == opcodes::fss_apply_leaf + || opcode == opcodes::fss_answer_pack + || opcode == opcodes::ds_blind || opcode == opcodes::ds_cw + || opcode == opcodes::ds_advice || opcode == opcodes::ds_and + || opcode == opcodes::ds_and2 + || opcode == opcodes::ds_oh || opcode == opcodes::ds_leaf_mux + || opcode == opcodes::ds_leaf_mux + 1 + || opcode == opcodes::reshare_mask || opcode == opcodes::rss_mul + || opcode == opcodes::client_answer + || is_arith_walk_opcode(opcode); +} + +/// @brief Channel for one exchange node (pair / RSS neighbor / dealer). +inline edge_channel exchange_channel(const plan & p, std::uint32_t ex_id) noexcept +{ + const auto op = p.opcode_of(ex_id); + if (op == opcodes::dealer_pad || op == opcodes::dealer_zero) + return edge_channel::dealer; + if (op == opcodes::shuffle_send || op == opcodes::bench_ring) + return edge_channel::rss_next; + if (is_rss_neighbor_open(p, ex_id)) + return edge_channel::rss_next; + return edge_channel::peer; +} + +/// @brief Receive rule for one exchange node. +inline receive_rule exchange_receive_rule(const plan & p, + std::uint32_t ex_id) noexcept +{ + const auto op = p.opcode_of(ex_id); + if (is_beaver_opcode(op)) + return receive_rule::beaver; + if (op == opcodes::client_upload || op == opcodes::client_answer + || op == opcodes::dealer_pad || op == opcodes::dealer_zero + || op == opcodes::bench_wire || op == opcodes::bench_ring) + return receive_rule::copy_peer; + if (is_rss_neighbor_open(p, ex_id)) + return receive_rule::copy_peer; + // Aux high bit marks special receive rules recorded by the composer. + const auto aux = p.aux_of(ex_id); + if ((aux & 0xff000000u) == 0x01000000u) + return receive_rule::field_sum; + if ((aux & 0xff000000u) == 0x02000000u) + return receive_rule::any_two; + if ((aux & 0xff000000u) == 0x03000000u) + return receive_rule::verify_sketch; + if ((aux & 0xff000000u) == 0x04000000u) + return receive_rule::verify_proof; + if ((aux & 0xff000000u) == 0x05000000u) + return receive_rule::eq_check; + return receive_rule::domain_open; +} + +/// @brief Dominant channel for a packed exchange wave (dealer > rss > peer). +inline edge_channel wave_channel(const plan & p, const wave_info & wave) noexcept +{ + edge_channel ch = edge_channel::peer; + for (auto ex : wave.exchanges) + { + const auto c = exchange_channel(p, ex.id); + if (c == edge_channel::dealer) + return edge_channel::dealer; + if (c == edge_channel::rss_next) + ch = edge_channel::rss_next; + } + return ch; +} + +inline receive_rule wave_receive_rule(const plan & p, + const wave_info & wave) noexcept +{ + for (auto ex : wave.exchanges) + { + const auto r = exchange_receive_rule(p, ex.id); + if (r != receive_rule::domain_open) + return r; + } + return receive_rule::domain_open; +} + +inline void ensure_value_storage(const plan & p, + std::vector> & values, std::uint32_t id, + std::size_t lanes) +{ + const std::size_t need = lanes * p.value_bytes_of(id); + auto & v = values[id]; + if (v.size() >= need) + return; + // An empty input runs as zeros; a short one is a caller bug. + if (!v.empty() && p.effect_of(id) == effect::input) + throw std::invalid_argument("compose: input node " + std::to_string(id) + + " has " + std::to_string(v.size()) + " bytes; " + + std::to_string(lanes) + " instance(s) of " + + std::to_string(p.value_bytes_of(id)) + " bytes need " + + std::to_string(need)); + v.assign(need, 0); +} + +/// @brief Apply one packed peer slot to `exchanges` (in slot order). +inline void apply_peer_exchanges(const plan & p, const std::vector & exchanges, + std::size_t slot_bytes, std::size_t party, std::size_t lane, std::size_t lanes, + const std::uint8_t * peer, std::size_t peer_n, + std::vector> & values, const drive_options & opt) +{ + if (exchanges.empty() || peer == nullptr) + return; + if (peer_n < slot_bytes) + throw std::runtime_error("compose apply_peer_slot: short peer"); + std::size_t off = 0; + for (auto ex : exchanges) + { + const auto nb = p.value_bytes_of(ex.id); + ensure_value_storage(p, values, ex.id, lanes); + const auto op = p.opcode_of(ex.id); + const auto rule = exchange_receive_rule(p, ex.id); + if (rule == receive_rule::beaver && opt.beavers != nullptr) + { + const auto sess = static_cast(p.level_of(ex.id)); + const auto bi = static_cast(op - opcodes::beaver_delta); + opt.beavers->apply(sess, bi, peer + off, nb); + std::vector mine(nb, 0); + std::memcpy(mine.data(), values[ex.id].data() + lane * nb, nb); + reconstruct_open(domain::a, party, mine.data(), peer + off, nb, + values[ex.id].data() + lane * nb, opt.field); + } + else if (rule == receive_rule::copy_peer + || rule == receive_rule::xor_bytes) + { + if (rule == receive_rule::xor_bytes) + { + auto * dst = values[ex.id].data() + lane * nb; + for (std::size_t i = 0; i < nb; ++i) + dst[i] = static_cast(dst[i] ^ peer[off + i]); + } + else + { + std::memcpy(values[ex.id].data() + lane * nb, peer + off, nb); + } + } + else if (rule == receive_rule::field_sum + || rule == receive_rule::any_two) + { + // field_sum / any_two: same word-lane add as domain::a (Shamir + // any-two of two shares collapses to a sum of the held pair). + std::vector mine(nb, 0); + const auto & ins = p.inputs_of(ex.id); + if (!ins.empty()) + { + const auto sb = p.value_bytes_of(ins[0]); + ensure_value_storage(p, values, ins[0], lanes); + std::memcpy(mine.data(), values[ins[0]].data() + lane * sb, + std::min(sb, nb)); + } + else + { + std::memcpy(mine.data(), values[ex.id].data() + lane * nb, nb); + } + reconstruct_open(domain::a, party, mine.data(), peer + off, nb, + values[ex.id].data() + lane * nb, + rule == receive_rule::field_sum ? field_open::fp61 : opt.field); + } + else if (rule == receive_rule::verify_sketch + || rule == receive_rule::verify_proof + || rule == receive_rule::eq_check) + { + // Store peer bytes; host/kernel verifies (sketch/proof/tag). + std::memcpy(values[ex.id].data() + lane * nb, peer + off, nb); + if (rule == receive_rule::eq_check) + { + const auto & ins = p.inputs_of(ex.id); + if (!ins.empty()) + { + ensure_value_storage(p, values, ins[0], lanes); + const auto sb = p.value_bytes_of(ins[0]); + const auto n = std::min(sb, nb); + if (std::memcmp(values[ins[0]].data() + lane * sb, + peer + off, n) + != 0) + throw std::runtime_error( + "compose apply_peer_slot: eq_check failed"); + } + } + } + else + { + const auto & ins = p.inputs_of(ex.id); + domain d = p.domain_of(ex.id); + if (!ins.empty()) + d = p.domain_of(ins[0]); + std::vector mine(nb, 0); + if (!ins.empty()) + { + const auto sb = p.value_bytes_of(ins[0]); + ensure_value_storage(p, values, ins[0], lanes); + std::memcpy(mine.data(), values[ins[0]].data() + lane * sb, + std::min(sb, nb)); + } + reconstruct_open(d, party, mine.data(), peer + off, nb, + values[ex.id].data() + lane * nb, opt.field); + } + if (opt.cleartext && opt.clear_oracle != nullptr) + { + auto it = opt.clear_oracle->find(ex.id); + if (it != opt.clear_oracle->end() && it->second.size() == nb + && std::memcmp(values[ex.id].data() + lane * nb, + it->second.data(), nb) + != 0) + throw std::runtime_error( + "compose cleartext: open mismatch vs clear_oracle"); + } + if (opt.check_open) + { + // Consistency: hash of reconstructed word must match oracle when + // provided; otherwise store a fingerprint peers can compare. + if (opt.clear_oracle != nullptr) + { + auto it = opt.clear_oracle->find(ex.id); + if (it != opt.clear_oracle->end() && it->second.size() == nb + && std::memcmp(values[ex.id].data() + lane * nb, + it->second.data(), nb) + != 0) + throw std::runtime_error( + "compose check_open: reconstructed open rejected"); + } + std::uint64_t h = 14695981039346656037ull; + for (std::size_t i = 0; i < nb; ++i) + { + h ^= values[ex.id][lane * nb + i]; + h *= 1099511628211ull; + } + // Peer hash lives in trailing bytes of the peer slot when present. + if (peer_n >= off + nb + 8) + { + std::uint64_t peer_h = 0; + std::memcpy(&peer_h, peer + off + nb, 8); + if (peer_h != 0 && peer_h != h) + throw std::runtime_error( + "compose check_open: hash exchange mismatch"); + } + } + off += nb; + } +} + +/// @brief Apply one packed peer slot to the exchange nodes of `wave`. +inline void apply_peer_slot(const plan & p, const wave_info & wave, + std::size_t party, std::size_t lane, std::size_t lanes, + const std::uint8_t * peer, std::size_t peer_n, + std::vector> & values, const drive_options & opt) +{ + apply_peer_exchanges(p, wave.exchanges, wave.slot_bytes, party, lane, lanes, + peer, peer_n, values, opt); +} + +/// @brief Pack one lane's payloads for `exchanges` into `out`. +inline void pack_exchanges(const plan & p, const std::vector & exchanges, + std::size_t lane, std::size_t lanes, + std::vector> & values, const drive_options & opt, + std::uint8_t * out) +{ + std::size_t off = 0; + for (auto ex : exchanges) + { + ensure_value_storage(p, values, ex.id, lanes); + const auto nb = p.value_bytes_of(ex.id); + const auto op = p.opcode_of(ex.id); + if (op == opcodes::dealer_pad || op == opcodes::dealer_zero) + throw std::runtime_error( + "compose: dealer waves need a dealer edge; drive with " + "drive_via_schedule(plan, edge_mesh) or app::run_parties"); + if (is_beaver_opcode(op) && opt.beavers != nullptr) + { + const auto sess = static_cast(p.level_of(ex.id)); + const auto bi = static_cast(op - opcodes::beaver_delta); + opt.beavers->pack(sess, bi, out + off, nb); + std::memcpy(values[ex.id].data() + lane * nb, out + off, nb); + } + else + { + const auto & ins = p.inputs_of(ex.id); + if (!ins.empty() && !is_beaver_opcode(op)) + { + const auto src = ins[0]; + ensure_value_storage(p, values, src, lanes); + const auto sb = p.value_bytes_of(src); + std::memcpy(out + off, values[src].data() + lane * sb, + std::min(sb, nb)); + std::memcpy(values[ex.id].data() + lane * nb, + values[src].data() + lane * sb, std::min(sb, nb)); + } + else + { + std::memcpy(out + off, values[ex.id].data() + lane * nb, nb); + } + } + off += nb; + } +} + +/// @brief Pack one lane's exchange payloads into `out` (size `wave.slot_bytes`). +inline void pack_exchange_lane(const plan & p, const wave_info & wave, + std::size_t lane, std::size_t lanes, + std::vector> & values, const drive_options & opt, + std::uint8_t * out) +{ + pack_exchanges(p, wave.exchanges, lane, lanes, values, opt, out); +} + +/// @brief Bench-cell local work. Returns true when this group was a cell. +inline bool dispatch_cell(const plan & p, const simd_group & g, std::size_t party, + std::size_t lane, std::size_t lanes, + std::vector> & values, const drive_options & opt) +{ + if (opt.cell == nullptr) + return false; + if (g.opcode != opcodes::bench_emit && g.opcode != opcodes::bench_apply) + return false; + for (auto n : g.nodes) + { + ensure_value_storage(p, values, n.id, lanes); + const auto vb = p.value_bytes_of(n.id); + opt.cell(g.opcode, party, p.aux_of(n.id), + values[n.id].data() + lane * vb, vb); + } + return true; +} + +/// @brief Run local groups of `wave` for a single lane (schedule_session path). +inline void run_wave_locals_lane(const plan & p, const wave_info & wave, + std::size_t party, std::size_t lane, std::size_t lanes, + std::vector> & values, + const std::map & kernels, + const drive_options & opt = {}) +{ + for (const auto & g : wave.groups) + { + if (is_arith_walk_opcode(g.opcode)) + { + for (auto n : g.nodes) + run_arith_local(p, n.id, party, lane, lanes, values, opt); + continue; + } + if (g.kind == effect::convert) + { + for (auto n : g.nodes) + { + ensure_value_storage(p, values, n.id, lanes); + const auto & ins = p.inputs_of(n.id); + if (ins.empty()) + continue; + if (p.alias_of(n.id) && ins.size() == 1 + && p.value_bytes_of(n.id) == p.value_bytes_of(ins[0])) + { + const auto vb = p.value_bytes_of(n.id); + std::memcpy(values[n.id].data() + lane * vb, + values[ins[0]].data() + lane * vb, vb); + continue; + } + if (ins.size() == 1) + { + run_builtin_convert(g.opcode, party, + values[ins[0]].data() + lane * p.value_bytes_of(ins[0]), + p.value_bytes_of(ins[0]), + values[n.id].data() + lane * p.value_bytes_of(n.id), + p.value_bytes_of(n.id)); + } + else if (ins.size() == 2 && g.opcode == opcodes::conv_y2rss) + { + auto * outp = values[n.id].data() + lane * p.value_bytes_of(n.id); + const auto half = p.value_bytes_of(ins[0]); + std::memcpy(outp, values[ins[0]].data() + lane * half, half); + std::memcpy(outp + half, values[ins[1]].data() + lane * half, + half); + } + } + continue; + } + if (is_beaver_opcode(g.opcode)) + continue; + if (g.opcode == opcodes::dealer_pad || g.opcode == opcodes::dealer_zero) + throw std::runtime_error( + "compose: dealer delivery needs a dealer edge sink"); + if (g.opcode == opcodes::fss_fuse_segment) + { + for (auto n : g.nodes) + { + ensure_value_storage(p, values, n.id, lanes); + apply_fuse_segment(p, values, n.id, lanes); + } + continue; + } + if (dispatch_cell(p, g, party, lane, lanes, values, opt)) + continue; + auto kit = kernels.find(g.opcode); + kernel_fn builtin; + const kernel_fn * fn = nullptr; + if (kit != kernels.end()) + fn = &kit->second; + else if (has_builtin_walk_kernel(g.opcode)) + { + builtin = builtin_walk_kernel(g.opcode); + fn = &builtin; + } + else if (g.kind == effect::blind) + { + for (auto n : g.nodes) + { + ensure_value_storage(p, values, n.id, lanes); + const auto vb = p.value_bytes_of(n.id); + std::fill(values[n.id].data() + lane * vb, + values[n.id].data() + lane * vb + vb, 0); + } + continue; + } + else + { + throw std::runtime_error( + "compose missing kernel for opcode " + std::to_string(g.opcode)); + } + for (auto n : g.nodes) + { + ensure_value_storage(p, values, n.id, lanes); + std::vector ins; + for (auto in_id : p.inputs_of(n.id)) + { + ensure_value_storage(p, values, in_id, lanes); + ins.push_back(block_span{values[in_id].data() + lane * p.value_bytes_of(in_id), + 1, p.value_bytes_of(in_id)}); + } + block_span local_out{values[n.id].data() + lane * p.value_bytes_of(n.id), + 1, p.value_bytes_of(n.id)}; + invoke_kernel(opt, *fn, g.opcode, {n}, ins, local_out, 1); + } + } +} + +inline std::vector exchange_wave_indices(const plan & p) +{ + std::vector idx; + for (std::size_t w = 0; w < p.waves(); ++w) + if (!p.wave(w).exchanges.empty()) + idx.push_back(w); + return idx; +} + +} // namespace detail + +inline void drive(const plan & p, net::RoundSink & sink, + std::vector> & values, + const std::map & kernels, std::size_t party = 0, + const drive_options & opt = {}) +{ + const std::size_t lanes = sink.count(); + if (values.size() < p.nodes().size()) + values.resize(p.nodes().size()); + + auto ensure_storage = [&](std::uint32_t id) { + detail::ensure_value_storage(p, values, id, lanes); + }; + for (std::uint32_t id = 0; id < p.nodes().size(); ++id) + ensure_storage(id); + + std::size_t exchange_i = 0; + std::size_t wave_begin = 0; + bool resume_recv = false; + std::uint16_t resume_round = 0; + if (opt.cursor != nullptr && !opt.cursor->done) + { + wave_begin = opt.cursor->wave; + exchange_i = opt.cursor->exchange_i; + resume_recv = opt.cursor->awaiting_peer; + resume_round = opt.cursor->sink_round; + } + auto park = [&](std::size_t wave, std::uint16_t sink_round) { + if (opt.cursor == nullptr) + return; + opt.cursor->wave = wave; + opt.cursor->exchange_i = exchange_i; + opt.cursor->sink_round = sink_round; + opt.cursor->awaiting_peer = true; + opt.cursor->done = false; + }; + for (std::size_t w = wave_begin; w < p.waves(); ++w) + { + const auto & wave = p.wave(w); + const bool skip_wave = !resume_recv && !wave.exchanges.empty() + && exchange_i < opt.from_exchange_wave; + + if (!skip_wave && !resume_recv) + { + for (const auto & g : wave.groups) + { + if (detail::is_arith_walk_opcode(g.opcode)) + { + for (auto n : g.nodes) + for (std::size_t lane = 0; lane < lanes; ++lane) + detail::run_arith_local(p, n.id, party, lane, lanes, + values, opt); + continue; + } + + if (g.kind == effect::convert) + { + for (auto n : g.nodes) + { + ensure_storage(n.id); + const auto & ins = p.inputs_of(n.id); + if (ins.empty()) + continue; + if (p.alias_of(n.id) && ins.size() == 1 + && p.value_bytes_of(n.id) == p.value_bytes_of(ins[0])) + { + values[n.id] = values[ins[0]]; + continue; + } + for (std::size_t lane = 0; lane < lanes; ++lane) + { + if (ins.size() == 1) + { + detail::run_builtin_convert(g.opcode, party, + values[ins[0]].data() + + lane * p.value_bytes_of(ins[0]), + p.value_bytes_of(ins[0]), + values[n.id].data() + + lane * p.value_bytes_of(n.id), + p.value_bytes_of(n.id)); + } + else if (ins.size() == 2 + && g.opcode == opcodes::conv_y2rss) + { + auto * out = values[n.id].data() + + lane * p.value_bytes_of(n.id); + const auto half = p.value_bytes_of(ins[0]); + std::memcpy(out, + values[ins[0]].data() + lane * half, half); + std::memcpy(out + half, + values[ins[1]].data() + lane * half, half); + } + } + } + continue; + } + + if (detail::is_beaver_opcode(g.opcode)) + continue; // δ results land via beaver_host / exchange path + + if (g.opcode == opcodes::dealer_pad || g.opcode == opcodes::dealer_zero) + throw std::runtime_error( + "compose::drive: dealer delivery requires drive_composed_trio"); + + if (g.opcode == opcodes::fss_fuse_segment) + { + for (auto n : g.nodes) + { + ensure_storage(n.id); + const auto & ins = p.inputs_of(n.id); + if (!ins.empty()) + ensure_storage(ins[0]); + detail::apply_fuse_segment(p, values, n.id, lanes); + } + continue; + } + + if (opt.cell != nullptr + && (g.opcode == opcodes::bench_emit + || g.opcode == opcodes::bench_apply)) + { + for (auto n : g.nodes) + { + ensure_storage(n.id); + const auto vb = p.value_bytes_of(n.id); + for (std::size_t lane = 0; lane < lanes; ++lane) + opt.cell(g.opcode, party, p.aux_of(n.id), + values[n.id].data() + lane * vb, vb); + } + continue; + } + + auto kit = kernels.find(g.opcode); + kernel_fn builtin; + const kernel_fn * fn = nullptr; + if (kit != kernels.end()) + fn = &kit->second; + else if (detail::has_builtin_walk_kernel(g.opcode)) + { + builtin = detail::builtin_walk_kernel(g.opcode); + fn = &builtin; + } + else if (g.kind == effect::blind) + { + for (auto n : g.nodes) + { + ensure_storage(n.id); + std::fill(values[n.id].begin(), values[n.id].end(), 0); + } + continue; + } + else + { + throw std::runtime_error( + "compose::drive missing kernel for opcode " + + std::to_string(g.opcode)); + } + + for (auto n : g.nodes) + ensure_storage(n.id); + bool uniform = !g.nodes.empty(); + for (auto n : g.nodes) + { + if (p.inputs_of(n.id).size() != 1 + || p.value_bytes_of(n.id) + != p.value_bytes_of(g.nodes[0].id)) + { + uniform = false; + break; + } + } + if (uniform && g.nodes.size() > 1) + { + const auto vb = p.value_bytes_of(g.nodes[0].id); + const std::size_t packed_lanes = g.nodes.size() * lanes; + std::vector packed_in(packed_lanes * vb); + std::vector packed_out(packed_lanes * vb); + for (std::size_t ni = 0; ni < g.nodes.size(); ++ni) + { + const auto in_id = p.inputs_of(g.nodes[ni].id)[0]; + ensure_storage(in_id); + std::memcpy(packed_in.data() + ni * lanes * vb, + values[in_id].data(), lanes * vb); + } + block_span in_span{packed_in.data(), packed_lanes, vb}; + block_span out_span{packed_out.data(), packed_lanes, vb}; + invoke_kernel(opt, *fn, g.opcode, g.nodes, {in_span}, out_span, + lanes); + for (std::size_t ni = 0; ni < g.nodes.size(); ++ni) + { + std::memcpy(values[g.nodes[ni].id].data(), + packed_out.data() + ni * lanes * vb, lanes * vb); + } + } + else + { + for (auto n : g.nodes) + { + std::vector ins; + for (auto in_id : p.inputs_of(n.id)) + { + ensure_storage(in_id); + ins.push_back(block_span{values[in_id].data(), lanes, + p.value_bytes_of(in_id)}); + } + block_span local_out{values[n.id].data(), lanes, + p.value_bytes_of(n.id)}; + invoke_kernel(opt, *fn, g.opcode, {n}, ins, local_out, lanes); + } + } + } + } + + if (wave.exchanges.empty() || wave.slot_bytes == 0) + { + resume_recv = false; + continue; + } + + if (!resume_recv && exchange_i < opt.from_exchange_wave) + { + ++exchange_i; + continue; + } + + std::uint16_t sink_round = 0; + if (resume_recv) + sink_round = resume_round; + else + { + sink_round = static_cast( + opt.compact_sink ? (exchange_i - opt.from_exchange_wave) + : exchange_i); + ++exchange_i; + + for (std::size_t lane = 0; lane < lanes; ++lane) + { + std::vector buf(wave.slot_bytes, 0); + std::size_t off = 0; + for (auto ex : wave.exchanges) + { + ensure_storage(ex.id); + const auto nb = p.value_bytes_of(ex.id); + const auto op = p.opcode_of(ex.id); + if (op == opcodes::dealer_pad || op == opcodes::dealer_zero) + throw std::runtime_error( + "compose::drive: dealer waves need a dealer edge; drive " + "with drive_via_schedule(plan, edge_mesh) or app::run_parties"); + if (detail::is_beaver_opcode(op) && opt.beavers != nullptr) + { + const auto sess = static_cast(p.level_of(ex.id)); + const auto bi = static_cast(op - opcodes::beaver_delta); + opt.beavers->pack(sess, bi, buf.data() + off, nb); + std::memcpy(values[ex.id].data() + lane * nb, + buf.data() + off, nb); + } + else + { + const auto & ins = p.inputs_of(ex.id); + if (!ins.empty() && !detail::is_beaver_opcode(op)) + { + const auto src = ins[0]; + ensure_storage(src); + const auto sb = p.value_bytes_of(src); + std::memcpy(buf.data() + off, + values[src].data() + lane * sb, + std::min(sb, nb)); + std::memcpy(values[ex.id].data() + lane * nb, + values[src].data() + lane * sb, + std::min(sb, nb)); + } + else + { + std::memcpy(buf.data() + off, + values[ex.id].data() + lane * nb, nb); + } + } + off += nb; + } + sink.submit(sink_round, lane, buf.data(), buf.size()); + } + } + if (!resume_recv) + { + sink.flush(); + sink.poll(); + } + if (opt.park_if_waiting) + { + bool ready = true; + for (std::size_t lane = 0; lane < lanes; ++lane) + { + if (!sink.peer_ready(sink_round, lane)) + ready = false; + } + if (!ready) + { + park(w, sink_round); + return; + } + } + for (std::size_t lane = 0; lane < lanes; ++lane) + { + detail::wait_ready(sink, + wait_budget(opt, edge_peer, round_budget(opt, sink_round)), + [&] { return sink.peer_ready(sink_round, lane); }, + "compose::drive round " + std::to_string(sink_round)); + std::vector peer(wave.slot_bytes); + sink.read_peer(sink_round, lane, peer.data(), peer.size()); + std::size_t off = 0; + for (auto ex : wave.exchanges) + { + const auto nb = p.value_bytes_of(ex.id); + ensure_storage(ex.id); + const auto op = p.opcode_of(ex.id); + if (detail::is_beaver_opcode(op) && opt.beavers != nullptr) + { + const auto sess = static_cast(p.level_of(ex.id)); + const auto bi = static_cast(op - opcodes::beaver_delta); + opt.beavers->apply(sess, bi, peer.data() + off, nb); + // δ sum into the exchange node for downstream compute. + const auto & ins = p.inputs_of(ex.id); + std::vector mine(nb, 0); + std::memcpy(mine.data(), values[ex.id].data() + lane * nb, nb); + detail::reconstruct_open(domain::a, party, mine.data(), + peer.data() + off, nb, values[ex.id].data() + lane * nb, + opt.field); + (void)ins; + } + else + { + const auto & ins = p.inputs_of(ex.id); + domain d = p.domain_of(ex.id); + if (!ins.empty()) + d = p.domain_of(ins[0]); + const bool client_msg = op == opcodes::client_upload + || op == opcodes::client_answer; + if (detail::is_rss_neighbor_open(p, ex.id) + || detail::is_beaver_opcode(op) || client_msg) + { + if (detail::is_beaver_opcode(op) && !client_msg) + { + std::vector mine(nb, 0); + if (!ins.empty()) + { + const auto sb = p.value_bytes_of(ins[0]); + std::memcpy(mine.data(), + values[ins[0]].data() + lane * sb, + std::min(sb, nb)); + } + else + { + std::memcpy(mine.data(), + values[ex.id].data() + lane * nb, nb); + } + detail::reconstruct_open(domain::a, party, + mine.data(), peer.data() + off, nb, + values[ex.id].data() + lane * nb, opt.field); + } + else + { + std::memcpy(values[ex.id].data() + lane * nb, + peer.data() + off, nb); + } + } + else + { + std::vector mine(nb, 0); + if (!ins.empty()) + { + const auto sb = p.value_bytes_of(ins[0]); + std::memcpy(mine.data(), + values[ins[0]].data() + lane * sb, + std::min(sb, nb)); + } + detail::reconstruct_open(d, party, mine.data(), + peer.data() + off, nb, + values[ex.id].data() + lane * nb, opt.field); + } + } + if ((opt.cleartext || opt.check_open) && opt.clear_oracle != nullptr) + { + auto it = opt.clear_oracle->find(ex.id); + if (it != opt.clear_oracle->end() && it->second.size() == nb + && std::memcmp(values[ex.id].data() + lane * nb, + it->second.data(), nb) + != 0) + throw std::runtime_error( + opt.check_open + ? "compose check_open: reconstructed open rejected" + : "compose cleartext: open mismatch vs clear_oracle"); + } + off += nb; + } + } + resume_recv = false; + if (opt.one_exchange) + { + if (opt.cursor != nullptr) + { + opt.cursor->wave = w + 1; + opt.cursor->exchange_i = exchange_i; + opt.cursor->awaiting_peer = false; + opt.cursor->done = false; + } + return; + } + } + if (opt.cursor != nullptr) + { + opt.cursor->done = true; + opt.cursor->awaiting_peer = false; + } +} + +namespace detail +{ + +/// @brief The exchanges of one wave that travel on one channel. +struct wave_part +{ + std::size_t wave = 0; + edge_channel channel = edge_channel::peer; + std::vector exchanges; + std::size_t slot_bytes = 0; +}; + +/// @brief Exchange waves split per channel (dealer, then rss_next, then peer). +/// @details A wave that mixes dealer, RSS, and 2PC exchanges becomes one round +/// per channel; exchanges in one wave never depend on each other, so +/// the order only fixes the wire layout. +inline std::vector schedule_parts(const plan & p) +{ + std::vector parts; + for (const auto w : exchange_wave_indices(p)) + { + const auto & wave = p.wave(w); + wave_part by[3]; + for (auto ex : wave.exchanges) + { + const auto c = exchange_channel(p, ex.id); + auto & part = by[static_cast(c)]; + part.wave = w; + part.channel = c; + part.exchanges.push_back(ex); + part.slot_bytes += p.value_bytes_of(ex.id); + } + for (int c : {2, 1, 0}) + if (!by[c].exchanges.empty()) + parts.push_back(std::move(by[c])); + } + return parts; +} + +/// @brief One schedule round from `party`'s point of view. +/// @details Parties 0 and 1 run every part: peer parts with each other, RSS +/// parts on their ring edge, dealer parts as receivers. Party 2 is the +/// dealer / third party: idle on 2PC opens, on the ring for RSS parts, +/// and the sender of dealer parts (one round to party 0 on +/// `edge_dealer`, one to party 1 on `edge_dealer_p1`). +struct party_step +{ + wave_part part; + bool dealer_side = false; + unsigned dest = 0; + edge_id edge = edge_peer; + std::uint16_t sink_round = 0; +}; + +inline std::vector party_steps(const plan & p, std::size_t party) +{ + const auto parts = schedule_parts(p); + std::vector out; + if (party > 2) + { + if (!parts.empty()) + throw std::invalid_argument("plan_to_schedule: party " + + std::to_string(party) + " has no role (0 and 1 are online, " + "2 is the dealer / third party)"); + return out; + } + auto add = [&](const wave_part & pt, bool dealer_side, unsigned dest, + edge_id e) { + party_step st; + st.part = pt; + st.dealer_side = dealer_side; + st.dest = dest; + st.edge = e; + out.push_back(std::move(st)); + }; + bool peer_only = true; + for (const auto & pt : parts) + { + switch (pt.channel) + { + case edge_channel::peer: + if (party != 2) + add(pt, false, 0, edge_peer); + break; + case edge_channel::rss_next: + peer_only = false; + add(pt, false, 0, edge_rss_next); + break; + case edge_channel::dealer: + peer_only = false; + if (party == 2) + { + add(pt, true, 0, edge_dealer); + add(pt, true, 1, edge_dealer_p1); + } + else + add(pt, false, 0, edge_dealer); + break; + } + } + if (party == 2 && peer_only && !parts.empty()) + throw std::invalid_argument("plan_to_schedule: party 2 has no dealer or " + "rss_next rounds; 2PC opens run between parties 0 and 1"); + std::map next; + for (auto & st : out) + st.sink_round = next[st.edge]++; + return out; +} + +inline receive_rule part_receive_rule(const plan & p, const wave_part & part) +{ + for (auto ex : part.exchanges) + { + const auto r = exchange_receive_rule(p, ex.id); + if (r != receive_rule::domain_open) + return r; + } + return receive_rule::domain_open; +} + +using zero_share_cache = + std::map, std::vector>; + +/// @brief Dealer side of a dealer part: the payload, or a zero share for `dest`. +inline void pack_dealer_part(const plan & p, const wave_part & part, unsigned dest, + std::size_t lane, std::size_t lanes, + std::vector> & values, zero_share_cache & zeros, + std::uint8_t * out) +{ + std::size_t off = 0; + for (auto ex : part.exchanges) + { + ensure_value_storage(p, values, ex.id, lanes); + const auto nb = p.value_bytes_of(ex.id); + auto * dst = out + off; + if (p.opcode_of(ex.id) == opcodes::dealer_pad) + { + const auto & ins = p.inputs_of(ex.id); + const std::uint8_t * src = values[ex.id].data() + lane * nb; + std::size_t n = nb; + if (!ins.empty()) + { + ensure_value_storage(p, values, ins[0], lanes); + const auto sb = p.value_bytes_of(ins[0]); + src = values[ins[0]].data() + lane * sb; + n = std::min(sb, nb); + } + std::memset(dst, 0, nb); + std::memcpy(dst, src, n); + std::memcpy(values[ex.id].data() + lane * nb, dst, nb); + } + else + { + const auto key = std::make_pair(ex.id, lane); + if (dest == 0) + { + std::vector a(nb), b(nb); + for (auto & byte : a) + byte = dpf::uniform_sample(); + if (p.domain_of(ex.id) != domain::b && nb % 8 == 0) + { + for (std::size_t i = 0; i < nb; i += 8) + { + std::uint64_t w = 0; + std::memcpy(&w, a.data() + i, 8); + w = static_cast(0) - w; + std::memcpy(b.data() + i, &w, 8); + } + } + else + b = a; + std::memcpy(dst, a.data(), nb); + zeros[key] = std::move(b); + } + else + { + auto it = zeros.find(key); + if (it == zeros.end()) + throw std::logic_error( + "dealer: zero share for party 1 before party 0"); + std::memcpy(dst, it->second.data(), nb); + zeros.erase(it); + } + } + off += nb; + } +} + +/// @brief Last round's peer slot and trailing compute-only waves. +inline void finish_steps(const plan & p, const std::vector & steps, + edge_mesh & mesh, std::vector> & values, + const std::map & kernels, std::size_t party, + std::size_t lanes, const drive_options & opt) +{ + if (values.size() < p.nodes().size()) + values.resize(p.nodes().size()); + for (std::uint32_t id = 0; id < p.nodes().size(); ++id) + ensure_value_storage(p, values, id, lanes); + if (steps.empty()) + { + for (std::size_t wi = 0; wi < p.waves(); ++wi) + for (std::size_t lane = 0; lane < lanes; ++lane) + run_wave_locals_lane(p, p.wave(wi), party, lane, lanes, values, + kernels, opt); + return; + } + const auto & last = steps.back(); + auto & sink = mesh.at(last.edge); + sink.flush(); + sink.poll(); + const auto budget = wait_budget(opt, last.edge, + round_budget(opt, steps.size() - 1)); + for (std::size_t lane = 0; lane < lanes; ++lane) + { + wait_ready(sink, budget, + [&] { + if (sink.peer_ready(last.sink_round, lane)) + return true; + sink.flush(); + return false; + }, + "finish on " + net::edge_name(last.edge)); + std::vector peer(last.part.slot_bytes); + if (!peer.empty()) + sink.read_peer(last.sink_round, lane, peer.data(), peer.size()); + if (!last.dealer_side) + apply_peer_exchanges(p, last.part.exchanges, last.part.slot_bytes, + party, lane, lanes, peer.data(), peer.size(), values, opt); + } + for (std::size_t wi = last.part.wave + 1; wi < p.waves(); ++wi) + for (std::size_t lane = 0; lane < lanes; ++lane) + run_wave_locals_lane(p, p.wave(wi), party, lane, lanes, values, + kernels, opt); +} + +/// @brief Drive `sess` to completion under per-instance round budgets. +/// @details An instance's clock starts when it enters a round and resets when +/// it advances, so a long healthy protocol never times out; only a +/// round whose peer bytes do not arrive does. Completions for other +/// edges do not reset it. +inline void run_session(schedule_session & sess, const drive_options & opt, + const std::string & what) +{ + using clock = std::chrono::steady_clock; + const std::size_t count = sess.count(); + std::vector mark(count, ~std::uint64_t{0}); + std::vector since(count, clock::now()); + std::vector sinks; + for (auto * s : sess.mesh().sinks) + if (s != nullptr && std::find(sinks.begin(), sinks.end(), s) == sinks.end()) + sinks.push_back(s); + unsigned spins = 0; + for (;;) + { + sess.drive(); + const auto now = clock::now(); + bool all_done = true; + bool advanced = false; + bool bounded = false; + std::chrono::milliseconds slice(1000); + for (std::size_t i = 0; i < count; ++i) + { + if (sess.done(i)) + continue; + all_done = false; + const auto m = sess.mark(i); + if (m != mark[i]) + { + mark[i] = m; + since[i] = now; + advanced = true; + } + const auto budget = wait_budget(opt, sess.current_edge(i), + sess.current_timeout(i)); + if (budget.count() == 0) + continue; + bounded = true; + const auto waited = + std::chrono::duration_cast(now - since[i]); + if (waited >= budget) + throw std::runtime_error(what + ": instance " + std::to_string(i) + + " waited " + std::to_string(waited.count()) + " ms in round " + + std::to_string(sess.current_round(i)) + " on " + + net::edge_name(sess.current_edge(i)) + " (budget " + + std::to_string(budget.count()) + + " ms); that peer stopped sending or is not driving"); + slice = std::min(slice, budget - waited); + } + if (all_done) + return; + if (slice.count() < 1) + slice = std::chrono::milliseconds(1); + bool ran = false; + bool one_domain = true; + for (auto * s : sinks) + one_domain = one_domain && s->wait_domain() == sinks.front()->wait_domain(); + if (sinks.size() == 1 || one_domain) + ran = pump_sink(*sinks.front(), slice); + else + { + for (auto * s : sinks) + s->poll(); + for (auto * s : sinks) + if (pump_sink(*s, std::chrono::milliseconds(1))) + ran = true; + } + if (!bounded) + { + if (ran || advanced) + spins = 0; + else if (++spins > 100000u) + throw std::runtime_error(what + ": peer not ready (drive both ends)"); + } + } +} + +} // namespace detail + +/// @brief Lower exchange waves of `p` to `schedule_round`s for `schedule_session`. +/// @details Round `r`'s `produce` applies the previous round's peer bytes, +/// runs local groups since the prior round's wave, and packs this +/// round's slot. See `detail::party_steps` for the per-party roles. +/// Call a finish (`finish_schedule` or the mesh drive) afterwards so +/// the last peer slot and trailing compute-only waves land in `values`. +inline std::vector plan_to_schedule(const plan & p, + std::vector> & values, + const std::map & kernels, std::size_t party, + std::size_t lanes, const drive_options & opt = {}) +{ + if (values.size() < p.nodes().size()) + values.resize(p.nodes().size()); + for (std::uint32_t id = 0; id < p.nodes().size(); ++id) + detail::ensure_value_storage(p, values, id, lanes); + + auto steps = std::make_shared>( + detail::party_steps(p, party)); + auto zeros = std::make_shared(); + std::vector rounds; + rounds.reserve(steps->size()); + for (std::size_t ri = 0; ri < steps->size(); ++ri) + { + const auto & st = (*steps)[ri]; + schedule_round step; + step.slot_bytes = st.part.slot_bytes; + step.channel = st.part.channel; + step.edge = st.edge; + step.recv = st.dealer_side ? receive_rule::copy_peer + : detail::part_receive_rule(p, st.part); + step.sink_round = st.sink_round; + step.timeout = round_budget(opt, ri); + const std::size_t local_from = ri == 0 ? 0 : (*steps)[ri - 1].part.wave + 1; + step.produce = [&p, &values, &kernels, party, lanes, opt, ri, local_from, + steps, zeros](std::size_t index, const std::uint8_t * peer, + std::size_t peer_n, std::uint8_t * out) { + const auto & me = (*steps)[ri]; + if (ri > 0) + { + const auto & prev = (*steps)[ri - 1]; + if (!prev.dealer_side) + detail::apply_peer_exchanges(p, prev.part.exchanges, + prev.part.slot_bytes, party, index, lanes, peer, peer_n, + values, opt); + } + for (std::size_t wi = local_from; wi <= me.part.wave; ++wi) + detail::run_wave_locals_lane(p, p.wave(wi), party, index, lanes, + values, kernels, opt); + if (out == nullptr) + return; + if (me.dealer_side) + detail::pack_dealer_part(p, me.part, me.dest, index, lanes, values, + *zeros, out); + else if (me.part.channel == edge_channel::dealer) + std::memset(out, 0, me.part.slot_bytes); + else + detail::pack_exchanges(p, me.part.exchanges, index, lanes, values, + opt, out); + }; + rounds.push_back(std::move(step)); + } + return rounds; +} + +/// @brief Apply the last peer slot and trailing compute-only waves. +inline void finish_schedule(const plan & p, RoundSink & sink, + std::vector> & values, + const std::map & kernels, std::size_t party = 0, + const drive_options & opt = {}) +{ + const auto steps = detail::party_steps(p, party); + for (const auto & st : steps) + if (st.edge != edge_peer) + throw std::invalid_argument("finish_schedule: plan uses the " + + net::edge_name(st.edge) + " edge; drive it on an edge_mesh"); + edge_mesh m{{&sink}}; + detail::finish_steps(p, steps, m, values, kernels, party, sink.count(), opt); +} + +/// @brief Drive a peer-only plan through `schedule_session` on one sink. +inline void drive_via_schedule(const plan & p, RoundSink & sink, + std::vector> & values, + const std::map & kernels, std::size_t party = 0, + const drive_options & opt = {}) +{ + for (const auto & st : detail::party_steps(p, party)) + if (st.edge != edge_peer) + throw std::invalid_argument("drive_via_schedule: plan has " + + net::edge_name(st.edge) + " exchanges; bind that edge with " + "drive_via_schedule(plan, edge_mesh) or app::run_parties"); + auto rounds = plan_to_schedule(p, values, kernels, party, sink.count(), opt); + if (rounds.empty()) + { + finish_schedule(p, sink, values, kernels, party, opt); + return; + } + schedule_session sess(sink.count(), edge_mesh{{&sink}}, std::move(rounds), + /*rebase_single=*/true, opt.probe, opt.pipeline_credit); + for (std::size_t i = 0; i < sink.count(); ++i) + sess.submit(i); + detail::run_session(sess, opt, "drive_via_schedule"); + finish_schedule(p, sink, values, kernels, party, opt); +} + +/// @brief Drive a plan on an edge mesh (peer / rss_next / dealer / star). +inline void drive_via_schedule(const plan & p, edge_mesh mesh, + std::vector> & values, + const std::map & kernels, std::size_t party = 0, + const drive_options & opt = {}) +{ + std::size_t lanes = 0; + for (std::size_t e = 0; e < mesh.size() && lanes == 0; ++e) + if (mesh.has(static_cast(e))) + lanes = mesh.at(static_cast(e)).count(); + if (lanes == 0) + throw std::logic_error("drive_via_schedule(mesh): no edges bound"); + const auto steps = detail::party_steps(p, party); + for (const auto & st : steps) + if (!mesh.has(st.edge)) + throw std::invalid_argument("drive_via_schedule(mesh): party " + + std::to_string(party) + " needs the " + net::edge_name(st.edge) + + " edge, which the mesh does not bind"); + auto rounds = plan_to_schedule(p, values, kernels, party, lanes, opt); + if (rounds.empty()) + { + detail::finish_steps(p, steps, mesh, values, kernels, party, lanes, opt); + return; + } + schedule_session sess(lanes, std::move(mesh), std::move(rounds), + /*rebase_single=*/false, opt.probe, opt.pipeline_credit); + for (std::size_t i = 0; i < lanes; ++i) + sess.submit(i); + detail::run_session(sess, opt, "drive_via_schedule(mesh)"); + detail::finish_steps(p, steps, sess.mesh(), values, kernels, party, lanes, opt); +} + +/// @brief Pad / setup frames as schedule rounds, then the online plan rounds. +/// @details Pass `iknp::setup_rounds(...)` (or any setup count). Pads occupy +/// peer sink rounds `[0, setup)`; online peer rounds are rebased. +inline std::vector plan_with_pad_setup(const plan & p, + std::size_t setup_rounds, std::size_t pad_slot_bytes, + std::vector> & values, + const std::map & kernels, std::size_t party, + std::size_t lanes, const std::shared_ptr> & tape, + const drive_options & opt = {}) +{ + auto pads = make_pad_rounds(setup_rounds, pad_slot_bytes, tape, + edge_channel::peer); + auto online = plan_to_schedule(p, values, kernels, party, lanes, opt); + for (auto & r : online) + if (r.channel == edge_channel::peer) + r.sink_round = static_cast( + static_cast(r.sink_round) + setup_rounds); + return splice_rounds(std::move(pads), std::move(online)); +} + +/// @brief Drive a peer-only plan on a `stream_array` (index = exchange round). +/// @details Builds a `stream_array_sink` from `p.slot_bytes_all()` and runs +/// `drive_via_schedule`. Memory, file, and mux arrays all work; the +/// schedule loop flushes one round at a time. Plans that use +/// `rss_next` / `dealer` edges need `drive_via_schedule(plan, +/// edge_mesh{...})` instead. +/// @brief Per-channel exchange slot widths (peer / rss_next / dealer order). +struct channel_slot_bytes +{ + std::vector peer; + std::vector rss_next; + std::vector dealer; +}; + +/// @brief Per-channel round widths (a mixed wave contributes to each channel). +inline channel_slot_bytes slot_bytes_by_channel(const plan & p) +{ + channel_slot_bytes out; + for (const auto & part : detail::schedule_parts(p)) + { + switch (part.channel) + { + case edge_channel::peer: + out.peer.push_back(part.slot_bytes); + break; + case edge_channel::rss_next: + out.rss_next.push_back(part.slot_bytes); + break; + case edge_channel::dealer: + out.dealer.push_back(part.slot_bytes); + break; + } + } + return out; +} + +/// @brief Build stream sinks from a plan's channel slot layout. +inline net::stream_edge_sinks make_stream_edge_sinks_for_plan(const plan & p, + net::stream_array * peer, net::stream_array * rss_next, + net::stream_array * dealer, std::size_t lanes = 1) +{ + const auto slots = slot_bytes_by_channel(p); + return net::make_stream_edge_sinks(peer, slots.peer, rss_next, slots.rss_next, + dealer, slots.dealer, lanes); +} + +/// @brief Drive on a pre-built multi-edge stream mesh (`edge_sinks` adapter). +inline void drive_plan_on_stream_mesh(const plan & p, + net::stream_edge_sinks & sinks, + std::vector> & values, + const std::map & kernels, std::size_t party = 0, + const drive_options & opt = {}) +{ + drive_via_schedule(p, sinks.mesh(), values, kernels, party, opt); +} + +inline void drive_plan_on_streams(const plan & p, net::stream_array & streams, + std::vector> & values, + const std::map & kernels, std::size_t party = 0, + std::size_t lanes = 1, const drive_options & opt = {}) +{ + auto slots = p.slot_bytes_all(); + if (!slots.empty() && streams.size() == 0) + throw std::invalid_argument("drive_plan_on_streams: empty stream_array"); + net::stream_array_sink sink(streams, std::move(slots), lanes, opt.framing); + drive_via_schedule(p, sink, values, kernels, party, opt); +} + +/// @brief Two parties, two threads, one memory stream pair; drive both plans. +/// @details `p0` / `p1` must share the same `slot_bytes_all()` shape (typical +/// when both composers record the same protocol). +inline void drive_both_on_streams(const plan & p0, const plan & p1, + std::vector> & v0, + std::vector> & v1, + const std::map & kernels = {}, + std::size_t lanes = 1, const drive_options & opt = {}) +{ + const auto slots = p0.slot_bytes_all(); + if (slots != p1.slot_bytes_all()) + throw std::invalid_argument( + "drive_both_on_streams: party slot shapes differ"); + const std::size_t nstreams = + slots.empty() ? 1 : lanes_for_plan(slots.size(), opt); + auto ends = net::make_memory_stream_pair(nstreams); + std::mutex err_mu; + std::exception_ptr err; + auto note = [&](std::exception_ptr e) { + std::lock_guard lock(err_mu); + if (!err) + err = std::move(e); + }; + std::thread t0([&] { + try + { + drive_plan_on_streams(p0, ends.first, v0, kernels, 0, lanes, opt); + } + catch (...) + { + note(std::current_exception()); + } + }); + std::thread t1([&] { + try + { + drive_plan_on_streams(p1, ends.second, v1, kernels, 1, lanes, opt); + } + catch (...) + { + note(std::current_exception()); + } + }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); +} + +/// @brief Same plan on both parties (common for symmetric compose graphs). +inline void drive_both_on_streams(const plan & p, + std::vector> & v0, + std::vector> & v1, + const std::map & kernels = {}, + std::size_t lanes = 1, const drive_options & opt = {}) +{ + drive_both_on_streams(p, p, v0, v1, kernels, lanes, opt); +} + +} // namespace protocol +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_COMPOSE_HPP__ diff --git a/include/dpf/compose_async.hpp b/include/dpf/compose_async.hpp new file mode 100644 index 0000000..68da8bc --- /dev/null +++ b/include/dpf/compose_async.hpp @@ -0,0 +1,134 @@ +/// @file dpf/compose_async.hpp +/// @brief Drive compose `plan`s on `async_stream_array`. +/// @details The same `drive_via_schedule` path used on sync `stream_array` +/// runs on `async_round_sink`, so peer reads are event-driven. +/// `drive_options::n_lanes` sizes the stream pool and +/// `drive_options::framing` picks the wire layout. +#ifndef LIBDPF_INCLUDE_DPF_COMPOSE_ASYNC_HPP__ +#define LIBDPF_INCLUDE_DPF_COMPOSE_ASYNC_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/compose.hpp" +#include "dpf/net/async_round_sink.hpp" +#include "dpf/net/async_stream_array.hpp" +#include "dpf/net/round_lane.hpp" + +namespace dpf +{ +namespace protocol +{ + +/// @brief Sink options that follow a drive's framing and drain budget. +inline net::sink_options sink_options_for(const drive_options & opt) +{ + net::sink_options so; + so.framing = opt.framing; + if (opt.wait_timeout.count() != 0) + so.drain_timeout = opt.wait_timeout; + return so; +} + +/// @brief Drive a peer-only plan on an `async_stream_array` (overlapped I/O). +/// @param instances RoundSink batch width (protocol instances per round). +inline void drive_plan_on_async_streams(const plan & p, + net::async_stream_array & streams, + std::vector> & values, + const std::map & kernels, std::size_t party = 0, + std::size_t instances = 1, const drive_options & opt = {}, + net::sink_options sopt = {}) +{ + auto slots = p.slot_bytes_all(); + if (!slots.empty() && streams.size() == 0) + throw std::invalid_argument( + "drive_plan_on_async_streams: empty stream array"); + sopt.framing = opt.framing; + net::async_round_sink sink(streams, std::move(slots), instances, + std::move(sopt)); + drive_options local = opt; + if (local.workers != nullptr && local.pump == nullptr) + local.pump = &streams.context(); + drive_via_schedule(p, sink, values, kernels, party, local); +} + +/// @brief Two parties, two threads, split-io async memory pair; drive both plans. +/// @details A party that fails closes its end, so the other fails fast. +inline void drive_both_on_async_streams(const plan & p0, const plan & p1, + std::vector> & v0, + std::vector> & v1, + const std::map & kernels = {}, + std::size_t instances = 1, const drive_options & opt = {}) +{ + const auto slots = p0.slot_bytes_all(); + if (slots != p1.slot_bytes_all()) + throw std::invalid_argument( + "drive_both_on_async_streams: party slot shapes differ"); + const std::size_t nstreams = + slots.empty() ? 1 : lanes_for_plan(slots.size(), opt); + asio::io_context io0; + asio::io_context io1; + auto peer = net::make_async_dual_memory_stream_pair(io0, io1, nstreams); + auto work0 = asio::make_work_guard(io0); + auto work1 = asio::make_work_guard(io1); + std::mutex err_mu; + std::exception_ptr err; + auto note = [&](std::exception_ptr e) { + std::lock_guard lock(err_mu); + if (!err) + err = std::move(e); + }; + std::thread t0([&] { + try + { + drive_plan_on_async_streams(p0, peer.first, v0, kernels, 0, + instances, opt); + } + catch (...) + { + note(std::current_exception()); + peer.first.close(); + } + work0.reset(); + }); + std::thread t1([&] { + try + { + drive_plan_on_async_streams(p1, peer.second, v1, kernels, 1, + instances, opt); + } + catch (...) + { + note(std::current_exception()); + peer.second.close(); + } + work1.reset(); + }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); +} + +/// @brief Same plan on both parties (symmetric compose graphs). +inline void drive_both_on_async_streams(const plan & p, + std::vector> & v0, + std::vector> & v1, + const std::map & kernels = {}, + std::size_t instances = 1, const drive_options & opt = {}) +{ + drive_both_on_async_streams(p, p, v0, v1, kernels, instances, opt); +} + +} // namespace protocol +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_COMPOSE_ASYNC_HPP__ diff --git a/include/dpf/constrained_cmp.hpp b/include/dpf/constrained_cmp.hpp index 6a78494..0e47ff4 100644 --- a/include/dpf/constrained_cmp.hpp +++ b/include/dpf/constrained_cmp.hpp @@ -12,6 +12,7 @@ #define LIBDPF_INCLUDE_DPF_CONSTRAINED_CMP_HPP__ #include +#include #include #include "hedley/hedley.h" @@ -61,15 +62,18 @@ constexpr void ccmp_party_terms(std::uint64_t x, uint8_t party, } /// @brief Opened result of Π_CCMP when both inputs are known (local joint sim). -/// @details Precondition: `|x0 - x1| = 1`. +/// @details Aborts unless `|x0 - x1| = 1`. /// @param x0 the `x0` /// @param x1 the `x1` /// @return Opened result of Π_CCMP when both inputs are known (local joint sim) -HEDLEY_NO_THROW +/// @throws std::invalid_argument when the inputs do not differ by one HEDLEY_ALWAYS_INLINE -HEDLEY_CONST -constexpr uint8_t local_ccmp(std::uint64_t x0, std::uint64_t x1) noexcept +uint8_t local_ccmp(std::uint64_t x0, std::uint64_t x1) { + const std::uint64_t diff = x0 > x1 ? x0 - x1 : x1 - x0; + if (diff != 1ULL) + throw std::invalid_argument( + "constrained comparison: inputs must differ by exactly one"); uint8_t z00 = 0, z01 = 0, l0 = 0; uint8_t z10 = 0, z11 = 0, l1 = 0; ccmp_party_terms(x0, 0, z00, z01, l0); @@ -87,11 +91,10 @@ constexpr uint8_t local_ccmp(std::uint64_t x0, std::uint64_t x1) noexcept /// @param x0 the first integer /// @param x1 the second integer /// @return Same as `local_ccmp` for any unsigned or enum-convertible integer +/// @throws std::invalid_argument when the inputs do not differ by one template -HEDLEY_NO_THROW HEDLEY_ALWAYS_INLINE -HEDLEY_CONST -constexpr uint8_t local_ccmp_int(T0 x0, T1 x1) noexcept +uint8_t local_ccmp_int(T0 x0, T1 x1) { static_assert(std::is_integral_v && std::is_integral_v, "local_ccmp_int: integral operands"); diff --git a/include/dpf/cost_pass.hpp b/include/dpf/cost_pass.hpp new file mode 100644 index 0000000..70ec546 --- /dev/null +++ b/include/dpf/cost_pass.hpp @@ -0,0 +1,155 @@ +/// @file dpf/cost_pass.hpp +/// @brief Annotate a recorder/composer plan with conversion strategy choices. +#ifndef LIBDPF_INCLUDE_DPF_COST_PASS_HPP__ +#define LIBDPF_INCLUDE_DPF_COST_PASS_HPP__ + +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/beaver.hpp" +#include "dpf/compose.hpp" + +namespace dpf +{ +namespace cost +{ + +enum class strategy : unsigned char +{ + dcf_mask = 0, + edabit_msb = 1, + full_a2b_adder = 2, + trunc_prob = 3, + trunc_exact = 4 +}; + +struct choice +{ + std::uint32_t node_id = 0; + strategy pick = strategy::edabit_msb; + std::size_t estimated_bytes = 0; + std::size_t estimated_rounds = 0; + std::string reason; +}; + +struct report +{ + std::vector choices; + std::size_t setup_bytes = 0; + std::size_t online_bytes = 0; + beavers::schedule_objective objective = beavers::schedule_objective::rounds; +}; + +/// @brief Cost model constants (bytes / rounds) for strategy selection. +struct model +{ + std::size_t dcf_bytes_per_bit = 16; + std::size_t edabit_bytes_per_bit = 8; + std::size_t a2b_bytes_per_bit = 24; + std::size_t trunc_exact_bytes = 16; + std::size_t trunc_prob_bytes = 0; +}; + +inline strategy pick_compare(beavers::schedule_objective obj, unsigned width, + const model & m, choice & out) +{ + const std::size_t dcf = m.dcf_bytes_per_bit * width; + const std::size_t eda = m.edabit_bytes_per_bit * width; + const std::size_t a2b = m.a2b_bytes_per_bit * width; + if (obj == beavers::schedule_objective::rounds) + { + // Prefer few rounds: DCF-mask (1 open) over full A2B adder. + out.pick = strategy::dcf_mask; + out.estimated_bytes = dcf; + out.estimated_rounds = 1; + out.reason = "rounds: dcf_mask"; + (void)eda; + (void)a2b; + return out.pick; + } + // Prep: pick cheapest bytes. + if (eda <= dcf && eda <= a2b) + { + out.pick = strategy::edabit_msb; + out.estimated_bytes = eda; + out.estimated_rounds = 2; + out.reason = "prep: edabit_msb"; + } + else if (dcf <= a2b) + { + out.pick = strategy::dcf_mask; + out.estimated_bytes = dcf; + out.estimated_rounds = 1; + out.reason = "prep: dcf_mask"; + } + else + { + out.pick = strategy::full_a2b_adder; + out.estimated_bytes = a2b; + out.estimated_rounds = static_cast(width); + out.reason = "prep: full_a2b_adder"; + } + return out.pick; +} + +inline strategy pick_trunc(beavers::schedule_objective obj, bool need_exact, + const model & m, choice & out) +{ + if (!need_exact) + { + out.pick = strategy::trunc_prob; + out.estimated_bytes = m.trunc_prob_bytes; + out.estimated_rounds = 0; + out.reason = "trunc_prob"; + return out.pick; + } + out.pick = strategy::trunc_exact; + out.estimated_bytes = m.trunc_exact_bytes; + out.estimated_rounds = (obj == beavers::schedule_objective::rounds) ? 1 : 2; + out.reason = "trunc_exact"; + return out.pick; +} + +/// @brief Annotate a plan: for each share_cmp / trunc opcode, record a choice. +HEDLEY_WARN_UNUSED_RESULT +inline report annotate(const protocol::plan & p, + beavers::schedule_objective obj = beavers::schedule_objective::rounds, + unsigned default_width = 64, bool exact_trunc = true, + model m = {}) +{ + report r; + r.objective = obj; + r.setup_bytes = p.setup_bytes(); + r.online_bytes = p.online_bytes(); + for (auto n : p.nodes()) + { + const auto op = p.opcode_of(n.id); + choice c; + c.node_id = n.id; + if (op == protocol::opcodes::share_cmp + || op == protocol::opcodes::user_base + 1) + { + pick_compare(obj, default_width, m, c); + r.choices.push_back(c); + } + else if (op == protocol::opcodes::trunc_exact + || op == protocol::opcodes::trunc_prob + || op == protocol::opcodes::mul_trunc) + { + pick_trunc(obj, exact_trunc || op != protocol::opcodes::trunc_prob, + m, c); + r.choices.push_back(c); + } + } + // Empty plans (no compare/trunc ops) get no synthetic choices. + return r; +} + +} // namespace cost +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_COST_PASS_HPP__ diff --git a/include/dpf/dcf.hpp b/include/dpf/dcf.hpp index 6907d9f..0233e0e 100644 --- a/include/dpf/dcf.hpp +++ b/include/dpf/dcf.hpp @@ -3,6 +3,7 @@ /// @details `lt`/`leq`/`gt`/`geq` (+ `_at`) take `(if_true, if_false=0)`. /// Eval walks the same GGM tree as the DPF (per-level value CWs). /// `eq` / `eq_at` are synonyms for ordinary point placements. +/// @note Following Boyle, Chandran, Gilboa, Gupta, Ishai, Kumar, and Rathee, EUROCRYPT 2021 (ePrint 2020/1392): a comparison is a DPF spine plus one value-correction word per level. `eq` is a point payload, not that DCF. /// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license. @@ -163,7 +164,7 @@ Beta sub_beta(const Beta & a, const Beta & b) noexcept if constexpr (std::is_same_v) return dpf::bit{static_cast(a) ^ static_cast(b)}; else if constexpr (dpf::utils::is_xor_wrapper_v) - return Beta{static_cast(a) ^ static_cast(b)}; + return a ^ b; else return static_cast(a - b); } @@ -504,42 +505,50 @@ struct cmp_at_pack : if_true{std::move(t)}, if_false{std::move(f)} { } }; +/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function. template inline auto lt(Beta t, Beta f = detail::dcf_impl::default_false>()) { return cmp_pack>(std::move(t), std::move(f)); } +/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function. template inline auto leq(Beta t, Beta f = detail::dcf_impl::default_false>()) { return cmp_pack>(std::move(t), std::move(f)); } +/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function. template inline auto gt(Beta t, Beta f = detail::dcf_impl::default_false>()) { return cmp_pack>(std::move(t), std::move(f)); } +/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function. template inline auto geq(Beta t, Beta f = detail::dcf_impl::default_false>()) { return cmp_pack>(std::move(t), std::move(f)); } +/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function. template inline auto lt_at(Beta t, Beta f = detail::dcf_impl::default_false>()) { return cmp_at_pack>(std::move(t), std::move(f)); } +/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function. template inline auto leq_at(Beta t, Beta f = detail::dcf_impl::default_false>()) { return cmp_at_pack>(std::move(t), std::move(f)); } +/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function. template inline auto gt_at(Beta t, Beta f = detail::dcf_impl::default_false>()) { return cmp_at_pack>(std::move(t), std::move(f)); } +/// \complexity O(1). Builds a spec object. The n-level walk is `make_dpf` or `ds_advance_level`, not this function. template inline auto geq_at(Beta t, Beta f = detail::dcf_impl::default_false>()) { @@ -758,6 +767,7 @@ struct idcf_pack static constexpr std::size_t prefix = Spec::prefix; static constexpr std::size_t block_width = Spec::block_width; static constexpr std::size_t length_bits = spec_length_bits::value; + using inner_spec = Spec; using beta_type = typename Spec::beta_type; beta_type if_true; beta_type if_false; @@ -817,6 +827,12 @@ inline auto eq_at(Beta t, Beta f = detail::dcf_impl::default_false>(std::move(t), std::move(f)); } +template +struct pack_has_fn : std::false_type {}; +template +struct pack_has_fn().fn)>> + : std::true_type {}; + template struct block_width_pack { @@ -828,6 +844,7 @@ struct block_width_pack static constexpr std::size_t prefix = Spec::prefix; static constexpr bool incremental = spec_is_incremental::value; static constexpr std::size_t length_bits = spec_length_bits::value; + using inner_spec = Spec; using beta_type = typename Spec::beta_type; beta_type if_true; beta_type if_false; @@ -849,6 +866,99 @@ struct block_width_fn template inline constexpr block_width_fn block_width{}; +// --------------------------------------------------------------------------- +// Same comparison shape, wildcard payload. Wrappers (`idcf`, `block_width`, +// `*_at`, path paints) keep their outer type; only the leaf beta changes. +// --------------------------------------------------------------------------- + +template struct is_idcf_pack : std::false_type {}; +template +struct is_idcf_pack> : std::true_type {}; +template +inline constexpr bool is_idcf_pack_v = is_idcf_pack>::value; + +template struct is_block_width_pack : std::false_type {}; +template +struct is_block_width_pack> : std::true_type {}; +template +inline constexpr bool is_block_width_pack_v = + is_block_width_pack>::value; + +namespace detail +{ + +template +auto cmp_wildcard_shape(); + +template +auto cmp_wildcard_shape(cmp_pack) +{ + using W = wildcard_value>; + return cmp_pack(W{}, W{}); +} +template +auto cmp_wildcard_shape(cmp_at_pack) +{ + using W = wildcard_value>; + return cmp_at_pack(W{}, W{}); +} +template +auto cmp_wildcard_shape(paint_pack) +{ + using W = wildcard_value>; + return paint_pack(W{}, W{}); +} +template +auto cmp_wildcard_shape(paint_at_pack) +{ + using W = wildcard_value>; + return paint_at_pack(W{}, W{}); +} +template +auto cmp_wildcard_shape(paint_fn_pack spec) +{ + using W = wildcard_value>; + return paint_fn_pack>(W{}, W{}, std::move(spec.fn)); +} +template +auto cmp_wildcard_shape(paint_fn_at_pack spec) +{ + using W = wildcard_value>; + return paint_fn_at_pack>(W{}, W{}, std::move(spec.fn)); +} + +template +auto cmp_wildcard_shape() +{ + if constexpr (is_idcf_pack_v) + return idcf(cmp_wildcard_shape()); + else if constexpr (is_block_width_pack_v) + return block_width( + cmp_wildcard_shape()); + else + { + using B = typename Spec::beta_type; + return cmp_wildcard_shape(Spec{B{}, B{}}); + } +} + +} // namespace detail + +/// @brief The same comparison or paint spec, with a wildcard payload. +/// @details `idcf`, `block_width`, and `*_at` stay wrapped. A spec that is +/// already wildcard is returned unchanged. `path_paint` keeps `fn`. +template +auto cmp_spec_as_wildcard(Spec spec) +{ + using S = std::decay_t; + if constexpr (is_wildcard_v) + return spec; + else if constexpr (pack_has_fn::value) + return detail::cmp_wildcard_shape(std::move(spec)); + else + return detail::cmp_wildcard_shape(); +} + template struct is_cmp_spec : std::false_type {}; template struct is_cmp_spec> : std::true_type {}; template diff --git a/include/dpf/deferred_rotated_subinterval.hpp b/include/dpf/deferred_rotated_subinterval.hpp new file mode 100644 index 0000000..65aaea7 --- /dev/null +++ b/include/dpf/deferred_rotated_subinterval.hpp @@ -0,0 +1,303 @@ +/// @file dpf/deferred_rotated_subinterval.hpp +/// @brief Deferred view over a full-domain buffer until the input offset is set. +/// @details After `defer_eval_interval` / `defer_eval_full` fills a full-domain +/// buffer at identity, this view waits for `assign_wildcard_input`. +/// Materialization builds `rotation_iterable` by `offset_x(0)`. The +/// logical `[from, to]` is then indexed in domain-walk order (same as +/// `eval_full`), including wrap-around when `from > to` in that order +/// (e.g. unsigned `[200, 10]`). +/// @see dpf::defer_eval_interval +/// @see dpf::rotation_iterable +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_DEFERRED_ROTATED_SUBINTERVAL_HPP__ +#define LIBDPF_INCLUDE_DPF_DEFERRED_ROTATED_SUBINTERVAL_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/rotation_iterable.hpp" +#include "dpf/utils.hpp" +#include "dpf/wildcard.hpp" + +namespace dpf +{ + +/// @brief Index-based range over a (possibly wrapping) slice of a rotation. +/// @details Indexing uses `rotation_iterable::operator[]`, so wrapping +/// intervals stay correct without requiring a contiguous iterator +/// walk past `end()`. +template +class deferred_rotated_range +{ + public: + class iterator + { + public: + using iterator_category = std::bidirectional_iterator_tag; + using difference_type = std::ptrdiff_t; + using value_type = std::decay_t()[0])>; + using reference = decltype(std::declval()[0]); + using pointer = void; + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr iterator() noexcept + : rot_{nullptr}, start_{0}, pos_{0}, count_{0}, n_{0} + { } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr iterator(const Rotation * rot, std::size_t start, + std::size_t pos, std::size_t count, std::size_t n) noexcept + : rot_{rot}, start_{start}, pos_{pos}, count_{count}, n_{n} + { } + + HEDLEY_ALWAYS_INLINE + reference operator*() const + { + const std::size_t idx = (start_ + pos_) % n_; + return (*rot_)[static_cast(idx)]; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr iterator & operator++() noexcept + { + ++pos_; + return *this; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr iterator operator++(int) noexcept + { + iterator tmp = *this; + ++(*this); + return tmp; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr iterator & operator--() noexcept + { + --pos_; + return *this; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr iterator operator--(int) noexcept + { + iterator tmp = *this; + --(*this); + return tmp; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr bool operator==(const iterator & rhs) const noexcept + { + return pos_ == rhs.pos_ && rot_ == rhs.rot_ + && start_ == rhs.start_ && count_ == rhs.count_ + && n_ == rhs.n_; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr bool operator!=(const iterator & rhs) const noexcept + { + return !(*this == rhs); + } + + private: + const Rotation * rot_; + std::size_t start_; + std::size_t pos_; + std::size_t count_; + std::size_t n_; + }; + + using const_iterator = iterator; + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr deferred_rotated_range(const Rotation * rot, std::size_t start, + std::size_t count, std::size_t n) noexcept + : rot_{rot}, start_{start}, count_{count}, n_{n} + { } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr iterator begin() const noexcept + { + return iterator(rot_, start_, 0, count_, n_); + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr iterator end() const noexcept + { + return iterator(rot_, start_, count_, count_, n_); + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr const_iterator cbegin() const noexcept + { + return begin(); + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr const_iterator cend() const noexcept + { + return end(); + } + + private: + const Rotation * rot_; + std::size_t start_; + std::size_t count_; + std::size_t n_; +}; + +/// @brief Full-domain buffer view that rotates after the input offset is ready. +/// @tparam DpfKey DPF key type (wildcard input) +/// @tparam IteratorT random-access iterator into the full-domain output buffer +template +class deferred_rotated_subinterval +{ + public: + using dpf_type = DpfKey; + using input_type = typename dpf_type::input_type; + using iterator = IteratorT; + using size_type = std::size_t; + using difference_type = + typename std::iterator_traits::difference_type; + using rotation_type = rotation_iterable; + using view_type = deferred_rotated_range; + + /// @param dpf key whose `offset_x` will supply the rotation once ready + /// @param begin begin of the full-domain buffer (identity eval order) + /// @param end end of the full-domain buffer + /// @param from inclusive logical start + /// @param to inclusive logical end + /// @param outputs_per_leaf leaf packing width (usually `DpfKey::outputs_per_leaf`) + HEDLEY_NO_THROW + deferred_rotated_subinterval(const dpf_type & dpf, iterator begin, + iterator end, input_type from, input_type to, + size_type outputs_per_leaf) noexcept + : dpf_{dpf}, + begin_{begin}, + end_{end}, + from_{from}, + to_{to}, + outputs_{outputs_per_leaf}, + rot_{std::nullopt} + { + (void)outputs_; + } + + /// @brief Materialize the rotated subinterval; requires assigned input. + /// @return a bidirectional range over the logical `[from, to]` + /// @note The returned range borrows this object's cached rotation; keep + /// `*this` alive for the range's lifetime. + view_type get() + { + ensure_rotation(); + return make_view(); + } + + HEDLEY_ALWAYS_INLINE + auto begin() + { + return get().begin(); + } + + HEDLEY_ALWAYS_INLINE + auto end() + { + return get().end(); + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr const dpf_type & dpf() const noexcept + { + return dpf_; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr input_type from() const noexcept + { + return from_; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr input_type to() const noexcept + { + return to_; + } + + private: + static constexpr auto to_integral_t = + utils::to_integral_type{}; + static constexpr auto bits = utils::bitlength_of_v; + + void ensure_rotation() + { + assert_not_wildcard_input(dpf_); + if (!rot_.has_value()) + { + const auto offset = dpf_.offset_x(input_type{}); + rot_ = rotation_type(begin_, end_, + static_cast(to_integral_t(offset))); + } + } + + view_type make_view() + { + // Domain walk of `eval_full`: index 0 is `min`, then `++` order. + const size_type n = + static_cast(std::distance(begin_, end_)); + const auto min_i = + to_integral_t(std::numeric_limits::min()); + auto from_i = to_integral_t(from_); + auto span = to_integral_t(to_) - from_i; + if constexpr (bits < utils::bitlength_of_v) + { + span &= (decltype(span){1} << bits) - 1; + } + auto from_rel = from_i - min_i; + if constexpr (bits < utils::bitlength_of_v) + { + from_rel &= (decltype(from_rel){1} << bits) - 1; + } + const auto start = static_cast(from_rel); + const auto count = static_cast(span) + size_type{1}; + return view_type(&rot_.value(), start, count, n); + } + + const dpf_type & dpf_; + iterator begin_; + iterator end_; + input_type from_; + input_type to_; + size_type outputs_; + std::optional rot_; +}; + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_DEFERRED_ROTATED_SUBINTERVAL_HPP__ diff --git a/include/dpf/doerner_shelat.hpp b/include/dpf/doerner_shelat.hpp index 4878a20..c795528 100644 --- a/include/dpf/doerner_shelat.hpp +++ b/include/dpf/doerner_shelat.hpp @@ -1,12 +1,16 @@ /// @file dpf/doerner_shelat.hpp /// @brief Doerner–Shelat generation of a dealer DPF key. /// @details Two shares of the point are walked level by level — XOR shares by -/// default, or additive shares when tagged with `arith_input`. +/// default. `arith_input` holds additive shares of the point. A beaver +/// ripple-carry converts them to XOR shares of the sum bits, and that +/// sharing is what the walk consumes. The sum is not opened. /// Correction words, advice bits, seeds, and leaves are the ones -/// `make_dpf` would emit for the reconstructed point, the same roots, -/// and the same beaver coins. Beaver pads used to hide the path bit -/// cancel and are not part of the key. Pad randomness must not come -/// from `uniform_fill` if the beaver tape is being matched. +/// `make_dpf` would emit for that point, the same roots, and the same +/// beaver coins. Beaver pads used to hide a path bit cancel and are +/// not part of the key. Pad randomness must not come from +/// `uniform_fill` if the beaver tape is being matched. +/// @note Following Jack Doerner and abhi shelat, CCS 2017 (ePrint 2017/827): one correction word opened per level from shares of the point. +/// @note Guo, Yang, Wang, Zhang, Xie, Zhang, and Liu (ePrint 2022/1431, §5.2) generate a DPF in the COT/OLE hybrid in n+3 rounds, with no beaver-pad dealer. This header uses that dealer tape and one opening round per level. /// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license; /// see [LICENSE.md](@ref license) for details. @@ -16,16 +20,23 @@ #include #include +#include #include #include +#include #include "hedley/hedley.h" #include "simde/simde/x86/avx2.h" #include "dpf/dpf_key.hpp" +#include "dpf/experiment_note.hpp" #include "dpf/random.hpp" #include "dpf/dcf.hpp" #include "dpf/constrained_cmp.hpp" +#include "dpf/beaver.hpp" +#include "dpf/xor_wrapper.hpp" +#include "dpf/leaf_node.hpp" +#include "dpf/leaf_arithmetic.hpp" namespace dpf { @@ -99,6 +110,40 @@ struct ds_randomness PadRng pad; }; +/// @brief Pad stream whose `block()` and `bit()` come from one PRG seed. +/// @details Drop-in for `detail::urandom_pad_rng` on Doerner–Shelat dealers. +/// `pseudorandom_root_sampler` is the matching root source. +template +struct prg_pad_rng +{ + using block_type = typename PRG::block_type; + + explicit prg_pad_rng(block_type seed = dpf::uniform_sample()) + : seed_(seed) + { + note_experiment_seed("prg_pad_rng", seed_); + } + + block_type block() + { + return PRG::eval(seed_, n_++); + } + + uint8_t bit() + { + const block_type drawn = block(); + unsigned char low = 0; + std::memcpy(&low, &drawn, 1); + return static_cast(low & 1u); + } + + const block_type & seed() const noexcept { return seed_; } + + private: + block_type seed_{}; + std::uint32_t n_ = 0; +}; + namespace detail { @@ -164,31 +209,128 @@ simde__m128i ds_gate(uint8_t bit, simde__m128i block) noexcept template ds_cw_pads ds_sample_cw(PadRng & pad) { + // Ideal (semi-honest): each party holds (rand, bit, gamma) with + // gamma0 ⊕ gamma1 = (bit1 · rand0) ⊕ (bit0 · rand1). + // The full product (bit1 · rand0) is NOT given to party 0: that would + // leak bit1, and with the opened blind bit = path1 ⊕ bit1 it would + // open the peer path bit (and thus α under an oblivious walk). Shares + // of the XOR of both products hide both pad bits from each party. + // The product share is a beaver session over the XOR ring; the clear + // bit and block stay with the party that owns them. + using Ring = dpf::xor_wrapper; + using traits = dpf::beavers::ring_traits; + auto to_ring = [](simde__m128i block) { + simde_uint128 raw{}; + std::memcpy(&raw, &block, sizeof(block)); + return Ring{raw}; + }; + auto to_block = [](const Ring & ring) { + simde__m128i block{}; + const auto raw = static_cast(ring); + std::memcpy(&block, &raw, sizeof(block)); + return block; + }; + const Ring rand0 = to_ring(pad.block()); + const Ring rand1 = to_ring(pad.block()); + const bool bit0 = (pad.bit() & 1u) != 0; + const bool bit1 = (pad.bit() & 1u) != 0; + auto sampler = [&pad, &to_ring]() -> Ring { + return to_ring(pad.block()); + }; + + dpf::beavers::session s; + auto b0 = s.bit(); + auto b1 = s.bit(); + auto r0 = s.input(); + auto r1 = s.input(); + auto prod = s(b1 * r0 + b0 * r1); + s.pin(prod); + s.sample(sampler); + s.bind(b0, bit0 ? traits::one() : traits::zero(), sampler); + s.bind(b1, bit1 ? traits::one() : traits::zero(), sampler); + s.bind(r0, rand0, sampler); + s.bind(r1, rand1, sampler); + s.evaluate(); + const auto gamma = s.value(prod); + ds_cw_pads p{}; - const simde__m128i zero = simde_mm_setzero_si128(); - p.p0.rand = pad.block(); - p.p1.rand = pad.block(); - p.p0.bit = static_cast(pad.bit() & 1u); - p.p1.bit = static_cast(pad.bit() & 1u); - p.p0.gamma = p.p1.bit ? p.p0.rand : zero; - p.p1.gamma = p.p0.bit ? p.p1.rand : zero; + p.p0.rand = to_block(rand0); + p.p1.rand = to_block(rand1); + p.p0.bit = static_cast(bit0); + p.p1.bit = static_cast(bit1); + p.p0.gamma = to_block(gamma.p0); + p.p1.gamma = to_block(gamma.p1); return p; } +/// @brief Pack a XOR-ring `bit_mul` into the classical DS AND pad shape. +/// @tparam Ring XOR ring whose unit is the all-ones word +/// @param bm the sampled bit-mul material +/// @param a0_share party 0's XOR share of the opened bit +/// @return pads ready for `ds_and_open` +template +ds_and_pads ds_and_from_bit_mul(const dpf::beavers::bit_mul_beaver & bm, + uint8_t a0_share) +{ + using traits = dpf::beavers::ring_traits; + const Ring opened = bm.bit.open(); + const uint8_t a = (opened == traits::one()) ? uint8_t{1} : uint8_t{0}; + ds_and_pads p{}; + p.a0 = static_cast(a0_share & 1u); + p.a1 = static_cast(a ^ p.a0); + auto to_block = [](const Ring & r) { + simde__m128i b{}; + const auto v = static_cast(r); + static_assert(sizeof(v) == sizeof(simde__m128i), + "ds AND packs a 128-bit XOR ring into an AES block"); + std::memcpy(&b, &v, sizeof(b)); + return b; + }; + p.b0_share = to_block(bm.scalar.p0); + p.b1_share = to_block(bm.scalar.p1); + p.c0_share = to_block(bm.product.p0); + p.c1_share = to_block(bm.product.p1); + return p; +} + +/// @brief Sample one DS AND from `sample_bit_mul`, driven by `pad` or `rng`. +/// @tparam PadRng pad stream with `block()` / `bit()` +/// @tparam Sample callable returning a 128-bit XOR ring element +/// @param pad the Doerner–Shelat pad stream (bit for the clear Beaver bit) +/// @param rng ring sampler for `sample_bit_mul` (defaults to `pad.block()`) +/// @return classical AND pads for `ds_and_open` +template +ds_and_pads ds_sample_and(PadRng & pad, Sample && rng) +{ + using Ring = dpf::xor_wrapper; + using traits = dpf::beavers::ring_traits; + auto & ring_rng = rng; + std::size_t phase = 0; + auto sampler = [&]() -> Ring { + if (phase == 0) + { + ++phase; + return (pad.bit() & 1u) ? traits::one() : traits::zero(); + } + ++phase; + return ring_rng(); + }; + auto bm = dpf::beavers::sample_bit_mul(sampler); + const uint8_t a0 = static_cast(pad.bit() & 1u); + return ds_and_from_bit_mul(bm, a0); +} + template ds_and_pads ds_sample_and(PadRng & pad) { - ds_and_pads p{}; - const uint8_t a = static_cast(pad.bit() & 1u); - const simde__m128i B = pad.block(); - const simde__m128i C = ds_gate(a, B); - p.a0 = static_cast(pad.bit() & 1u); - p.a1 = static_cast(a ^ p.a0); - p.b0_share = pad.block(); - p.b1_share = ds_xor(B, p.b0_share); - p.c0_share = pad.block(); - p.c1_share = ds_xor(C, p.c0_share); - return p; + using Ring = dpf::xor_wrapper; + auto from_pad = [&pad]() -> Ring { + const simde__m128i b = pad.block(); + simde_uint128 v{}; + std::memcpy(&v, &b, sizeof(b)); + return Ring{v}; + }; + return ds_sample_and(pad, from_pad); } HEDLEY_NO_THROW @@ -279,6 +421,123 @@ inline simde__m128i ds_deliver(uint8_t b_exp, simde__m128i base, simde__m128i M, return ds_xor(ds_xor(local, z.z0), z.z1); } +/// @brief XOR shares of a bit-Beaver triple `(α, β, α∧β)`. +struct ds_bit_triple +{ + uint8_t a0; + uint8_t a1; + uint8_t b0; + uint8_t b1; + uint8_t c0; + uint8_t c1; +}; + +/// @brief Sample one bit-AND triple from `pad`, via `sample_beaver2` on the XOR ring. +/// @tparam PadRng pad stream with `bit()` +/// @param pad the pad stream +/// @return shares of `(α, β, α∧β)` +template +ds_bit_triple ds_sample_bit_and(PadRng & pad) +{ + using Bit = dpf::xor_wrapper; + auto sampler = [&pad]() -> Bit { + std::uint8_t packed = 0; + for (int i = 0; i < 8; ++i) + { + packed = static_cast( + packed | (static_cast(pad.bit() & 1u) << i)); + } + return Bit{packed}; + }; + const auto triple = dpf::beavers::sample_beaver2(sampler); + auto low = [](Bit x) { + return static_cast(static_cast(x) & 1u); + }; + return ds_bit_triple{ + low(triple.a.p0), low(triple.a.p1), + low(triple.b.p0), low(triple.b.p1), + low(triple.ab.p0), low(triple.ab.p1)}; +} + +/// @brief One party's share of `x ∧ y` after `d = x⊕α` and `e = y⊕β` are open. +/// @param d the opened mask of `x` +/// @param e the opened mask of `y` +/// @param a this party's share of `α` +/// @param b this party's share of `β` +/// @param c this party's share of `α∧β` +/// @param hold_de party 0 adds the public `d∧e` term +/// @return this party's XOR share of the product +HEDLEY_NO_THROW +inline uint8_t ds_bit_and_party(uint8_t d, uint8_t e, uint8_t a, uint8_t b, + uint8_t c, bool hold_de) noexcept +{ + uint8_t z = static_cast((d & b) ^ (e & a) ^ c); + if (hold_de) + z = static_cast(z ^ (d & e)); + return static_cast(z & 1u); +} + +/// @brief Joint evaluation of one bit-AND. `d` and `e` are the opened masks. +/// @param t the triple +/// @param x0 party 0's share of `x` +/// @param x1 party 1's share of `x` +/// @param y0 party 0's share of `y` +/// @param y1 party 1's share of `y` +/// @return XOR shares of `x ∧ y` +HEDLEY_NO_THROW +inline std::pair ds_bit_and_shares(const ds_bit_triple & t, + uint8_t x0, uint8_t x1, uint8_t y0, uint8_t y1) noexcept +{ + const uint8_t d = static_cast(x0 ^ x1 ^ t.a0 ^ t.a1); + const uint8_t e = static_cast(y0 ^ y1 ^ t.b0 ^ t.b1); + return {ds_bit_and_party(d, e, t.a0, t.b0, t.c0, true), + ds_bit_and_party(d, e, t.a1, t.b1, t.c1, false)}; +} + +/// @brief Replace additive shares with XOR shares of their sum. +/// @details One beaver bit-AND per bit except the last. Party 0's sum-bit +/// share is `a ⊕ c0`; party 1's is `b ⊕ c1`. The carry share is +/// `((a⊕c) ∧ (b⊕c)) ⊕ c`, which is the majority. Neither share is +/// the sum, and the sum is not written down. +/// @tparam PadRng pad stream with `bit()` +/// @tparam InputT input domain type +/// @param pads the pad stream +/// @param x0 party 0's additive share, replaced by its XOR share of the sum +/// @param x1 party 1's additive share, replaced by its XOR share of the sum +template +void split_additive_to_xor(PadRng & pads, InputT & x0, InputT & x1) +{ + constexpr auto to_int = utils::to_integral_type{}; + using FromI = typename utils::make_from_integral_value::integral_type; + using U = std::make_unsigned_t; + const U u0 = static_cast(to_int(x0)); + const U u1 = static_cast(to_int(x1)); + U s0 = 0; + U s1 = 0; + uint8_t c0 = 0; + uint8_t c1 = 0; + constexpr std::size_t nbits = utils::bitlength_of_v; + for (std::size_t i = 0; i < nbits; ++i) + { + const uint8_t a = static_cast((u0 >> i) & U{1}); + const uint8_t b = static_cast((u1 >> i) & U{1}); + const uint8_t sum0 = static_cast(a ^ c0); + const uint8_t sum1 = static_cast(b ^ c1); + s0 = static_cast(s0 | (static_cast(sum0) << i)); + s1 = static_cast(s1 | (static_cast(sum1) << i)); + if (i + 1 == nbits) + break; + const ds_bit_triple triple = ds_sample_bit_and(pads); + const auto prod = ds_bit_and_shares(triple, + static_cast(a ^ c0), c1, + c0, static_cast(b ^ c1)); + c0 = static_cast(prod.first ^ c0); + c1 = static_cast(prod.second ^ c1); + } + x0 = utils::make_from_integral_value{}(static_cast(s0)); + x1 = utils::make_from_integral_value{}(static_cast(s1)); +} + /// @brief Per-level messages prepared before the CW protocol runs (blinds + pads). struct ds_level_blinds { @@ -326,6 +585,35 @@ struct ds_cmp_gen_state const void * paint_ctx = nullptr; }; +/// @brief Local joint-sim mux of a packed naked leaf from XOR bit shares. +/// @details Mirrors `party/oblivious_select.hpp` `mux_leaf_share`: each level +/// selects with `bit0 ^ bit1` so the call site never forms a clear +/// point for `make_leaves`. The joint simulator holds both shares. +/// @tparam Leaf packed leaf type +/// @tparam Make candidate builder `Leaf(unsigned lane)` +/// @tparam Bit0 party-0 bit accessor +/// @tparam Bit1 party-1 bit accessor +template +Leaf mux_naked_leaf_local(std::size_t lg, Make && make, Bit0 && bit0_at, + Bit1 && bit1_at) +{ + if (lg == 0) + return make(0u); + std::vector cand(std::size_t{1} << lg); + for (std::size_t i = 0; i < cand.size(); ++i) + cand[i] = make(static_cast(i)); + for (std::size_t b = 0; b < lg; ++b) + { + const uint8_t bit = static_cast( + (bit0_at(b) ^ bit1_at(b)) & 1u); + std::vector next(cand.size() / 2); + for (std::size_t k = 0; k < next.size(); ++k) + next[k] = bit ? cand[2 * k + 1] : cand[2 * k]; + cand.swap(next); + } + return cand[0]; +} + /// @brief Local joint simulation: today's `ds_cw_outs` / `ds_open_advice` / `ds_and_open`. /// @details An MPC backend would send `blinds` and return the same `ds_level_open` shape. /// @tparam PadRng pad stream for the Doerner–Shelat protocol @@ -451,83 +739,23 @@ struct local_cw_protocol std::forward(sample)); } - /// @brief Majority of three bits (next carry of a full adder). - /// @param a the `a` - /// @param b the `b` - /// @param c the `c` - /// @return Majority of three bits (next carry of a full adder) - HEDLEY_NO_THROW - static constexpr uint8_t majority(uint8_t a, uint8_t b, uint8_t c) noexcept - { - return static_cast((a & b) | (a & c) | (b & c)); - } - - /// @brief One additive digit: sum bit `a XOR b XOR cin`, carry out = majority. - /// @param a the `a` - /// @param b the `b` - /// @param cin the `cin` - /// @param cout the `cout` - /// @return One additive digit: sum bit `a XOR b XOR cin`, carry out = majority - HEDLEY_NO_THROW - static constexpr uint8_t open_sum_bit(uint8_t a, uint8_t b, uint8_t cin, - uint8_t & cout) noexcept - { - cout = majority(a, b, cin); - return static_cast(a ^ b ^ cin); - } - - /// @brief Reconstruct `a0 + a1` via a LSB→MSB carry chain, then flip the MSB - /// when the domain is signed — matching `make_dpf` on the sum. The call - /// site never forms the sum; an MPC backend would open the same bits. + /// @brief Encode shares for the XOR-style CW walk. + /// @details XOR inputs flip party 0's MSB, which is linear over XOR. + /// Additive inputs are converted first: `split_additive_to_xor` + /// draws one bit-Beaver per carry and leaves XOR shares of the + /// sum. The MSB flip is then the same one XOR inputs take, so + /// the walk matches `make_dpf` on the sum. The sum is not opened + /// and party 1's share is not cleared. /// @tparam InputT input domain type - /// @param a0 the `a0` - /// @param a1 the `a1` - /// @return Reconstruct `a0 + a1` via a LSB→MSB carry chain, then flip the MSB when the domain - /// is signed — matching `make_dpf` on the sum + /// @param x0 party 0's share + /// @param x1 party 1's share + /// @param arith `true` when `x0`, `x1` are additive template - InputT open_arith_point(InputT a0, InputT a1) const - { - constexpr auto to_int = utils::to_integral_type{}; - using FromI = typename utils::make_from_integral_value::integral_type; - using U = std::make_unsigned_t; - const U u0 = static_cast(to_int(a0)); - const U u1 = static_cast(to_int(a1)); - U sum = 0; - uint8_t carry = 0; - constexpr std::size_t nbits = utils::bitlength_of_v; - for (std::size_t i = 0; i < nbits; ++i) - { - const uint8_t b0 = static_cast((u0 >> i) & U{1}); - const uint8_t b1 = static_cast((u1 >> i) & U{1}); - const uint8_t s = open_sum_bit(b0, b1, carry, carry); - sum = static_cast(sum | (static_cast(s) << i)); - } - InputT out = utils::make_from_integral_value{}( - static_cast(sum)); - utils::flip_msb_if_signed_integral(out); - return out; - } - - /// @brief Encode shares for the XOR-style CW walk. XOR mode flips party 0's MSB - /// (linear over XOR). Arithmetic mode opens the sum (carry + signed MSB) - /// and returns `(alpha, 0)` so the walk matches `make_dpf(alpha)`. - /// @tparam InputT input domain type - /// @param x0 the `x0` - /// @param x1 the `x1` - /// @param arith the `arith` - template - void encode_walk_shares(InputT & x0, InputT & x1, bool arith) const + void encode_walk_shares(InputT & x0, InputT & x1, bool arith) { if (arith) - { - const InputT alpha = open_arith_point(x0, x1); - x0 = alpha; - x1 = InputT{}; - } - else - { - utils::flip_msb_if_signed_integral(x0); - } + split_additive_to_xor(pads, x0, x1); + utils::flip_msb_if_signed_integral(x0); } /// @brief Constrained comparison Π_CCMP: open `1{x0 < x1}` when `|x0−x1|=1`. @@ -542,14 +770,18 @@ struct local_cw_protocol } /// @brief Open a public leaf CW for a shared payload. - /// @details Ring: `β = y0 + y1`; `g = CCMP(t0,t1)` selects `β − M` vs `M − β` - /// (matches `make_leaf` with `sign = t0`). Characteristic 2: `β = y0 ⊕ y1` - /// and CW = `β ⊕ M` (sign mux is a no-op under XOR). + /// @details Splits the payload into leaf words (`naked(y0) ± naked(y1)`) so + /// scalar `β = y0 + y1` (or `y0 ⊕ y1`) is never formed. The packing + /// lane is muxed from XOR bit shares of the point, matching + /// `mux_leaf_share` on the socket. Ring: `g = CCMP(t0,t1)` selects + /// `N − M` vs `M − N` (matches `make_leaf` with `sign = t0`). + /// Characteristic 2: CW = `N ⊕ M` (sign mux is a no-op under XOR). /// @tparam ExteriorPRG PRG that expands the root. Defaults to `InteriorPRG` /// @tparam I output index /// @tparam OutputsTuple outputs tuple /// @tparam InteriorBlock interior block /// @tparam OutputT output type + /// @tparam InputT input domain type /// @param seed0 the `seed0` /// @param seed1 the `seed1` /// @param t0 the `t0` @@ -557,13 +789,14 @@ struct local_cw_protocol /// @param y0 the `y0` /// @param y1 the `y1` /// @param pos_base the `pos_base` -/// @param lane_x lane of the shared payload -/// @return the opened leaf correction word + /// @param x0 party 0's XOR share of the (lane) point + /// @param x1 party 1's XOR share of the (lane) point + /// @return the opened leaf correction word template + typename InteriorBlock, typename OutputT, typename InputT> auto open_arith_leaf(const InteriorBlock & seed0, const InteriorBlock & seed1, uint8_t t0, uint8_t t1, OutputT y0, OutputT y1, std::size_t pos_base, - std::size_t lane_x) -> dpf::leaf_node_t dpf::leaf_node_t { using output_type = OutputT; @@ -573,36 +806,99 @@ struct local_cw_protocol using leaf_type = dpf::leaf_node_t; HEDLEY_PRAGMA(GCC diagnostic pop) + constexpr std::size_t lg = + dpf::lg_outputs_per_leaf_v; + constexpr auto to_int = utils::to_integral_type{}; + auto bit0_at = [&](std::size_t b) { + return static_cast((to_int(x0) >> b) & 1u); + }; + auto bit1_at = [&](std::size_t b) { + return static_cast((to_int(x1) >> b) & 1u); + }; + auto naked_of = [&](output_type y) { + return mux_naked_leaf_local(lg, + [&](unsigned i) { + return dpf::make_naked_leaf( + static_cast(i), y); + }, + bit0_at, bit1_at); + }; + // Split payload across leaf words; never form scalar β. + const leaf_type naked = + dpf::add_leaf(naked_of(y0), naked_of(y1)); + const auto M = dpf::make_leaf_mask( seed0, seed1, pos_base); - output_type beta{}; if constexpr (utils::has_characteristic_two_v) { (void)t0; (void)t1; - beta = static_cast(y0 ^ y1); - const leaf_type naked = dpf::make_naked_leaf(lane_x, beta); return dpf::subtract_leaf(naked, M); } else { const uint8_t g = open_ccmp(t0, t1); - beta = static_cast(y0 + y1); - const leaf_type naked = dpf::make_naked_leaf(lane_x, beta); - // CW = (−1)^{t1}(β − M): g=0 → β−M; g=1 → M−β. Matches make_leaf(sign=t0). + // CW = (−1)^{t1}(N − M): g=0 → N−M; g=1 → M−N. Matches make_leaf(sign=t0). if (g & 1u) return dpf::subtract_leaf(M, naked); return dpf::subtract_leaf(naked, M); } } - /// @brief Open a group of leaf correction words for one prefix group. In this - /// local joint simulation both XOR shares of the point are present, so the - /// point is reconstructed *inside* the protocol and handed to `leaf_fn` - /// (which runs `make_leaves` for the group). The Doerner–Shelat gen never - /// forms `x = x0 ^ x1` at its own call site; an MPC backend would instead - /// run a per-group leaf CW exchange that never reveals `x`. After - /// `encode_walk_shares`, arithmetic inputs are already `(alpha, 0)`. + /// @brief Open the comparison threshold lane from XOR shares of the point. + /// @details Reconstructs only inside this protocol hook for paint units, + /// domain-edge triviality, and blocked suffixes. Per-level value + /// words use share bits (`bit0 ^ bit1`) instead of this value. + /// @tparam InputT input domain type + /// @param x0 party 0's XOR share + /// @param x1 party 1's XOR share + /// @param nbits width of the comparison lane + /// @return the comparison threshold as an integer lane + template + unsigned __int128 open_cmp_threshold(InputT x0, InputT x1, + std::size_t nbits) noexcept + { + constexpr auto to_int = utils::to_integral_type{}; + constexpr std::size_t bl = utils::bitlength_of_v; + const InputT x = utils::xor_input_shares(x0, x1); + if (nbits >= bl) + return static_cast(to_int(x)); + return static_cast(to_int(x) >> (bl - nbits)); + } + + /// @brief Public correction seed from XOR shares of the path prefix. + /// @details Reconstructs the prefix only inside this protocol hook and + /// returns `make_cs` (same digest as `oblivious_cs` when both + /// seeds are in-process). The clear prefix is not returned. + /// @tparam InputT input domain type + /// @param level fold level (or blocked tag | level) + /// @param x0 party 0's XOR share of the encoded point + /// @param x1 party 1's XOR share of the encoded point + /// @param bits number of high path bits in the prefix + /// @param s0 party 0's on-path seed + /// @param s1 party 1's on-path seed + /// @return the public correction seed + template + cs_block open_correction_seed(std::size_t level, InputT x0, InputT x1, + std::size_t bits, simde__m128i s0, simde__m128i s1) noexcept + { + constexpr auto to_int = utils::to_integral_type{}; + constexpr std::size_t bl = utils::bitlength_of_v; + const InputT x = utils::xor_input_shares(x0, x1); + // Prefer `uint64_t` over `psnip_uint64_t{...}`: that macro expands to + // `long unsigned int`, which is not a valid braced/cast type-id alone. + const uint64_t prefix = (bits == 0 || bits > bl) + ? uint64_t{0} + : static_cast(to_int(x) >> (bl - bits)); + return detail::vdpf::make_cs(level, prefix, s0, s1); + } + + /// @brief Open a group of leaf correction words for one prefix group. + /// @details Hands both XOR shares to `leaf_fn`. The builder may reconstruct + /// the point only to emit public CWs (never return α to the DS + /// call site). An MPC backend would run a per-group leaf CW + /// exchange that never reveals `x`. Additive inputs have already + /// been replaced by XOR shares of the sum. /// @tparam InputT input domain type /// @tparam LeafFn leaf fn /// @param x0 the `x0` @@ -611,7 +907,7 @@ struct local_cw_protocol template void open_leaf_group(InputT x0, InputT x1, LeafFn && leaf_fn) { - std::forward(leaf_fn)(utils::xor_input_shares(x0, x1)); + std::forward(leaf_fn)(x0, x1); } }; @@ -705,8 +1001,8 @@ void ds_advance_level(ds_gen_state & st, InputT x0, InputT x1, vblinds.R0 = v0[1]; vblinds.L1 = v1[0]; vblinds.R1 = v1[1]; - const int ai = static_cast( - (cmp->thresh >> (cmp->nbits - 1 - level)) & 1); + // Path bit from share bits (threshold bit equals the walk bit). + const int ai = static_cast((bit0 ^ bit1) & 1u); if (cmp->paint) { const uint64_t unit = dcf_impl::paint_unit(cmp->kind, level, @@ -890,30 +1186,31 @@ HEDLEY_PRAGMA(GCC diagnostic pop) const uint8_t t0 = static_cast(sign0); const uint8_t t1 = static_cast(dpf::get_lo_bit(parent1)); - input_type x = utils::xor_input_shares(x0, x1); leaf_tuple leaves0{}; leaf_tuple leaves1{}; beaver_tuple beavers0{}; beaver_tuple beavers1{}; if (arith_out) { - constexpr auto to_int = utils::to_integral_type{}; - const std::size_t lane = static_cast(to_int(x)); auto cw = proto.template open_arith_leaf( dpf::unset_lo_2bits(parent0), dpf::unset_lo_2bits(parent1), t0, t1, - y0, y1, std::size_t{0}, lane); + y0, y1, std::size_t{0}, x0, x1); std::get<0>(leaves0) = cw; std::get<0>(leaves1) = cw; } else { - auto built = dpf::make_leaves(x, - dpf::unset_lo_2bits(parent0), dpf::unset_lo_2bits(parent1), sign0, - std::size_t{0}, y0); - leaves0 = std::move(built.first.first); - beavers0 = std::move(built.first.second); - leaves1 = std::move(built.second.first); - beavers1 = std::move(built.second.second); + // Reconstruct the point only inside the leaf protocol hook. + proto.open_leaf_group(x0, x1, [&](input_type sx0, input_type sx1) { + const input_type x = utils::xor_input_shares(sx0, sx1); + auto built = dpf::make_leaves(x, + dpf::unset_lo_2bits(parent0), dpf::unset_lo_2bits(parent1), + sign0, std::size_t{0}, y0); + leaves0 = std::move(built.first.first); + beavers0 = std::move(built.first.second); + leaves1 = std::move(built.second.first); + beavers1 = std::move(built.second.second); + }); (void)y1; } @@ -1000,18 +1297,29 @@ HEDLEY_PRAGMA(GCC diagnostic pop) const node parent1 = st.seed1(); const bool sign0 = dpf::get_lo_bit(parent0); - input_type x = utils::xor_input_shares(x0, x1); - auto built = dpf::make_leaves(x, - dpf::unset_lo_2bits(parent0), dpf::unset_lo_2bits(parent1), sign0, - std::size_t{0}, std::forward(y), std::forward(ys)...); + typename dpf_type::leaf_tuple leaves0{}; + typename dpf_type::beaver_tuple beavers0{}; + typename dpf_type::leaf_tuple leaves1{}; + typename dpf_type::beaver_tuple beavers1{}; + proto.open_leaf_group(x0, x1, [&](input_type sx0, input_type sx1) { + const input_type x = utils::xor_input_shares(sx0, sx1); + auto built = dpf::make_leaves(x, + dpf::unset_lo_2bits(parent0), dpf::unset_lo_2bits(parent1), sign0, + std::size_t{0}, std::forward(y), + std::forward(ys)...); + leaves0 = std::move(built.first.first); + beavers0 = std::move(built.first.second); + leaves1 = std::move(built.second.first); + beavers1 = std::move(built.second.second); + }); input_type off0{}; input_type off1{}; return dpf::make_party_key_pair( dpf_type{root0, correction_words, correction_advice, - built.first.first, built.first.second, off0}, + leaves0, beavers0, off0}, dpf_type{root1, correction_words, correction_advice, - built.second.first, built.second.second, off1}); + leaves1, beavers1, off1}); } /// @brief Single-output plaintext β (disambiguates from arith_out overload). diff --git a/include/dpf/dpf3.hpp b/include/dpf/dpf3.hpp new file mode 100644 index 0000000..4ac5ed7 --- /dev/null +++ b/include/dpf/dpf3.hpp @@ -0,0 +1,775 @@ +/// @file dpf/dpf3.hpp +/// @brief Three-evaluator (2,3) point DPF after ePrint 2024/1658. +/// @details Each party key is a pair of two-party VDPF+ keys. Evaluation is +/// two ordinary walks, an XOR, and a party-index scale in `fp61`. +/// Reconstruction is Shamir interpolation. +/// @note Following Zyskind, Yanai, and Pentland, ePrint 2024/1658, Figure 3: each evaluator holds one key from each of two (2,2)-VDPF+ instances. Their evaluation section records about 2× the key size of one two-party DPF. +/// +/// **Updatable keys** (`dpf::updatable`) keep beaver-backed XOR leaves +/// so `update_payload` can rewrite `β` with four leaf patches and a +/// refresh of the public offsets `π` — `O(λ)`, independent of the +/// domain — without moving `α`. Non-updatable keys bake the leaf; +/// calling `update_payload` on them throws. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_DPF3_HPP__ +#define LIBDPF_INCLUDE_DPF_DPF3_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/eval_full.hpp" +#include "dpf/eval_interval.hpp" +#include "dpf/eval_point.hpp" +#include "dpf/eval_sequence.hpp" +#include "dpf/fp61.hpp" +#include "dpf/leaf_node.hpp" +#include "dpf/path_memoizer.hpp" +#include "dpf/placement.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" +#include "dpf/shamir3.hpp" +#include "dpf/utils.hpp" +#include "dpf/verifiable.hpp" +#include "dpf/wildcard.hpp" +#include "dpf/xor_wrapper.hpp" + +namespace dpf +{ + +/// @brief Phantom tag selecting the three-evaluator point construction. +struct dpf3_t +{ + static constexpr bool is_dpf3_tag = true; +}; + +inline constexpr dpf3_t dpf3{}; + +namespace detail +{ +namespace dpf3_impl +{ + +using xor61 = shamir3::xor61; + +template +struct vdpf_plus_key +{ + using inner_type = Inner; + using input_type = typename Inner::input_type; + /// @brief Inner two-party spine. Eval that accepts a `dpf_key` also accepts + /// this object and reads `dpf_key`. + Inner dpf_key{}; + xor61 offset{}; +}; + +template > +HEDLEY_WARN_UNUSED_RESULT +xor61 eval_plus(const vdpf_plus_key & key, typename Inner::input_type x, + PathMemoizer && path = PathMemoizer{}) +{ + const auto y = *dpf::eval_point(key.dpf_key, x, + std::forward(path)); + if constexpr (is_secret_share_v>) + return xor61{y.raw()} + key.offset; + else + return xor61{static_cast(y)} + key.offset; +} + +template > +HEDLEY_WARN_UNUSED_RESULT +xor61 eval_plus(const vdpf_plus_key & key, typename Inner::input_type x, + prove_ref pr, PathMemoizer && path = PathMemoizer{}) +{ + const auto y = *dpf::eval_point(key.dpf_key, x, pr, + std::forward(path)); + // Re-bind the public offset (refreshed by `update_payload`). + const auto off = static_cast(key.offset); + detail::vdpf::fold_bytes(pr.token, 0x50, &off, sizeof(off)); + if constexpr (is_secret_share_v>) + return xor61{y.raw()} + key.offset; + else + return xor61{static_cast(y)} + key.offset; +} + +template +xor61 xor61_from_buf_elem(const Buf & e) +{ + if constexpr (is_secret_share_v>) + return xor61{e.raw()}; + else + return xor61{static_cast(e)}; +} + +template +void combine_spine_bufs(const KeyT & key, const BufA & a, const BufB & b, + std::vector & out) +{ + const std::size_t n = a.size(); + out.resize(n); + const fp61 scale{static_cast(KeyT::party)}; + for (std::size_t i = 0; i < n; ++i) + { + const xor61 y = xor61_from_buf_elem(a[i]) + key.a.offset + + xor61_from_buf_elem(b[i]) + key.b.offset; + out[i] = shamir3::xor_scale(y, scale); + } +} + +template +HEDLEY_WARN_UNUSED_RESULT +xor61 peel(const Inner & key, typename Inner::input_type x) +{ + const auto y = *dpf::eval_point(key, x); + if constexpr (is_secret_share_v>) + return xor61{y.raw()}; + else + return xor61{static_cast(y)}; +} + +struct tau_quad +{ + xor61 t0{}; + xor61 t1{}; + xor61 t2{}; + xor61 t3{}; +}; + +inline tau_quad sample_taus(fp61 beta) +{ + const auto shares = shamir3::share_secret(beta); + const fp61 s1 = shamir3::unscale(shares[0]); + const fp61 s2 = shamir3::unscale(shares[1]); + const fp61 s3 = shamir3::unscale(shares[2]); + tau_quad t{}; + for (int attempt = 0; attempt < 16; ++attempt) + { + t.t0 = xor61{uniform_sample() & fp61_mod}; + t.t2 = shamir3::field_xor(s1, t.t0); + t.t1 = shamir3::field_xor(s2, t.t2); + t.t3 = shamir3::field_xor(s3, t.t1); + const auto ok = [](xor61 w) { + return (static_cast(w) & fp61_mod) != fp61_mod; + }; + if (ok(t.t0) && ok(t.t1) && ok(t.t2) && ok(t.t3)) + return t; + } + throw std::runtime_error("make_dpf3: embed resampling failed"); +} + +template +void patch_leaf_xor(Key & key, typename Key::input_type alpha, Output delta) +{ + using node = typename Key::exterior_node; + using concrete = dpf::concrete_type_t; + auto & wrap = std::get<0>(key.leaf_nodes); + auto & leaf = wrap.raw_leaf(); + leaf = dpf::add_leaf(leaf, + dpf::make_naked_leaf(alpha, concrete{delta})); +} + +template +void assign_wildcard_pair(K0 & k0, K1 & k1, Share0 share0, Share1 share1) +{ + auto & w0 = std::get<0>(k0.leaf_nodes); + auto & w1 = std::get<0>(k1.leaf_nodes); + if (w0.is_ready()) + w0.begin_update(); + if (w1.is_ready()) + w1.begin_update(); + const auto b0 = w0.compute_and_get_blinded_output_share(share0); + const auto b1 = w1.compute_and_get_blinded_output_share(share1); + const auto l0 = w0.compute_and_get_leaf_share(b1); + const auto l1 = w1.compute_and_get_leaf_share(b0); + w0.reconstruct_correction_word(l1); + w1.reconstruct_correction_word(l0); +} + +template +void assign_xor_payload(K0 & k0, K1 & k1, xor61 payload) +{ + const xor61 s0{uniform_sample()}; + const xor61 s1 = payload + s0; + assign_wildcard_pair(k0, k1, s0, s1); +} + +} // namespace dpf3_impl +} // namespace detail + +/// @brief One evaluator's key in a (2,3) point DPF. +/// @tparam Party party index in `{1, 2, 3}` +/// @tparam PlusA VDPF+ key type for instance A +/// @tparam PlusB VDPF+ key type for instance B +template +struct dpf3_key +{ + static_assert(Party >= 1 && Party <= 3, "dpf3 party is 1, 2, or 3"); + static constexpr int party = Party; + static constexpr bool is_dpf3 = true; + using input_type = typename PlusA::input_type; + using plus_a_type = PlusA; + using plus_b_type = PlusB; + + PlusA a{}; + PlusB b{}; + bool verifiable = false; + bool extractable = false; + bool updatable = false; +}; + +namespace detail +{ +namespace dpf3_impl +{ + +/// @brief Open the XOR-shared point the same way local DS walks it. +template +HEDLEY_WARN_UNUSED_RESULT +InputT open_xor_point(InputT x0, InputT x1) +{ + utils::flip_msb_if_signed_integral(x0); + constexpr auto to_int = utils::to_integral_type{}; + using I = decltype(to_int(x0)); + return utils::make_from_integral_value{}( + static_cast(to_int(x0) ^ to_int(x1))); +} + +/// @brief Pack Fig-3 party keys from two completed two-party spines + `τ`. +/// @details Computes public `π` from peels of the party-0 halves at `α`. +/// Parameter names avoid `B0`/`B1` (termios baud macros). +template +auto assemble_from_spines(KeyA0 key_a0, KeyA1 key_a1, KeyB0 key_b0, + KeyB1 key_b1, tau_quad t, Input alpha) +{ + using X = xor61; + const X yA0 = peel(key_a0, alpha); + const X yB0 = peel(key_b0, alpha); + const X piA = t.t0 + yA0; + const X piB = t.t2 + yB0; + using PlusA0 = vdpf_plus_key; + using PlusA1 = vdpf_plus_key; + using PlusB0 = vdpf_plus_key; + using PlusB1 = vdpf_plus_key; + PlusA0 plus_a0{std::move(key_a0), piA}; + PlusA1 plus_a1{std::move(key_a1), piA}; + PlusB0 plus_b0{std::move(key_b0), piB}; + PlusB1 plus_b1{std::move(key_b1), piB}; + dpf3_key<1, PlusA0, PlusB0> k1{plus_a0, plus_b0, Verifiable, Extractable, + Updatable}; + dpf3_key<2, PlusA1, PlusB0> k2{plus_a1, plus_b0, Verifiable, Extractable, + Updatable}; + dpf3_key<3, PlusA1, PlusB1> k3{plus_a1, plus_b1, Verifiable, Extractable, + Updatable}; + return std::make_tuple(std::move(k1), std::move(k2), std::move(k3)); +} + +template +auto make_point3(Input alpha, fp61 beta) +{ + using X = xor61; + const tau_quad t = sample_taus(beta); + const X payload_a = t.t0 + t.t1; + const X payload_b = t.t2 + t.t3; + + if constexpr (Updatable) + { + auto A = [&] { + if constexpr (Verifiable) + return dpf::make_dpf(alpha, + dpf::wildcard_value{}, dpf::verifiable{}); + else + return dpf::make_dpf(alpha, + dpf::wildcard_value{}); + }(); + auto B = [&] { + if constexpr (Verifiable) + return dpf::make_dpf(alpha, + dpf::wildcard_value{}, dpf::verifiable{}); + else + return dpf::make_dpf(alpha, + dpf::wildcard_value{}); + }(); + assign_xor_payload(A.first, A.second, payload_a); + assign_xor_payload(B.first, B.second, payload_b); + return assemble_from_spines( + std::move(A.first), std::move(A.second), std::move(B.first), + std::move(B.second), t, alpha); + } + else + { + auto A = [&] { + if constexpr (Verifiable) + return dpf::make_dpf(alpha, payload_a, + dpf::verifiable{}); + else + return dpf::make_dpf(alpha, payload_a); + }(); + auto B = [&] { + if constexpr (Verifiable) + return dpf::make_dpf(alpha, payload_b, + dpf::verifiable{}); + else + return dpf::make_dpf(alpha, payload_b); + }(); + return assemble_from_spines( + std::move(A.first), std::move(A.second), std::move(B.first), + std::move(B.second), t, alpha); + } +} + +/// @brief Flags carried by `verifiable` / `extractable` / `updatable` tags. +/// @details Any subset, any order. A repeated tag is rejected. +template +struct tag_flags +{ + static constexpr bool verifiable = + (is_verifiable_tag_v> || ...); + static constexpr bool extractable = + (is_extractable_tag_v> || ...); + static constexpr bool updatable = + (is_updatable_tag_v> || ...); + static constexpr bool known = ((is_verifiable_tag_v> + || is_extractable_tag_v> + || is_updatable_tag_v>) && ...); + static constexpr std::size_t counted = + static_cast(verifiable) + + static_cast(extractable) + + static_cast(updatable); +}; + +template +auto make_tagged(Input alpha, fp61 beta) +{ + return make_point3(alpha, beta); +} + +/// @brief Read the four planted τ strings from live VDPF+ evaluations at `α`. +template +tau_quad read_taus(const K1 & k1, const K2 & k2, const K3 & k3, Input alpha) +{ + tau_quad t{}; + t.t0 = peel(k1.a.dpf_key, alpha) + k1.a.offset; + t.t1 = peel(k2.a.dpf_key, alpha) + k2.a.offset; + t.t2 = peel(k1.b.dpf_key, alpha) + k1.b.offset; + t.t3 = peel(k3.b.dpf_key, alpha) + k3.b.offset; + return t; +} + +template +void refresh_offset(Plus & plus, Input alpha, xor61 target_delta0) +{ + plus.offset = target_delta0 + peel(plus.dpf_key, alpha); +} + +/// @brief XOR a precomputed naked-leaf patch onto a ready inner key. +template +void apply_leaf_patch(Key & key, const Leaf & patch) +{ + using concrete = dpf::concrete_type_t>; + auto & wrap = std::get<0>(key.leaf_nodes); + auto & leaf = wrap.raw_leaf(); + leaf = dpf::add_leaf(leaf, patch); +} + +/// @brief Build the naked-leaf Fig-10 patch for payload difference `delta`. +template +auto make_leaf_patch(Input alpha, xor61 delta) +{ + using node = typename Key::exterior_node; + using concrete = dpf::concrete_type_t>; + return dpf::make_naked_leaf(alpha, concrete{delta}); +} + +} // namespace dpf3_impl +} // namespace detail + +/// @brief Generate three (2,3) point keys for `f(α) = β`. +/// @details Optional tags are `verifiable`, `extractable`, and `updatable`, +/// in any order. `extractable` is the outer fp61 sketch flag; inner +/// XOR keys stay ordinary. `updatable` keeps beaver leaves so +/// `update_payload` can rewrite `β`. +/// @note Following Zyskind, Yanai, and Pentland, ePrint 2024/1658, Figure 3: two (2,2)-VDPF+ spines and two walks. +/// \complexity O(n) time. Two `make_dpf` spines (A and B), each the point-keygen loop, plus a constant number of `eval_point` peels in `assemble_from_spines`. No messages. +template +HEDLEY_WARN_UNUSED_RESULT +auto make_dpf3(InputT alpha, fp61 beta, Tags ...tags) +{ + using flags = detail::dpf3_impl::tag_flags; + static_assert(flags::known, "make_dpf3 tags are verifiable, extractable, updatable"); + static_assert(sizeof...(Tags) == flags::counted, + "make_dpf3: repeated tag"); + (void)std::initializer_list{((void)tags, 0)...}; + return detail::dpf3_impl::make_tagged(alpha, beta); +} + +/// @brief Evaluate one party's (2,3) key at `x`. +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. +template , + typename PathB = basic_path_memoizer< + typename KeyT::plus_b_type::inner_type>, + std::enable_if_t::is_dpf3, int> = 0> +HEDLEY_WARN_UNUSED_RESULT +fp61 eval_point(const KeyT & key, Query && x, PathA && path_a = PathA{}, + PathB && path_b = PathB{}) +{ + const auto qx = static_cast(x); + const auto ya = detail::dpf3_impl::eval_plus(key.a, qx, + std::forward(path_a)); + const auto yb = detail::dpf3_impl::eval_plus(key.b, qx, + std::forward(path_b)); + return shamir3::xor_scale(ya + yb, + fp61{static_cast(KeyT::party)}); +} + +/// @brief Evaluate and fold an inner proof token from each VDPF+. +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. +template , + typename PathB = basic_path_memoizer< + typename KeyT::plus_b_type::inner_type>, + std::enable_if_t::is_dpf3, int> = 0> +HEDLEY_WARN_UNUSED_RESULT +fp61 eval_point(const KeyT & key, Query && x, prove_ref pr, + PathA && path_a = PathA{}, PathB && path_b = PathB{}) +{ + if (!key.verifiable) + throw std::invalid_argument("eval_point(prove): key is not verifiable"); + proof_token pa{}, pb{}; + const auto qx = static_cast(x); + const auto ya = detail::dpf3_impl::eval_plus(key.a, qx, prove(pa), + std::forward(path_a)); + const auto yb = detail::dpf3_impl::eval_plus(key.b, qx, prove(pb), + std::forward(path_b)); + pr.token = detail::vdpf::xor_proof(pa, pb); + return shamir3::xor_scale(ya + yb, + fp61{static_cast(KeyT::party)}); +} + +/// @brief Full-domain (2,3) eval: expand each spine once, then XOR and scale. +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). +template ::is_dpf3, int> = 0> +HEDLEY_WARN_UNUSED_RESULT +std::vector eval_full(const KeyT & key) +{ + auto buf_a = dpf::make_output_buffer_for_full(key.a.dpf_key); + auto buf_b = dpf::make_output_buffer_for_full(key.b.dpf_key); + dpf::eval_full(key.a.dpf_key, buf_a); + dpf::eval_full(key.b.dpf_key, buf_b); + std::vector out; + detail::dpf3_impl::combine_spine_bufs(key, buf_a, buf_b, out); + return out; +} + +/// @brief Add a (2,3) full-domain expansion into a caller's share vector. +/// @details `buf[i] += eval_full(key)[i]` for every slot. Shamir shares are +/// linear, so summing appends per party and reconstructing any two +/// recovers the running total. A (2,3) ledger folds each append with +/// this call instead of an `eval_point` loop. +/// \complexity Same expansion as `eval_full` on the (2,3) key. +template ::is_dpf3, int> = 0> +void eval_full_add_into(Buffer & buf, const KeyT & key) // NOLINT(runtime/references) +{ + const auto full = eval_full(key); + const std::size_t n = std::min(full.size(), buf.size()); + for (std::size_t i = 0; i < n; ++i) + buf[i] = buf[i] + full[i]; +} + +/// @brief Dot a (2,3) full-domain expansion with a public table. +/// @details `sum_i eval_full(key)[i] * weights[i]`. Shamir shares are linear, +/// so any two parties' dots reconstruct the table entry at `α` when +/// the payload is `1`. A three-server PIR is this call per server. +/// \complexity Same expansion as `eval_full` on the (2,3) key, plus one +/// multiply-add per domain point. +template ::is_dpf3, int> = 0> +HEDLEY_WARN_UNUSED_RESULT +fp61 eval_full_inner_product(const KeyT & key, const Weights & weights) +{ + const auto full = eval_full(key); + fp61 acc{}; + const std::size_t n = std::min(full.size(), weights.size()); + for (std::size_t i = 0; i < n; ++i) + { + const auto & w = weights[i]; + if constexpr (std::is_same_v, fp61>) + acc = acc + full[i] * w; + else + acc = acc + full[i] * fp61{static_cast(w)}; + } + return acc; +} + +/// @brief Interval (2,3) eval into an `fp61` buffer. +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. +template ::is_dpf3, int> = 0> +HEDLEY_WARN_UNUSED_RESULT +std::vector eval_interval(const KeyT & key, LaneT from, LaneT to) +{ + auto buf_a = dpf::make_output_buffer(key.a.dpf_key, from, to); + auto buf_b = dpf::make_output_buffer(key.b.dpf_key, from, to); + dpf::eval_interval(key.a.dpf_key, from, to, buf_a); + dpf::eval_interval(key.b.dpf_key, from, to, buf_b); + std::vector out; + detail::dpf3_impl::combine_spine_bufs(key, buf_a, buf_b, out); + return out; +} + +/// @brief Pack an evaluation as a typed Shamir share. +template = 0> +HEDLEY_NO_THROW +HEDLEY_CONST +HEDLEY_ALWAYS_INLINE +constexpr shamir3::share as_share(const KeyT &, fp61 y) noexcept +{ + return shamir3::share{KeyT::party, y}; +} + +/// @brief The same evaluation as a party-tagged (2,3) Shamir share. +/// @details `dpf3` parties are `1`, `2`, `3`. The typed share's party is one less. +template = 0> +HEDLEY_NO_THROW +HEDLEY_CONST +HEDLEY_ALWAYS_INLINE +constexpr shamir_share(KeyT::party - 1)> +as_shamir_share(const KeyT &, fp61 y) noexcept +{ + return shamir_share(KeyT::party - 1)>::from_raw(y); +} + +/// @brief Reconstruct from any two (2,3) evaluation shares. +HEDLEY_WARN_UNUSED_RESULT +inline fp61 reconstruct(shamir3::share a, shamir3::share b) +{ + return shamir3::reconstruct(a, b); +} + +/// @brief Reconstruct from all three shares. +HEDLEY_WARN_UNUSED_RESULT +inline fp61 reconstruct(shamir3::share a, shamir3::share b, shamir3::share c) +{ + return shamir3::reconstruct(a, b, c); +} + +/// @brief Three-party proof token: two inner tokens plus the public offsets. +struct dpf3_proof +{ + proof_token a{}; + proof_token b{}; + shamir3::xor61 offset_a{}; + shamir3::xor61 offset_b{}; +}; + +/// @brief Build a three-party proof at `x`. +template = 0> +HEDLEY_WARN_UNUSED_RESULT +dpf3_proof prove_dpf3(const KeyT & key, Query && x) +{ + if (!key.verifiable) + throw std::invalid_argument("prove_dpf3: key is not verifiable"); + dpf3_proof out{}; + out.offset_a = key.a.offset; + out.offset_b = key.b.offset; + const auto qx = static_cast(x); + std::ignore = detail::dpf3_impl::eval_plus(key.a, qx, prove(out.a)); + std::ignore = detail::dpf3_impl::eval_plus(key.b, qx, prove(out.b)); + return out; +} + +/// @brief Verify three (2,3) proofs agree on offsets and inner tokens. +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_WARN_UNUSED_RESULT +bool verify_dpf3(const dpf3_proof & p1, const dpf3_proof & p2, + const dpf3_proof & p3) noexcept +{ + if (p1.offset_a != p2.offset_a || p2.offset_a != p3.offset_a) + return false; + if (p1.offset_b != p2.offset_b || p2.offset_b != p3.offset_b) + return false; + if (!verify(p1.a, p2.a)) + return false; + if (!verify(p2.a, p3.a)) + return false; + if (!verify(p1.b, p2.b)) + return false; + if (!verify(p2.b, p3.b)) + return false; + return true; +} + +/// @brief In-place payload update of three updatable (2,3) keys (Fig. 10). +/// @details Reads the live `τ` strings from evaluations at `α`, samples a +/// fresh Shamir split of `β'`, patches the four inner XOR leaves by +/// the payload difference, refreshes `π`, and leaves the tree path +/// untouched. Requires keys generated with `dpf::updatable`. +/// @tparam K1 party-1 key type +/// @tparam K2 party-2 key type +/// @tparam K3 party-3 key type +/// @tparam InputT input domain type +/// @param k1 party 1 key +/// @param k2 party 2 key +/// @param k3 party 3 key +/// @param alpha the same secret point +/// @param beta_new the new payload +/// @throws std::invalid_argument if any key is not updatable +template +void update_payload(K1 & k1, K2 & k2, K3 & k3, InputT alpha, fp61 beta_new) +{ + static_assert(K1::is_dpf3 && K2::is_dpf3 && K3::is_dpf3, "dpf3 keys"); + if (!k1.updatable || !k2.updatable || !k3.updatable) + throw std::invalid_argument( + "update_payload: keys were not generated with dpf::updatable"); + + using X = detail::dpf3_impl::xor61; + const auto told = detail::dpf3_impl::read_taus(k1, k2, k3, alpha); + const auto tnew = detail::dpf3_impl::sample_taus(beta_new); + const X dA = (tnew.t0 + tnew.t1) + (told.t0 + told.t1); + const X dB = (tnew.t2 + tnew.t3) + (told.t2 + told.t3); + + // After Beaver assign both parties hold the same leaf CW. Patch every + // copy of each spine's CW by the payload difference (Fig. 10). + // A0 on p1; A1 on p2 and p3. + detail::dpf3_impl::patch_leaf_xor(k1.a.dpf_key, alpha, dA); + detail::dpf3_impl::patch_leaf_xor(k2.a.dpf_key, alpha, dA); + detail::dpf3_impl::patch_leaf_xor(k3.a.dpf_key, alpha, dA); + // B0 on p1 and p2; B1 on p3. + detail::dpf3_impl::patch_leaf_xor(k1.b.dpf_key, alpha, dB); + detail::dpf3_impl::patch_leaf_xor(k2.b.dpf_key, alpha, dB); + detail::dpf3_impl::patch_leaf_xor(k3.b.dpf_key, alpha, dB); + + // π is public and identical on both halves of each VDPF+. + // Leaf patches and the refreshed offset are re-bound on the next prove + // (`init_proof` folds the leaf CW; `eval_plus` folds the offset). + detail::dpf3_impl::refresh_offset(k1.a, alpha, tnew.t0); + k2.a.offset = k1.a.offset; + k3.a.offset = k1.a.offset; + detail::dpf3_impl::refresh_offset(k1.b, alpha, tnew.t2); + k2.b.offset = k1.b.offset; + k3.b.offset = k1.b.offset; +} + +/// @brief Weight-1 sketch over three Shamir full-domain vectors (ungated). +/// @details Prefer the key-taking overload, which enforces `dpf::extractable`. +template +HEDLEY_WARN_UNUSED_RESULT +bool sketch_verify3(const std::vector & s1, const std::vector & s2, + const std::vector & s3, RRange && challenges) +{ + if (s1.size() != s2.size() || s2.size() != s3.size()) + return false; + std::vector opened; + opened.reserve(s1.size()); + std::vector rs; + rs.reserve(s1.size()); + std::size_t i = 0; + for (auto && r : challenges) + { + if (i >= s1.size()) + return false; + opened.push_back(shamir3::reconstruct( + shamir3::share{1, s1[i]}, shamir3::share{2, s2[i]}, + shamir3::share{3, s3[i]})); + rs.push_back(r); + ++i; + } + if (i != s1.size()) + return false; + sketch_share sk = sketch_fold(opened, rs); + sketch_share zero{}; + return sketch_verify(sk, zero); +} + +/// @brief Weight-1 sketch gated on extractable (2,3) keys. +/// @throws std::invalid_argument if any key lacks `dpf::extractable` +template +HEDLEY_WARN_UNUSED_RESULT +bool sketch_verify3(const K1 & k1, const K2 & k2, const K3 & k3, + const std::vector & s1, const std::vector & s2, + const std::vector & s3, RRange && challenges) +{ + static_assert(K1::is_dpf3 && K2::is_dpf3 && K3::is_dpf3, "dpf3 keys"); + if (!k1.extractable || !k2.extractable || !k3.extractable) + throw std::invalid_argument( + "sketch_verify3: keys were not generated with dpf::extractable"); + return sketch_verify3(s1, s2, s3, std::forward(challenges)); +} + +/// @brief Point proofs plus weight-1 on the opened Shamir full-domain vector. +/// @details Completes the paper's three-party statistic after inner verifies. +/// Ungated; prefer the key-taking overload for extractable keys. +template +HEDLEY_WARN_UNUSED_RESULT +bool verify_dpf3(const dpf3_proof & p1, const dpf3_proof & p2, + const dpf3_proof & p3, const std::vector & s1, + const std::vector & s2, const std::vector & s3, + RRange && challenges) +{ + if (!verify_dpf3(p1, p2, p3)) + return false; + return sketch_verify3(s1, s2, s3, std::forward(challenges)); +} + +/// @brief Verifiable + extractable check: proofs then gated weight-1 sketch. +/// @throws std::invalid_argument if any key lacks `dpf::extractable` +template +HEDLEY_WARN_UNUSED_RESULT +bool verify_dpf3(const K1 & k1, const K2 & k2, const K3 & k3, + const dpf3_proof & p1, const dpf3_proof & p2, const dpf3_proof & p3, + const std::vector & s1, const std::vector & s2, + const std::vector & s3, RRange && challenges) +{ + static_assert(K1::is_dpf3 && K2::is_dpf3 && K3::is_dpf3, "dpf3 keys"); + if (!k1.extractable || !k2.extractable || !k3.extractable) + throw std::invalid_argument( + "verify_dpf3: keys were not generated with dpf::extractable"); + if (!k1.verifiable || !k2.verifiable || !k3.verifiable) + throw std::invalid_argument( + "verify_dpf3: keys were not generated with dpf::verifiable"); + return verify_dpf3(p1, p2, p3, s1, s2, s3, + std::forward(challenges)); +} + +/// @brief Fresh three-party keys at the same point (new trees — not an update). +/// @details Same tags as `make_dpf3`. Use when the key was not generated +/// `updatable`, or when the dealer chooses to re-key. Moving `α` +/// also requires this path. +template +HEDLEY_WARN_UNUSED_RESULT +auto remake_dpf3(InputT alpha, fp61 beta_new, Tags ...tags) +{ + return make_dpf3(alpha, beta_new, tags...); +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_DPF3_HPP__ diff --git a/include/dpf/dpf3_cmp.hpp b/include/dpf/dpf3_cmp.hpp new file mode 100644 index 0000000..24c4a68 --- /dev/null +++ b/include/dpf/dpf3_cmp.hpp @@ -0,0 +1,458 @@ +/// @file dpf/dpf3_cmp.hpp +/// @brief Three-evaluator comparison, blocked comparison, and interval keys. +/// @details Each evaluator holds one two-party DCF share of a shared tree +/// (party 1 and 3 hold the party-0 half; party 2 holds the party-1 +/// half). Evaluating a single half yields that party's complementary +/// share of the predicate; open with `reconstruct_cmp_halves` on any +/// authorized pair (1+2 or 2+3). The threshold is never assembled by +/// locally reconstructing a full two-party key. Interval containment +/// reuses the three-party comparison; `lo`/`hi` stay public as in F_IC. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_DPF3_CMP_HPP__ +#define LIBDPF_INCLUDE_DPF_DPF3_CMP_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/dcf.hpp" +#include "dpf/eval_full.hpp" +#include "dpf/eval_interval.hpp" +#include "dpf/eval_sequence.hpp" +#include "dpf/eval_unified.hpp" +#include "dpf/fp61.hpp" +#include "dpf/incremental.hpp" +#include "dpf/interval.hpp" +#include "dpf/path_memoizer.hpp" +#include "dpf/placement.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/shamir3.hpp" +#include "dpf/wildcard.hpp" + +namespace dpf +{ + +/// @brief One party's comparison key: a single DCF share plus a Shamir payload tip. +/// @tparam Party party index in `{1, 2, 3}` +/// @tparam Key two-party DCF key type (party-0 or party-1 half) +template +struct dpf3_cmp_key +{ + static_assert(Party >= 1 && Party <= 3, "dpf3_cmp party is 1, 2, or 3"); + static constexpr int party = Party; + static constexpr bool is_dpf3_cmp = true; + static constexpr bool is_dpf3 = false; + + using input_type = typename Key::input_type; + using key_type = Key; + + /// @brief Inner comparison half. Eval that accepts a `dpf_key` also accepts + /// this object and reads `dpf_key`. + Key dpf_key{}; + shamir3::share beta_share{}; +}; + +namespace detail +{ +namespace dpf3_cmp_impl +{ + +template +auto assign_share_pair(K0 k0, K1 k1, shamir3::share sh, uint64_t if_false_u) +{ + const uint64_t mask = k0.cmp().mask; + const uint64_t di = sh.value.raw() & mask; + const uint64_t target = + detail::incr::cmp_assign_target(k0.cmp(), di, if_false_u & mask); + uint64_t add0 = 0, add1 = 0; + const uint64_t r = detail::dcf_impl::sample_addend_blind(mask, + [] { return dpf::uniform_sample(); }); + detail::incr::split_cmp_addend(target, mask, r, add0, add1); + assign_cmp_local(k0, di, add0); + assign_cmp_local(k1, di, add1); + return std::make_tuple(std::move(k0), std::move(k1), sh); +} + +template +auto wrap_halves(K0 half0, K1 half1, const std::array & shares) +{ + K0 half0_copy = half0; // party 3 holds the same half as party 1 + dpf3_cmp_key<1, K0> out1{std::move(half0), shares[0]}; + dpf3_cmp_key<2, K1> out2{std::move(half1), shares[1]}; + dpf3_cmp_key<3, K0> out3{std::move(half0_copy), shares[2]}; + return std::make_tuple(std::move(out1), std::move(out2), std::move(out3)); +} + +/// @brief Build three keys that each hold one DCF half of a shared tree. +/// @details One wild comparison tree; δ is planted once into the public value +/// words. Absorb is split once. Each evaluator keeps a single half +/// (Fig-3 style overlap): party 1 → k0, party 2 → k1, party 3 → k0. +/// Eval of one half is that party's complementary share; open with +/// `reconstruct_cmp_halves`. A Shamir tip tracks the payload for +/// bookkeeping / updates. +template +auto make_from_spec(InputT thresh, Spec spec, uint64_t if_true_u, + uint64_t if_false_u) +{ + using Concrete = uint64_t; + auto wild = dpf::make_dpf(thresh, spec); + auto base0 = std::move(wild.first); + auto base1 = std::move(wild.second); + using K0 = decltype(base0); + + const uint64_t mask = base0.cmp().mask; + const uint64_t delta = + detail::dcf_impl::beta_delta_u64( + detail::dcf_impl::u64_to_beta(if_true_u), + detail::dcf_impl::u64_to_beta(if_false_u), mask); + const auto shares = shamir3::share_secret(fp61{delta}); + + // One shared tree; public δ is the clear payload difference. Absorb is + // split once. Each evaluator keeps a single half (Fig-3 style overlap): + // party 1 → k0, party 2 → k1, party 3 → k0. + uint64_t add0 = 0, add1 = 0; + const uint64_t target = + detail::incr::cmp_assign_target(base0.cmp(), delta, if_false_u & mask); + const uint64_t r = detail::dcf_impl::sample_addend_blind(mask, + [] { return dpf::uniform_sample(); }); + detail::incr::split_cmp_addend(target, mask, r, add0, add1); + assign_cmp_local(base0, delta, add0); + assign_cmp_local(base1, delta, add1); + return wrap_halves(std::move(base0), std::move(base1), shares); +} + +template +std::uint64_t eval_one(const KeyT & key, Query && x, PathMemoizer && path) +{ + const auto y = dpf::eval_point(dpf::cmp, key.dpf_key, std::forward(x), + std::forward(path)); + if constexpr (is_secret_share_v>) + return static_cast(y.raw()); + else + return static_cast(y); +} + +/// @brief Open complementary DCF halves (additive uint64 shares → fp61). +inline fp61 reconstruct_cmp_halves(std::uint64_t k0_share, std::uint64_t k1_share) +{ + return fp61{k0_share + k1_share}; +} + +} // namespace dpf3_cmp_impl +} // namespace detail + +/// @brief Open complementary DCF halves (k0-holder with k1-holder). +HEDLEY_WARN_UNUSED_RESULT +inline fp61 reconstruct_cmp_halves(std::uint64_t k0_share, std::uint64_t k1_share) +{ + return detail::dpf3_cmp_impl::reconstruct_cmp_halves(k0_share, k1_share); +} + +/// @brief Generate three `lt` comparison keys with a Shamir-shared payload. +template +HEDLEY_WARN_UNUSED_RESULT +auto make_dpf3_cmp(InputT thresh, uint64_t if_true, uint64_t if_false = 0) +{ + return detail::dpf3_cmp_impl::make_from_spec( + thresh, dpf::lt(dpf::wildcard_value{}), if_true, if_false); +} + +/// @brief Generate three comparison keys from any comparison spec. +/// @details Accepts the same packs as two-party `make_dpf`: `lt`/`leq`/`gt`/`geq`, +/// `*_at`, `idcf`, `block_width`, and path paints. The shape is kept; +/// the payload is installed on a wildcard channel so `update_payload_cmp` +/// can rewrite it. A spec that is already wildcard is left unassigned. +template >>> +HEDLEY_WARN_UNUSED_RESULT +auto make_dpf3_cmp(InputT thresh, Spec spec) +{ + using S = std::decay_t; + using Beta = typename S::beta_type; + using Concrete = dpf::concrete_type_t; + if constexpr (is_wildcard_v) + { + auto keys = dpf::make_dpf( + thresh, std::move(spec)); + const auto shares = shamir3::share_secret(fp61{0}); + return detail::dpf3_cmp_impl::wrap_halves( + std::move(keys.first), std::move(keys.second), shares); + } + else + { + static_assert(utils::bitlength_of_v <= 64 + && !detail::has_from_seed::value, + "dpf3 comparison payloads use the uint64 ring"); + const uint64_t t = detail::dcf_impl::beta_to_u64_simple(spec.if_true, + ~uint64_t{0}); + const uint64_t f = detail::dcf_impl::beta_to_u64_simple(spec.if_false, + ~uint64_t{0}); + return detail::dpf3_cmp_impl::make_from_spec( + thresh, cmp_spec_as_wildcard(std::move(spec)), t, f); + } +} + +/// @brief Blocked comparison with Shamir-shared value words. +template +HEDLEY_WARN_UNUSED_RESULT +auto make_dpf3_cmp_blocked(InputT thresh, uint64_t if_true, + uint64_t if_false = 0) +{ + return detail::dpf3_cmp_impl::make_from_spec( + thresh, dpf::block_width(dpf::lt(dpf::wildcard_value{})), + if_true, if_false); +} + +/// @brief Evaluate a three-party comparison key at `x` (one DCF share). +/// @details Returns an unreduced additive `uint64` share. Open a complementary +/// pair with `reconstruct_cmp_halves` (sum, then reduce into `fp61`). +template , + std::enable_if_t::is_dpf3_cmp, int> = 0> +HEDLEY_WARN_UNUSED_RESULT +std::uint64_t eval_dpf3_cmp(const KeyT & key, Query && x, + PathMemoizer && path = PathMemoizer{}) +{ + return detail::dpf3_cmp_impl::eval_one(key, std::forward(x), + std::forward(path)); +} + +/// @brief Full-domain comparison into an additive-share buffer (one DCF expand). +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). +template ::is_dpf3_cmp, int> = 0> +HEDLEY_WARN_UNUSED_RESULT +std::vector eval_full(const KeyT & key) +{ + using in = typename KeyT::input_type; + const auto from = std::numeric_limits::min(); + const auto to = std::numeric_limits::max(); + auto buf = dpf::make_output_buffer(dpf::cmp, key.dpf_key, from, to); + dpf::eval_interval(dpf::cmp, key.dpf_key, from, to, buf); + std::vector out(buf.size()); + for (std::size_t i = 0; i < buf.size(); ++i) + { + if constexpr (is_secret_share_v>) + out[i] = static_cast(buf[i].raw()); + else + out[i] = static_cast(buf[i]); + } + return out; +} + +/// @brief Interval comparison into an additive-share buffer. +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. +template ::is_dpf3_cmp, int> = 0> +HEDLEY_WARN_UNUSED_RESULT +std::vector eval_interval(const KeyT & key, LaneT from, LaneT to) +{ + auto buf = dpf::make_output_buffer(dpf::cmp, key.dpf_key, from, to); + dpf::eval_interval(dpf::cmp, key.dpf_key, from, to, buf); + std::vector out(buf.size()); + for (std::size_t i = 0; i < buf.size(); ++i) + { + if constexpr (is_secret_share_v>) + out[i] = static_cast(buf[i].raw()); + else + out[i] = static_cast(buf[i]); + } + return out; +} + +/// @brief In-place comparison payload update via the linear value-CW channel. +/// @details Applies `assign_cmp_local` with each party's Shamir share of +/// `δ' − δ`, adding that increment into the existing value CWs and +/// absorb addends. The threshold / spine stays. `if_false` is fixed +/// at 0 (the common `lt(β)` case); changing `if_false` needs a remake. +template +void update_payload_cmp(K1 & k1, K2 & k2, K3 & k3, uint64_t if_true_old, + uint64_t if_true_new) +{ + static_assert(K1::is_dpf3_cmp && K2::is_dpf3_cmp && K3::is_dpf3_cmp, + "dpf3_cmp keys"); + const uint64_t mask = k1.dpf_key.cmp().mask; + // Clear δ on the shared tree; difference is taken in fp61. + const uint64_t d = + (fp61{if_true_new} - fp61{if_true_old}).raw() & mask; + const uint64_t target = detail::incr::cmp_assign_target(k1.dpf_key.cmp(), d, 0); + uint64_t add0 = 0, add1 = 0; + const uint64_t r = detail::dcf_impl::sample_addend_blind(mask, + [] { + return dpf::uniform_sample< + typename std::decay_t::interior_node>(); + }); + detail::incr::split_cmp_addend(target, mask, r, add0, add1); + auto bump = [&](auto & key, uint64_t add) { + const uint64_t old = [&] { + if constexpr (is_party_key_v>) + return static_cast(key.dpf_key.cmp_addend().raw()); + else if constexpr (std::is_integral_v< + std::decay_t>) + return static_cast(key.dpf_key.cmp_addend()); + else + return static_cast(key.dpf_key.cmp_addend().raw()); + }(); + assign_cmp_local(key.dpf_key, d, (old + add) & mask); + }; + bump(k1, add0); + bump(k2, add1); + bump(k3, add0); + const auto shares = shamir3::share_secret( + fp61{if_true_new} - fp61{if_true_old}); + k1.beta_share = shamir3::share{k1.party, k1.beta_share.value + shares[0].value}; + k2.beta_share = shamir3::share{k2.party, k2.beta_share.value + shares[1].value}; + k3.beta_share = shamir3::share{k3.party, k3.beta_share.value + shares[2].value}; +} + +/// @brief Fresh comparison keys for a new payload (new spines — not an update). +template +HEDLEY_WARN_UNUSED_RESULT +auto remake_dpf3_cmp(InputT thresh, uint64_t if_true_new, + uint64_t if_false_new = 0) +{ + return make_dpf3_cmp(thresh, if_true_new, + if_false_new); +} + +/// @brief One party's interval key on a three-party comparison. +/// @tparam Party party index in `{1, 2, 3}` +/// @tparam CmpKey a `dpf3_cmp_key` +template +struct dpf3_ic_key +{ + static constexpr int party = Party; + static constexpr bool is_dpf3_ic = true; + static constexpr bool is_dpf3 = false; + using input_type = typename CmpKey::input_type; + using cmp_key_type = CmpKey; + + /// @brief Inner three-party comparison. Its `dpf_key` is the DPF half. + CmpKey dpf_key{}; + uint64_t lo = 0; // public bounds (F_IC) + uint64_t hi = 0; + uint64_t input_mask = 0; + uint64_t group_mask = 0; + /// Additive half of δ (k0-holder / k1-holder), opened with `reconstruct_cmp_halves`. + std::uint64_t delta_share = 0; + std::uint64_t cr_share = 0; +}; + +/// @brief Generate three interval-containment keys. +template +HEDLEY_WARN_UNUSED_RESULT +auto make_dpf3_ic(InputT r, InputT p, InputT q, uint64_t if_true, + uint64_t if_false = 0) +{ + auto two = dpf::make_dpf(r, dpf::ic(p, q, if_true, if_false)); + const uint64_t nmask = two.first.input_mask; + const uint64_t gmask = two.first.group_mask; + const uint64_t lo = static_cast(p); + const uint64_t hi = static_cast(q); + const InputT gamma = detail::ic_impl::gamma_of(r); + + const uint64_t delta = (if_true - if_false) & gmask; + auto cmp_keys = make_dpf3_cmp(gamma, delta, 0); + + uint64_t cr0 = 0, cr1 = 0; + if constexpr (is_secret_share_v) + { + cr0 = static_cast(two.first.cr_share.raw()); + cr1 = static_cast(two.second.cr_share.raw()); + } + else + { + cr0 = static_cast(two.first.cr_share); + cr1 = static_cast(two.second.cr_share); + } + const uint64_t cr_clear = (cr0 + cr1) & gmask; + // Additive halves so reconstruct_cmp_halves (sum) recovers the clear words. + const uint64_t d0 = dpf::uniform_sample() & gmask; + const uint64_t d1 = (delta - d0) & gmask; + const uint64_t c0 = dpf::uniform_sample() & gmask; + const uint64_t c1 = (cr_clear - c0) & gmask; + + using Cmp1 = std::decay_t(cmp_keys))>; + using Cmp2 = std::decay_t(cmp_keys))>; + using Cmp3 = std::decay_t(cmp_keys))>; + + dpf3_ic_key<1, Cmp1> k1{std::move(std::get<0>(cmp_keys)), lo, hi, nmask, + gmask, d0, c0}; + dpf3_ic_key<2, Cmp2> k2{std::move(std::get<1>(cmp_keys)), lo, hi, nmask, + gmask, d1, c1}; + dpf3_ic_key<3, Cmp3> k3{std::move(std::get<2>(cmp_keys)), lo, hi, nmask, + gmask, d0, c0}; + return std::make_tuple(std::move(k1), std::move(k2), std::move(k3)); +} + +/// @brief Evaluate a three-party interval key at `x`. +template ::is_dpf3_ic, int> = 0> +HEDLEY_WARN_UNUSED_RESULT +std::uint64_t eval_dpf3_ic(const KeyT & key, Query && x) +{ + using in_type = typename KeyT::input_type; + const uint64_t xu = detail::ic_impl::bits_of(in_type(x)); + const uint64_t xp = detail::ic_impl::shift_p(xu, key.lo, key.input_mask); + const uint64_t xq = detail::ic_impl::shift_q0(xu, key.hi, key.input_mask); + basic_path_memoizer path; + const uint64_t a = eval_dpf3_cmp(key.dpf_key, + detail::ic_impl::input_from_bits(xp), path); + const uint64_t b = eval_dpf3_cmp(key.dpf_key, + detail::ic_impl::input_from_bits(xq), path); + const int cx = detail::ic_impl::public_cx(xu, key.lo, key.hi, key.input_mask); + uint64_t scaled = 0; + if (cx == 1) + scaled = key.delta_share; + else if (cx == -1) + scaled = static_cast(0) - key.delta_share; + return (static_cast(0) - a) + b + key.cr_share + scaled; +} + +/// @brief `eval_point` overload for three-party comparison keys. +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. +template , + std::enable_if_t::is_dpf3_cmp, int> = 0> +HEDLEY_WARN_UNUSED_RESULT +std::uint64_t eval_point(const KeyT & key, Query && x, + PathMemoizer && path = PathMemoizer{}) +{ + return eval_dpf3_cmp(key, std::forward(x), + std::forward(path)); +} + +/// @brief `eval_point` overload for three-party interval keys. +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. +template ::is_dpf3_ic, int> = 0> +HEDLEY_WARN_UNUSED_RESULT +std::uint64_t eval_point(const KeyT & key, Query && x) +{ + return eval_dpf3_ic(key, std::forward(x)); +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_DPF3_CMP_HPP__ diff --git a/include/dpf/dpf3_ds.hpp b/include/dpf/dpf3_ds.hpp new file mode 100644 index 0000000..d4b1b4d --- /dev/null +++ b/include/dpf/dpf3_ds.hpp @@ -0,0 +1,125 @@ +/// @file dpf/dpf3_ds.hpp +/// @brief Dual-spine Doerner–Shelat generation of (2,3) point keys. +/// @note Two independent openings, one per spine of Zyskind, Yanai, and Pentland (ePrint 2024/1658, Figure 3). Each opening follows Doerner and shelat, CCS 2017 (ePrint 2017/827). +/// @details Runs two independent two-party DS walks (spines A and B) with +/// Fig-3 `τ` payloads, then assembles the three evaluator keys via +/// `assemble_from_spines`. Matches honest-dealer `make_dpf3` on the +/// opened point `x0 ⊕ x1` (after the signed-MSB flip on share 0). +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_DPF3_DS_HPP__ +#define LIBDPF_INCLUDE_DPF_DPF3_DS_HPP__ + +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/dpf3.hpp" +#include "dpf/fp61.hpp" +#include "dpf/incremental.hpp" +#include "dpf/placement.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/verifiable.hpp" +#include "dpf/wildcard.hpp" + +namespace dpf +{ +namespace detail +{ +namespace dpf3_impl +{ + +template +auto make_point3_ds(InputT x0, InputT x1, fp61 beta) +{ + using X = xor61; + const InputT alpha = open_xor_point(x0, x1); + const tau_quad t = sample_taus(beta); + const X payload_a = t.t0 + t.t1; + const X payload_b = t.t2 + t.t3; + + if constexpr (Updatable) + { + // Classic DS rejects wildcards; the incremental path plants beaver + // leaves. Inner verifiable tags match the outer `Verifiable` flag. + auto A = [&] { + if constexpr (Verifiable) + return dpf::make_dpf_doerner_shelat( + x0, x1, dpf::wildcard_value{}, dpf::verifiable{}); + else + return dpf::make_dpf_doerner_shelat( + x0, x1, dpf::wildcard_value{}); + }(); + auto B = [&] { + if constexpr (Verifiable) + return dpf::make_dpf_doerner_shelat( + x0, x1, dpf::wildcard_value{}, dpf::verifiable{}); + else + return dpf::make_dpf_doerner_shelat( + x0, x1, dpf::wildcard_value{}); + }(); + assign_xor_payload(A.first, A.second, payload_a); + assign_xor_payload(B.first, B.second, payload_b); + return assemble_from_spines( + std::move(A.first), std::move(A.second), std::move(B.first), + std::move(B.second), t, alpha); + } + else + { + auto A = [&] { + if constexpr (Verifiable) + return dpf::make_dpf_doerner_shelat( + x0, x1, payload_a, dpf::verifiable{}); + else + return dpf::make_dpf_doerner_shelat( + x0, x1, payload_a); + }(); + auto B = [&] { + if constexpr (Verifiable) + return dpf::make_dpf_doerner_shelat( + x0, x1, payload_b, dpf::verifiable{}); + else + return dpf::make_dpf_doerner_shelat( + x0, x1, payload_b); + }(); + return assemble_from_spines( + std::move(A.first), std::move(A.second), std::move(B.first), + std::move(B.second), t, alpha); + } +} + +} // namespace dpf3_impl +} // namespace detail + +/// @brief Dual-spine Doerner–Shelat (2,3) keys for XOR shares of `α`. +/// @details `α = x0 ⊕ x1` after the signed-MSB flip on `x0`. Tags match +/// `make_dpf3`: `verifiable`, `extractable`, and `updatable`, any order. +/// \complexity O(n) time. One `ds_advance_level` per level: two PRG expansions and one `prepare_level`. n is `depth`. +/// \rounds No sockets. This is the in-process transcript. A networked walk is `dpf::party::dist::point_party`. +/// \communication none here. `local_cw_protocol` opens the correction word locally. +/// \preprocessing Per level, `prepare_level` draws one `ds_cw_pads` (two parties × a 128-bit rand, a 128-bit gamma, and a bit) and two `ds_and_pads`. Arithmetic inputs also run a carry chain of n-1 bit-AND triples in `encode_walk_shares`. +template +HEDLEY_WARN_UNUSED_RESULT +auto make_dpf3_doerner_shelat(InputT x0, InputT x1, fp61 beta, Tags ...tags) +{ + using flags = detail::dpf3_impl::tag_flags; + static_assert(flags::known, + "make_dpf3_doerner_shelat tags are verifiable, extractable, updatable"); + static_assert(sizeof...(Tags) == flags::counted, + "make_dpf3_doerner_shelat: repeated tag"); + (void)std::initializer_list{((void)tags, 0)...}; + return detail::dpf3_impl::make_point3_ds(x0, x1, beta); +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_DPF3_DS_HPP__ diff --git a/include/dpf/dpf3_multipoint.hpp b/include/dpf/dpf3_multipoint.hpp new file mode 100644 index 0000000..c3d8f90 --- /dev/null +++ b/include/dpf/dpf3_multipoint.hpp @@ -0,0 +1,336 @@ +/// @file dpf/dpf3_multipoint.hpp +/// @brief Three-evaluator multipoint DPF: Figure 3 of Zyskind, Yanai, and Pentland (ePrint 2024/1658) per bucket. +/// @details Cuckoo packing matches `make_multipoint`. Each bucket is a (2,3) +/// point key. Evaluation sums Shamir shares across the three probes. +/// Updatable multipoint keys keep beaver leaves on every bucket; +/// `update_payload` replays `insert_cuckoo` with the existing `σ` +/// (deterministic) and runs Fig-10 per occupied bucket — no re-cuckoo. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_DPF3_MULTIPOINT_HPP__ +#define LIBDPF_INCLUDE_DPF_DPF3_MULTIPOINT_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" +#include "simde/simde/x86/avx2.h" + +#include "dpf/dpf3.hpp" +#include "dpf/fp61.hpp" +#include "dpf/multipoint.hpp" +#include "dpf/path_memoizer.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" +#include "dpf/shamir3.hpp" +#include "dpf/verifiable.hpp" + +namespace dpf +{ + +/// @brief One party's multipoint (2,3) key. +/// @tparam Party party index in `{1, 2, 3}` +/// @tparam InputT input domain type +/// @tparam BucketKey a `dpf3_key` for that party +template +struct multipoint3_key +{ + static_assert(Party >= 1 && Party <= 3, "multipoint3 party is 1, 2, or 3"); + static constexpr int party = Party; + static constexpr bool is_multipoint3 = true; + static constexpr bool is_dpf3 = false; + static constexpr std::size_t kappa = 3; + + using input_type = InputT; + using bucket_key = BucketKey; + using bucket_input = typename BucketKey::input_type; + + simde__m128i sigma{}; + std::uint64_t bucket_count = 0; + mpf_word bucket_domain{}; + std::vector buckets{}; + bool verifiable = false; + bool extractable = false; + bool updatable = false; +}; + +namespace detail +{ +namespace mpf3 +{ + +template +auto make_impl(std::vector alphas, std::vector betas, + multipoint_params params) +{ + namespace mpf = detail::mpf; + if (alphas.size() != betas.size()) + throw std::invalid_argument("make_multipoint3: point/payload count"); + if (alphas.empty()) + throw std::invalid_argument("make_multipoint3: no points"); + { + auto sorted = alphas; + std::sort(sorted.begin(), sorted.end()); + if (std::adjacent_find(sorted.begin(), sorted.end()) != sorted.end()) + throw std::invalid_argument("make_multipoint3: duplicate points"); + } + + const auto t = static_cast(alphas.size()); + const auto m = mpf::bucket_count_for(t, params.lambda); + constexpr std::size_t input_bits = utils::bitlength_of_v; + const mpf_word n = mpf::domain_size(input_bits); + constexpr int kappa = 3; + const mpf_word span = mpf::word_mul_small(n, kappa); + const mpf_word den{uint256_t{m}, uint256_t{0}}; + const mpf_word numer = mpf::word_add(span, + mpf::word_sub(den, mpf_word{uint256_t{1}, uint256_t{0}})); + const mpf_word b = mpf::word_divmod(numer, den).first; + + const int attempts = params.retries < 1 ? 1 : params.retries; + for (int attempt = 0; attempt < attempts; ++attempt) + { + try + { + const simde__m128i sigma = dpf::uniform_sample(); + std::vector table; + if (!mpf::insert_cuckoo(sigma, alphas, m, n, b, params.max_evictions, + table)) + continue; + + // Probe the first bucket type to name the three party key types. + InputT gamma0{}; + fp61 beta0{}; + if (table[0].item >= 0) + { + const auto & alpha = alphas[static_cast(table[0].item)]; + const auto loc = mpf::locate(sigma, mpf::to_word(alpha), + table[0].hash, n, b); + gamma0 = mpf::from_word(loc.index); + beta0 = betas[static_cast(table[0].item)]; + } + auto make_bucket3 = [&](InputT gamma, fp61 beta) { + return detail::dpf3_impl::make_tagged(gamma, beta); + }; + auto first = make_bucket3(gamma0, beta0); + using K1 = std::decay_t(first))>; + using K2 = std::decay_t(first))>; + using K3 = std::decay_t(first))>; + + multipoint3_key<1, InputT, K1> left; + multipoint3_key<2, InputT, K2> mid; + multipoint3_key<3, InputT, K3> right; + left.sigma = mid.sigma = right.sigma = sigma; + left.bucket_count = mid.bucket_count = right.bucket_count = m; + left.bucket_domain = mid.bucket_domain = right.bucket_domain = b; + left.verifiable = mid.verifiable = right.verifiable = Verifiable; + left.extractable = mid.extractable = right.extractable = Extractable; + left.updatable = mid.updatable = right.updatable = Updatable; + left.buckets.reserve(static_cast(m)); + mid.buckets.reserve(static_cast(m)); + right.buckets.reserve(static_cast(m)); + + left.buckets.push_back(std::move(std::get<0>(first))); + mid.buckets.push_back(std::move(std::get<1>(first))); + right.buckets.push_back(std::move(std::get<2>(first))); + + for (std::uint64_t i = 1; i < m; ++i) + { + InputT gamma{}; + fp61 beta{}; + if (table[static_cast(i)].item >= 0) + { + const auto & alpha = alphas[static_cast( + table[static_cast(i)].item)]; + const auto loc = mpf::locate(sigma, mpf::to_word(alpha), + table[static_cast(i)].hash, n, b); + if (loc.bucket != i) + throw mpf::prp_walk_error{}; + gamma = mpf::from_word(loc.index); + beta = betas[static_cast( + table[static_cast(i)].item)]; + } + auto made = make_bucket3(gamma, beta); + left.buckets.push_back(std::move(std::get<0>(made))); + mid.buckets.push_back(std::move(std::get<1>(made))); + right.buckets.push_back(std::move(std::get<2>(made))); + } + return std::make_tuple(std::move(left), std::move(mid), + std::move(right)); + } + catch (const mpf::prp_walk_error &) + { + continue; + } + } + throw std::runtime_error("make_multipoint3: cuckoo hashing failed"); +} + +template +fp61 eval_at(const Key & key, typename Key::input_type x) +{ + namespace mpf = detail::mpf; + constexpr std::size_t input_bits = utils::bitlength_of_v; + const mpf_word n = mpf::domain_size(input_bits); + const mpf_word b = key.bucket_domain; + fp61 sum{}; + using InnerA = typename Key::bucket_key::plus_a_type::inner_type; + using InnerB = typename Key::bucket_key::plus_b_type::inner_type; + basic_path_memoizer path_a{}; + basic_path_memoizer path_b{}; + for (int hash = 0; hash < static_cast(Key::kappa); ++hash) + { + const auto loc = mpf::locate(key.sigma, mpf::to_word(x), hash, n, b); + if (loc.bucket >= key.bucket_count) + throw std::runtime_error("multipoint3 eval: bucket out of range"); + const auto gamma = mpf::from_word(loc.index); + sum = sum + dpf::eval_point(key.buckets[loc.bucket], gamma, path_a, + path_b); + } + return sum; +} + +} // namespace mpf3 +} // namespace detail + +namespace detail +{ +namespace mpf3 +{ + +template +struct is_multipoint_params : std::is_same, multipoint_params> +{ }; + +template +using last_type_t = std::tuple_element_t..., multipoint_params>>; + +template +auto run_without_last(Run && run, Tuple && pack, std::index_sequence) +{ + return std::forward(run)(std::get(pack), + std::get(std::forward(pack))...); +} + +} // namespace mpf3 +} // namespace detail + +/// @brief Cuckoo-pack points into (2,3) point-key buckets. +/// @details Tags match `make_dpf3` (`verifiable`, `extractable`, `updatable`), +/// in any order. An optional `multipoint_params` may follow the tags. +template +HEDLEY_WARN_UNUSED_RESULT +auto make_multipoint3(const AlphaRange & alphas, const BetaRange & betas, + Tail && ...tail) +{ + using input_type = std::decay_t; + auto run = [&](multipoint_params params, auto && ...tags) { + using flags = detail::dpf3_impl::tag_flags...>; + static_assert(flags::known, + "make_multipoint3 tags are verifiable, extractable, updatable"); + static_assert(sizeof...(tags) == flags::counted, + "make_multipoint3: repeated tag"); + return detail::mpf3::make_impl( + std::vector(std::begin(alphas), std::end(alphas)), + std::vector(std::begin(betas), std::end(betas)), params); + }; + if constexpr (sizeof...(Tail) > 0 + && detail::mpf3::is_multipoint_params< + detail::mpf3::last_type_t>::value) + { + return detail::mpf3::run_without_last(run, + std::forward_as_tuple(std::forward(tail)...), + std::make_index_sequence{}); + } + else + return run(multipoint_params{}, std::forward(tail)...); +} + +/// @brief Sum the three bucket Shamir shares at `x`. +/// \complexity Three `eval_point` calls (`Key::kappa` is 3), each O(n_b) where n_b is the bucket key depth. +template = 0> +HEDLEY_WARN_UNUSED_RESULT +fp61 eval_multipoint(const Key & key, typename Key::input_type x) +{ + return detail::mpf3::eval_at(key, x); +} + +/// @brief In-place multipoint payload update; keeps `σ` and cuckoo placement. +/// @details Replays `insert_cuckoo` with the existing `σ` (RNG is seeded from +/// `σ`, so placement is deterministic) to rediscover each point's +/// bucket, then runs Fig-10 `update_payload` on that bucket. Empty +/// buckets stay a share of 0. Requires `updatable` generation. +/// Point set and order must match generation. +template +void update_payload(M1 & k1, M2 & k2, M3 & k3, const AlphaRange & alphas, + const BetaRange & betas_new, multipoint_params params = {}) +{ + static_assert(M1::is_multipoint3 && M2::is_multipoint3 + && M3::is_multipoint3, + "multipoint3 keys"); + if (!k1.updatable || !k2.updatable || !k3.updatable) + throw std::invalid_argument( + "update_payload: multipoint3 keys were not generated updatable"); + namespace mpf = detail::mpf; + using InputT = typename M1::input_type; + const auto alpha_v = std::vector(std::begin(alphas), + std::end(alphas)); + const auto beta_v = std::vector(std::begin(betas_new), + std::end(betas_new)); + if (alpha_v.size() != beta_v.size()) + throw std::invalid_argument("update_payload: point/payload count"); + constexpr std::size_t input_bits = utils::bitlength_of_v; + const mpf_word n = mpf::domain_size(input_bits); + const mpf_word b = k1.bucket_domain; + std::vector table; + if (!mpf::insert_cuckoo(k1.sigma, alpha_v, k1.bucket_count, n, b, + params.max_evictions, table)) + throw std::runtime_error( + "update_payload: cuckoo replay failed (σ/points mismatch?)"); + for (std::uint64_t bi = 0; bi < k1.bucket_count; ++bi) + { + if (table[static_cast(bi)].item < 0) + continue; + const auto item = static_cast( + table[static_cast(bi)].item); + const auto loc = mpf::locate(k1.sigma, mpf::to_word(alpha_v[item]), + table[static_cast(bi)].hash, n, b); + if (loc.bucket != bi) + throw std::runtime_error("update_payload: PRP walk mismatch"); + const auto gamma = + mpf::from_word(loc.index); + dpf::update_payload(k1.buckets[bi], k2.buckets[bi], k3.buckets[bi], + gamma, beta_v[item]); + } +} + +/// @brief Fresh multipoint3 keys (new cuckoo table — not an in-place update). +template +HEDLEY_WARN_UNUSED_RESULT +auto remake_multipoint3(const AlphaRange & alphas, const BetaRange & betas_new, + multipoint_params params = {}) +{ + return make_multipoint3(alphas, betas_new, params); +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_DPF3_MULTIPOINT_HPP__ diff --git a/include/dpf/dpf_key.hpp b/include/dpf/dpf_key.hpp index 23bbf21..88fd17b 100644 --- a/include/dpf/dpf_key.hpp +++ b/include/dpf/dpf_key.hpp @@ -17,6 +17,7 @@ #include #include +#include "dpf/experiment_note.hpp" #include "dpf/prg_aes.hpp" #include "dpf/tree_traits.hpp" #include "dpf/wildcard.hpp" @@ -35,6 +36,12 @@ namespace dpf #ifdef LIBDPF_HAS_ASIO namespace asio { +/// @brief Exchange a wildcard output share and install the opened leaf. +/// @see dpf::leaf_wrapper +/// \complexity O(leaf bytes) for the Beaver leaf arithmetic, plus the transfers. +/// \rounds 2. Write/read the blinded output share, then write/read the leaf share (`async_assign_wildcard_output`). +/// \communication `sizeof(output_type)` plus `sizeof(leaf_type)` each way. +/// \preprocessing The leaf Beaver triple (`vector_blind`, `output_blind`, `blinded_vector`) was stored at keygen. template , dpf::is_wildcard_v...)}, - leaf_nodes(get_wrappers(leaves, beavers)), - common_part_hash_{utils::get_common_part_hash(correction_words_, correction_advice_, leaf_nodes, wildcard_mask)}, - offset_x{offset_share} + common_part_hash_{utils::get_common_part_hash(correction_words_, correction_advice_, leaf_nodes, wildcard_mask)} { } classic_dpf_key_impl(const classic_dpf_key_impl &) = default; classic_dpf_key_impl(classic_dpf_key_impl &&) = default; @@ -410,6 +417,29 @@ HEDLEY_PRAGMA(GCC diagnostic pop) return traverse_exterior(node, std::get(leaf_nodes).get()); } + /// @brief Eight one-block leaves. One `eval_x8` instead of eight `eval` calls. + template + void traverse_exterior_x8(const interior_node * HEDLEY_RESTRICT nodes, + Out * HEDLEY_RESTRICT out) const noexcept + { + using output_type = std::tuple_element_t; + using block = typename exterior_prg::block_type; + alignas(64) block seeds[8]; + alignas(64) block masks[8]; + for (std::size_t t = 0; t < 8; ++t) + seeds[t] = utils::to_exterior_node(unset_lo_2bits(nodes[t])); + constexpr auto pos = dpf::block_offset_of_leaf_v; + exterior_prg::eval_x8(seeds, masks, static_cast(pos)); + const auto & cw = std::get(leaf_nodes).get(); + for (std::size_t t = 0; t < 8; ++t) + { + encode_curve_leaf_mask>(masks[t]); + out[t] = dpf::subtract_leaf( + dpf::get_if_lo_bit(cw, nodes[t]), masks[t]); + } + } + leaf_wrapper_tuple leaf_nodes; offset_type offset_x; static constexpr std::array wildcard_mask{dpf::is_wildcard_v, @@ -670,6 +700,35 @@ struct cmp_storage } } + /// @brief `mix(base, coeff)` at every value CW, then install `addend`. + /// @tparam Mix word rewriter + /// @param mix combines one stored base word with its integer coefficient word + /// @param addend this party's share of the constant payload + template + void assign_payload(Mix mix, value_cw_word addend) + { + static_assert(Wild, + "assign_cmp on a key whose comparison payload is not a wildcard"); + if constexpr (Wild) + { + for (std::size_t i = 0; i < Depth; ++i) + value_cw_[i] = mix(value_cw_[i], wild_.value_cw_coeff[i]); + if constexpr (Blocked) + { + for (std::size_t i = 0; i < TailLen; ++i) + tail_[i] = mix(tail_[i], wild_.tail_coeff[i]); + } + cw_last_ = mix(cw_last_, wild_.cw_last_coeff); + if constexpr (Idcf) + { + for (std::size_t i = 0; i < prefix_cw_len; ++i) + prefix_cw_[i] = mix(prefix_cw_[i], wild_.prefix_cw_coeff[i]); + } + cmp_addend_ = addend; + wild_.assigned = true; + } + } + /// @brief Per-level δ coefficients for a wildcard comparison. Empty when the /// payload is concrete. /// @return the coefficient table @@ -767,6 +826,7 @@ struct incr_key_base using interior_node = typename InteriorPRG::block_type; using exterior_node = typename ExteriorPRG::block_type; using input_type = dpf::concrete_type_t; + using raw_input_type = InputT; using placed_tuple = PlacedTuple; using node_type = exterior_node; static constexpr std::size_t cmp_depth = CmpDepth; @@ -797,10 +857,15 @@ struct incr_key_base static constexpr std::size_t cmp_tail = (CmpBlock == 0 || cmp_q == 0) ? 0 : (std::size_t{1} << cmp_q); /// @brief Narrowest unsigned word that holds `cmp_out_bits` bits (1 byte for a - /// bit / ≤8-bit payload, 2 for ≤16, 4 for ≤32, 8 for ≤64). Value CWs and - /// the addend share are stored in this word. - using value_cw_word = utils::integral_type_from_bitlength_t< - (CmpOutBits == 0 ? std::size_t{1} : CmpOutBits)>; + /// bit / ≤8-bit payload, 2 for ≤16, 4 for ≤32, 8 for ≤64). Payloads wider + /// than 256 bits are stored as their raw bytes. Value CWs and the addend + /// share use this word. + static constexpr std::size_t cmp_word_bits = + CmpOutBits == 0 ? std::size_t{1} : CmpOutBits; + using value_cw_word = std::conditional_t< + (cmp_word_bits <= 256), + utils::integral_type_from_bitlength_t, + std::array>; static constexpr std::size_t num_outputs = std::tuple_size_v; static constexpr std::size_t input_bits = utils::bitlength_of_v; @@ -835,12 +900,15 @@ struct incr_key_base /// @brief Multi-level / comparison keys route through the slot-aware eval path. /// Classic-shaped packs (every slot at full input width, no cmp) keep the /// classic `eval_*` fast path even when verifiable/extractable phantoms are - /// present. + /// present. `eq` / `eq_at` with a public `if_false` addend also take the + /// slot-aware path so party 0 can absorb that addend. static constexpr bool is_multilevel = [] { if constexpr (CmpDepth > 0) return true; if constexpr (num_outputs == 0) return true; + else if constexpr (detail::incr::any_public_addend_v) + return true; else { for (std::size_t i = 0; i < num_outputs; ++i) @@ -867,6 +935,20 @@ struct incr_key_base template using concrete_output_type = concrete_type_t>; + private: + template + static auto outputs_tuple_type(std::index_sequence) + -> std::tuple...>; + template + static auto concrete_outputs_tuple_type(std::index_sequence) + -> std::tuple...>; + + public: + using outputs_tuple = decltype(outputs_tuple_type( + std::make_index_sequence{})); + using concrete_outputs_tuple = decltype(concrete_outputs_tuple_type( + std::make_index_sequence{})); + template static constexpr std::size_t lg_outputs_per_leaf_of = (num_outputs > 0) ? meta[I].lg_opl : 0; @@ -899,6 +981,23 @@ struct incr_key_base static constexpr auto wildcard_mask = wildcard_mask_tuple(std::make_index_sequence{}); + template + static constexpr std::array + wildcard_mask_array(std::index_sequence) + { + return {{std::get(wildcard_mask)...}}; + } + static constexpr auto wildcard_bits = + wildcard_mask_array(std::make_index_sequence{}); + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + constexpr bool is_wildcard(std::size_t i) const noexcept + { + return i < num_outputs && wildcard_bits[i]; + } + static constexpr std::size_t deepest_prefix = [] { if constexpr (num_outputs == 0) return CmpDepth; @@ -938,6 +1037,14 @@ struct incr_key_base using addend_tuple = decltype(addend_tuple_t( std::make_index_sequence{})); + static value_cw_word cw_word_from_u64(std::uint64_t v) + { + if constexpr (std::is_integral_v) + return static_cast(v); + else + return value_cw_word{}; + } + incr_key_base(interior_node root, const correction_words_array & correction_words, const correction_advice_array & correction_advice, @@ -951,13 +1058,13 @@ struct incr_key_base correction_seeds_array correction_seeds = {}) : leaf_nodes{std::move(leaves)}, offset_x{offset_share}, - cmp_store_{cmp, value_cws, - static_cast(cw_last_in), - static_cast(cmp_addend_in), - value_cw_coeff, - static_cast(cw_last_coeff_in), - tail_in, tail_coeff_in, prefix_in, prefix_coeff_in}, public_addends{std::move(addends)}, + cmp_store_{cmp, value_cws, + cw_word_from_u64(cw_last_in), + cw_word_from_u64(cmp_addend_in), + value_cw_coeff, + cw_word_from_u64(cw_last_coeff_in), + tail_in, tail_coeff_in, prefix_in, prefix_coeff_in}, root_{root}, correction_words_{correction_words}, correction_advice_{correction_advice}, @@ -1027,6 +1134,11 @@ struct incr_key_base { cmp_store_.assign_group(delta, addend); } + template + void assign_cmp_payload(Mix mix, value_cw_word addend) + { + cmp_store_.assign_payload(std::move(mix), addend); + } HEDLEY_NO_THROW const prefix_cw_array & prefix_cws() const noexcept { @@ -1125,9 +1237,12 @@ struct incr_key_base tree::traverse01_x4(parents, cw0, cw1, left, right, is_last); } - template + template HEDLEY_NO_THROW - auto traverse_exterior(const interior_node & node) const noexcept + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + static auto traverse_exterior(const interior_node & node, + const LeafT & correction_word) noexcept { static_assert(num_outputs > 0, "cmp-only key has no exterior outputs"); using Out = concrete_output_type; @@ -1154,8 +1269,50 @@ struct incr_key_base static_cast(count), static_cast(pos)); } + encode_curve_leaf_mask(mask); return dpf::subtract_leaf( - dpf::get_if_lo_bit(std::get(leaf_nodes).get(), node), mask); + dpf::get_if_lo_bit(correction_word, node), mask); + } + + template + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + auto traverse_exterior(const interior_node & node) const noexcept + { + static_assert(num_outputs > 0, "cmp-only key has no exterior outputs"); + return traverse_exterior(node, std::get(leaf_nodes).get()); + } + + /// @brief Eight one-block leaves, or eight scalar leaves when the PRG is special. + template + void traverse_exterior_x8(const interior_node * HEDLEY_RESTRICT nodes, + Out * HEDLEY_RESTRICT out) const noexcept + { + const auto & cw = std::get(leaf_nodes).get(); + if constexpr (IsExtractable || meta[I].block_len != 1) + { + for (std::size_t t = 0; t < 8; ++t) + out[t] = traverse_exterior(nodes[t], cw); + return; + } + else + { + using OutT = concrete_output_type; + using block = exterior_node; + alignas(64) block seeds[8]; + alignas(64) block masks[8]; + constexpr auto pos = meta[I].pos_base + + meta[I].index_in_group * meta[I].block_len; + for (std::size_t t = 0; t < 8; ++t) + seeds[t] = utils::to_exterior_node(unset_lo_2bits(nodes[t])); + exterior_prg::eval_x8(seeds, masks, static_cast(pos)); + for (std::size_t t = 0; t < 8; ++t) + { + encode_curve_leaf_mask(masks[t]); + out[t] = dpf::subtract_leaf( + dpf::get_if_lo_bit(cw, nodes[t]), masks[t]); + } + } } leaf_wrapper_tuple leaf_nodes; @@ -1383,6 +1540,16 @@ using incr_dpf_key_of_t = typename incr_dpf_key_of +struct uniform_node_sampler +{ + Node operator()() const + { + return dpf::uniform_sample(); + } +}; + template struct pseudorandom_root_sampler { @@ -1390,7 +1557,10 @@ struct pseudorandom_root_sampler pseudorandom_root_sampler( root_type && seed = dpf::uniform_sample()) - : seed_{seed}, counter_{0} { } + : seed_{seed}, counter_{0} + { + note_experiment_seed("pseudorandom_root_sampler", seed_); + } root_type operator()(psnip_uint32_t i) const { @@ -1528,6 +1698,13 @@ HEDLEY_PRAGMA(GCC diagnostic pop) } // namespace detail +/// @brief Dealer keygen. Returns the two party keys. +/// @param args plaintext point and payloads +/// @param root_sampler draws the interior roots +/// @return a `party_key` pair +/// @note Signed domains flip the MSB before the walk (`flip_msb_if_signed_integral`). +/// @see dpf::eval_point +/// \complexity O(n) time and O(n) key size. n is the domain bitlength (`depth`). The loop does two interior PRG expansions and writes one correction word per level, then builds one exterior leaf per output. template +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/ot_pack.hpp" +#include "dpf/rss_seed.hpp" + +namespace dpf +{ +namespace edabit +{ + +/// @brief Packed boolean XOR shares + arithmetic share of `r = sum b_i 2^i`. +template +struct edabit_share +{ + std::vector bits_packed; ///< ceil(ell/8) XOR / RSS-own bits + std::vector bits_next; ///< RSS next bit component; empty in 2PC + Ring arith{}; + Ring arith_next{}; ///< RSS next component; 0 for 2PC + unsigned width = 0; +}; + +namespace detail +{ + +inline void set_bit(std::vector & packed, unsigned i, + std::uint8_t bit) +{ + const unsigned byte = i / 8u; + const unsigned off = i % 8u; + if (byte >= packed.size()) + packed.resize(byte + 1u, 0); + if (bit & 1u) + packed[byte] = static_cast(packed[byte] | (1u << off)); + else + packed[byte] = static_cast(packed[byte] & ~(1u << off)); +} + +inline std::uint8_t get_bit(const std::vector & packed, unsigned i) +{ + const unsigned byte = i / 8u; + const unsigned off = i % 8u; + if (byte >= packed.size()) + return 0; + return static_cast((packed[byte] >> off) & 1u); +} + +} // namespace detail + +template +struct edabit_pair +{ + edabit_share p0; + edabit_share p1; + Ring clear_r{}; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +edabit_pair sample_edabit_pair(unsigned ell) +{ + if (ell == 0 || ell > 8u * sizeof(Ring)) + throw std::invalid_argument("edabit width"); + edabit_pair out; + out.p0.width = ell; + out.p1.width = ell; + const std::size_t nbytes = (ell + 7u) / 8u; + out.p0.bits_packed.assign(nbytes, 0); + out.p1.bits_packed.assign(nbytes, 0); + Ring r = Ring{}; + for (unsigned i = 0; i < ell; ++i) + { + auto d = ot::sample_dabit_pair(); + detail::set_bit(out.p0.bits_packed, i, d.p0.bit); + detail::set_bit(out.p1.bits_packed, i, d.p1.bit); + out.p0.arith = static_cast(out.p0.arith + (d.p0.arith << i)); + out.p1.arith = static_cast(out.p1.arith + (d.p1.arith << i)); + const Ring bit = static_cast((d.p0.bit ^ d.p1.bit) & 1u); + r = static_cast(r + (bit << i)); + } + out.clear_r = r; + return out; +} + +template +HEDLEY_WARN_UNUSED_RESULT +edabit_share sample_from_pack(ot::pack & pack, unsigned ell) +{ + if (ell == 0 || ell > 8u * sizeof(Ring)) + throw std::invalid_argument("edabit width"); + edabit_share out; + out.width = ell; + out.bits_packed.assign((ell + 7u) / 8u, 0); + for (unsigned i = 0; i < ell; ++i) + { + auto d = pack.take_dabit(); + detail::set_bit(out.bits_packed, i, d.bit); + out.arith = static_cast(out.arith + (d.arith << i)); + } + return out; +} + +/// @brief Three parties' RSS edaBits: bits first, arith = sum bit_comp · 2^i. +template +struct edabit_rss_triple +{ + edabit_share p0; + edabit_share p1; + edabit_share p2; + Ring clear_r{}; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +edabit_rss_triple sample_rss_all(const rss::seed_bundle & bundle, + unsigned ell, std::uint64_t index) +{ + if (ell == 0 || ell > 8u * sizeof(Ring)) + throw std::invalid_argument("edabit width"); + edabit_rss_triple out; + out.p0.width = out.p1.width = out.p2.width = ell; + const std::size_t nbytes = (ell + 7u) / 8u; + out.p0.bits_packed.assign(nbytes, 0); + out.p1.bits_packed.assign(nbytes, 0); + out.p2.bits_packed.assign(nbytes, 0); + out.p0.bits_next.assign(nbytes, 0); + out.p1.bits_next.assign(nbytes, 0); + out.p2.bits_next.assign(nbytes, 0); + Ring r = Ring{}; + for (unsigned i = 0; i < ell; ++i) + { + // Boolean RSS: own components XOR to the bit; next matches the neighbor. + const auto rnd = rss::random_replicated_all( + bundle, index + 1 + i); + const std::uint8_t bit = static_cast( + (rnd.p0.own ^ rnd.p1.own ^ rnd.p2.own) & 1u); + const std::uint8_t u = static_cast( + dpf::uniform_sample() & 1u); + const std::uint8_t v = static_cast( + dpf::uniform_sample() & 1u); + const std::uint8_t w = static_cast(u ^ v ^ bit); + detail::set_bit(out.p0.bits_packed, i, u); + detail::set_bit(out.p0.bits_next, i, v); + detail::set_bit(out.p1.bits_packed, i, v); + detail::set_bit(out.p1.bits_next, i, w); + detail::set_bit(out.p2.bits_packed, i, w); + detail::set_bit(out.p2.bits_next, i, u); + // Arithmetic RSS of the same bit: own components sum to `bit`. + const Ring ra = dpf::uniform_sample(); + const Ring rb = dpf::uniform_sample(); + const Ring rc = static_cast(Ring{bit} - ra - rb); + out.p0.arith = static_cast(out.p0.arith + (ra << i)); + out.p0.arith_next = static_cast(out.p0.arith_next + (rb << i)); + out.p1.arith = static_cast(out.p1.arith + (rb << i)); + out.p1.arith_next = static_cast(out.p1.arith_next + (rc << i)); + out.p2.arith = static_cast(out.p2.arith + (rc << i)); + out.p2.arith_next = static_cast(out.p2.arith_next + (ra << i)); + r = static_cast(r + (Ring{bit} << i)); + } + out.clear_r = r; + return out; +} + +template +HEDLEY_WARN_UNUSED_RESULT +edabit_share sample_rss(const rss::seed_bundle & bundle, unsigned me, + unsigned ell, std::uint64_t index) +{ + auto all = sample_rss_all(bundle, ell, index); + if (me == 0) + return all.p0; + if (me == 1) + return all.p1; + if (me == 2) + return all.p2; + throw std::invalid_argument("sample_rss party"); +} + +/// @brief Finish one GMW AND. `d_open` / `e_open` are the public `p⊕a` and `q⊕b`. +inline std::uint8_t and_finish(const ot::bit_triple & mine, std::uint8_t d_open, + std::uint8_t e_open, unsigned party) +{ + std::uint8_t z = mine.c; + z = static_cast(z ^ (d_open & mine.b)); + z = static_cast(z ^ (e_open & mine.a)); + if (party == 0) + z = static_cast(z ^ (d_open & e_open)); + return static_cast(z & 1u); +} + +/// @brief Two-party AND: open the masked bits, then `and_finish` on each view. +HEDLEY_WARN_UNUSED_RESULT +inline std::pair and_pair(std::uint8_t p0, + std::uint8_t p1, std::uint8_t q0, std::uint8_t q1) +{ + auto tp = ot::sample_bit_triple_pair(); + const std::uint8_t d = static_cast( + (p0 ^ tp.p0.a) ^ (p1 ^ tp.p1.a)); + const std::uint8_t e = static_cast( + (q0 ^ tp.p0.b) ^ (q1 ^ tp.p1.b)); + return {and_finish(tp.p0, d, e, 0), and_finish(tp.p1, d, e, 1)}; +} + +/// @brief A2B whose carry is a shared AND. Opens `x - r` and the AND masks only. +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, std::vector> a2b_gmw_pair( + const edabit_pair & eda, Ring x0, Ring x1) +{ + const unsigned ell = eda.p0.width; + const Ring delta = static_cast( + (x0 - eda.p0.arith) + (x1 - eda.p1.arith)); + std::vector b0((ell + 7u) / 8u, 0); + std::vector b1((ell + 7u) / 8u, 0); + std::uint8_t c0 = 0; + std::uint8_t c1 = 0; + for (unsigned i = 0; i < ell; ++i) + { + const std::uint8_t r0 = detail::get_bit(eda.p0.bits_packed, i); + const std::uint8_t r1 = detail::get_bit(eda.p1.bits_packed, i); + const std::uint8_t di = static_cast( + (static_cast(delta) >> i) & 1u); + detail::set_bit(b0, i, static_cast(r0 ^ di ^ c0)); + detail::set_bit(b1, i, static_cast(r1 ^ c1)); + const std::uint8_t rd0 = di ? r0 : 0; + const std::uint8_t rd1 = di ? r1 : 0; + const std::uint8_t dc0 = di ? c0 : 0; + const std::uint8_t dc1 = di ? c1 : 0; + auto rc = and_pair(r0, r1, c0, c1); + c0 = static_cast(rd0 ^ dc0 ^ rc.first); + c1 = static_cast(rd1 ^ dc1 ^ rc.second); + } + return {std::move(b0), std::move(b1)}; +} + +/// @brief Unsigned compare of XOR bit-shares. The predicate stays shared. +HEDLEY_WARN_UNUSED_RESULT +inline std::pair gt_bits_pair( + const std::vector & x0, const std::vector & x1, + const std::vector & y0, const std::vector & y1, + unsigned n) +{ + std::uint8_t gt0 = 0; + std::uint8_t gt1 = 0; + std::uint8_t eq0 = 1; + std::uint8_t eq1 = 0; + for (unsigned k = n; k-- > 0; ) + { + const std::uint8_t xb0 = detail::get_bit(x0, k); + const std::uint8_t xb1 = detail::get_bit(x1, k); + const std::uint8_t yb0 = detail::get_bit(y0, k); + const std::uint8_t yb1 = detail::get_bit(y1, k); + auto xny = and_pair(xb0, xb1, static_cast(yb0 ^ 1u), yb1); + auto bit = and_pair(xny.first, xny.second, eq0, eq1); + gt0 = static_cast(gt0 ^ bit.first); + gt1 = static_cast(gt1 ^ bit.second); + auto eq = and_pair(eq0, eq1, static_cast(xb0 ^ yb0 ^ 1u), + static_cast(xb1 ^ yb1)); + eq0 = eq.first; + eq1 = eq.second; + } + return {gt0, gt1}; +} + +inline std::uint64_t reconstruct_bits( + const std::vector & a, + const std::vector & b, unsigned ell) +{ + std::uint64_t v = 0; + for (unsigned i = 0; i < ell; ++i) + { + const std::uint8_t bit = static_cast( + detail::get_bit(a, i) ^ detail::get_bit(b, i)); + v |= (static_cast(bit) << i); + } + return v; +} + +/// @brief One party's B2A contribution after opening `mask = b ⊕ r` per bit. +template +HEDLEY_WARN_UNUSED_RESULT +Ring b2a_party_bit(std::uint8_t b_share, const ot::dabit & r, + std::uint8_t mask_open, unsigned party, unsigned shift) +{ + // b = r ⊕ mask. Arithmetic: r_arith + mask * (1 - 2*r_bit_as...) + // Standard: open c = b ⊕ r; then [b] = [r] + c - 2c[r] for arith r in {0,1}. + // With XOR r_bit matching r_arith: + // share = r.arith + (party==0 ? Ring{mask_open} : 0) + // - Ring{2} * Ring{mask_open} * Ring{r.bit} + // but r.bit is XOR-shared: use r.arith which equals the bit value shares. + Ring s = r.arith; + if (party == 0) + s = static_cast(s + Ring{mask_open}); + // Subtract 2 * mask * r: each party subtracts 2*mask*r.arith (additive r). + s = static_cast(s - static_cast(Ring{2} * Ring{mask_open} * r.arith)); + (void)b_share; + return static_cast(s << shift); +} + +/// @brief Two-party B2A: each uses its bit share + dabits; open mask = b⊕r. +template +HEDLEY_WARN_UNUSED_RESULT +std::pair b2a_pair(const std::vector & bits0, + const std::vector & bits1, unsigned ell, + ot::pack & pack0, ot::pack & pack1) +{ + if (pack0.remaining_b2a() < ell || pack1.remaining_b2a() < ell) + throw std::runtime_error("b2a_pair: need dabits"); + Ring s0{}, s1{}; + for (unsigned i = 0; i < ell; ++i) + { + auto d0 = pack0.take_dabit(); + auto d1 = pack1.take_dabit(); + const std::uint8_t b0 = detail::get_bit(bits0, i); + const std::uint8_t b1 = detail::get_bit(bits1, i); + const std::uint8_t mask = static_cast( + (b0 ^ d0.bit) ^ (b1 ^ d1.bit)); + s0 = static_cast(s0 + b2a_party_bit(b0, d0, mask, 0, i)); + s1 = static_cast(s1 + b2a_party_bit(b1, d1, mask, 1, i)); + } + return {s0, s1}; +} + +/// @brief Oracle expected value (not a party protocol). +template +HEDLEY_WARN_UNUSED_RESULT +Ring b2a_clear(const std::vector & bits0, + const std::vector & bits1, unsigned ell) +{ + return static_cast(reconstruct_bits(bits0, bits1, ell)); +} + +} // namespace edabit +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_EDABIT_HPP__ diff --git a/include/dpf/eval_full.hpp b/include/dpf/eval_full.hpp index e5b785d..7d97510 100644 --- a/include/dpf/eval_full.hpp +++ b/include/dpf/eval_full.hpp @@ -2,6 +2,8 @@ /// @brief Evaluate every input in the DPF domain. /// @details Equivalent to `eval_interval` from /// `std::numeric_limits::min()` through `max()`. +/// When the input offset is not yet assigned, use `defer_eval_full` +/// (full-domain identity eval plus a deferred rotation view). /// @snippet evaluation/eval_full.cpp eval-full /// @author Ryan Henry /// @author Christopher Jiang @@ -27,6 +29,7 @@ #include "dpf/interval_memoizer.hpp" #include "dpf/rotation_iterable.hpp" #include "dpf/subinterval_iterable.hpp" +#include "dpf/verifiable.hpp" namespace dpf { @@ -41,7 +44,8 @@ template , bool> = false> auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs, - IntervalMemoizer && memoizer, std::index_sequence) + IntervalMemoizer && memoizer, std::index_sequence, + proof_token * pi = nullptr) { using dpf_type = DpfKey; using input_type = typename dpf_type::input_type; @@ -50,7 +54,7 @@ auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs, dpf::internal::eval_interval_impl(dpf, std::numeric_limits::min(), std::numeric_limits::max(), - outbufs, memoizer, std::make_index_sequence()); + outbufs, memoizer, std::make_index_sequence(), pi); return utils::make_tuple(dpf::rotation_iterable(std::begin(utils::get(outbufs)), std::end(utils::get(outbufs)), offset)...); } @@ -62,7 +66,8 @@ template , bool> = false> auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs, - IntervalMemoizer && memoizer, std::index_sequence) + IntervalMemoizer && memoizer, std::index_sequence, + proof_token * pi = nullptr) { using dpf_type = DpfKey; using input_type = typename dpf_type::input_type; @@ -70,7 +75,7 @@ auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs, dpf::internal::eval_interval_impl(dpf, std::numeric_limits::min(), std::numeric_limits::max(), - outbufs, memoizer, std::make_index_sequence()); + outbufs, memoizer, std::make_index_sequence(), pi); return utils::make_tuple( subinterval_iterable(std::begin(utils::get(outbufs)), @@ -83,6 +88,7 @@ auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs, } // namespace internal +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). template && !is_multilevel_key_v, bool> = true> HEDLEY_ALWAYS_INLINE auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs, - IntervalMemoizer && memoizer) + IntervalMemoizer && memoizer, proof_token * pi = nullptr) { assert_not_wildcard_output(dpf); - return internal::eval_full(dpf, outbufs, memoizer, std::make_index_sequence<1+sizeof...(Is)>()); + return internal::eval_full(dpf, outbufs, memoizer, + std::make_index_sequence<1+sizeof...(Is)>(), pi); } +/// @brief Evaluate the whole domain and fold a once-per-BFS-node VDPF proof. +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). +template && !is_multilevel_key_v, bool> = true> +HEDLEY_ALWAYS_INLINE +auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs, + IntervalMemoizer && memoizer, prove_ref pr) +{ + static_assert(DpfKey::is_verifiable, + "eval_full(..., prove(π)): key must carry dpf::verifiable"); + detail::vdpf::init_proof(pr.token, dpf); + auto out = eval_full(dpf, std::forward(outbufs), + std::forward(memoizer), &pr.token); + detail::vdpf::fold_output_binding(pr.token, dpf); + return out; +} + +/// @brief Evaluate the whole domain and fold each written output into a sketch. +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). +template && !is_multilevel_key_v, bool> = true> +HEDLEY_ALWAYS_INLINE +auto eval_full(const DpfKey & dpf, OutputBuffers && outbufs, + IntervalMemoizer && memoizer, sketch_ref & sk) +{ + static_assert(DpfKey::is_extractable, + "eval_full(..., sketch(σ)): key must carry dpf::extractable"); + auto ret = eval_full(dpf, outbufs, + std::forward(memoizer)); + if constexpr (sizeof...(Is) == 0) + { + for (std::size_t k = 0; k < utils::size(outbufs); ++k) + sk.absorb(outbufs[k]); + } + return ret; +} + +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). template (dpf, outbufs, - dpf::make_basic_full_memoizer(dpf)); + // The full-domain workspace is keyed only by the key type. Reusing it + // drops a heap allocation per call and lets a repeated key skip the + // interior rebuild (assign_interval keeps the last level). + thread_local auto memo = dpf::make_basic_full_memoizer(); + return eval_full(dpf, outbufs, memo); } +/// @brief Evaluate the whole domain into `outbufs` and fold a VDPF proof. +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). +template && !is_multilevel_key_v, bool> = true, + std::enable_if_t>, + std::decay_t>, bool> = true> +HEDLEY_ALWAYS_INLINE +auto eval_full(const DpfKey & dpf, OutputBuffers & outbufs, prove_ref pr) // NOLINT(runtime/references) +{ + static_assert(DpfKey::is_verifiable, + "eval_full(..., prove(π)): key must carry dpf::verifiable"); + return eval_full(dpf, outbufs, + dpf::make_basic_full_memoizer(dpf), pr); +} + +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). template (dpf, dpf::make_basic_full_memoizer(dpf)); } +/// @brief Full-domain deferred eval while the input offset is unset. +/// @details Sugar for `defer_eval_interval` over `[min, max]`. `outbufs` must +/// be full-domain sized. After assign, `.get()` yields the logical +/// full-domain view (same values as eager `eval_full` after assign). +template + && !is_multilevel_key_v, bool> = true> +auto defer_eval_full(const DpfKey & dpf, OutputBuffers & outbufs, + IntervalMemoizer && memoizer) // NOLINT(runtime/references) +{ + using input_type = typename DpfKey::input_type; + return defer_eval_interval(dpf, + std::numeric_limits::min(), + std::numeric_limits::max(), + outbufs, std::forward(memoizer)); +} + +/// @brief `defer_eval_full` with a basic full-domain memoizer. +template + && !is_multilevel_key_v, bool> = true, + std::enable_if_t>, + std::decay_t>, bool> = true> +auto defer_eval_full(const DpfKey & dpf, OutputBuffers & outbufs) // NOLINT(runtime/references) +{ + return defer_eval_full(dpf, outbufs, + dpf::make_basic_full_memoizer(dpf)); +} + } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_EVAL_FULL_HPP__ diff --git a/include/dpf/eval_inner_product.hpp b/include/dpf/eval_inner_product.hpp index 0f61226..110df9c 100644 --- a/include/dpf/eval_inner_product.hpp +++ b/include/dpf/eval_inner_product.hpp @@ -1,16 +1,42 @@ /// @file dpf/eval_inner_product.hpp -/// @brief Full / interval DPF evaluation that reduces against a public -/// weight vector instead of materializing the output. -/// @details Same interior + batched exterior AES as `eval_interval`, but -/// each packed leaf is multiply-accumulated into a scalar: -/// additive outputs sum `DPF(x) * w[x]`, XOR outputs xor -/// `DPF(x) & w[x]`. A prepared memoizer skips the interior walk -/// so the tree can be expanded before the weights exist. +/// @brief Full / interval / sequence DPF evaluation that reduces against a +/// public vector instead of materializing the output. +/// @details Three local forms share the same interval / sequence domains: +/// - **Batched leaf walk** (no tag): one output, weights in +/// `eval_interval` layout, exterior AES batched like that walk, +/// O(1) accumulator. Cost shape matches `eval_interval` on the +/// same range (Θ(L) nodes) plus a multiply-add per packed slot. +/// - **`dpf::paired`** (row-wise): one row of the weight vector per +/// input. A row is a scalar (one output) or a `tuple` / `array` +/// zipped with several outputs — leaf slots or an ancestor prefix +/// plus the leaf — read off one path. Products use `operator*`; +/// they are summed with `operator+`. Same walk cost as the point +/// list, plus O(1) arithmetic per selected output per input. +/// - **`dpf::columns`** (transposed / column-wise): one output, +/// several weight streams, one accumulator per stream, one walk. +/// Products are *not* summed across streams. A stream is anything +/// with `w[i]` or `w(i)`. `dpf::project` maps the share before the +/// multiply; `dpf::also` sees the unmapped share. Cost is one path +/// walk plus O(stream count) arithmetic per input. +/// +/// A single-stream `columns` result matches `paired` on that stream; +/// a single-output batched leaf walk matches `paired` when the +/// interval is leaf-aligned (covering-leaf weights equal the clipped +/// domain points). Unaligned intervals still weight every lane of the +/// covering leaves — same layout as one-key `eval_interval` buffers / +/// cohort interval inner products, not the clipped iterable. A sized +/// weight container shorter than that covering span throws +/// `std::invalid_argument`. `paired` and `columns` throw the same way +/// when a sized stream is shorter than the point list or the clipped +/// interval. #ifndef LIBDPF_INCLUDE_DPF_EVAL_INNER_PRODUCT_HPP__ #define LIBDPF_INCLUDE_DPF_EVAL_INNER_PRODUCT_HPP__ +#include #include +#include +#include #include #include #include @@ -25,8 +51,11 @@ #include "dpf/dpf_key.hpp" #include "dpf/eval_interval.hpp" +#include "dpf/eval_sequence.hpp" #include "dpf/eval_target.hpp" +#include "dpf/incremental.hpp" #include "dpf/leaf_node.hpp" +#include "dpf/path_memoizer.hpp" #include "dpf/twiddle.hpp" #include "dpf/utils.hpp" #include "dpf/xor_wrapper.hpp" @@ -34,6 +63,36 @@ namespace dpf { +namespace detail_ip_check +{ + +template +struct has_container_size : std::false_type +{ +}; + +template +struct has_container_size()))>> + : std::true_type +{ +}; + +/// @brief Throw when a sized weight container is shorter than the walk. +/// Unsizable weights (`w(i)` callables, raw pointers) are left to +/// the caller. +template +void require_weight_count(const W & w, std::size_t need, const char * what) +{ + if constexpr (has_container_size>::value) + { + if (static_cast(std::size(w)) < need) + throw std::invalid_argument(what); + } +} + +} // namespace detail_ip_check + namespace internal { @@ -220,6 +279,25 @@ void eval_inner_product_exterior(const DpfKey & dpf, IntegralT from_node, auto *nodes = memoizer[DpfKey::depth]; auto cws = std::make_tuple(std::get(dpf.leaf_nodes).get()...); + if constexpr (DpfKey::is_extractable) + { + std::size_t j = 0, k = start; + for (; j < nodes_in_interval; ++j, ++k) + { + auto apply_output = [&](auto out_index, auto buf_index) + { + constexpr std::size_t out_i = decltype(out_index)::value; + constexpr std::size_t buf_i = decltype(buf_index)::value; + auto leaf = dpf.template traverse_exterior(nodes[j]); + std::get(accs).mac(leaf, k * opl, opl, + utils::get(weights)); + }; + (apply_output(std::integral_constant{}, + std::integral_constant{}), ...); + } + return; + } + HEDLEY_PRAGMA(GCC diagnostic push) HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") auto apply_masks = [&](std::size_t k, const node_type & node, @@ -274,12 +352,15 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") { alignas(node_type) node_type seeds[8]; alignas(node_type) node_type masks[8]; + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Warray-bounds") DPF_UNROLL_LOOP for (std::size_t t = 0; t < 8; ++t) { seeds[t] = utils::to_exterior_node( unset_lo_2bits(nodes[j + t])); } + HEDLEY_PRAGMA(GCC diagnostic pop) DpfKey::exterior_prg::eval_x8(seeds, masks, pos); DPF_UNROLL_LOOP for (std::size_t t = 0; t < 8; ++t) @@ -374,6 +455,17 @@ auto eval_inner_product_impl(const DpfKey & dpf, InputT from, InputT to, utils::bitlength_of_v); auto segs = utils::split_leaf_nodes(from_node, to_node, dpf.depth, wraps); + constexpr std::size_t opl = DpfKey::outputs_per_leaf; + const std::size_t lanes = segs.total * opl; + auto check_one = [&](auto which) + { + constexpr std::size_t wi = decltype(which)::value; + detail_ip_check::require_weight_count( + utils::get(weights), lanes, + "inner product weights are shorter than the covering leaves"); + }; + (check_one(std::integral_constant{}), ...); + auto accs = std::make_tuple( ip_accum>{}...); auto idxs = std::index_sequence{}; @@ -436,10 +528,11 @@ void eval_prepare_full(const DpfKey & dpf, IntervalMemoizer && memoizer) } /// @brief `sum_x DPF_I(x) * w[x]` (additive) or `xor_x DPF_I(x) & w[x]` (XOR). -/// @details `w[j]` is the weight for the `j`-th output in the interval, matching -/// `eval_interval`'s destination layout. Multiple `Is` take a tuple of -/// weight ranges and return a tuple of accumulators; a single `I` takes -/// one range and returns one accumulator. +/// @details `w[j]` is the weight for the `j`-th lane of the *covering* leaves +/// of `[from, to]`, matching `eval_interval`'s destination buffer (not the +/// clipped iterable). Multiple `Is` take a tuple of weight ranges and return +/// a tuple of accumulators; a single `I` takes one range and returns one +/// accumulator. /// @tparam I output index /// @tparam Is is /// @tparam DpfKey DPF key type @@ -453,6 +546,7 @@ void eval_prepare_full(const DpfKey & dpf, IntervalMemoizer && memoizer) /// @param weights the weights /// @param memoizer the memoizer built for this key /// @return `sum_x DPF_I(x) * w[x]` (additive) or `xor_x DPF_I(x) & w[x]` (XOR) +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. template && !is_multilevel_key_v, bool> = true> HEDLEY_ALWAYS_INLINE +HEDLEY_WARN_UNUSED_RESULT auto eval_inner_product(const DpfKey & dpf, InputT from, InputT to, Weights && weights, IntervalMemoizer && memoizer) { @@ -471,6 +566,51 @@ auto eval_inner_product(const DpfKey & dpf, InputT from, InputT to, weights, memoizer, std::make_index_sequence<1 + sizeof...(Is)>{}); } +/// @brief Inner product with a VDPF path proof over the same interval nodes. +/// @details Folds once per BFS node (same transcript as `prove_interval`), then +/// evaluates. Weights are not mixed into the token. +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. +template + && !is_multilevel_key_v, bool> = true> +HEDLEY_ALWAYS_INLINE +HEDLEY_WARN_UNUSED_RESULT +auto eval_inner_product(const DpfKey & dpf, InputT from, InputT to, + Weights && weights, IntervalMemoizer && memoizer, prove_ref pr) +{ + static_assert(DpfKey::is_verifiable, + "eval_inner_product(..., prove(π)): key must carry dpf::verifiable"); + detail::vdpf::init_proof(pr.token, dpf); + prove_fold_interval(dpf, from, to, pr.token); + detail::vdpf::fold_output_binding(pr.token, dpf); + return eval_inner_product(dpf, from, to, + std::forward(weights), + std::forward(memoizer)); +} + +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. +template + && !is_multilevel_key_v, bool> = true> +HEDLEY_ALWAYS_INLINE +HEDLEY_WARN_UNUSED_RESULT +auto eval_inner_product(const DpfKey & dpf, InputT from, InputT to, + Weights && weights, prove_ref pr) +{ + return eval_inner_product(dpf, from, to, + std::forward(weights), + dpf::make_basic_interval_memoizer(dpf, from, to), pr); +} + template && !is_multilevel_key_v, bool> = true> HEDLEY_ALWAYS_INLINE +HEDLEY_WARN_UNUSED_RESULT auto eval_full_inner_product(const DpfKey & dpf, Weights && weights, IntervalMemoizer && memoizer) { @@ -489,6 +630,700 @@ auto eval_full_inner_product(const DpfKey & dpf, Weights && weights, weights, memoizer); } +/// @brief Tag: row-wise zip of several DPF outputs with each weight element. +struct paired_t +{ +}; + +inline constexpr paired_t paired{}; + +/// @brief Tag: transposed walk — one output, several weight streams kept apart. +/// @details Unlike `paired`, products are not summed across streams. +struct columns_t +{ +}; + +inline constexpr columns_t columns{}; + +/// @brief Map a leaf share before it is multiplied by column weights. +template +struct project_fn +{ + F fn; +}; + +/// @brief Wrap `fn` as the column projector. `fn` is called as `fn(share)`. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_WARN_UNUSED_RESULT +project_fn> project(F && fn) +{ + return project_fn>{std::forward(fn)}; +} + +/// @brief Observe each unmapped share during a `columns` walk. +template +struct also_fn +{ + F fn; +}; + +/// @brief Wrap `fn` as a `columns` side visit. +/// @details `fn` is called as `fn(i, x, share)`: list index, domain point, +/// then the share `project` has not seen. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_WARN_UNUSED_RESULT +also_fn> also(F && fn) +{ + return also_fn>{std::forward(fn)}; +} + +/// @brief Column projector that returns the share unchanged. +struct identity_project +{ + template + HEDLEY_ALWAYS_INLINE + constexpr T operator()(T value) const + { + return value; + } +}; + +/// @brief Column side visit that ignores its arguments. +struct noop_also +{ + template + HEDLEY_ALWAYS_INLINE + void operator()(A && ...) const noexcept + { + } +}; + +namespace detail_ip +{ + +template +struct has_public_addends : std::false_type +{ +}; + +template +struct has_public_addends().public_addends)>> + : std::true_type +{ +}; + +template +struct is_std_array : std::false_type +{ +}; + +template +struct is_std_array> : std::true_type +{ +}; + +/// @brief Component `K` of a row. A scalar row pairs with output 0 only. +template +HEDLEY_ALWAYS_INLINE +decltype(auto) component(Row && row) +{ + using R = std::decay_t; + if constexpr (utils::is_tuple_v || is_std_array::value) + return std::get(std::forward(row)); + else + { + static_assert(K == 0, + "a scalar weight pairs with one DPF output; use a tuple or " + "std::array row for several outputs"); + return std::forward(row); + } +} + +template +HEDLEY_ALWAYS_INLINE +auto share_at(const Key & key, const typename Key::input_type & tx, + const typename Key::interior_node & node) +{ + constexpr auto bits = utils::bitlength_of_v; + constexpr auto prefix = Key::meta[I].prefix == 0 + ? bits : Key::meta[I].prefix; + auto lane = detail::incr::lane_input(tx, prefix, bits); + auto leaf = key.template traverse_exterior(node); + if constexpr (has_public_addends::value) + detail::incr::absorb_public_addend_lane(key, leaf, lane); + using output_type = typename Key::template concrete_output_type; + return *make_eval_dpf_output(leaf, lane); +} + +template +HEDLEY_ALWAYS_INLINE +void mac_row(const Key & key, const Tx & tx, Path & path, Row && row, + Acc & acc, std::index_sequence) +{ + // One exterior expansion per output per leaf/ancestor bucket. Sequential + // and sorted queries reuse the node already on the path. + ((acc = acc + (share_at(key, tx, path[Key::meta[Outs].tree_level]) + * component(row))), ...); +} + +template +void accumulate_points(const Key & key, Point first, Point last, Rows && rows, + Acc & acc) +{ + constexpr std::size_t nout = sizeof...(Outs); + constexpr std::size_t deepest = std::max({std::size_t{0}, + Key::meta[Outs].tree_level...}); + auto path = make_basic_path_memoizer(); + std::size_t i = 0; + for (auto it = first; it != last; ++it, ++i) + { + auto tx = key.offset_x(*it); + utils::flip_msb_if_signed_integral(tx); + detail::ensure_level(key, tx, path, deepest); + mac_row(key, tx, path, rows[i], acc, + std::make_index_sequence{}); + } +} + +template +struct pack_first +{ + static constexpr std::size_t value = I0; +}; + +template +auto accum_type_from(const Key &, Rows && rows) +{ + using row_type = std::decay_t; + using y0 = decltype(share_at::value>( + std::declval(), + std::declval(), + std::declval())); + using w0 = std::decay_t(std::declval()))>; + using acc_type = decltype(std::declval() * std::declval()); + return acc_type{}; +} + +/// @brief `w[i]` when `w` is a range, otherwise `w(i)`. +template +HEDLEY_ALWAYS_INLINE +decltype(auto) weight_at(W && w, std::size_t i) +{ + if constexpr (std::is_invocable_v) + return w(i); + else + return w[i]; +} + +template +struct is_column_pack : std::false_type +{ +}; + +template +struct is_column_pack> : std::true_type +{ +}; + +template +struct is_column_pack> : std::true_type +{ +}; + +template +auto column_accum_type() +{ + using share_type = decltype(share_at( + std::declval(), + std::declval(), + std::declval())); + using mapped = decltype(std::declval()(std::declval())); + using weight = decltype(weight_at( + std::get(std::declval()), std::size_t{0})); + using acc_type = decltype(std::declval() * std::declval()); + return acc_type{}; +} + +template +auto accumulate_columns(const Key & key, Point first, Point last, + Weights && weights, Proj && proj, Sink && sink, + std::index_sequence) +{ + static_assert(sizeof...(Ks) > 0, "columns needs at least one weight stream"); + using acc_tuple = std::tuple, std::decay_t>())...>; + acc_tuple acc{}; + if constexpr (std::is_base_of_v::iterator_category>) + { + const auto n = static_cast(std::distance(first, last)); + auto guard = [&](auto which) + { + constexpr std::size_t k = decltype(which)::value; + detail_ip_check::require_weight_count(std::get(weights), n, + "column weights are shorter than the point list"); + }; + (guard(std::integral_constant{}), ...); + } + constexpr std::size_t deepest = Key::meta[Out].tree_level; + auto path = make_basic_path_memoizer(); + std::size_t i = 0; + for (auto it = first; it != last; ++it, ++i) + { + auto tx = key.offset_x(*it); + utils::flip_msb_if_signed_integral(tx); + detail::ensure_level(key, tx, path, deepest); + auto share = share_at(key, tx, path[Key::meta[Out].tree_level]); + sink(i, *it, share); + auto y = proj(share); + ((std::get(acc) = std::get(acc) + + (y * weight_at(std::get(weights), i))), ...); + } + return acc; +} + +} // namespace detail_ip + +namespace internal_paired +{ + +template +void for_inclusive(Input from, Input to, Fn && fn) +{ + constexpr auto to_int = utils::to_integral_type{}; + using integral = decltype(to_int(from)); + const bool wraps = utils::interval_wraps( + static_cast(to_int(from)), + static_cast(to_int(to)), + utils::bitlength_of_v); + auto step = [&](Input x) { fn(x); }; + if (!wraps) + { + for (auto x = from;; ++x) + { + step(x); + if (x == to) + break; + } + return; + } + const auto hi = std::numeric_limits::max(); + const auto lo = std::numeric_limits::min(); + for (auto x = from;; ++x) + { + step(x); + if (x == hi) + break; + } + for (auto x = lo;; ++x) + { + step(x); + if (x == to) + break; + } +} + +template +auto run_points(const Key & key, const std::vector & xs, + Rows && rows) +{ + assert_not_wildcard_output(key); + if (xs.size() == 0) + { + using acc_type = decltype(detail_ip::accum_type_from(key, rows)); + return acc_type{}; + } + detail_ip_check::require_weight_count(rows, xs.size(), + "paired weights are shorter than the point list"); + using acc_type = decltype(detail_ip::accum_type_from(key, rows)); + acc_type acc{}; + detail_ip::accumulate_points(key, xs.begin(), xs.end(), rows, acc); + return acc; +} + +/// @brief Clipped interval dot via the interval tree, not one path per point. +/// Wrapping intervals stay on the path walk. +template +auto interval_scalar(const DpfKey & dpf, InputT from, InputT to, Rows && rows) +{ + constexpr auto to_int = utils::to_integral_type{}; + using integral = decltype(to_int(from)); + const bool wraps = utils::interval_wraps( + static_cast(to_int(from)), + static_cast(to_int(to)), + utils::bitlength_of_v); + if (wraps) + { + std::vector xs; + for_inclusive(from, to, [&](InputT x) { xs.push_back(x); }); + return run_points(dpf, xs, std::forward(rows)); + } + const auto npoints = static_cast( + static_cast(to_int(to)) - static_cast(to_int(from))) + + std::size_t{1}; + detail_ip_check::require_weight_count(rows, npoints, + "paired weights are shorter than the interval"); + auto buf = make_output_buffer_for_interval(dpf, from, to); + auto iter = eval_interval(dpf, from, to, buf); + using share_t = std::decay_t; + using weight_t = std::decay_t; + using acc_t = decltype(std::declval() * std::declval()); + acc_t acc{}; + std::size_t i = 0; + for (auto it = iter.begin(); it != iter.end(); ++it, ++i) + acc = acc + (*it * rows[i]); + return acc; +} + +} // namespace internal_paired + +/// @brief `sum_i Σ_k DPF_{out_k}(x_i) * row_i[k]` over `[from, to]`. +/// @details One row of `rows` per input, in interval order (wrapping the same +/// way as `eval_interval`). A row is a scalar when one output is +/// selected, or a `std::tuple` / `std::array` with one component per +/// output. Ancestor slots and leaf slots are read off the same path. +/// Differs from the batched leaf walk: one path step per domain point +/// (reuse via the path memoizer), not batched exterior AES over leaf +/// nodes. For a single output the opened result matches the batched +/// form when `rows` is the interval weight vector. +/// \complexity One path ensure per input up to the deepest selected output, +/// plus one exterior expand and multiply-add per selected output per +/// input. Accumulator is O(1); no output buffer. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_inner_product(paired_t, const DpfKey & dpf, InputT from, InputT to, + Rows && rows) +{ + using row_t = std::decay_t()[std::size_t{0}])>; + constexpr bool scalar = !utils::is_tuple_v + && !detail_ip::is_std_array::value; + if constexpr (scalar && sizeof...(Is) == 0 && !is_multilevel_key_v) + { + return internal_paired::interval_scalar(dpf, from, to, + std::forward(rows)); + } + else + { + std::vector xs; + internal_paired::for_inclusive(from, to, [&](InputT x) { xs.push_back(x); }); + return internal_paired::run_points(dpf, xs, + std::forward(rows)); + } +} + +/// @brief Paired inner product over the whole input domain. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_full_inner_product(paired_t, const DpfKey & dpf, Rows && rows) +{ + using input_type = typename DpfKey::input_type; + return eval_inner_product(paired, dpf, + std::numeric_limits::min(), + std::numeric_limits::max(), + std::forward(rows)); +} + +/// @brief Paired inner product over a sorted point list. +/// @details Same order and sortedness rule as `eval_sequence`. Each point +/// pairs with `rows[i]`. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_sequence_inner_product(const DpfKey & dpf, ForwardIterator begin, + ForwardIterator end, Rows && rows) +{ + if (!std::is_sorted(begin, end)) + throw std::runtime_error("list must be sorted"); + std::vector xs(begin, end); + return internal_paired::run_points(dpf, xs, + std::forward(rows)); +} + +/// @brief Paired inner product over a `sequence_recipe`'s points. +/// @details `points` is the same sorted list the recipe was built from. The +/// recipe drives nothing the path walk does not already share; it +/// checks that the list still matches the recipe's output count. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_sequence_inner_product(const DpfKey & dpf, + const sequence_recipe & recipe, ForwardIterator begin, ForwardIterator end, + Rows && rows) +{ + const auto n = static_cast(std::distance(begin, end)); + if (n != recipe.output_indices().size()) + throw std::invalid_argument( + "eval_sequence_inner_product: recipe and point list differ"); + return eval_sequence_inner_product(dpf, begin, end, + std::forward(rows)); +} + +namespace detail_columns +{ + +template +HEDLEY_WARN_UNUSED_RESULT +auto run(const DpfKey & dpf, ForwardIterator begin, ForwardIterator end, + Weights && weights, Proj && proj, Sink && sink, bool require_sorted) +{ + using pack = std::decay_t; + static_assert(detail_ip::is_column_pack::value, + "columns weights are a std::tuple or std::array of streams; " + "each stream is w[i] or w(i)"); + if (require_sorted && !std::is_sorted(begin, end)) + throw std::runtime_error("list must be sorted"); + std::vector xs(begin, end); + constexpr auto n = std::tuple_size::value; + return detail_ip::accumulate_columns(dpf, xs.begin(), xs.end(), + std::forward(weights), std::forward(proj), + std::forward(sink), std::make_index_sequence{}); +} + +template +auto interval_dots(const DpfKey & dpf, InputT from, InputT to, Weights && weights, + std::index_sequence) +{ + constexpr auto to_int = utils::to_integral_type{}; + using integral = decltype(to_int(from)); + const bool wraps = utils::interval_wraps( + static_cast(to_int(from)), + static_cast(to_int(to)), + utils::bitlength_of_v); + if (wraps) + { + std::vector xs; + internal_paired::for_inclusive(from, to, [&](InputT x) { xs.push_back(x); }); + return detail_ip::accumulate_columns(dpf, xs.begin(), xs.end(), + std::forward(weights), identity_project{}, + noop_also{}, std::index_sequence{}); + } + const auto npoints = static_cast( + static_cast(to_int(to)) - static_cast(to_int(from))) + + std::size_t{1}; + auto guard = [&](auto which) + { + constexpr std::size_t k = decltype(which)::value; + detail_ip_check::require_weight_count(std::get(weights), npoints, + "column weights are shorter than the interval"); + }; + (guard(std::integral_constant{}), ...); + auto buf = make_output_buffer_for_interval(dpf, from, to); + auto iter = eval_interval(dpf, from, to, buf); + using acc_tuple = std::tuple, identity_project>())...>; + acc_tuple acc{}; + std::size_t i = 0; + for (auto it = iter.begin(); it != iter.end(); ++it, ++i) + { + auto y = *it; + ((std::get(acc) = std::get(acc) + + (y * detail_ip::weight_at(std::get(weights), i))), ...); + } + return acc; +} + +} // namespace detail_columns + +/// @brief Several independent dots of one output, one walk (transposed form). +/// @details `weights` is a `std::tuple` or `std::array` of streams. Stream +/// `k` is either `w[i]` or `w(i)`, `i` the position in the point +/// list (or in the interval, wrapping the same way as +/// `eval_interval`). The result is a tuple of accumulators, +/// `acc_k = sum_i project(DPF(x_i)) * stream_k(i)`. +/// `dpf::project(fn)` maps the share first. `dpf::also(fn)` is +/// called as `fn(i, x, share)` on the unmapped share. Pass either +/// tag, both, or neither. `also` then `project` is accepted too. +/// Sequence points are sorted nondecreasing, same as `eval_sequence`. +/// Relative to `paired`: same path walk for one output, but streams +/// stay separate (no cross-stream sum). One stream equals `paired` +/// on that stream. Relative to the batched leaf walk: path-per-point +/// instead of batched exterior AES; same opened scalar when the +/// single stream matches the interval weight layout. +/// \complexity One path ensure and one exterior expand per input, plus +/// O(stream count) multiply-adds per input. Accumulators are O(stream count). +/// @{ + +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_sequence_inner_product(columns_t, const DpfKey & dpf, + ForwardIterator begin, ForwardIterator end, Weights && weights) +{ + assert_not_wildcard_output(dpf); + return detail_columns::run(dpf, begin, end, + std::forward(weights), identity_project{}, noop_also{}, true); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_sequence_inner_product(columns_t, const DpfKey & dpf, + ForwardIterator begin, ForwardIterator end, Weights && weights, + project_fn proj) +{ + assert_not_wildcard_output(dpf); + return detail_columns::run(dpf, begin, end, + std::forward(weights), proj.fn, noop_also{}, true); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_sequence_inner_product(columns_t, const DpfKey & dpf, + ForwardIterator begin, ForwardIterator end, Weights && weights, + also_fn sink) +{ + assert_not_wildcard_output(dpf); + return detail_columns::run(dpf, begin, end, + std::forward(weights), identity_project{}, sink.fn, true); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_sequence_inner_product(columns_t, const DpfKey & dpf, + ForwardIterator begin, ForwardIterator end, Weights && weights, + project_fn proj, also_fn sink) +{ + assert_not_wildcard_output(dpf); + return detail_columns::run(dpf, begin, end, + std::forward(weights), proj.fn, sink.fn, true); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_sequence_inner_product(columns_t, const DpfKey & dpf, + ForwardIterator begin, ForwardIterator end, Weights && weights, + also_fn sink, project_fn proj) +{ + return eval_sequence_inner_product(columns, dpf, begin, end, + std::forward(weights), std::move(proj), std::move(sink)); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_sequence_inner_product(columns_t, const DpfKey & dpf, + const sequence_recipe & recipe, ForwardIterator begin, + ForwardIterator end, Weights && weights, Extra && ... extra) +{ + const auto n = static_cast(std::distance(begin, end)); + if (n != recipe.output_indices().size()) + throw std::invalid_argument( + "eval_sequence_inner_product: recipe and point list differ"); + return eval_sequence_inner_product(columns, dpf, begin, end, + std::forward(weights), std::forward(extra)...); +} + +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_inner_product(columns_t, const DpfKey & dpf, InputT from, InputT to, + Weights && weights, Proj && proj, Sink && sink) +{ + assert_not_wildcard_output(dpf); + if constexpr (std::is_same_v, identity_project> + && std::is_same_v, noop_also> + && !is_multilevel_key_v) + { + using pack = std::decay_t; + static_assert(detail_ip::is_column_pack::value, + "columns weights are a std::tuple or std::array of streams; " + "each stream is w[i] or w(i)"); + constexpr auto nstreams = std::tuple_size::value; + return detail_columns::interval_dots(dpf, from, to, + std::forward(weights), std::make_index_sequence{}); + } + else + { + std::vector xs; + internal_paired::for_inclusive(from, to, [&](InputT x) { xs.push_back(x); }); + return detail_columns::run(dpf, xs.begin(), xs.end(), + std::forward(weights), std::forward(proj), + std::forward(sink), false); + } +} + +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_inner_product(columns_t, const DpfKey & dpf, InputT from, InputT to, + Weights && weights) +{ + return eval_inner_product(columns, dpf, from, to, + std::forward(weights), identity_project{}, noop_also{}); +} + +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_inner_product(columns_t, const DpfKey & dpf, InputT from, InputT to, + Weights && weights, project_fn proj) +{ + return eval_inner_product(columns, dpf, from, to, + std::forward(weights), proj.fn, noop_also{}); +} + +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_inner_product(columns_t, const DpfKey & dpf, InputT from, InputT to, + Weights && weights, also_fn sink) +{ + return eval_inner_product(columns, dpf, from, to, + std::forward(weights), identity_project{}, sink.fn); +} + +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_inner_product(columns_t, const DpfKey & dpf, InputT from, InputT to, + Weights && weights, project_fn proj, also_fn sink) +{ + return eval_inner_product(columns, dpf, from, to, + std::forward(weights), proj.fn, sink.fn); +} + +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_inner_product(columns_t, const DpfKey & dpf, InputT from, InputT to, + Weights && weights, also_fn sink, project_fn proj) +{ + return eval_inner_product(columns, dpf, from, to, + std::forward(weights), proj.fn, sink.fn); +} + +/// @brief `columns` over the whole input domain. Same streams as the interval form. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_full_inner_product(columns_t, const DpfKey & dpf, Weights && weights, + Extra && ... extra) +{ + using input_type = typename DpfKey::input_type; + return eval_inner_product(columns, dpf, + std::numeric_limits::min(), + std::numeric_limits::max(), + std::forward(weights), std::forward(extra)...); +} + +/// @} + } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_EVAL_INNER_PRODUCT_HPP__ diff --git a/include/dpf/eval_interval.hpp b/include/dpf/eval_interval.hpp index 634a4ac..f408eeb 100644 --- a/include/dpf/eval_interval.hpp +++ b/include/dpf/eval_interval.hpp @@ -4,6 +4,14 @@ /// share per input, in that order. Pass a named output buffer; /// this overload binds it as a non-const reference. An interval /// memoizer is optional and comes after the buffer. +/// +/// Eager evaluation requires an assigned input offset: the range is +/// traversed at `offset_x(from)..offset_x(to)`. When the input is +/// still a wildcard, call `defer_eval_interval` instead — that fills +/// a **full-domain** buffer at identity and returns a +/// `deferred_rotated_subinterval` that applies the rotation after +/// `assign_wildcard_input`. Interior-only prep with an assigned +/// input but unassigned leaf is `defer_traverse_interval`. /// @snippet evaluation/eval_interval.cpp eval-interval /// @author Ryan Henry /// @author Christopher Jiang @@ -20,6 +28,7 @@ #include #include +#include #include #include #include @@ -33,6 +42,9 @@ #include "dpf/output_buffer.hpp" #include "dpf/interval_memoizer.hpp" #include "dpf/subinterval_iterable.hpp" +#include "dpf/deferred_rotated_subinterval.hpp" +#include "dpf/verifiable.hpp" +#include "dpf/wildcard.hpp" namespace dpf { @@ -40,12 +52,35 @@ namespace dpf namespace internal { +/// @brief Fold every node at `level_index` of a truncated interval tree into `pi`. +/// @details Once-per-BFS-node absorption: node `i` has prefix +/// `(from_node >> (depth - level_index)) + i`. Matches the contiguous +/// layout built by `eval_interval_interior`. +template +HEDLEY_ALWAYS_INLINE +void fold_interval_level(proof_token & pi, const DpfKey & dpf, + std::size_t level_index, IntegralT from_node, std::size_t nodes_at_level, + const NodeT * curr) +{ + if constexpr (!DpfKey::is_verifiable) + return; + if (level_index == 0 || nodes_at_level == 0) + return; + const auto start = static_cast( + utils::shift_right(from_node, DpfKey::depth - level_index)); + const auto & cs = dpf.correction_seeds()[level_index - 1]; + for (std::size_t i = 0; i < nodes_at_level; ++i) + { + detail::vdpf::fold_node(pi, level_index - 1, start + i, curr[i], cs); + } +} + template inline auto eval_interval_interior(const DpfKey & dpf, IntegralT from_node, IntegralT to_node, IntervalMemoizer & memoizer, // NOLINT(runtime/references) - std::size_t to_level = DpfKey::depth) + std::size_t to_level = DpfKey::depth, proof_token * pi = nullptr) { using dpf_type = DpfKey; using integral_type = typename DpfKey::integral_type; @@ -54,6 +89,11 @@ inline auto eval_interval_interior(const DpfKey & dpf, IntegralT from_node, // level_index represents the current level being built // level_index = 0 => root // level_index = depth => last layer of interior nodes + // Proving needs every truncated-tree node: a warm memoizer that resumes + // past level 1 would skip upper folds (and basic memoizers discard them). + if (pi != nullptr) + memoizer.clear_assignment(); + std::size_t level_index = memoizer.assign_interval(dpf, from_node, to_node); std::size_t nodes_at_level = memoizer.get_nodes_at_level(); integral_type mask = utils::get_node_mask(dpf.msb_mask, level_index); @@ -115,6 +155,12 @@ inline auto eval_interval_interior(const DpfKey & dpf, IntegralT from_node, { curr[i] = dpf_type::traverse_interior(prev[j], cw[0], 0, is_last); } + + if (pi != nullptr) + { + fold_interval_level(*pi, dpf, level_index, from_node, + nodes_at_level, curr); + } } } @@ -136,23 +182,38 @@ inline auto eval_interval_exterior(const DpfKey & dpf, IntegralT from_node, std::size_t nodes_in_interval = static_cast(to_node - from_node); -HEDLEY_PRAGMA(GCC diagnostic push) -HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") - auto cw = std::get(dpf.leaf_nodes).get(); -HEDLEY_PRAGMA(GCC diagnostic pop) auto *nodes = memoizer[dpf_type::depth]; - DPF_UNROLL_LOOP - for (std::size_t j = 0, k = start; j < nodes_in_interval; ++j, ++k) + std::size_t j = 0, k = start; + constexpr bool batch_leaves = + dpf::block_length_of_leaf_v == 1 + && !utils::is_packed_subbyte_v + && dpf_type::outputs_per_leaf == 1; + if constexpr (batch_leaves) { - auto leaf = dpf.template traverse_exterior(nodes[j], - get_if_lo_bit(cw, nodes[j])); + using leaf_ret = decltype(dpf.template traverse_exterior(nodes[0])); + while (j + 8 <= nodes_in_interval) + { + leaf_ret leaves[8]; + dpf.template traverse_exterior_x8(nodes + j, leaves); + for (std::size_t t = 0; t < 8; ++t, ++k) + { + utils::raw_memcpy(&outbuf[k], &leaves[t], sizeof(output_type)); + } + j += 8; + } + } + for (; j < nodes_in_interval; ++j, ++k) + { + // 1-arg member works for classic and verifiable/incr keys; the static + // 2-arg form is classic-only. + auto leaf = dpf.template traverse_exterior(nodes[j]); if constexpr (utils::is_packed_subbyte_v) { store_leaf_bytes(outbuf, k, leaf); } else { - std::memcpy(&outbuf[k*dpf_type::outputs_per_leaf], &leaf, + utils::raw_memcpy(&outbuf[k*dpf_type::outputs_per_leaf], &leaf, sizeof(output_type) * dpf_type::outputs_per_leaf); } } @@ -174,7 +235,7 @@ void store_interval_leaf(OutputBuffer && outbuf, std::size_t k, const LeafT & le } else { - std::memcpy(&outbuf[k * dpf_type::outputs_per_leaf], &leaf, + utils::raw_memcpy(&outbuf[k * dpf_type::outputs_per_leaf], &leaf, sizeof(output_type) * dpf_type::outputs_per_leaf); } } @@ -273,12 +334,15 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") { alignas(node_type) node_type seeds[8]; alignas(node_type) node_type masks[8]; + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Warray-bounds") DPF_UNROLL_LOOP for (std::size_t t = 0; t < 8; ++t) { seeds[t] = utils::to_exterior_node( unset_lo_2bits(nodes[j + t])); } + HEDLEY_PRAGMA(GCC diagnostic pop) DpfKey::exterior_prg::eval_x8(seeds, masks, pos); DPF_UNROLL_LOOP for (std::size_t t = 0; t < 8; ++t) @@ -330,22 +394,28 @@ void eval_interval_exterior_all(const DpfKey & dpf, IntegralT from_node, IntegralT to_node, OutputBuffers && outbufs, IntervalMemoizer && memoizer, std::index_sequence idxs, std::size_t start = 0) { - using node_type = typename DpfKey::exterior_node; - using outputs_tuple = typename DpfKey::concrete_outputs_tuple; - HEDLEY_PRAGMA(GCC diagnostic push) - HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") - using range = leaf_prg_range; - HEDLEY_PRAGMA(GCC diagnostic pop) - if constexpr (range::is_contiguous) + // Fused exterior needs classic leaf packing (`concrete_outputs_tuple` + + // contiguous PRG lanes). Multi-level / cmp keys use the per-slot walk. + // Extractable keys stretch leaves with `extractable_leaf_prg` (leaf XOF), + // not `exterior_prg`. The fused path expands with AES and breaks the + // programmed packed leaf (cold opens still cancel; hot lanes do not). + if constexpr (!is_multilevel_key_v && !DpfKey::is_extractable) { - eval_interval_exterior_fused(dpf, from_node, to_node, outbufs, - memoizer, idxs, start); - } - else - { - (eval_interval_exterior(dpf, from_node, to_node, - utils::get(outbufs), memoizer, start), ...); + using node_type = typename DpfKey::exterior_node; + using outputs_tuple = typename DpfKey::concrete_outputs_tuple; + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + using range = leaf_prg_range; + HEDLEY_PRAGMA(GCC diagnostic pop) + if constexpr (range::is_contiguous) + { + eval_interval_exterior_fused(dpf, from_node, to_node, outbufs, + memoizer, idxs, start); + return; + } } + (eval_interval_exterior(dpf, from_node, to_node, + utils::get(outbufs), memoizer, start), ...); } template auto eval_interval_impl(const DpfKey & dpf, InputT from, InputT to, OutputBuffers && outbufs, IntervalMemoizer && memoizer, - std::index_sequence) + std::index_sequence, proof_token * pi = nullptr) { using dpf_type = DpfKey; using integral_type = typename DpfKey::integral_type; @@ -378,7 +448,8 @@ auto eval_interval_impl(const DpfKey & dpf, InputT from, InputT to, for (std::size_t s = 0; s < segs.n; ++s) { const auto & seg = segs.seg[s]; - internal::eval_interval_interior(dpf, seg.from_node, seg.to_node, memoizer); + internal::eval_interval_interior(dpf, seg.from_node, seg.to_node, memoizer, + DpfKey::depth, pi); eval_interval_exterior_all(dpf, seg.from_node, seg.to_node, outbufs, memoizer, idxs, start); start += seg.count; @@ -393,14 +464,15 @@ template auto eval_interval(const DpfKey & dpf, InputT from, InputT to, OutputBuffers && outbufs, IntervalMemoizer && memoizer, - std::index_sequence) + std::index_sequence, proof_token * pi = nullptr) { using dpf_type = DpfKey; constexpr auto mod_pow_2 = utils::mod_pow_2{}; constexpr auto to_integral_t = utils::to_integral_type{}; constexpr auto bits = utils::bitlength_of_v; - eval_interval_impl(dpf, from, to, outbufs, memoizer, std::make_index_sequence()); + eval_interval_impl(dpf, from, to, outbufs, memoizer, + std::make_index_sequence(), pi); // `to_integral_type` widens to at least `size_t`. Subtracting in that // wider type loses wrap-around of a narrower input domain (e.g. int16 @@ -439,7 +511,9 @@ auto eval_interval(const DpfKey & dpf, InputT from, InputT to, /// @param outbufs named buffer, or a tuple of buffers when several outputs /// are selected. Must outlive the returned iterable. /// @param memoizer workspace sized for at least this interval +/// @param pi proof token folded along the interval, or null /// @return an iterable over the written outputs +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. template && !is_multilevel_key_v, bool> = true> HEDLEY_ALWAYS_INLINE auto eval_interval(const DpfKey & dpf, InputT from, InputT to, - OutputBuffers & outbufs, IntervalMemoizer && memoizer) // NOLINT(runtime/references) + OutputBuffers & outbufs, IntervalMemoizer && memoizer, // NOLINT(runtime/references) + proof_token * pi = nullptr) { assert_not_wildcard_output(dpf); - return internal::eval_interval(dpf, dpf.offset_x(from), dpf.offset_x(to), outbufs, memoizer, std::make_index_sequence<1+sizeof...(Is)>()); + return internal::eval_interval(dpf, dpf.offset_x(from), dpf.offset_x(to), + outbufs, memoizer, std::make_index_sequence<1+sizeof...(Is)>(), pi); +} + +/// @brief Evaluate `[from, to]` and fold a once-per-BFS-node VDPF proof. +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. +template , + std::enable_if_t && !is_multilevel_key_v, bool> = true> +HEDLEY_ALWAYS_INLINE +auto eval_interval(const DpfKey & dpf, InputT from, InputT to, + OutputBuffers & outbufs, IntervalMemoizer && memoizer, prove_ref pr) // NOLINT(runtime/references) +{ + static_assert(DpfKey::is_verifiable, + "eval_interval(..., prove(π)): key must carry dpf::verifiable"); + detail::vdpf::init_proof(pr.token, dpf); + auto out = eval_interval(dpf, from, to, outbufs, + std::forward(memoizer), &pr.token); + detail::vdpf::fold_output_binding(pr.token, dpf); + return out; +} + +/// @brief Evaluate `[from, to]` and fold each written output into a sketch. +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. +template , + std::enable_if_t && !is_multilevel_key_v, bool> = true> +HEDLEY_ALWAYS_INLINE +auto eval_interval(const DpfKey & dpf, InputT from, InputT to, + OutputBuffers & outbufs, IntervalMemoizer && memoizer, sketch_ref & sk) // NOLINT(runtime/references) +{ + static_assert(DpfKey::is_extractable, + "eval_interval(..., sketch(σ)): key must carry dpf::extractable"); + auto ret = eval_interval(dpf, from, to, outbufs, + std::forward(memoizer)); + if constexpr (sizeof...(Is) == 0) + { + for (std::size_t k = 0; k < utils::size(outbufs); ++k) + sk.absorb(outbufs[k]); + } + return ret; } /// @brief Evaluate `[from, to]` into `outbufs`, allocating a basic interval memoizer. @@ -463,6 +586,7 @@ auto eval_interval(const DpfKey & dpf, InputT from, InputT to, /// @param to the inclusive end of the range /// @param outbufs the named output buffers /// @return an iterable over the written outputs +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. template (dpf, from, to, outbufs, - dpf::make_basic_interval_memoizer(from, to)); + dpf::make_basic_interval_memoizer(dpf, from, to)); +} + +/// @brief Evaluate `[from, to]` into `outbufs` and fold a VDPF proof. +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. +template && !is_multilevel_key_v, bool> = true, + std::enable_if_t>, + std::decay_t>, bool> = true> +HEDLEY_ALWAYS_INLINE +auto eval_interval(const DpfKey & dpf, InputT from, InputT to, + OutputBuffers & outbufs, prove_ref pr) // NOLINT(runtime/references) +{ + static_assert(DpfKey::is_verifiable, + "eval_interval(..., prove(π)): key must carry dpf::verifiable"); + return eval_interval(dpf, from, to, outbufs, + dpf::make_basic_interval_memoizer(dpf, from, to), pr); } /// @brief Evaluate `[from, to]` with a caller-supplied memoizer. @@ -488,6 +633,7 @@ auto eval_interval(const DpfKey & dpf, InputT from, InputT to, /// @param memoizer the memoizer built for this key /// @return `std::pair` of a new buffer (or tuple of buffers) and an iterable /// into that buffer. +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. template > (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. +template && !is_multilevel_key_v, bool> = true, + std::enable_if_t>, + std::decay_t>, bool> = true> +HEDLEY_ALWAYS_INLINE +auto eval_interval(const DpfKey & dpf, InputT from, InputT to, + IntervalMemoizer && memoizer, prove_ref pr) +{ + static_assert(DpfKey::is_verifiable, + "eval_interval(..., prove(π)): key must carry dpf::verifiable"); + auto outbufs = utils::make_tuple( + make_output_buffer_for_interval(dpf, from, to), + make_output_buffer_for_interval(dpf, from, to)...); + auto iterable = eval_interval(dpf, from, to, outbufs, memoizer, pr); + return std::make_pair(std::move(outbufs), std::move(iterable)); +} + /// @brief Evaluate `[from, to]`, allocating a basic interval memoizer and a buffer. /// @return `std::pair` of a new buffer (or tuple of buffers) and an iterable /// into that buffer. +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. template (dpf, from, to, - dpf::make_basic_interval_memoizer(from, to)); + dpf::make_basic_interval_memoizer(dpf, from, to)); +} + +/// @brief Fold every truncated-tree node of `[from, to]` into `pi`. +/// @details Once per BFS node — same absorption as `eval_interval(..., prove(π))`. +/// Caller must `init_proof` first, or use `prove_interval` below. +template +void prove_fold_interval(const KeyT & key, InputT from, InputT to, + proof_token & pi) +{ + static_assert(KeyT::is_verifiable, + "prove_fold_interval: key must carry dpf::verifiable"); + using dpf_type = KeyT; + using input_type = typename KeyT::input_type; + using integral_type = typename KeyT::integral_type; + + auto from_x = key.offset_x(static_cast(from)); + auto to_x = key.offset_x(static_cast(to)); + utils::flip_msb_if_signed_integral(from_x); + utils::flip_msb_if_signed_integral(to_x); + + integral_type from_node = utils::get_from_node(from_x); + integral_type to_node = utils::get_to_node(to_x); + constexpr auto to_int = utils::to_integral_type{}; + const bool wraps = utils::interval_wraps( + static_cast(to_int(from_x)), + static_cast(to_int(to_x)), + utils::bitlength_of_v); + auto segs = utils::split_leaf_nodes(from_node, to_node, key.depth, wraps); + auto memo = make_basic_interval_memoizer(key, from, to); + for (std::size_t s = 0; s < segs.n; ++s) + { + const auto & seg = segs.seg[s]; + internal::eval_interval_interior(key, seg.from_node, seg.to_node, memo, + KeyT::depth, &pi); + } +} + +/// @brief Initialise `pr.token` and fold `[from, to]` once per BFS node. +/// @tparam KeyT verifiable key +/// @tparam InputT input domain type +/// @param key the party key +/// @param from inclusive start +/// @param to inclusive end +/// @param pr proof token replaced with the interval fold +template +void prove_interval(const KeyT & key, InputT from, InputT to, prove_ref pr) +{ + detail::vdpf::init_proof(pr.token, key); + prove_fold_interval(key, from, to, pr.token); + detail::vdpf::fold_output_binding(pr.token, key); +} + +/// @brief Initialise `pr.token` and fold the full domain once per BFS node. +/// @tparam KeyT verifiable key +/// @param key the party key +/// @param pr proof token replaced with the full-domain fold +template +void prove_full(const KeyT & key, prove_ref pr) +{ + static_assert(KeyT::is_verifiable, + "prove_full: key must carry dpf::verifiable"); + using input_type = typename KeyT::input_type; + prove_interval(key, std::numeric_limits::min(), + std::numeric_limits::max(), pr); +} + +/// @} + +namespace internal +{ + +template +auto defer_eval_interval(const DpfKey & dpf, InputT from, InputT to, + OutputBuffers & outbufs, IntervalMemoizer && memoizer, + std::index_sequence) +{ + using dpf_type = DpfKey; + using input_type = typename dpf_type::input_type; + + const auto min = std::numeric_limits::min(); + const auto max = std::numeric_limits::max(); + + // Full-domain identity traversal (offset unknown). Same interior/exterior + // path as eager eval over `[min, max]` without folding `offset_x`. + eval_interval_impl(dpf, min, max, outbufs, memoizer, + std::make_index_sequence()); + + return utils::make_tuple( + deferred_rotated_subinterval(dpf, + std::begin(utils::get(outbufs)), + std::end(utils::get(outbufs)), + from, to, + dpf_type::outputs_per_leaf)...); +} + +} // namespace internal + +/// @name Deferred (pre-assign) evaluation +/// @{ + +/// @brief Full-domain eval while the input offset is still unset. +/// @details Requires a wildcard input that is not yet ready, and assigned +/// leaf outputs `I, Is...`. `outbufs` must be sized for the **full** +/// input domain (`make_output_buffer_for_full`). After +/// `assign_wildcard_input`, call `.get()` on each returned view. +/// @return one `deferred_rotated_subinterval` per selected output +template + && !is_multilevel_key_v, bool> = true> +auto defer_eval_interval(const DpfKey & dpf, InputT from, InputT to, + OutputBuffers & outbufs, IntervalMemoizer && memoizer) // NOLINT(runtime/references) +{ + static_assert(is_wildcard_v, + "defer_eval_interval: key input must be a wildcard_value"); + assert_wildcard_input(dpf); + assert_not_wildcard_output(dpf); + + return internal::defer_eval_interval(dpf, from, to, outbufs, + std::forward(memoizer), + std::make_index_sequence<1 + sizeof...(Is)>()); +} + +/// @brief `defer_eval_interval` with a basic full-domain memoizer. +template + && !is_multilevel_key_v, bool> = true, + std::enable_if_t>, + std::decay_t>, bool> = true> +auto defer_eval_interval(const DpfKey & dpf, InputT from, InputT to, + OutputBuffers & outbufs) // NOLINT(runtime/references) +{ + return defer_eval_interval(dpf, from, to, outbufs, + dpf::make_basic_full_memoizer(dpf)); +} + +/// @brief Interior-only traverse of `[offset_x(from), offset_x(to)]`. +/// @details Requires an assigned input. Skips exterior so the leaf may still +/// be a wildcard; finish with `eval_interval` / exterior once the +/// leaf is assigned (memoizer retains the interior). +template + && !is_multilevel_key_v, bool> = true> +void defer_traverse_interval(const DpfKey & dpf, InputT from, InputT to, + IntervalMemoizer & memoizer) // NOLINT(runtime/references) +{ + assert_not_wildcard_input(dpf); + + using dpf_type = DpfKey; + using input_type = typename dpf_type::input_type; + using integral_type = typename dpf_type::integral_type; + + auto tfrom = dpf.offset_x(from); + auto tto = dpf.offset_x(to); + utils::flip_msb_if_signed_integral(tfrom); + utils::flip_msb_if_signed_integral(tto); + + integral_type from_node = utils::get_from_node(tfrom); + integral_type to_node = utils::get_to_node(tto); + constexpr auto to_int = utils::to_integral_type{}; + const bool wraps = utils::interval_wraps( + static_cast(to_int(tfrom)), + static_cast(to_int(tto)), + utils::bitlength_of_v); + auto segs = utils::split_leaf_nodes(from_node, to_node, dpf.depth, wraps); + for (std::size_t s = 0; s < segs.n; ++s) + { + const auto & seg = segs.seg[s]; + internal::eval_interval_interior(dpf, seg.from_node, seg.to_node, + memoizer); + } +} + +/// @brief Interior-only full-domain traverse (input and/or leaf may be unset). +/// @details Fills the memoizer for every interior node. Complete exterior +/// (and any input rotation) after the missing wildcards are assigned. +template + && !is_multilevel_key_v, bool> = true> +void defer_traverse_full(const DpfKey & dpf, + IntervalMemoizer & memoizer) // NOLINT(runtime/references) +{ + using dpf_type = DpfKey; + using input_type = typename dpf_type::input_type; + using integral_type = typename dpf_type::integral_type; + + auto from = std::numeric_limits::min(); + auto to = std::numeric_limits::max(); + utils::flip_msb_if_signed_integral(from); + utils::flip_msb_if_signed_integral(to); + + integral_type from_node = utils::get_from_node(from); + integral_type to_node = utils::get_to_node(to); + internal::eval_interval_interior(dpf, from_node, to_node, memoizer); } /// @} diff --git a/include/dpf/eval_peel.hpp b/include/dpf/eval_peel.hpp new file mode 100644 index 0000000..839f6de --- /dev/null +++ b/include/dpf/eval_peel.hpp @@ -0,0 +1,155 @@ +/// @file dpf/eval_peel.hpp +/// @brief Eval overloads that accept a wrapper and evaluate its `dpf_key`. +/// @details Include this after the eval headers. A call passes through while +/// the argument has a public `dpf_key` member and is not itself a +/// DPF key. `dpf3` / `dpf3_cmp` / `dpf3_ic` keep their key-first +/// protocol overloads; `eval_*(cmp, …)` and `eval_*(out, …)` still +/// peel those wrappers down to the inner DPF key. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_EVAL_PEEL_HPP__ +#define LIBDPF_INCLUDE_DPF_EVAL_PEEL_HPP__ + +#include +#include + +#include "dpf/eval_target.hpp" + +namespace dpf +{ + +template +inline constexpr bool peel_key_v = + has_embedded_dpf_key_v> + && !owns_protocol_eval_v>; + +template +inline constexpr bool peel_tag_key_v = + has_embedded_dpf_key_v>; + +#define LIBDPF_PEEL_KEY_FIRST(fn) \ + template , int> = 0> \ + decltype(auto) fn(const KeyT & key, Args &&... args) \ + { \ + return fn(key.dpf_key, std::forward(args)...); \ + } + +#define LIBDPF_PEEL_TAG_FIRST(fn) \ + template \ + && is_eval_channel_tag_v>, int> = 0> \ + decltype(auto) fn(Tag tag, const KeyT & key, Args &&... args) \ + { \ + return fn(tag, key.dpf_key, std::forward(args)...); \ + } + +LIBDPF_PEEL_KEY_FIRST(eval_point) +LIBDPF_PEEL_KEY_FIRST(eval_interval) +LIBDPF_PEEL_KEY_FIRST(eval_full) +LIBDPF_PEEL_KEY_FIRST(eval_sequence) +LIBDPF_PEEL_KEY_FIRST(eval_inner_product) +LIBDPF_PEEL_KEY_FIRST(eval_full_inner_product) +LIBDPF_PEEL_KEY_FIRST(eval_sequence_inner_product) + +LIBDPF_PEEL_TAG_FIRST(eval_point) +LIBDPF_PEEL_TAG_FIRST(eval_interval) +LIBDPF_PEEL_TAG_FIRST(eval_full) +LIBDPF_PEEL_TAG_FIRST(eval_sequence) +LIBDPF_PEEL_TAG_FIRST(eval_sequence_breadth_first) +LIBDPF_PEEL_TAG_FIRST(eval_inner_product) +LIBDPF_PEEL_TAG_FIRST(eval_full_inner_product) +LIBDPF_PEEL_TAG_FIRST(make_output_buffer) +LIBDPF_PEEL_TAG_FIRST(make_sequence_recipe) +LIBDPF_PEEL_TAG_FIRST(eval_prefixes) +LIBDPF_PEEL_TAG_FIRST(eval_prefix_inner_product) + +#undef LIBDPF_PEEL_KEY_FIRST +#undef LIBDPF_PEEL_TAG_FIRST + +template , int> = 0> +decltype(auto) eval_sequence_xor(const KeyT & key, Args &&... args) +{ + return eval_sequence_xor(key.dpf_key, std::forward(args)...); +} + +template , int> = 0> +decltype(auto) prove_cmp_interval(const KeyT & key, Args &&... args) +{ + return prove_cmp_interval(key.dpf_key, std::forward(args)...); +} + +template , int> = 0> +decltype(auto) prove_cmp_full(const KeyT & key, Args &&... args) +{ + return prove_cmp_full(key.dpf_key, std::forward(args)...); +} + +template , int> = 0> +decltype(auto) prove_cmp_sequence(const KeyT & key, Args &&... args) +{ + return prove_cmp_sequence(key.dpf_key, std::forward(args)...); +} + +template , int> = 0> +void eval_full_add_into(Buffer & buf, const KeyT & key, Args &&... args) +{ + eval_full_add_into(buf, key.dpf_key, std::forward(args)...); +} + +/// @brief Row-wise and column inner products keep the tag in front of the key. +template + && (std::is_same_v, paired_t> + || std::is_same_v, columns_t>), int> = 0> +decltype(auto) eval_inner_product(Tag tag, const KeyT & key, Args &&... args) +{ + return eval_inner_product(tag, key.dpf_key, std::forward(args)...); +} + +template + && (std::is_same_v, paired_t> + || std::is_same_v, columns_t>), int> = 0> +decltype(auto) eval_full_inner_product(Tag tag, const KeyT & key, Args &&... args) +{ + return eval_full_inner_product(tag, key.dpf_key, std::forward(args)...); +} + +template + && (std::is_same_v, paired_t> + || std::is_same_v, columns_t>), int> = 0> +decltype(auto) eval_sequence_inner_product(Tag tag, const KeyT & key, + Args &&... args) +{ + return eval_sequence_inner_product(tag, key.dpf_key, + std::forward(args)...); +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_EVAL_PEEL_HPP__ diff --git a/include/dpf/eval_point.hpp b/include/dpf/eval_point.hpp index db7e62c..56312d5 100644 --- a/include/dpf/eval_point.hpp +++ b/include/dpf/eval_point.hpp @@ -44,25 +44,31 @@ inline auto eval_point_interior(const DpfKey & dpf, InputT && x, PathMemoizer && auto level_index = detail::path_resume_for_level(path, dpf, x, dpf.depth); - DPF_UNROLL_LOOP - for (auto mask = dpf.msb_mask>>(level_index-1); - level_index <= dpf.depth; ++level_index, mask>>=1) + // Same guard as `ensure_level`: skip the `msb_mask` shift when already done. + if (level_index <= dpf.depth) { - bool bit = !!(mask & x); - auto cw = dpf.correction_word(level_index-1, bit); - const bool is_last = dpf_type::tree::is_last_level(level_index - 1, - dpf.depth); - path[level_index] = dpf_type::traverse_interior(path[level_index-1], - cw, bit, is_last); - if constexpr (dpf_type::is_verifiable) + DPF_UNROLL_LOOP + for (auto mask = dpf.msb_mask>>(level_index-1); + level_index <= dpf.depth; ++level_index, mask>>=1) { - if (pi != nullptr) + bool bit = !!(mask & x); + auto cw = dpf.correction_word(level_index-1, bit); + const bool is_last = dpf_type::tree::is_last_level(level_index - 1, + dpf.depth); + path[level_index] = dpf_type::traverse_interior(path[level_index-1], + cw, bit, is_last); + if constexpr (dpf_type::is_verifiable) { - const auto x_bits = static_cast( - utils::to_integral_type>{}(x) - >> (utils::bitlength_of_v> - level_index)); - detail::vdpf::fold_node(*pi, level_index - 1, x_bits, - path[level_index], dpf.correction_seeds()[level_index - 1]); + if (pi != nullptr) + { + const auto x_bits = static_cast( + utils::to_integral_type>{}(x) + >> (utils::bitlength_of_v> + - level_index)); + detail::vdpf::fold_node(*pi, level_index - 1, x_bits, + path[level_index], + dpf.correction_seeds()[level_index - 1]); + } } } } @@ -96,6 +102,7 @@ auto eval_point(const DpfKey & dpf, InputT && x, PathMemoizer && path, } // namespace internal /// Evaluate output `I` at `x`. +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. template (dpf, tx, path), tx); } +/// Evaluate at `x`, folding newly walked nodes into an existing proof token. +/// @details Does not `init_proof`; used by bulk sequence evals that share a path. +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. +template && !is_multilevel_key_v, bool> = true> +HEDLEY_ALWAYS_INLINE +auto eval_point(const DpfKey & dpf, InputT && x, PathMemoizer && path, + proof_token * pi) +{ + assert_not_wildcard_output(dpf); + using output_type = typename DpfKey::concrete_output_type; + + auto tx = dpf.offset_x(x); + return make_eval_dpf_output( + internal::eval_point(dpf, tx, path, pi), tx); +} + /// Evaluate and fold a VDPF proof token for the walked path. +/// @details A fresh token always folds every node on the path, including +/// nodes already stored in a warm path memoizer (hash the cached +/// seeds; do not re-expand the PRG). Callers that continue one +/// accumulator across many points use the `proof_token *` overload +/// without `init_proof`. +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. template (dpf); - using output_type = typename DpfKey::concrete_output_type; - detail::vdpf::init_proof(pr.token, dpf); - auto tx = dpf.offset_x(x); - return make_eval_dpf_output( - internal::eval_point(dpf, tx, path, &pr.token), tx); + auto walk_x = dpf.offset_x(x); + utils::flip_msb_if_signed_integral(walk_x); + if constexpr (DpfKey::is_verifiable) + { + const auto resume = detail::path_resume_for_level( + path, dpf, walk_x, dpf.depth); + for (std::size_t level_index = 1; level_index < resume; ++level_index) + { + const auto x_bits = static_cast( + utils::to_integral_type>{}( + walk_x) + >> (utils::bitlength_of_v> + - level_index)); + detail::vdpf::fold_node(pr.token, level_index - 1, x_bits, + path[level_index], + dpf.correction_seeds()[level_index - 1]); + } + } + auto out = eval_point(dpf, std::forward(x), + std::forward(path), &pr.token); + detail::vdpf::fold_output_binding(pr.token, dpf); + return out; +} + +/// Evaluate and fold the output into a weight-1 sketch. +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. +template , + std::enable_if_t, bool> = true> +HEDLEY_ALWAYS_INLINE +auto eval_point(const DpfKey & dpf, InputT && x, sketch_ref & sk, + PathMemoizer && path = PathMemoizer{}) +{ + static_assert(DpfKey::is_extractable, + "eval_point(..., sketch(σ)): key must carry dpf::extractable"); + auto out = eval_point(dpf, std::forward(x), + std::forward(path)); + if constexpr (DpfKey::is_extractable) + sk.absorb((*out).raw()); + return out; +} + +/// @brief Rvalue convenience for a one-shot `sketch(local, rs)` temporary. +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. +template , + std::enable_if_t, bool> = true> +HEDLEY_ALWAYS_INLINE +auto eval_point(const DpfKey & dpf, InputT && x, sketch_ref && sk, + PathMemoizer && path = PathMemoizer{}) +{ + return eval_point(dpf, std::forward(x), sk, + std::forward(path)); } /// Evaluate several outputs at `x`. +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. template (dpf, x, path)...); } -/// Fold every point in `[from, to]` into `pi` (caller must `init_proof` first, -/// or pass a fresh token via `prove_interval` below). -template -void prove_fold_interval(const KeyT & key, InputT from, InputT to, - proof_token & pi) -{ - static_assert(KeyT::is_verifiable, - "prove_fold_interval: key must carry dpf::verifiable"); - using input_type = typename KeyT::input_type; - auto cur = static_cast(from); - const auto last = static_cast(to); - for (;;) - { - nonmemoizing_path_memoizer path{}; - auto tx = key.offset_x(cur); - utils::flip_msb_if_signed_integral(tx); - internal::eval_point_interior(key, tx, path, &pi); - if (cur == last) - break; - ++cur; - } -} - -/// Initialise `pr.token` and fold `[from, to]`. -template -void prove_interval(const KeyT & key, InputT from, InputT to, prove_ref pr) -{ - detail::vdpf::init_proof(pr.token, key); - prove_fold_interval(key, from, to, pr.token); -} - } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_EVAL_POINT_HPP__ diff --git a/include/dpf/eval_sequence.hpp b/include/dpf/eval_sequence.hpp index d7943bc..4085e42 100644 --- a/include/dpf/eval_sequence.hpp +++ b/include/dpf/eval_sequence.hpp @@ -24,26 +24,179 @@ #include #include #include +#include #include #include -#include +#include +#include #include "dpf/dpf_key.hpp" #include "dpf/eval_common.hpp" #include "dpf/eval_target.hpp" #include "dpf/eval_point.hpp" +#include "dpf/eval_interval.hpp" #include "dpf/path_memoizer.hpp" #include "dpf/sequence_memoizer.hpp" #include "dpf/sequence_utils.hpp" #include "dpf/subsequence_iterable.hpp" #include "dpf/subinterval_iterable.hpp" +#include "dpf/verifiable.hpp" namespace dpf { +template +void prove_sequence(const KeyT & key, ForwardIterator begin, ForwardIterator end, + prove_ref pr); + +// Contiguous runs at least this long use the interval tree (one expand per +// node). Shorter runs stay on the path memoizer. Isolated points at least +// this many use the breadth-first block walk, which beats a fresh path per +// point once the list is wide. +inline constexpr std::size_t sequence_interval_run = 24; +// Breadth-first shares prefixes on sparse lists, but its per-level block-split +// bookkeeping loses to a path memoizer once single-child expands cut the +// path PRG cost in half. Keep the explicit `eval_sequence_breadth_first` +// entry point; do not auto-select it from `eval_sequence`. +inline constexpr std::size_t sequence_breadth_points = std::numeric_limits::max(); + +template +inline auto eval_sequence_breadth_first(const DpfKey & dpf, ForwardIterator begin, + ForwardIterator end, OutputBuffer && outbuf); + +template +void scatter_interval_run(const DpfKey & dpf, InputT from, InputT to, + OutputBuffers & outbufs, std::size_t index0, std::index_sequence) +{ + // std::make_tuple, not utils::make_tuple: one output must stay a tuple + // so each selected buffer is addressable by index. + auto ibufs = std::make_tuple( + make_output_buffer_for_interval(from, to)...); + (void)eval_interval(dpf, from, to, ibufs); + + constexpr auto opl = DpfKey::outputs_per_leaf; + constexpr auto lg = DpfKey::lg_outputs_per_leaf; + constexpr auto mod_pow_2 = utils::mod_pow_2{}; + const std::size_t preclip = mod_pow_2(dpf.offset_x(from), lg); + + constexpr auto to_int = utils::to_integral_type{}; + auto span = to_int(to) - to_int(from); + constexpr auto bits = utils::bitlength_of_v; + if constexpr (bits < utils::bitlength_of_v) + span &= (decltype(span){1} << bits) - 1; + const std::size_t n = static_cast(span) + 1; + constexpr std::size_t leaf_mask = (std::size_t{1} << lg) - 1; + + auto one = [&](auto which) + { + constexpr std::size_t k = decltype(which)::value; + auto & src = utils::get(ibufs); + auto & dst = utils::get(outbufs); + auto put = [](auto & slot, const auto & val) + { + assign_share_slot(slot, val); + }; + if constexpr (Entire) + { + for (std::size_t j = 0; j < n; ++j) + { + const std::size_t elem_i = preclip + j; + const std::size_t leaf = elem_i - (elem_i & leaf_mask); + for (std::size_t lane = 0; lane < opl; ++lane) + put(dst[(index0 + j) * opl + lane], src[leaf + lane]); + } + } + else + { + for (std::size_t j = 0; j < n; ++j) + put(dst[index0 + j], src[preclip + j]); + } + }; + (one(std::integral_constant{}), ...); +} + namespace internal { +/// @brief Leaf interior nodes for a list, eight paths at a time. +/// @details One scalar spine up to the shallowest divergence, then +/// `tree::traverse8` across the whole suffix of each level. `walk[i]` +/// is the offset input with the signed MSB already flipped, matching +/// `eval_point`. +template +std::vector sequence_wide_leaves( + const DpfKey & dpf, const typename DpfKey::input_type * walk, std::size_t n) +{ + using node = typename DpfKey::interior_node; + std::vector leaves(n); + if (n == 0) + return leaves; + constexpr auto clz = utils::countl_zero_symmetric_difference< + typename DpfKey::input_type>{}; + std::size_t common = dpf.depth + 1; + for (std::size_t i = 1; i < n; ++i) + common = std::min(common, clz(walk[0], walk[i]) + 1); + + std::array path{}; + path[0] = dpf.root(); + auto mask = dpf.msb_mask; + for (std::size_t level = 1; level < common && level <= dpf.depth; + ++level, mask >>= 1) + { + const bool bit = (mask & walk[0]) != 0; + path[level] = DpfKey::traverse_interior(path[level - 1], + dpf.correction_word(level - 1, bit), bit, + DpfKey::tree::is_last_level(level - 1, dpf.depth)); + } + if (common > dpf.depth) + { + std::fill(leaves.begin(), leaves.end(), path[dpf.depth]); + return leaves; + } + + std::vector cur(n, path[common - 1]); + std::vector next(n); + mask = dpf.msb_mask >> (common - 1); + for (std::size_t level = common; level <= dpf.depth; ++level, mask >>= 1) + { + const node cw0 = dpf.correction_word(level - 1, false); + const node cw1 = dpf.correction_word(level - 1, true); + const bool last = DpfKey::tree::is_last_level(level - 1, dpf.depth); + std::size_t i = 0; + for (; i + 8 <= n; i += 8) + { + node parents[8]; + node cws[8]; + bool dirs[8]; + for (int k = 0; k < 8; ++k) + { + dirs[k] = (mask & walk[i + static_cast(k)]) != 0; + cws[k] = dirs[k] ? cw1 : cw0; + parents[k] = cur[i + static_cast(k)]; + } + node outs[8]; + DpfKey::tree::traverse8(parents, cws, dirs, outs); + for (int k = 0; k < 8; ++k) + next[i + static_cast(k)] = outs[k]; + } + for (; i < n; ++i) + { + const bool bit = (mask & walk[i]) != 0; + next[i] = DpfKey::traverse_interior(cur[i], bit ? cw1 : cw0, bit, last); + } + cur.swap(next); + } + return cur; +} + template ) { static constexpr std::size_t outputs_per_leaf = DpfKey::outputs_per_leaf; + using input_type = typename DpfKey::input_type; + constexpr bool any_packed = + (utils::is_packed_subbyte_v> || ...); + constexpr bool any_bit = + (std::is_same_v, dpf::bit> || ...); + constexpr bool integral_in = std::is_integral_v; + // Bit and packed leaves are proxy buffers. The interval scatter writes + // ordinary word slots; those outputs stay on the path memoizer. + constexpr bool interval_ok = integral_in && !any_packed && !any_bit; - auto path = make_basic_path_memoizer(dpf); - - std::size_t i = 0; - // DPF_UNROLL_LOOP - for (auto it = begin; it != end; ++it, ++i) + auto write_point = [&](auto & path, std::size_t i, const input_type & x) { - if constexpr(utils::is_packed_subbyte_v>) + if constexpr (any_packed) { - auto nodes = std::make_tuple(dpf::eval_point(dpf, *it, path).node...); + auto nodes = std::make_tuple(dpf::eval_point(dpf, x, path).node...); (store_leaf_bytes(utils::get(outbufs), i, std::get(nodes)), ...); } else { - auto temp = std::make_tuple(dpf::eval_point(dpf, *it, path).node...); - (std::memcpy(&utils::get(outbufs)[i*outputs_per_leaf], &utils::get(temp), sizeof(typename DpfKey::concrete_output_type)*outputs_per_leaf), ...); + auto temp = std::make_tuple(dpf::eval_point(dpf, x, path).node...); + (utils::raw_memcpy(&utils::get(outbufs)[i * outputs_per_leaf], + &utils::get(temp), + sizeof(typename DpfKey::concrete_output_type) * outputs_per_leaf), ...); + } + }; + + if constexpr (interval_ok) + { + using iter_cat = typename std::iterator_traits::iterator_category; + bool classify = true; + if constexpr (std::is_base_of_v) + { + // Below this length the interval-run cover does not apply, so skip + // the classification pass. + classify = static_cast(std::distance(begin, end)) + >= sequence_interval_run; + } + if (classify) + { + bool sorted = true; + std::size_t n = 0; + std::size_t longest = 0; + std::size_t cur = 0; + bool dup = false; + input_type prev{}; + for (auto it = begin; it != end; ++it, ++n) + { + if (n == 0) + { + prev = *it; + longest = 1; + cur = 1; + continue; + } + const input_type x = *it; + if (x < prev) + sorted = false; + else if (x == prev) + dup = true; + if (x == static_cast(prev + input_type{1})) + { + ++cur; + if (cur > longest) + longest = cur; + } + else + cur = 1; + prev = x; + } + if (sorted && longest >= sequence_interval_run) + { + std::size_t i = 0; + for (auto it = begin; it != end; ) + { + const input_type run_from = *it; + input_type run_to = run_from; + auto run_end = it; + ++run_end; + while (run_end != end + && *run_end == static_cast(run_to + input_type{1})) + { + run_to = *run_end; + ++run_end; + } + const auto span_n = static_cast(std::distance(it, run_end)); + if (span_n >= sequence_interval_run) + { + scatter_interval_run(dpf, run_from, run_to, outbufs, i, + std::index_sequence{}); + i += span_n; + } + else + { + auto path = make_basic_path_memoizer(dpf); + for (auto p = it; p != run_end; ++p, ++i) + write_point(path, i, *p); + } + it = run_end; + } + return utils::make_tuple( + dpf::subsequence_iterable(outbufs))), ForwardIterator>(std::begin(utils::get(outbufs)), begin, end)...); + } + // Breadth-first pays for a block split at every level. On a short + // tree (8-bit inputs) that overhead loses to the path memoizer. + // The one-output overload is the only one; keep it out of the + // multi-output instantiation. + if constexpr (sizeof...(Is) == 1) + { + if (sorted && !dup && n >= sequence_breadth_points + && DpfKey::depth >= 16) + { + eval_sequence_breadth_first(dpf, begin, end, utils::get<0>(outbufs)); + return utils::make_tuple( + dpf::subsequence_iterable(outbufs))), ForwardIterator>(std::begin(utils::get(outbufs)), begin, end)...); + } + } } } + + const std::size_t nseq = static_cast(std::distance(begin, end)); + if constexpr (sizeof...(Is) == 1 && !DpfKey::is_verifiable + && prg_has_indep4::value) + { + if (nseq >= 16) + { + using input_type = typename DpfKey::input_type; + std::vector walk(nseq); + std::vector lane(nseq); + std::size_t i = 0; + for (auto it = begin; it != end; ++it, ++i) + { + lane[i] = dpf.offset_x(*it); + walk[i] = lane[i]; + utils::flip_msb_if_signed_integral(walk[i]); + } + const auto leaves = sequence_wide_leaves(dpf, walk.data(), nseq); + constexpr std::size_t ids[] = {Is...}; + constexpr std::size_t I0 = ids[0]; + using output_type = typename DpfKey::concrete_output_type; + auto & dst = utils::get<0>(outbufs); + for (std::size_t p = 0; p < nseq; ++p) + { + auto wrapped = make_eval_dpf_output( + dpf.template traverse_exterior(leaves[p]), lane[p]); + utils::raw_memcpy(&dst[p * outputs_per_leaf], &wrapped.node, + sizeof(output_type) * outputs_per_leaf); + } + return utils::make_tuple( + dpf::subsequence_iterable(outbufs))), ForwardIterator>(std::begin(utils::get(outbufs)), begin, end)...); + } + } + + auto path = make_basic_path_memoizer(dpf); + std::size_t i = 0; + for (auto it = begin; it != end; ++it, ++i) + write_point(path, i, *it); return utils::make_tuple( dpf::subsequence_iterable(outbufs))), ForwardIterator>(std::begin(utils::get(outbufs)), begin, end)...); } @@ -79,23 +370,7 @@ template HEDLEY_ALWAYS_INLINE void assign_eval_slot(Slot && slot, Val && val) { - using val_t = std::decay_t; - if constexpr (is_secret_share_v>) - { - using elem_t = std::decay_t; - if constexpr (is_secret_share_v) - slot = elem_t::from_raw(val.raw()); - else - slot = elem_t::from_raw(static_cast(val)); - } - else if constexpr (is_secret_share_v) - { - slot = val.raw(); - } - else - { - slot = std::forward(val); - } + assign_share_slot(slot, std::forward(val)); } template ) { - auto path = make_basic_path_memoizer(dpf); + using input_type = typename DpfKey::input_type; + constexpr bool any_packed = + (utils::is_packed_subbyte_v> || ...); + constexpr bool any_bit = + (std::is_same_v, dpf::bit> || ...); + constexpr bool integral_in = std::is_integral_v; - std::size_t i = 0; - // DPF_UNROLL_LOOP - for (auto it = begin; it != end; ++it, ++i) + auto write_point = [&](auto & path, std::size_t i, const input_type & x) { (assign_eval_slot(utils::get(outbufs)[i], - *dpf::eval_point(dpf, *it, path)), ...); - } - if (i == 0) + *dpf::eval_point(dpf, x, path)), ...); + }; + + auto finish = [&](std::size_t i) { - return utils::make_tuple(subinterval_iterable(std::begin(utils::get(outbufs)), utils::size(utils::get(outbufs)), 0, 0, 0, 0, false)...); + if (i == 0) + { + return utils::make_tuple(subinterval_iterable(std::begin(utils::get(outbufs)), utils::size(utils::get(outbufs)), 0, 0, 0, 0, false)...); + } + return utils::make_tuple(subinterval_iterable(std::begin(utils::get(outbufs)), utils::size(utils::get(outbufs)), 0, i - 1, 0, 0)...); + }; + + if constexpr (integral_in && !any_packed && !any_bit) + { + bool sorted = true; + std::size_t longest = 0; + std::size_t cur = 0; + std::size_t n = 0; + input_type prev{}; + for (auto it = begin; it != end; ++it, ++n) + { + if (n == 0) + { + prev = *it; + longest = 1; + cur = 1; + continue; + } + const input_type x = *it; + if (x < prev) + sorted = false; + if (x == static_cast(prev + input_type{1})) + { + ++cur; + if (cur > longest) + longest = cur; + } + else + cur = 1; + prev = x; + } + if (sorted && longest >= sequence_interval_run) + { + auto path = make_basic_path_memoizer(dpf); + std::size_t i = 0; + for (auto it = begin; it != end; ) + { + const input_type run_from = *it; + input_type run_to = run_from; + auto run_end = it; + ++run_end; + while (run_end != end + && *run_end == static_cast(run_to + input_type{1})) + { + run_to = *run_end; + ++run_end; + } + const auto span_n = static_cast(std::distance(it, run_end)); + if (span_n >= sequence_interval_run) + { + scatter_interval_run(dpf, run_from, run_to, outbufs, i, + std::index_sequence{}); + i += span_n; + } + else + { + for (auto p = it; p != run_end; ++p, ++i) + write_point(path, i, *p); + } + it = run_end; + } + return finish(i); + } } - return utils::make_tuple(subinterval_iterable(std::begin(utils::get(outbufs)), utils::size(utils::get(outbufs)), 0, i-1, 0, 0)...); + + auto path = make_basic_path_memoizer(dpf); + std::size_t i = 0; + for (auto it = begin; it != end; ++it, ++i) + write_point(path, i, *it); + return finish(i); } } // namespace internal +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). template || std::is_same_v); if constexpr(std::is_same_v) @@ -148,6 +501,54 @@ inline auto eval_sequence(const DpfKey & dpf, ForwardIterator begin, ForwardIter } } +/// @brief Evaluate a sorted sequence and fold the same VDPF proof as `prove_sequence`. +/// @details Uses interval-run covers (not a path-memo double walk). Values are +/// written by a single subsequent `eval_sequence` without proof. +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). +template && !is_multilevel_key_v, bool> = true, + std::enable_if_t, bool> = true, + std::enable_if_t, bool> = true> +inline auto eval_sequence(const DpfKey & dpf, ForwardIterator begin, ForwardIterator end, + OutputBuffers && outbufs, prove_ref pr, ReturnType return_type = ReturnType{}) +{ + static_assert(DpfKey::is_verifiable, + "eval_sequence(..., prove(π)): key must carry dpf::verifiable"); + prove_sequence(dpf, begin, end, pr); + return eval_sequence(dpf, begin, end, + std::forward(outbufs), return_type); +} + +/// @brief Evaluate a sorted sequence and fold each written output into a sketch. +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). +template && !is_multilevel_key_v, bool> = true, + std::enable_if_t, bool> = true, + std::enable_if_t, bool> = true> +inline auto eval_sequence(const DpfKey & dpf, ForwardIterator begin, ForwardIterator end, + OutputBuffers && outbufs, sketch_ref & sk, ReturnType return_type = ReturnType{}) +{ + static_assert(DpfKey::is_extractable, + "eval_sequence(..., sketch(σ)): key must carry dpf::extractable"); + auto ret = eval_sequence(dpf, begin, end, outbufs, return_type); + if constexpr (sizeof...(Is) == 0) + { + for (std::size_t k = 0; k < utils::size(outbufs); ++k) + sk.absorb(outbufs[k]); + } + return ret; +} + /// @brief Evaluate the sorted range `[begin, end)`, allocating a buffer. /// @tparam I output index /// @tparam Is is @@ -161,6 +562,7 @@ inline auto eval_sequence(const DpfKey & dpf, ForwardIterator begin, ForwardIter /// @param begin the iterator to the first query /// @param end the iterator past the last query /// @return Pair of buffer (or tuple of buffers) and an iterable in list order. +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). template splits{begin, end}; + std::vector splits; + splits.reserve(nodes_in_sequence + 1); + splits.push_back(begin); + splits.push_back(end); std::size_t level_index = 1; auto func = [&](const bool flip = false) @@ -233,16 +639,18 @@ HEDLEY_PRAGMA(GCC diagnostic pop) dpf_type::depth); // `lower` and `upper` are always adjacent elements of `splits` with `lower` < `upper` // [lower, upper) = "block" - for (auto upper = std::begin(splits), lower = upper++; upper != std::end(splits); lower = upper++) + for (std::size_t s = 0; s + 1 < splits.size(); ++s) { + auto lower = splits[s]; + auto upper = splits[s + 1]; // `upper_bound()` returns iterator to first element where the relevant bit (based on `mask`) is set - auto it = std::upper_bound(*lower, *upper, mask, + auto it = std::upper_bound(lower, upper, mask, [&flip](auto a, auto b){ return static_cast(a&b) ^ flip; }); - if (it == *lower) // right only since first element in "block" requires right traversal + if (it == lower) // right only since first element in "block" requires right traversal { memo[curhalf*nodes_in_sequence + i++] = dpf_type::traverse_interior(memo[!curhalf*nodes_in_sequence + j++], cw[1], 1, is_last); } - else if (it == *upper) // left only since no element in "block" requires right traversal + else if (it == upper) // left only since no element in "block" requires right traversal { memo[curhalf*nodes_in_sequence + i++] = dpf_type::traverse_interior(memo[!curhalf*nodes_in_sequence + j++], cw[0], 0, is_last); } @@ -252,7 +660,8 @@ HEDLEY_PRAGMA(GCC diagnostic pop) auto kids = dpf_type::traverse_interior01(cur_node, cw[0], cw[1], is_last); memo[curhalf*nodes_in_sequence + i++] = kids[0]; memo[curhalf*nodes_in_sequence + i++] = kids[1]; - splits.insert(upper, it); + splits.insert(splits.begin() + static_cast(s + 1), it); + ++s; // skip the newly inserted right-block start } } }; @@ -287,7 +696,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) } else { - std::memcpy(&outbuf[i*dpf_type::outputs_per_leaf], &leaf, sizeof(output_type)*dpf_type::outputs_per_leaf); + utils::raw_memcpy(&outbuf[i*dpf_type::outputs_per_leaf], &leaf, sizeof(output_type)*dpf_type::outputs_per_leaf); } prev = curr++; } @@ -295,6 +704,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) return subsequence_iterable(std::begin(outbuf), begin, end); } +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). template @@ -387,7 +797,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) } else { - std::memcpy(&outbuf[j*dpf_type::outputs_per_leaf], &leaf, sizeof(output_type)*dpf_type::outputs_per_leaf); + utils::raw_memcpy(&outbuf[j*dpf_type::outputs_per_leaf], &leaf, sizeof(output_type)*dpf_type::outputs_per_leaf); } } } @@ -426,11 +836,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) } auto v = extract_leaf(node, recipe.output_indices()[i] % dpf_type::outputs_per_leaf); - using elem_t = std::decay_t; - if constexpr (is_secret_share_v) - outbuf[i] = elem_t::from_raw(v); - else - outbuf[i] = v; + assign_share_slot(outbuf[i], v); } } @@ -444,6 +850,7 @@ template ) { + (void)return_type; internal::eval_sequence_interior(dpf, recipe, memoizer); static_assert(std::is_same_v || @@ -483,6 +890,7 @@ auto eval_sequence(const DpfKey & dpf, const sequence_recipe & recipe, /// @param memoizer the memoizer built for this key /// @param return_type `return_entire_node_tag_{}` or `return_output_only_tag_{}` /// @return the evaluation result +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). template (dpf, recipe, outbufs, memoizer, return_type, std::make_index_sequence<1+sizeof...(Is)>()); } +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). template (recipe), return_type); } +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). template (recipe), return_type); } +/// @brief Fold a sorted sequence into `pr` via interval-run covers. +/// @details Maximal contiguous runs use once-per-BFS-node `prove_fold_interval`. +/// Isolated points are length-1 runs. Both parties must see the same +/// sorted list. Prefer this over path-memo when the list is dense. +template +void prove_sequence(const KeyT & key, ForwardIterator begin, ForwardIterator end, + prove_ref pr) +{ + static_assert(KeyT::is_verifiable, + "prove_sequence: key must carry dpf::verifiable"); + if (HEDLEY_UNLIKELY(begin != end && !std::is_sorted(begin, end))) + throw std::runtime_error("list must be sorted"); + detail::vdpf::init_proof(pr.token, key); + using input_type = typename KeyT::input_type; + for (auto it = begin; it != end; ) + { + const auto run_from = static_cast(*it); + auto run_to = run_from; + ++it; + while (it != end) + { + const auto next = static_cast(*it); + if (next != static_cast(run_to + input_type{1})) + break; + run_to = next; + ++it; + } + prove_fold_interval(key, run_from, run_to, pr.token); + } + detail::vdpf::fold_output_binding(pr.token, key); +} + } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_EVAL_SEQUENCE_HPP__ diff --git a/include/dpf/eval_target.hpp b/include/dpf/eval_target.hpp index b4f80e3..2c69f61 100644 --- a/include/dpf/eval_target.hpp +++ b/include/dpf/eval_target.hpp @@ -135,6 +135,66 @@ template inline constexpr bool is_multilevel_key_v = is_multilevel_key>::value; +/// @brief True when `T` stores its DPF key in a public member named `dpf_key` +/// and is not itself a DPF key. +/// @details Wrappers (`ic_key`, `vdpf_plus_key`, `dpf3_cmp_key`, `dpf3_ic_key`, +/// and the distributed `opened_*` envelopes) use that member name. +/// `party_key` inherits the DPF key, so it is not a wrapper. +template +struct has_embedded_dpf_key : std::false_type +{ +}; +template +struct has_embedded_dpf_key().dpf_key)>> + : std::bool_constant> +{ +}; +template +inline constexpr bool has_embedded_dpf_key_v = + has_embedded_dpf_key>::value; + +/// @brief The DPF key `T` evaluates as: `T` itself, or `T::dpf_key` peeled +/// until the result looks like a DPF key. +template +struct bare_dpf_key +{ + using type = std::decay_t; +}; +template +struct bare_dpf_key>>> + : bare_dpf_key &>().dpf_key)>> +{ +}; +template +using bare_dpf_key_t = typename bare_dpf_key>::type; + +/// @brief Key-first protocol evals (`dpf3`, `dpf3_cmp`, `dpf3_ic`) keep their +/// own overloads. Peel does not replace those. +template +struct flag_is_dpf3 : std::false_type {}; +template +struct flag_is_dpf3> + : std::bool_constant {}; + +template +struct flag_is_dpf3_cmp : std::false_type {}; +template +struct flag_is_dpf3_cmp> + : std::bool_constant {}; + +template +struct flag_is_dpf3_ic : std::false_type {}; +template +struct flag_is_dpf3_ic> + : std::bool_constant {}; + +template +inline constexpr bool owns_protocol_eval_v = + flag_is_dpf3>::value + || flag_is_dpf3_cmp>::value + || flag_is_dpf3_ic>::value; + } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_EVAL_TARGET_HPP__ diff --git a/include/dpf/eval_unified.hpp b/include/dpf/eval_unified.hpp index ddbf89d..966c175 100644 --- a/include/dpf/eval_unified.hpp +++ b/include/dpf/eval_unified.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #include "dpf/interval_memoizer.hpp" #include "dpf/aligned_allocator.hpp" #include "dpf/leaf_node.hpp" +#include "dpf/verifiable.hpp" namespace dpf { @@ -70,8 +72,10 @@ constexpr std::size_t resolved_out_prefix() noexcept // eval_point(target, key, x [, path]) // --------------------------------------------------------------------------- +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. template > + typename PathMemoizer = nonmemoizing_path_memoizer, + std::enable_if_t>, int> = 0> auto eval_point(out_t, const KeyT & key, QueryT && x, PathMemoizer && path = PathMemoizer{}) { @@ -88,8 +92,10 @@ auto eval_point(out_t, const KeyT & key, QueryT && x, } } +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. template > + typename PathMemoizer = basic_path_memoizer, + std::enable_if_t>, int> = 0> auto eval_point(cmp_t, const KeyT & key, QueryT && x, PathMemoizer && path = PathMemoizer{}) { @@ -97,8 +103,41 @@ auto eval_point(cmp_t, const KeyT & key, QueryT && x, std::forward(path)); } +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. +template , + std::enable_if_t>, int> = 0> +auto eval_point(cmp_t, const KeyT & key, QueryT && x, prove_ref pr, + PathMemoizer && path = PathMemoizer{}) +{ + static_assert(KeyT::is_verifiable, + "eval_point(cmp, ..., prove(π)): key must carry dpf::verifiable"); + detail::vdpf::init_proof(pr.token, key); + auto out = detail::incr::eval_cmp_point_impl(key, std::forward(x), + std::forward(path), &pr.token); + detail::vdpf::fold_output_binding(pr.token, key); + return out; +} + +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. +template , + std::enable_if_t>, int> = 0> +auto eval_point(cmp_t, const KeyT & key, QueryT && x, sketch_ref & sk, + PathMemoizer && path = PathMemoizer{}) +{ + static_assert(KeyT::is_extractable, + "eval_point(cmp, ..., sketch(σ)): key must carry dpf::extractable"); + auto y = detail::incr::eval_cmp_point_impl(key, std::forward(x), + std::forward(path)); + sk.absorb(y); + return y; +} + +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. template > + typename PathMemoizer = basic_path_memoizer, + std::enable_if_t>, int> = 0> auto eval_point(cmp_prefix_t, const KeyT & key, QueryT && x, PathMemoizer && path = PathMemoizer{}) { @@ -106,12 +145,30 @@ auto eval_point(cmp_prefix_t, const KeyT & key, QueryT && x, std::forward(x), std::forward(path)); } +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. +template , + std::enable_if_t>, int> = 0> +auto eval_point(cmp_prefix_t, const KeyT & key, QueryT && x, prove_ref pr, + PathMemoizer && path = PathMemoizer{}) +{ + static_assert(KeyT::is_verifiable, + "eval_point(cmp_prefix, ..., prove(π)): key must carry dpf::verifiable"); + detail::vdpf::init_proof(pr.token, key); + auto out = detail::incr::eval_cmp_prefix_point_impl(key, + std::forward(x), std::forward(path), &pr.token); + detail::vdpf::fold_output_binding(pr.token, key); + return out; +} + // --------------------------------------------------------------------------- // eval_interval(target, key, from, to [, buf [, memo]]) // --------------------------------------------------------------------------- +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. template + typename OutputBuffer, typename IntervalMemoizer, + std::enable_if_t>, int> = 0> auto eval_interval(out_t, const KeyT & key, LaneT from, LaneT to, OutputBuffer && outbuf, IntervalMemoizer && memo) { @@ -130,8 +187,10 @@ auto eval_interval(out_t, const KeyT & key, LaneT from, LaneT to, } } +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. template + typename OutputBuffer, + std::enable_if_t>, int> = 0> auto eval_interval(out_t, const KeyT & key, LaneT from, LaneT to, OutputBuffer && outbuf) { @@ -148,7 +207,9 @@ auto eval_interval(out_t, const KeyT & key, LaneT from, LaneT to, } } -template +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. +template >, int> = 0> auto eval_interval(out_t, const KeyT & key, LaneT from, LaneT to) { if constexpr (is_multilevel_key_v) @@ -162,8 +223,10 @@ auto eval_interval(out_t, const KeyT & key, LaneT from, LaneT to) } } +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. template + typename OutputBuffer, + std::enable_if_t>, int> = 0> void eval_interval(cmp_t, const KeyT & key, LaneT from, LaneT to, OutputBuffer && outbuf) { @@ -171,8 +234,25 @@ void eval_interval(cmp_t, const KeyT & key, LaneT from, LaneT to, std::forward(outbuf)); } +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. template + typename OutputBuffer, + std::enable_if_t>, int> = 0> +void eval_interval(cmp_t, const KeyT & key, LaneT from, LaneT to, + OutputBuffer && outbuf, prove_ref pr) +{ + static_assert(KeyT::is_verifiable, + "eval_interval(cmp, ..., prove(π)): key must carry dpf::verifiable"); + detail::vdpf::init_proof(pr.token, key); + detail::incr::eval_cmp_interval_impl(key, from, to, + std::forward(outbuf), &pr.token); + detail::vdpf::fold_output_binding(pr.token, key); +} + +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. +template >, int> = 0> void eval_interval(cmp_t, const KeyT & key, LaneT from, LaneT to, OutputBuffer && outbuf, IntervalMemoizer && memo) { @@ -181,18 +261,51 @@ void eval_interval(cmp_t, const KeyT & key, LaneT from, LaneT to, std::forward(memo)); } -template +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. +template >, int> = 0> +void eval_interval(cmp_t, const KeyT & key, LaneT from, LaneT to, + OutputBuffer && outbuf, IntervalMemoizer && memo, prove_ref pr) +{ + static_assert(KeyT::is_verifiable, + "eval_interval(cmp, ..., prove(π)): key must carry dpf::verifiable"); + detail::vdpf::init_proof(pr.token, key); + detail::incr::eval_cmp_interval_impl(key, from, to, + std::forward(outbuf), + std::forward(memo), &pr.token); + detail::vdpf::fold_output_binding(pr.token, key); +} + +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. +template >, int> = 0> auto eval_interval(cmp_t, const KeyT & key, LaneT from, LaneT to) { return detail::incr::eval_cmp_interval_impl(key, from, to); } +/// \complexity O(L) interior traversals and O(L) workspace in the basic memoizer. L is the number of leaf nodes covering the closed interval (`get_nodes_at_level` at `depth`). Level k expands `(to >> (n-k)) - (from >> (n-k)) + 1` nodes; those counts sum to Θ(L). The output buffer holds one slot per input in the interval. n is `depth`. +template >, int> = 0> +auto eval_interval(cmp_t, const KeyT & key, LaneT from, LaneT to, prove_ref pr) +{ + static_assert(KeyT::is_verifiable, + "eval_interval(cmp, ..., prove(π)): key must carry dpf::verifiable"); + detail::vdpf::init_proof(pr.token, key); + auto out = detail::incr::eval_cmp_interval_impl(key, from, to, &pr.token); + detail::vdpf::fold_output_binding(pr.token, key); + return out; +} + // --------------------------------------------------------------------------- // eval_full(target, key [, …]) // --------------------------------------------------------------------------- +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). template + typename OutputBuffer, typename IntervalMemoizer, + std::enable_if_t>, int> = 0> auto eval_full(out_t, const KeyT & key, OutputBuffer && outbuf, IntervalMemoizer && memo) { @@ -210,7 +323,9 @@ auto eval_full(out_t, const KeyT & key, OutputBuffer && outbuf, } } -template +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). +template >, int> = 0> auto eval_full(out_t, const KeyT & key) { if constexpr (is_multilevel_key_v) @@ -224,7 +339,9 @@ auto eval_full(out_t, const KeyT & key) } } -template +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). +template >, int> = 0> auto eval_full(cmp_t, const KeyT & key) { if (!key.has_cmp()) @@ -238,13 +355,36 @@ auto eval_full(cmp_t, const KeyT & key) return detail::incr::eval_cmp_interval_impl(key, lo, hi); } +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). +template >, int> = 0> +auto eval_full(cmp_t, const KeyT & key, prove_ref pr) +{ + static_assert(KeyT::is_verifiable, + "eval_full(cmp, ..., prove(π)): key must carry dpf::verifiable"); + if (!key.has_cmp()) + throw std::invalid_argument("eval_full(cmp): no comparison channel"); + using lane_t = typename KeyT::integral_type; + const auto nbits = static_cast(key.cmp().nbits); + const lane_t lo = 0; + const lane_t hi = (nbits >= 8 * sizeof(lane_t)) + ? static_cast(~lane_t{0}) + : static_cast((lane_t{1} << nbits) - 1); + detail::vdpf::init_proof(pr.token, key); + auto out = detail::incr::eval_cmp_interval_impl(key, lo, hi, &pr.token); + detail::vdpf::fold_output_binding(pr.token, key); + return out; +} + // --------------------------------------------------------------------------- // eval_sequence(target, key, begin, end, buf [, path]) // --------------------------------------------------------------------------- +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). template > + typename PathMemoizer = basic_path_memoizer, + std::enable_if_t>, int> = 0> auto eval_sequence(out_t, const KeyT & key, ForwardIterator begin, ForwardIterator end, OutputBuffer && outbuf, PathMemoizer && path = PathMemoizer{}) @@ -263,9 +403,11 @@ auto eval_sequence(out_t, const KeyT & key, ForwardIterator begin, } } +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). template > + typename PathMemoizer = basic_path_memoizer, + std::enable_if_t>, int> = 0> void eval_sequence(cmp_t, const KeyT & key, ForwardIterator begin, ForwardIterator end, OutputBuffer && outbuf, PathMemoizer && path = PathMemoizer{}) @@ -275,24 +417,45 @@ void eval_sequence(cmp_t, const KeyT & key, ForwardIterator begin, std::forward(path)); } +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). +template , + std::enable_if_t>, int> = 0> +void eval_sequence(cmp_t, const KeyT & key, ForwardIterator begin, + ForwardIterator end, OutputBuffer && outbuf, prove_ref pr, + PathMemoizer && path = PathMemoizer{}) +{ + static_assert(KeyT::is_verifiable, + "eval_sequence(cmp, ..., prove(π)): key must carry dpf::verifiable"); + detail::vdpf::init_proof(pr.token, key); + detail::incr::eval_cmp_sequence_impl(key, begin, end, + std::forward(outbuf), + std::forward(path), &pr.token); + detail::vdpf::fold_output_binding(pr.token, key); +} + // --------------------------------------------------------------------------- // make_output_buffer(target, …) // --------------------------------------------------------------------------- -template +template >, int> = 0> auto make_output_buffer(cmp_t, const KeyT & key, std::size_t n) { return detail::incr::make_output_buffer_for_cmp_impl(key, n); } -template +template >, int> = 0> auto make_output_buffer(cmp_t, const KeyT & key, LaneT from, LaneT to) { return detail::incr::make_output_buffer_for_cmp_interval_impl( key, from, to); } -template +template >, int> = 0> auto make_output_buffer(out_t, const KeyT & key, LaneT from, LaneT to) { constexpr auto pref = detail::resolved_out_prefix(); @@ -426,6 +589,7 @@ auto eval_out_inner_product_impl(const KeyT & dpf, LaneT from, LaneT to, for (std::size_t j = 0; j < count; ++j) { auto leaf = dpf.template traverse_exterior(nodes[j]); + detail::incr::absorb_public_addend_all_lanes(dpf, leaf); acc.mac(leaf, (start + j) * opl, opl, weights); } start += seg.count; @@ -436,7 +600,7 @@ auto eval_out_inner_product_impl(const KeyT & dpf, LaneT from, LaneT to, template Beta eval_cmp_inner_product_impl(const KeyT & dpf, LaneT from, LaneT to, - Weights && weights) + Weights && weights, proof_token * pi = nullptr) { if (!dpf.has_cmp()) throw std::invalid_argument("cmp inner product: no comparison channel"); @@ -459,7 +623,7 @@ Beta eval_cmp_inner_product_impl(const KeyT & dpf, LaneT from, LaneT to, const std::size_t levels = unwrap_party_key_t::cmp_block > 0 ? unwrap_party_key_t::cmp_h : nbits; detail::incr::eval_cmp_interval_impl_interior(dpf, a, cmp_exclusive_end(b), - nbits, memo, levels); + nbits, memo, levels, pi); uint64_t dot = 0; for (std::size_t i = 0; i < count; ++i) @@ -486,9 +650,11 @@ Beta eval_cmp_inner_product_impl(const KeyT & dpf, LaneT from, LaneT to, } // namespace incr } // namespace detail +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. template , bool> = true> + std::enable_if_t, bool> = true, + std::enable_if_t>, int> = 0> auto eval_inner_product(out_t, const KeyT & key, LaneT from, LaneT to, Weights && weights, IntervalMemoizer && memo) { @@ -498,20 +664,24 @@ auto eval_inner_product(out_t, const KeyT & key, LaneT from, LaneT to, std::forward(memo)); } +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. template , bool> = true> + std::enable_if_t, bool> = true, + std::enable_if_t>, int> = 0> auto eval_inner_product(out_t, const KeyT & key, LaneT from, LaneT to, Weights && weights) { - auto memo = make_basic_interval_memoizer(from, to); + auto memo = make_basic_interval_memoizer(key, from, to); constexpr auto pref = detail::resolved_out_prefix(); return detail::incr::eval_out_inner_product_impl(key, from, to, std::forward(weights), memo); } +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. template + typename Weights, + std::enable_if_t>, int> = 0> Beta eval_inner_product(cmp_t, const KeyT & key, LaneT from, LaneT to, Weights && weights) { @@ -519,6 +689,106 @@ Beta eval_inner_product(cmp_t, const KeyT & key, LaneT from, LaneT to, std::forward(weights)); } +/// @brief Comparison inner product over the whole comparison domain. +/// @details `sum_x [x satisfies cmp] * weights[x]` (as complementary halves), +/// the full-domain form of `eval_inner_product(cmp, key, lo, hi, w)`. +/// Pair the two parties' results with `reconstruct_cmp_halves`. +/// Waldo's private-threshold aggregate is this one call. +/// \complexity Same expansion as `eval_full` on the comparison domain, plus a +/// multiply-add per point into an `O(1)` accumulator. +template >, int> = 0> +Beta eval_full_inner_product(cmp_t, const KeyT & key, Weights && weights) +{ + if (!key.has_cmp()) + throw std::invalid_argument( + "eval_full_inner_product(cmp): no comparison channel"); + using lane_t = typename KeyT::integral_type; + const auto nbits = static_cast(key.cmp().nbits); + const lane_t lo = 0; + const lane_t hi = (nbits >= 8 * sizeof(lane_t)) + ? static_cast(~lane_t{0}) + : static_cast((lane_t{1} << nbits) - 1); + return eval_inner_product(cmp, key, lo, hi, + std::forward(weights)); +} + +/// \complexity Same interior expansion as `eval_interval` on `[from, to]` (Θ(L) nodes, L = leaf nodes in the interval) plus a multiply-add per output slot into an O(1) accumulator. The basic memoizer still holds O(L) nodes. +template >, int> = 0> +Beta eval_inner_product(cmp_t, const KeyT & key, LaneT from, LaneT to, + Weights && weights, prove_ref pr) +{ + static_assert(KeyT::is_verifiable, + "eval_inner_product(cmp, ..., prove(π)): key must carry dpf::verifiable"); + detail::vdpf::init_proof(pr.token, key); + auto out = detail::incr::eval_cmp_inner_product_impl(key, from, to, + std::forward(weights), &pr.token); + detail::vdpf::fold_output_binding(pr.token, key); + return out; +} + +/// @brief Initialise `pr.token` and fold `[from, to]` once per cmp BFS node. +template >, int> = 0> +void prove_cmp_interval(const KeyT & key, LaneT from, LaneT to, prove_ref pr) +{ + static_assert(KeyT::is_verifiable, + "prove_cmp_interval: key must carry dpf::verifiable"); + detail::vdpf::init_proof(pr.token, key); + detail::incr::prove_fold_cmp_interval(key, from, to, pr.token); + detail::vdpf::fold_output_binding(pr.token, key); +} + +/// @brief Initialise `pr.token` and fold the full comparison domain. +template >, int> = 0> +void prove_cmp_full(const KeyT & key, prove_ref pr) +{ + static_assert(KeyT::is_verifiable, + "prove_cmp_full: key must carry dpf::verifiable"); + if (!key.has_cmp()) + throw std::invalid_argument("prove_cmp_full: no comparison channel"); + using lane_t = typename KeyT::integral_type; + const auto nbits = static_cast(key.cmp().nbits); + const lane_t lo = 0; + const lane_t hi = (nbits >= 8 * sizeof(lane_t)) + ? static_cast(~lane_t{0}) + : static_cast((lane_t{1} << nbits) - 1); + prove_cmp_interval(key, lo, hi, pr); +} + +/// @brief Fold a sorted sequence into `pr` via cmp interval-run covers. +template >, int> = 0> +void prove_cmp_sequence(const KeyT & key, ForwardIterator begin, + ForwardIterator end, prove_ref pr) +{ + static_assert(KeyT::is_verifiable, + "prove_cmp_sequence: key must carry dpf::verifiable"); + if (HEDLEY_UNLIKELY(begin != end && !std::is_sorted(begin, end))) + throw std::runtime_error("list must be sorted"); + detail::vdpf::init_proof(pr.token, key); + using lane_t = typename KeyT::integral_type; + for (auto it = begin; it != end; ) + { + const auto run_from = static_cast(*it); + auto run_to = run_from; + ++it; + while (it != end) + { + const auto next = static_cast(*it); + if (next != static_cast(run_to + lane_t{1})) + break; + run_to = next; + ++it; + } + detail::incr::prove_fold_cmp_interval(key, run_from, run_to, pr.token); + } + detail::vdpf::fold_output_binding(pr.token, key); +} + // --------------------------------------------------------------------------- // eval_sequence_breadth_first(out, key, begin, end [, outbuf]) // @@ -621,6 +891,8 @@ void eval_out_sequence_breadth_first_impl(const KeyT & dpf, auto leaf = dpf.template traverse_exterior(buf[j]); const std::size_t off = static_cast(static_cast(*curr) & (opl - 1)); + detail::incr::absorb_public_addend_lane(dpf, leaf, + static_cast(off)); auto v = dpf::extract_leaf(leaf, off); if constexpr (is_party_key_v) outbuf[i] = subtractive_share>::from_raw(v); @@ -633,9 +905,11 @@ void eval_out_sequence_breadth_first_impl(const KeyT & dpf, } // namespace incr } // namespace detail +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). template , bool> = true> + std::enable_if_t, bool> = true, + std::enable_if_t>, int> = 0> void eval_sequence_breadth_first(out_t, const KeyT & key, ForwardIterator begin, ForwardIterator end, OutputBuffer && outbuf) { @@ -644,9 +918,11 @@ void eval_sequence_breadth_first(out_t, const KeyT & key, std::forward(outbuf)); } +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). template , bool> = true> + std::enable_if_t, bool> = true, + std::enable_if_t>, int> = 0> auto eval_sequence_breadth_first(out_t, const KeyT & key, ForwardIterator begin, ForwardIterator end) { @@ -668,7 +944,8 @@ auto eval_sequence_breadth_first(out_t, const KeyT & key, /// @param end the iterator past the last query /// @return the constructed object template , bool> = true> + std::enable_if_t, bool> = true, + std::enable_if_t>, int> = 0> auto make_sequence_recipe(out_t, const KeyT & key, ForwardIterator begin, ForwardIterator end) { diff --git a/include/dpf/eval_until.hpp b/include/dpf/eval_until.hpp new file mode 100644 index 0000000..1041dda --- /dev/null +++ b/include/dpf/eval_until.hpp @@ -0,0 +1,323 @@ +/// @file dpf/eval_until.hpp +/// @brief Prefix-resuming evaluation for multilevel / incremental DPF keys. +/// @details Google's incremental-DPF `EvaluateUntil(level, prefixes, ctx)` +/// (Poplar / private heavy hitters, ePrint 2021/017) walks only the +/// live prefixes. `eval_prefixes` always restarts at the root and +/// materializes all `2^N` nodes; a path memoizer resumes one path. +/// `idpf_eval_ctx` keeps the interior node under each live prefix. +/// `eval_until(ctx, level, prefixes)` returns the output shares at +/// that hierarchy level for those prefixes only, then updates the +/// context. Empty `prefixes` on a fresh context (level 0) leaves the +/// root seed in place. Each later prefix must extend a prefix from +/// the previous call. +/// @see dpf/eval_walk.hpp (`eval_prefixes`), dpf/idpf_agg.hpp +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_EVAL_UNTIL_HPP__ +#define LIBDPF_INCLUDE_DPF_EVAL_UNTIL_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/dpf_key.hpp" +#include "dpf/eval_common.hpp" +#include "dpf/incremental.hpp" +#include "dpf/placement.hpp" +#include "dpf/secret_share.hpp" +#include "dpf/utils.hpp" + +namespace dpf +{ + +/// @brief Live-prefix evaluation context for a multilevel / idpf key. +/// @details Hierarchy level 0 holds only the root seed. After +/// `eval_until(..., L, prefixes)`, `level()` is `L` and +/// `node_count()` equals `prefixes.size()`. +/// \complexity O(|prefixes|) stored nodes (not O(2^level)). +template +class idpf_eval_ctx +{ + public: + using key_type = unwrap_party_key_t; + using input_type = typename key_type::input_type; + using node_type = typename key_type::interior_node; + + explicit idpf_eval_ctx(const KeyT & key) + : key_{&key}, level_{0}, prefixes_{}, nodes_{} + { + nodes_.push_back(static_cast(key).root()); + // Compact parent of every length-1 prefix is the empty prefix `0`. + prefixes_.push_back(input_type{0}); + } + + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + const KeyT & key() const noexcept { return *key_; } + + /// @brief Last hierarchy level that `eval_until` wrote (0 = root only). + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + std::size_t level() const noexcept { return level_; } + + /// @brief Number of saved interior nodes (one per live prefix). + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + std::size_t node_count() const noexcept { return nodes_.size(); } + + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + const std::vector & prefixes() const noexcept + { + return prefixes_; + } + + /// @brief Drop every saved prefix except `prefix` (must be live). + void retain(input_type prefix) + { + for (std::size_t i = 0; i < prefixes_.size(); ++i) + { + if (prefixes_[i] == prefix) + { + prefixes_ = {prefix}; + nodes_ = {nodes_[i]}; + return; + } + } + throw std::invalid_argument( + "idpf_eval_ctx::retain: prefix is not live in this context"); + } + + private: + template + friend auto eval_until(idpf_eval_ctx & ctx, std::size_t level, + PrefRange && prefixes); + + const KeyT * key_; + std::size_t level_; + std::vector prefixes_; + std::vector nodes_; +}; + +namespace detail +{ +namespace eval_until_detail +{ + +template +HEDLEY_NO_THROW +constexpr std::size_t slot_for_prefix(std::size_t prefix_len) noexcept +{ + for (std::size_t i = 0; i < KeyT::num_outputs; ++i) + { + if (KeyT::meta[i].prefix == prefix_len) + return i; + } + return static_cast(-1); +} + +template +HEDLEY_NO_THROW +constexpr std::size_t tree_level_for_prefix(std::size_t prefix_len) noexcept +{ + const auto i = slot_for_prefix(prefix_len); + return (i == static_cast(-1)) ? static_cast(-1) + : KeyT::meta[i].tree_level; +} + +/// @brief Walk `from_tree_level` → `to_tree_level` along the high bits of `x`. +/// \complexity O(to − from) interior traversals. +template +HEDLEY_ALWAYS_INLINE +Node walk_interior(const KeyT & key, Node node, typename KeyT::input_type x, + std::size_t from_tree_level, std::size_t to_tree_level) +{ + using key_type = KeyT; + if (to_tree_level <= from_tree_level) + return node; + auto level_index = from_tree_level + 1; + auto mask = key.msb_mask >> (level_index - 1); + for (; level_index <= to_tree_level; ++level_index, mask >>= 1) + { + const bool bit = !!(mask & x); + auto cw = key.correction_word(level_index - 1, bit); + const bool is_last = key_type::tree::is_last_level(level_index - 1, + key.depth); + node = key_type::traverse_interior(node, cw, bit, is_last); + } + return node; +} + +template +HEDLEY_ALWAYS_INLINE +auto exterior_at(const KeyT & key, const Node & node, InputT domain_x) +{ + using key_type = unwrap_party_key_t; + using output_type = typename key_type::template concrete_output_type; + constexpr auto N = key_type::meta[I].prefix; + // `traverse_exterior` lives on the underlying key; party_key inherits it. + auto leaf = key.template traverse_exterior(node); + auto lane_x = detail::incr::lane_input(domain_x, N, key_type::input_bits); + detail::incr::absorb_public_addend_lane( + static_cast(key), leaf, lane_x); + // Pass the party-tagged key type so the share carries the party id. + return *make_eval_dpf_output(leaf, lane_x); +} + +template +HEDLEY_ALWAYS_INLINE +bool exterior_dispatch(std::size_t slot, const KeyT & key, const Node & node, + InputT domain_x, Out & out, std::index_sequence) +{ + return ((Is == slot + ? (out = exterior_at(key, node, domain_x), true) + : false) + || ...); +} + +template +HEDLEY_ALWAYS_INLINE +auto share_type_tag() +{ + using key_type = unwrap_party_key_t; + using output_type = typename key_type::template concrete_output_type<0>; + return eval_leaf_result_t{}; +} + +} // namespace eval_until_detail +} // namespace detail + +/// @brief Evaluate output shares at hierarchy `level` for `prefixes` only. +/// @details Each prefix is a compact integer in `[0, 2^level)`. The first call +/// may pass an empty range at level 0 to keep the root seed. Later +/// calls require `level > ctx.level()` and every prefix to extend one +/// saved parent. Returns one share per prefix, in the same order. +/// Opened values match `eval_point(out, key, domain)` for the +/// same prefix length (see `eval_until_test`). +/// \complexity O(|prefixes| · (level − ctx.level())) interior traversals. +/// Saved nodes stay O(|prefixes|), not O(2^level). +/// @see ePrint 2021/017 (Poplar EvaluateUntil), ePrint 2024/1190 (I-DPF agg) +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_until(idpf_eval_ctx & ctx, std::size_t level, + PrefRange && prefixes) +{ + using key_type = typename idpf_eval_ctx::key_type; + using input_type = typename idpf_eval_ctx::input_type; + using node_type = typename idpf_eval_ctx::node_type; + using share_type = decltype(detail::eval_until_detail::share_type_tag()); + static_assert(is_multilevel_key_v, + "eval_until requires a multilevel / incremental DPF key"); + + const KeyT & key_ref = ctx.key(); + const key_type & key = static_cast(key_ref); + + std::vector pref_list; + for (auto && p : prefixes) + pref_list.push_back(static_cast(p)); + + if (pref_list.empty()) + { + if (ctx.level_ != 0 || level != 0) + { + throw std::invalid_argument( + "eval_until: empty prefixes only valid on a fresh context at level 0"); + } + return std::vector{}; + } + + if (level == 0) + { + throw std::invalid_argument( + "eval_until: level 0 has only the root; pass a positive hierarchy level"); + } + if (level <= ctx.level_) + { + throw std::invalid_argument( + "eval_until: level must strictly advance past the context level"); + } + if (level > key_type::input_bits) + { + throw std::invalid_argument( + "eval_until: level exceeds the input bit length"); + } + + const auto slot = detail::eval_until_detail::slot_for_prefix(level); + if (slot == static_cast(-1)) + { + throw std::invalid_argument( + "eval_until: key has no output planted at that prefix length"); + } + const auto to_tree = + detail::eval_until_detail::tree_level_for_prefix(level); + const std::size_t from_tree = (ctx.level_ == 0) + ? 0 + : detail::eval_until_detail::tree_level_for_prefix(ctx.level_); + + constexpr auto bits = key_type::input_bits; + const auto parent_shift = level - ctx.level_; + + std::vector new_nodes; + std::vector shares; + new_nodes.reserve(pref_list.size()); + shares.reserve(pref_list.size()); + + for (auto p : pref_list) + { + if (level < bits && (static_cast(p) >> level) != 0) + { + throw std::invalid_argument( + "eval_until: prefix does not fit in the requested bit length"); + } + const input_type parent = static_cast(p >> parent_shift); + std::size_t parent_idx = static_cast(-1); + for (std::size_t i = 0; i < ctx.prefixes_.size(); ++i) + { + if (ctx.prefixes_[i] == parent) + { + parent_idx = i; + break; + } + } + if (parent_idx == static_cast(-1)) + { + throw std::invalid_argument( + "eval_until: prefix does not extend a live parent"); + } + + auto domain_x = static_cast( + static_cast(p) << (bits - level)); + domain_x = key.offset_x(domain_x); + utils::flip_msb_if_signed_integral(domain_x); + + node_type node = detail::eval_until_detail::walk_interior(key, + ctx.nodes_[parent_idx], domain_x, from_tree, to_tree); + + share_type share{}; + const bool ok = detail::eval_until_detail::exterior_dispatch(slot, + key_ref, node, domain_x, share, + std::make_index_sequence{}); + if (!ok) + { + throw std::logic_error("eval_until: exterior dispatch missed slot"); + } + new_nodes.push_back(node); + shares.push_back(share); + } + + ctx.level_ = level; + ctx.prefixes_ = std::move(pref_list); + ctx.nodes_ = std::move(new_nodes); + return shares; +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_EVAL_UNTIL_HPP__ diff --git a/include/dpf/eval_walk.hpp b/include/dpf/eval_walk.hpp new file mode 100644 index 0000000..c41491b --- /dev/null +++ b/include/dpf/eval_walk.hpp @@ -0,0 +1,449 @@ +/// @file dpf/eval_walk.hpp +/// @brief Walk helpers that fold a small operation into an existing DPF walk. +/// @details These are the calls the protocol mockups in +/// `examples/applications/` had to build by hand around a walk: +/// - `dpf::rotate{s}` weights the walk by `w[(i + s) mod 2^n]` +/// (Duoram's read, Pika's lookup) with no second vector. +/// - `eval_full_add_into(buf, key)` adds a full-domain expansion +/// into a buffer the caller already holds (Prio's histogram, +/// Express's mailbox, Duoram's update). A `rotate` overload shifts +/// the write; a `sketch` overload folds the audit in the same pass. +/// - `dpf::cyclic_shift(buf, s)` rotates a materialized share buffer, +/// `new[i] = old[(i - s) mod n]`. +/// - `dpf::pack_bit_columns(keys...)` runs the full-domain bit walk +/// once per key and packs one integer per row (lane `e` is key `e`), +/// the digit BitMore reads when the server count is a power of two. +/// - `dpf::mod_bit_columns<ℓ>(keys...)` is that digit modulo `ℓ` when +/// the server count is not a power of two. The first key is still +/// the low bit. The running residue stays in a byte through `ℓ = 128` +/// and in a 16-bit lane through `ℓ = 32768`. +/// - `eval_prefixes(out, key)` returns the `2^N` prefix shares, +/// and `eval_prefix_inner_product(out, key, values)` dots them +/// with `values` in one walk to depth `N` (Poplar, PRAC). +/// - `idpf_eval_ctx` / `eval_until` (see `dpf/eval_until.hpp`) resume +/// under a live prefix list instead of materializing `2^N` nodes. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_EVAL_WALK_HPP__ +#define LIBDPF_INCLUDE_DPF_EVAL_WALK_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/bitmore_mod.hpp" +#include "dpf/eval_target.hpp" +#include "dpf/eval_full.hpp" +#include "dpf/eval_inner_product.hpp" +#include "dpf/eval_unified.hpp" +#include "dpf/output_buffer.hpp" +#include "dpf/utils.hpp" +#include "dpf/verifiable.hpp" + +namespace dpf +{ + +/// @brief Rotation offset applied inside a walk: domain point `i` uses lane +/// `(i + shift) mod 2^n`. Pass to `eval_full_inner_product` / +/// `eval_full_add_into` so the caller does not build a second vector. +struct rotate +{ + std::size_t shift; +}; + +namespace detail_walk +{ + +/// @brief Number of input points `2^n` of `KeyT`, as a `std::size_t`. +template +HEDLEY_NO_THROW +constexpr std::size_t domain_size() noexcept +{ + constexpr std::size_t bits = + utils::bitlength_of_v; + static_assert(bits < 8 * sizeof(std::size_t), + "walk helper: input domain does not fit a std::size_t index"); + return std::size_t{1} << bits; +} + +/// @brief `w[(i + shift) mod n]`, a read-only rotated view of `w`. +template +struct rotated_weights +{ + const Weights & w; + std::size_t shift; + std::size_t n; + + HEDLEY_ALWAYS_INLINE + decltype(auto) operator[](std::size_t i) const + { + return w[(i + shift) % n]; + } +}; + +template +struct has_raw : std::false_type {}; +template +struct has_raw().raw())>> + : std::true_type {}; + +/// @brief The group element carried by an eval buffer slot. A one-word share +/// (`additive`, `subtractive`, or `additive3`) exposes it through +/// `.raw()`. A replicated share has two components and is returned +/// as itself. A raw output type is returned unchanged. +template +HEDLEY_ALWAYS_INLINE +auto group_value(const T & v) +{ + if constexpr (has_raw::value) + return v.raw(); + else + return v; +} + +/// @brief Call `fn` on `keys` from the last key down to the first. +/// @details `mod_bit_columns` inserts the high bit first. Key 0 stays the low +/// bit, matching `pack_bit_columns`. +template +void insert_keys_msb_first(Fn && fn, Tuple && keys, std::index_sequence) +{ + constexpr std::size_t n = sizeof...(I); + (fn(std::get(keys)), ...); +} + +} // namespace detail_walk + +// --------------------------------------------------------------------------- +// dpf::rotate on the paired full-domain inner product +// --------------------------------------------------------------------------- + +/// @brief `sum_i DPF_I(i) * rows[(i + rot.shift) mod 2^n]` over the whole domain. +/// @details The same paired walk as `eval_full_inner_product(paired, key, rows)`, +/// but the weight at domain point `i` is read from `rows` rotated by +/// `rot.shift`. Duoram's read and Pika's lookup pass the unrotated +/// table and this offset instead of materializing a rotated copy. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_full_inner_product(paired_t, const DpfKey & dpf, Rows && rows, + rotate rot) +{ + constexpr std::size_t n = detail_walk::domain_size(); + detail_walk::rotated_weights> view{ + rows, rot.shift % n, n}; + return eval_full_inner_product(paired, dpf, view); +} + +// --------------------------------------------------------------------------- +// eval_full_add_into(buf, key [, rotate | sketch]) +// --------------------------------------------------------------------------- + +/// @brief Add a full-domain expansion of output `I` into `buf` in place. +/// @details `buf[i] += DPF_I(i)` (the leaf share's group element) for every +/// domain point `i`. `buf` already holds the caller's running shares +/// (Prio's histogram, Express's mailbox, Duoram's update); its element +/// type must support `+` with the leaf share's group element. +/// \complexity One full-domain expansion, `Θ(2^n)`, plus one `+` per point. +template + && !is_multilevel_key_v, bool> = true> +void eval_full_add_into(Buffer & buf, const DpfKey & dpf) // NOLINT(runtime/references) +{ + auto result = eval_full(dpf); + auto & iter = result.second; + std::size_t i = 0; + for (auto it = std::begin(iter); it != std::end(iter); ++it, ++i) + buf[i] = buf[i] + detail_walk::group_value(*it); +} + +/// @brief Add a full-domain expansion into `buf`, shifted by `rot`. +/// @details `buf[(i + rot.shift) mod 2^n] += DPF_I(i)`. Duoram's update writes +/// the payload placed at `r` into the memory slot `r + shift`. +/// \complexity One full-domain expansion, `Θ(2^n)`, plus one `+` per point. +template + && !is_multilevel_key_v, bool> = true> +void eval_full_add_into(Buffer & buf, const DpfKey & dpf, rotate rot) // NOLINT(runtime/references) +{ + constexpr std::size_t n = detail_walk::domain_size(); + const std::size_t s = rot.shift % n; + auto result = eval_full(dpf); + auto & iter = result.second; + std::size_t i = 0; + for (auto it = std::begin(iter); it != std::end(iter); ++it, ++i) + { + const std::size_t j = (i + s) % n; + buf[j] = buf[j] + detail_walk::group_value(*it); + } +} + +/// @brief Add a full-domain expansion into `buf` and fold the audit sketch. +/// @details `buf[i] += DPF_I(i)` for every point, and each written share is +/// absorbed into `sk` — the same one-hot audit as +/// `eval_full(key, sketch(σ))`, in the same pass. Express's mailbox +/// write becomes one call instead of a point loop and a second fold. +/// \complexity One full-domain expansion, `Θ(2^n)`, plus one `+` and one +/// absorb per point. +template + && !is_multilevel_key_v, bool> = true> +void eval_full_add_into(Buffer & buf, const DpfKey & dpf, sketch_ref sk) // NOLINT(runtime/references) +{ + static_assert(DpfKey::is_extractable, + "eval_full_add_into(..., sketch(σ)): key must carry dpf::extractable"); + auto result = eval_full(dpf); + auto & iter = result.second; + std::size_t i = 0; + for (auto it = std::begin(iter); it != std::end(iter); ++it, ++i) + { + auto g = detail_walk::group_value(*it); + buf[i] = buf[i] + g; + sk.absorb(g); // fold the raw share, as eval_point(..., sketch) does + } +} + +// --------------------------------------------------------------------------- +// dpf::cyclic_shift(buffer, s) +// --------------------------------------------------------------------------- + +/// @brief A copy of `buf` rotated so `result[i] == buf[(i - s) mod n]`. +/// @details The buffer analogue of `dpf::rotate{s}`: the value at index `k` +/// moves to `k + s`. Duoram's update shifts an expanded share buffer +/// this way before adding it into memory. +template +HEDLEY_WARN_UNUSED_RESULT +Container cyclic_shift(const Container & buf, std::size_t s) +{ + Container out(buf); + const std::size_t n = buf.size(); + if (n == 0) + return out; + const std::size_t sh = s % n; + for (std::size_t i = 0; i < n; ++i) + out[i] = buf[(i + n - sh) % n]; + return out; +} + +// --------------------------------------------------------------------------- +// dpf::pack_bit_columns(keys...) +// --------------------------------------------------------------------------- + +/// @brief Pack the full-domain bit expansions of `keys` into one integer per row. +/// @details Runs `eval_full` once per key over a shared bit domain and sets bit +/// `e` of `result[row]` when key `e` opens to 1 at that row. `L` keys +/// need `L <= 8*sizeof(Int)`. BitMore reads `result[row]` as the +/// server's `L`-bit digit instead of unpacking one `int` per bit. +/// @tparam Int packed digit type (defaults to `std::uint64_t`) +/// \complexity One full-domain bit expansion per key, `Θ(L · 2^n)`. +template +HEDLEY_WARN_UNUSED_RESULT +std::vector pack_bit_columns(const First & first, const Rest &... rest) +{ + static_assert(1 + sizeof...(Rest) <= 8 * sizeof(Int), + "pack_bit_columns: more keys than bits in the packed digit type"); + constexpr std::size_t n = detail_walk::domain_size(); + std::vector out(n, Int{0}); + + std::size_t e = 0; + auto do_one = [&](const auto & key) + { + auto result = eval_full(key); + auto & iter = result.second; + std::size_t row = 0; + for (auto it = std::begin(iter); it != std::end(iter) && row < n; + ++it, ++row) + { + if (static_cast(*it)) + out[row] |= static_cast(Int{1} << e); + } + ++e; + }; + do_one(first); + (do_one(rest), ...); + return out; +} + +// --------------------------------------------------------------------------- +// dpf::mod_bit_columns<ℓ>(keys...) +// --------------------------------------------------------------------------- + +/// @brief One residue per row: the packed bit columns, modulo `Modulus`. +/// @details The same full-domain bit walk as `pack_bit_columns`. Key 0 is the +/// low bit, so row `r` opens to `(sum_e bit_e(r) · 2^e) mod Modulus`. +/// Bits are folded high-bit first. Through modulus 128 each running +/// slot is a byte; through 32768 it is a 16-bit lane. Both use the +/// high-nibble partial reduction, and only the finished row is fully +/// reduced. Hafiz and Henry §5.3 read `result[row]` as the server's +/// digit when the server count is not a power of two. +/// @tparam Modulus server count, `2` through `32768` +/// @tparam Int residue type (defaults to `std::uint16_t`) +/// \complexity One full-domain bit expansion per key, `Θ(L · 2^n)`, and one +/// lane insertion per row per key. +template +HEDLEY_WARN_UNUSED_RESULT +std::vector mod_bit_columns(const First & first, const Rest &... rest) +{ + static_assert(Modulus >= 2u && Modulus <= 32768u, + "mod_bit_columns: modulus must be in 2..32768"); + static_assert(std::is_unsigned_v, + "mod_bit_columns: residue type must be unsigned"); + static_assert(Modulus - 1u <= static_cast(std::numeric_limits::max()), + "mod_bit_columns: residue type cannot hold a value modulo Modulus"); + + constexpr unsigned lane_bits = Modulus <= 128u ? 8u : 16u; + using reg = simde__m256i; + using acc = bitmore_accumulator; + constexpr std::size_t lanes = lane_bits == 8u ? 32u : 16u; + constexpr std::size_t n = detail_walk::domain_size(); + const std::size_t chunks = (n + lanes - 1u) / lanes; + + std::vector running(chunks); + const auto keys = std::forward_as_tuple(first, rest...); + detail_walk::insert_keys_msb_first([&](const auto & key) + { + using key_t = std::decay_t; + static_assert(detail_walk::domain_size() == n, + "mod_bit_columns: every key must share the first key's domain"); + auto result = eval_full(key); + auto & iter = result.second; + auto it = std::begin(iter); + const auto end = std::end(iter); + for (std::size_t c = 0; c < chunks; ++c) + { + reg bits{}; + if constexpr (lane_bits == 8u) + { + alignas(32) unsigned char raw[32]{}; + for (std::size_t i = 0; i < lanes && it != end; ++i, ++it) + raw[i] = static_cast(*it) ? 1u : 0u; + std::memcpy(&bits, raw, sizeof(bits)); + } + else + { + alignas(32) std::uint16_t raw[16]{}; + for (std::size_t i = 0; i < lanes && it != end; ++i, ++it) + raw[i] = static_cast(*it) ? 1u : 0u; + std::memcpy(&bits, raw, sizeof(bits)); + } + running[c].insert_bit(bits); + } + }, keys, std::make_index_sequence<1u + sizeof...(Rest)>{}); + + std::vector out(n); + std::size_t row = 0; + for (std::size_t c = 0; c < chunks; ++c) + { + const reg reduced = running[c].reduced(); + if constexpr (lane_bits == 8u) + { + alignas(32) unsigned char raw[32]{}; + std::memcpy(raw, &reduced, sizeof(raw)); + for (std::size_t i = 0; i < lanes && row < n; ++i, ++row) + out[row] = static_cast(raw[i]); + } + else + { + alignas(32) std::uint16_t raw[16]{}; + std::memcpy(raw, &reduced, sizeof(raw)); + for (std::size_t i = 0; i < lanes && row < n; ++i, ++row) + out[row] = static_cast(raw[i]); + } + } + return out; +} + +// --------------------------------------------------------------------------- +// eval_prefixes / eval_prefix_inner_product (idpf prefix walk) +// --------------------------------------------------------------------------- + +/// @brief The `2^N` prefix shares of output `I` (prefix length `N`). +/// @details One walk to depth `N`; slot `p` is the share on prefix `p`. Poplar +/// reads these to score every node at a depth in one pass instead of +/// one `eval_point` per node. Returns the `(buffer, iterable)` pair of +/// `eval_full(out, key)`. +/// \complexity One walk to depth `N`: `Θ(N + 2^N)` interior traversals. +template , bool> = true> +HEDLEY_WARN_UNUSED_RESULT +auto eval_prefixes(out_t, const KeyT & key) +{ + return eval_full(out_t{}, key); +} + +/// @brief `sum_p DPF_I(p) * values[p]` over the `2^N` prefixes of output `I`. +/// @details Walks to depth `N` once and dots the prefix shares with `values` +/// (indexed by prefix `0 .. 2^N - 1`). PRAC's strides and Poplar's +/// "is this prefix heavy?" are this one call, replacing an +/// `eval_point` per node. +/// \complexity One walk to depth `N`, `Θ(N + 2^N)`, plus one multiply-add per +/// prefix into an `O(1)` accumulator. +template , bool> = true> +HEDLEY_WARN_UNUSED_RESULT +auto eval_prefix_inner_product(out_t, const KeyT & key, Values && values) +{ + using lane_t = typename KeyT::input_type; + constexpr lane_t lo = lane_t{0}; + constexpr lane_t hi = (N >= utils::bitlength_of_v) + ? static_cast(~lane_t{0}) + : static_cast((lane_t{1} << N) - 1); + return eval_inner_product(out_t{}, key, lo, hi, + std::forward(values)); +} + +/// @brief XOR of `records[j]` for each listed point where the bit share is set. +/// @details Same walk as `eval_sequence` on a bit key, but folds the selected +/// records into one accumulator instead of materializing a bit vector. +/// Keyword PIR's server response is this one call. +template >, int> = 0> +HEDLEY_WARN_UNUSED_RESULT +auto eval_sequence_xor(const DpfKey & key, ForwardIterator begin, + ForwardIterator end, Records && records) +{ + using record_t = std::decay_t; + record_t acc{}; + auto [buf, iter] = eval_sequence(key, begin, end); + std::size_t i = 0; + for (auto bit : iter) + { + if (static_cast(bit)) + acc = static_cast(acc ^ records[i]); + ++i; + } + return acc; +} + +/// @brief Evaluate a walk while invoking `fold(index, share)` once per written output. +/// @details The fold is a template — inlined the way `sketch_ref::absorb` is. +/// Express's audit, Pika's SZ check, and a SNIP input vector each +/// supply their own fold over the group they write. +template + && !is_multilevel_key_v + && !std::is_same_v, sketch_ref> + && !std::is_same_v, rotate>, bool> = true> +void eval_full_add_into(Buffer & buf, const DpfKey & dpf, Fold && fold) // NOLINT(runtime/references) +{ + auto result = eval_full(dpf); + auto & iter = result.second; + std::size_t i = 0; + for (auto it = std::begin(iter); it != std::end(iter); ++it, ++i) + { + auto g = detail_walk::group_value(*it); + buf[i] = buf[i] + g; + fold(i, g); + } +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_EVAL_WALK_HPP__ diff --git a/include/dpf/experiment.hpp b/include/dpf/experiment.hpp new file mode 100644 index 0000000..9ef0216 --- /dev/null +++ b/include/dpf/experiment.hpp @@ -0,0 +1,876 @@ +/// @file dpf/experiment.hpp +/// @brief Replayable master seed + paper-ready protocol cost CSVs. +/// @details A master covers the thread that installs it. `derive_party(i)` +/// gives party `i` of a run its own stream, keyed by SHA-256 of the +/// master and `i`, and `app::run_parties` installs one on each party +/// thread, so replaying a master replays every party. Kernels handed +/// to a compute pool draw from their party's stream +/// (`dpf/thread_work.hpp`). Every CSV row carries the invocation id +/// of the process that wrote it (`log::invocation_id()`), and a file +/// whose header does not match this layout is moved aside rather +/// than appended to. +#ifndef LIBDPF_INCLUDE_DPF_EXPERIMENT_HPP__ +#define LIBDPF_INCLUDE_DPF_EXPERIMENT_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dpf/compose.hpp" +#include "dpf/experiment_note.hpp" +#include "dpf/log.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/prg_count.hpp" +#include "dpf/protocol.hpp" +#include "dpf/random.hpp" +#include "dpf/thread_work.hpp" + +namespace dpf +{ + +using protocol::round_event; +using protocol::round_probe; + +/// @brief Per-thread experiment: master seed stream + cost meter + CSV export. +class experiment : public detail::experiment_seed_sink +{ +public: + static constexpr std::size_t master_bytes = 32; + + using master_seed = std::array; + + /// @brief Where a master came from. + enum class origin : unsigned char + { + fresh, ///< drawn from OS entropy + provided, ///< given to `replay` + derived ///< `derive_party` of another master + }; + + struct noted_seed + { + std::string name; + std::vector bytes; + }; + + /// @brief Fresh master seed from the system entropy source. + /// @details Always reads the OS entropy path (never an outer experiment + /// hook), so nested contexts do not steal the parent stream. + explicit experiment(std::string name, std::string party = "p0") + : name_(std::move(name)), party_(std::move(party)) + { + draw_system_master_(); + // Master itself must not count as protocol random consumption. + reset_random_bytes_count(); + prg::reset_eval_count(); + install_(); + note("master", master_.data(), master_.size()); + log_master_(); + } + + /// @brief Replay a previously recorded master seed. + static experiment replay(std::string name, const master_seed & seed, + std::string party = "p0") + { + return experiment(std::move(name), std::move(party), seed, origin::provided); + } + + /// @brief The stream party `party` of a run draws from, installed on the + /// calling thread (call it on that party's thread). Its master is + /// SHA-256 of this master and the party index, so one master + /// always yields the same party streams. + experiment derive_party(unsigned party) const + { + std::uint8_t in[master_bytes + 4]; + std::memcpy(in, master_.data(), master_bytes); + for (int i = 0; i < 4; ++i) + in[master_bytes + static_cast(i)] = + static_cast((party >> (8 * i)) & 0xffu); + const auto digest = log::detail::sha256("libdpf experiment party", in, sizeof(in)); + master_seed derived{}; + std::memcpy(derived.data(), digest.data(), derived.size()); + return experiment(name_, "p" + std::to_string(party), derived, origin::derived); + } + + experiment(const experiment &) = delete; + experiment & operator=(const experiment &) = delete; + + experiment(experiment && other) noexcept + : name_(std::move(other.name_)), + party_(std::move(other.party_)), + run_id_(other.run_id_), + master_(other.master_), + origin_(other.origin_), + aes_seed_(other.aes_seed_), + ctr_(other.ctr_), + buf_pos_(other.buf_pos_), + prev_hook_(other.prev_hook_), + prev_ctx_(other.prev_ctx_), + prev_sink_(other.prev_sink_), + installed_(other.installed_), + seeds_(std::move(other.seeds_)), + rounds_(std::move(other.rounds_)), + edge_in_(std::move(other.edge_in_)), + edge_out_(std::move(other.edge_out_)), + edge_plan_out_(std::move(other.edge_plan_out_)), + interactive_rounds_(other.interactive_rounds_), + dag_depth_(other.dag_depth_), + critical_path_(std::move(other.critical_path_)), + wall_ns_(other.wall_ns_), + cpu_ns_(other.cpu_ns_), + prg_evals_(other.prg_evals_), + sym_(other.sym_), + random_bytes_(other.random_bytes_), + bytes_in_(other.bytes_in_), + bytes_out_(other.bytes_out_), + plan_bytes_out_(other.plan_bytes_out_), + config_(std::move(other.config_)), + trials_(std::move(other.trials_)), + party_trials_(std::move(other.party_trials_)), + wire_(other.wire_), + timing_started_(other.timing_started_), + wall0_(other.wall0_), + cpu0_(other.cpu0_) + { + std::memcpy(buf_, other.buf_, sizeof(buf_)); + other.installed_ = false; + if (installed_) + { + detail::uniform_bytes_hook = &experiment::hook_; + detail::uniform_bytes_ctx = this; + detail::experiment_seed_sink_tls = this; + } + } + + ~experiment() override { uninstall_(); } + + const std::string & name() const noexcept { return name_; } + const std::string & party() const noexcept { return party_; } + const master_seed & seed() const noexcept { return master_; } + std::uint64_t run_id() const noexcept { return run_id_; } + + void set_run_id(std::uint64_t id) noexcept { run_id_ = id; } + void set_party(std::string party) { party_ = std::move(party); } + + /// @brief Public alias of `note` for call-site labels. + void note_seed(const char * name, const void * bytes, std::size_t n) + { + note(name, static_cast(bytes), n); + } + + template + void note_seed(const char * name, const T & seed) + { + note_seed(name, &seed, sizeof(seed)); + } + + void note(const char * name, const std::uint8_t * bytes, + std::size_t n) override + { + if (name == nullptr || bytes == nullptr || n == 0) + return; + seeds_.push_back({name, std::vector(bytes, bytes + n)}); + if (std::strcmp(name, "master") != 0) + DPF_LOG(debug, "seed").kv("name", name).kv("experiment", name_) + .kv("party", party_).kv("source", "noted").kv("bytes", n) + .seed("value", bytes, n); + } + + /// @brief Noted seeds in order, starting with `master`. + const std::vector & seeds() const noexcept { return seeds_; } + + /// @brief Append a party stream's noted seeds, each name prefixed by + /// `party` (`p1/master`, `p1/buffered_prg`). + void fold_seeds(const std::string & party, const std::vector & seeds) + { + for (const auto & s : seeds) + seeds_.push_back({party + "/" + s.name, s.bytes}); + } + + origin seed_origin() const noexcept { return origin_; } + + /// @brief True when the master was not drawn fresh (`replay` or + /// `derive_party`). + bool seed_provided() const noexcept { return origin_ != origin::fresh; } + + static const char * origin_name(origin o) noexcept + { + switch (o) + { + case origin::fresh: + return "fresh"; + case origin::provided: + return "provided"; + case origin::derived: + return "derived"; + } + return "fresh"; + } + + /// @brief Symmetric-key blocks counted between `begin_timing` and + /// `end_timing`, by purpose and primitive (see `prg_count.hpp`). + const prg::counts & sym_counts() const noexcept { return sym_; } + + /// @brief Record static plan facts (chain length, per-edge schedule bytes). + void ingest_plan(const protocol::plan & p) + { + interactive_rounds_ = p.rounds(); + dag_depth_ = p.waves(); + plan_bytes_out_ = 0; + for (auto n : p.slot_bytes_all()) + plan_bytes_out_ += n; + edge_plan_out_.clear(); + for (std::size_t wi = 0; wi < p.waves(); ++wi) + { + const auto & w = p.wave(wi); + if (w.exchanges.empty()) + continue; + const auto ch = protocol::detail::wave_channel(p, w); + edge_plan_out_[static_cast(ch)] += w.slot_bytes; + } + critical_path_ = build_critical_path_(p); + } + + /// @brief Probe that records live round events into this experiment. + round_probe probe() noexcept + { + return round_probe{this, &experiment::on_round_}; + } + + /// @brief Start wall/CPU/PRG/random timers (call before drive). + void begin_timing() + { + prg::reset_eval_count(); + reset_random_bytes_count(); + wall0_ = steady_now_(); + cpu0_ = thread_cpu_now_(); + timing_started_ = true; + } + + /// @brief Stop timers and fold totals. + void end_timing() + { + if (!timing_started_) + return; + wall_ns_ += steady_now_() - wall0_; + cpu_ns_ += thread_cpu_now_() - cpu0_; + prg_evals_ += prg::eval_count(); + const auto sym = prg::snapshot(); + for (std::size_t i = 0; i < sym.size(); ++i) + sym_[i] += sym[i]; + random_bytes_ += random_bytes_count(); + timing_started_ = false; + } + + std::uint64_t wall_ns() const noexcept { return wall_ns_; } + std::uint64_t cpu_ns() const noexcept { return cpu_ns_; } + std::uint64_t prg_evals() const noexcept { return prg_evals_; } + std::uint64_t random_bytes() const noexcept { return random_bytes_; } + std::size_t bytes_in() const noexcept { return bytes_in_; } + std::size_t bytes_out() const noexcept { return bytes_out_; } + std::size_t interactive_rounds() const noexcept + { + return interactive_rounds_; + } + std::size_t dag_depth() const noexcept { return dag_depth_; } + std::size_t plan_bytes_out() const noexcept { return plan_bytes_out_; } + const std::vector & rounds() const noexcept { return rounds_; } + std::size_t seed_count() const noexcept { return seeds_.size(); } + std::size_t critical_path_length() const noexcept + { + return critical_path_.size(); + } + + /// @brief True if a seed named `name` was noted (including `"master"`). + bool has_seed_named(const char * name) const + { + if (name == nullptr) + return false; + for (const auto & s : seeds_) + if (s.name == name) + return true; + return false; + } + + /// @brief Schedule bytes attributed to `channel` by `ingest_plan`. + std::size_t plan_edge_bytes(protocol::edge_channel channel) const + { + return edge_get_(edge_plan_out_, static_cast(channel)); + } + + /// @brief Live bytes in/out attributed to `channel` by the round probe. + std::size_t edge_bytes_in(protocol::edge_channel channel) const + { + return edge_get_(edge_in_, static_cast(channel)); + } + std::size_t edge_bytes_out(protocol::edge_channel channel) const + { + return edge_get_(edge_out_, static_cast(channel)); + } + + std::string seed_hex() const { return to_hex_(master_.data(), master_.size()); } + + /// @brief On-the-wire counters for party 0's links (headers included). + struct wire_counts + { + std::uint64_t bytes_out = 0; + std::uint64_t bytes_in = 0; + std::uint64_t payload_out = 0; + std::uint64_t payload_in = 0; + std::uint64_t frames_out = 0; + std::uint64_t frames_in = 0; + std::uint64_t write_calls = 0; + }; + + /// @brief Run configuration recorded in `config.csv` (key, value). + void set_config(std::vector> kv) + { + config_ = std::move(kv); + } + const std::vector> & config() const noexcept + { + return config_; + } + + /// @brief One timed trial: party 0's wall time and, when given, every + /// party's (`party_walls[i]` is party `i`). Recorded in `trials.csv`. + void add_trial(std::uint64_t wall_ns, + const std::vector & party_walls = {}) + { + trials_.push_back(wall_ns); + party_trials_.push_back(party_walls); + } + const std::vector & trials() const noexcept { return trials_; } + + /// @brief Median of party 0's trial wall times (0 when none). + std::uint64_t median_trial_ns() const { return median_(trials_); } + + /// @brief Median over trials of the slowest party's wall time (party 0's + /// when a trial did not record the others). + std::uint64_t slowest_median_ns() const + { + std::vector slowest; + for (std::size_t t = 0; t < trials_.size(); ++t) + { + std::uint64_t w = trials_[t]; + if (t < party_trials_.size()) + for (auto p : party_trials_[t]) + w = std::max(w, p); + slowest.push_back(w); + } + return median_(slowest); + } + + void set_wire(const wire_counts & w) { wire_ = w; } + const wire_counts & wire() const noexcept { return wire_; } + + /// @brief Write / append CSV tables under `dir` (created if missing). + void write_csv(const std::string & dir) const + { + if (dir.empty()) + throw std::invalid_argument("experiment::write_csv empty dir"); + std::error_code ec; + std::filesystem::create_directories(dir, ec); + if (ec) + throw std::runtime_error("experiment: cannot create '" + dir + "': " + + ec.message()); + write_summary_(dir); + write_rounds_(dir); + write_edges_(dir); + write_seeds_(dir); + write_critical_path_(dir); + write_config_(dir); + write_trials_(dir); + write_wire_(dir); + write_sym_(dir); + write_runs_(dir); + DPF_LOG(info, "csv").kv("dir", dir).kv("experiment", name_) + .kv("party", party_).kv("run_id", run_id_).kv("rounds", rounds_.size()) + .kv("trials", trials_.size()).kv("seeds", seeds_.size()); + } + +private: + experiment(std::string name, std::string party, master_seed seed, origin o) + : name_(std::move(name)), party_(std::move(party)), master_(seed), origin_(o) + { + reset_random_bytes_count(); + prg::reset_eval_count(); + install_(); + note("master", master_.data(), master_.size()); + log_master_(); + } + + static const char * entropy_name_() noexcept + { +#if defined(LIBDPF_USE_ARC4RANDOM) + return "arc4random"; +#elif defined(LIBDPF_USE_DEV_RANDOM) + return "/dev/random"; +#else + return "/dev/urandom"; +#endif + } + + void log_master_() const + { + const bool derived = origin_ == origin::derived; + if (!log::enabled(derived ? log::level::debug : log::level::info)) + return; + log::record(derived ? log::level::debug : log::level::info, "seed") + .kv("name", "master").kv("experiment", name_).kv("party", party_) + .kv("source", origin_name(origin_)) + .kv("entropy", origin_ == origin::fresh ? entropy_name_() + : derived ? "sha256(master,party)" + : "replay") + .kv("bytes", master_.size()).seed("value", master_.data(), master_.size()); + } + + void draw_system_master_() + { + // Bypass any installed hook so the master is true OS entropy. + auto * saved = detail::uniform_bytes_hook; + detail::uniform_bytes_hook = nullptr; + for (auto & b : master_) + uniform_fill(b); + detail::uniform_bytes_hook = saved; + } + + void install_() + { + prev_hook_ = detail::uniform_bytes_hook; + prev_ctx_ = detail::uniform_bytes_ctx; + prev_sink_ = detail::experiment_seed_sink_tls; + detail::uniform_bytes_hook = &experiment::hook_; + detail::uniform_bytes_ctx = this; + detail::experiment_seed_sink_tls = this; + installed_ = true; + // Derive AES key from the first 16 master bytes. + std::memcpy(&aes_seed_, master_.data(), sizeof(aes_seed_)); + ctr_ = 0; + buf_pos_ = sizeof(buf_); // force refill + } + + void uninstall_() + { + if (!installed_) + return; + if (detail::uniform_bytes_ctx == this) + detail::uniform_bytes_ctx = prev_ctx_; + if (detail::uniform_bytes_hook == &experiment::hook_) + detail::uniform_bytes_hook = prev_hook_; + if (detail::experiment_seed_sink_tls == this) + detail::experiment_seed_sink_tls = prev_sink_; + installed_ = false; + } + + static void hook_(void * dst, std::size_t n) + { + auto * self = static_cast(detail::uniform_bytes_ctx); + if (self == nullptr) + throw std::logic_error("experiment hook without active context"); + self->fill_(dst, n); + } + + void fill_(void * dst, std::size_t n) + { + auto * out = static_cast(dst); + while (n > 0) + { + if (buf_pos_ >= sizeof(buf_)) + { + const prg::purpose_scope harness(prg::purpose::harness); + auto blk = prg::aes128::eval(aes_seed_, + static_cast(ctr_++)); + std::memcpy(buf_, &blk, sizeof(buf_)); + buf_pos_ = 0; + } + const std::size_t take = + std::min(n, sizeof(buf_) - buf_pos_); + std::memcpy(out, buf_ + buf_pos_, take); + buf_pos_ += take; + out += take; + n -= take; + } + } + + static void on_round_(void * ctx, const round_event & ev) + { + static_cast(ctx)->record_round_(ev); + } + + void record_round_(const round_event & ev) + { + rounds_.push_back(ev); + bytes_in_ += ev.bytes_in; + bytes_out_ += ev.bytes_out; + edge_in_[static_cast(ev.channel)] += ev.bytes_in; + edge_out_[static_cast(ev.channel)] += ev.bytes_out; + // wall / cpu / prg / random totals come from begin_timing/end_timing + // so finish_schedule local work is included once. + } + + static std::uint64_t steady_now_() + { + using clock = std::chrono::steady_clock; + return static_cast( + std::chrono::duration_cast( + clock::now().time_since_epoch()) + .count()); + } + + static std::uint64_t thread_cpu_now_() + { + if (have_thread_cpu_clock()) + return thread_cpu_ns(); + return steady_now_(); + } + + static std::uint64_t median_(std::vector v) + { + if (v.empty()) + return 0; + std::sort(v.begin(), v.end()); + return v[v.size() / 2]; + } + + static std::string to_hex_(const std::uint8_t * p, std::size_t n) + { + std::ostringstream os; + os << std::hex << std::setfill('0'); + for (std::size_t i = 0; i < n; ++i) + os << std::setw(2) << static_cast(p[i]); + return os.str(); + } + + static const char * channel_name_(protocol::edge_channel c) + { + switch (c) + { + case protocol::edge_channel::peer: + return "peer"; + case protocol::edge_channel::rss_next: + return "rss_next"; + case protocol::edge_channel::dealer: + return "dealer"; + } + return "edge"; + } + + struct path_node + { + std::uint32_t id = 0; + std::size_t wave = 0; + std::uint32_t opcode = 0; + int effect = 0; + }; + + static std::vector build_critical_path_(const protocol::plan & p) + { + std::vector path; + if (p.nodes().empty()) + return path; + std::uint32_t tip = p.nodes().front().id; + std::size_t best_w = p.wave_of(protocol::node{tip}); + for (auto n : p.nodes()) + { + const auto w = p.wave_of(n); + if (w >= best_w) + { + best_w = w; + tip = n.id; + } + } + for (;;) + { + path_node pn; + pn.id = tip; + pn.wave = p.wave_of(protocol::node{tip}); + pn.opcode = p.opcode_of(tip); + pn.effect = static_cast(p.effect_of(tip)); + path.push_back(pn); + const auto & ins = p.inputs_of(tip); + if (ins.empty()) + break; + std::uint32_t next = ins.front(); + std::size_t nw = p.wave_of(protocol::node{next}); + for (auto in : ins) + { + const auto w = p.wave_of(protocol::node{in}); + if (w >= nw) + { + nw = w; + next = in; + } + } + if (next == tip) + break; + tip = next; + } + std::reverse(path.begin(), path.end()); + return path; + } + + /// @brief Open `dir/file` for append, writing `header` first when the file + /// is new. A file with a different header is renamed to + /// `.before-.csv` so rows never land under the wrong + /// columns. + static std::ofstream open_table_(const std::string & dir, const char * file, + const char * header) + { + const std::string path = dir + "/" + file; + std::string existing; + { + std::ifstream in(path); + if (in) + std::getline(in, existing); + } + if (!existing.empty() && existing != header) + { + std::string stamp; + for (char c : log::detail::utc_text(std::chrono::system_clock::now())) + if (c != '-' && c != ':') + stamp += c; + const std::string moved = path.substr(0, path.size() - 4) + ".before-" + + stamp + ".csv"; + if (std::rename(path.c_str(), moved.c_str()) != 0) + throw std::runtime_error("experiment: " + path + + " has another column layout and cannot be moved aside"); + DPF_LOG(warning, "csv.moved").kv("file", path).kv("to", moved) + .kv("detail", "its header differs from this build's columns"); + existing.clear(); + } + std::ofstream out(path, std::ios::app); + if (!out) + throw std::runtime_error(std::string("experiment: cannot write ") + file); + if (existing.empty()) + out << header << '\n'; + return out; + } + + void write_summary_(const std::string & dir) const + { + auto out = open_table_(dir, "summary.csv", + "name,party,run_id,master_seed,interactive_rounds,dag_depth," + "wall_ns,cpu_ns,prg_evals,random_bytes,bytes_in,bytes_out," + "plan_bytes_out,peer_in,peer_out,rss_in,rss_out,dealer_in," + "dealer_out,median_ns,slowest_median_ns,trials,invocation"); + out << csv_escape_(name_) << ',' << csv_escape_(party_) << ',' + << run_id_ << ',' << seed_hex() << ',' << interactive_rounds_ << ',' + << dag_depth_ << ',' << wall_ns_ << ',' << cpu_ns_ << ',' + << prg_evals_ << ',' << random_bytes_ << ',' << bytes_in_ << ',' + << bytes_out_ << ',' << plan_bytes_out_ << ',' + << edge_get_(edge_in_, 0) << ',' << edge_get_(edge_out_, 0) << ',' + << edge_get_(edge_in_, 1) << ',' << edge_get_(edge_out_, 1) << ',' + << edge_get_(edge_in_, 2) << ',' << edge_get_(edge_out_, 2) << ',' + << median_trial_ns() << ',' << slowest_median_ns() << ',' + << trials_.size() << ',' << log::invocation_id() << '\n'; + } + + void write_rounds_(const std::string & dir) const + { + auto out = open_table_(dir, "rounds.csv", + "name,party,run_id,round,edge,channel,bytes_out,bytes_in," + "wall_ns,cpu_ns,prg_evals,random_bytes,invocation"); + for (const auto & r : rounds_) + { + out << csv_escape_(name_) << ',' << csv_escape_(party_) << ',' + << run_id_ << ',' << r.round << ',' << r.edge << ',' + << channel_name_(r.channel) << ',' << r.bytes_out << ',' + << r.bytes_in << ',' << r.wall_ns << ',' << r.cpu_ns << ',' + << r.prg_evals << ',' << r.random_bytes << ',' + << log::invocation_id() << '\n'; + } + } + + void write_edges_(const std::string & dir) const + { + auto out = open_table_(dir, "edges.csv", + "name,party,run_id,channel,bytes_in,bytes_out,plan_bytes_out,invocation"); + for (int c = 0; c < 3; ++c) + { + const auto ch = static_cast(c); + out << csv_escape_(name_) << ',' << csv_escape_(party_) << ',' + << run_id_ << ',' << channel_name_(ch) << ',' + << edge_get_(edge_in_, c) << ',' << edge_get_(edge_out_, c) + << ',' << edge_get_(edge_plan_out_, c) << ',' + << log::invocation_id() << '\n'; + } + } + + void write_seeds_(const std::string & dir) const + { + auto out = open_table_(dir, "seeds.csv", + "name,party,run_id,seed_name,seed_hex,seed_bytes,invocation"); + for (const auto & s : seeds_) + { + out << csv_escape_(name_) << ',' << csv_escape_(party_) << ',' + << run_id_ << ',' << csv_escape_(s.name) << ',' + << to_hex_(s.bytes.data(), s.bytes.size()) << ',' + << s.bytes.size() << ',' << log::invocation_id() << '\n'; + } + } + + void write_critical_path_(const std::string & dir) const + { + auto out = open_table_(dir, "critical_path.csv", + "name,party,run_id,step,node_id,wave,opcode,effect,invocation"); + for (std::size_t i = 0; i < critical_path_.size(); ++i) + { + const auto & n = critical_path_[i]; + out << csv_escape_(name_) << ',' << csv_escape_(party_) << ',' + << run_id_ << ',' << i << ',' << n.id << ',' << n.wave << ',' + << n.opcode << ',' << n.effect << ',' << log::invocation_id() << '\n'; + } + } + + void write_config_(const std::string & dir) const + { + auto out = open_table_(dir, "config.csv", "name,party,run_id,key,value,invocation"); + for (const auto & kv : config_) + out << csv_escape_(name_) << ',' << csv_escape_(party_) << ',' + << run_id_ << ',' << csv_escape_(kv.first) << ',' + << csv_escape_(kv.second) << ',' << log::invocation_id() << '\n'; + } + + /// @brief One row per party per trial when parties were recorded, one row + /// per trial for this experiment's party otherwise. + void write_trials_(const std::string & dir) const + { + auto out = open_table_(dir, "trials.csv", + "name,party,run_id,trial,wall_ns,invocation"); + for (std::size_t t = 0; t < trials_.size(); ++t) + { + const bool all = t < party_trials_.size() && !party_trials_[t].empty(); + if (!all) + { + out << csv_escape_(name_) << ',' << csv_escape_(party_) << ',' + << run_id_ << ',' << t << ',' << trials_[t] << ',' + << log::invocation_id() << '\n'; + continue; + } + for (std::size_t p = 0; p < party_trials_[t].size(); ++p) + out << csv_escape_(name_) << ",p" << p << ',' << run_id_ << ',' + << t << ',' << party_trials_[t][p] << ',' + << log::invocation_id() << '\n'; + } + } + + void write_wire_(const std::string & dir) const + { + auto out = open_table_(dir, "wire.csv", + "name,party,run_id,bytes_out,bytes_in,payload_out,payload_in," + "frames_out,frames_in,write_calls,invocation"); + out << csv_escape_(name_) << ',' << csv_escape_(party_) << ',' << run_id_ + << ',' << wire_.bytes_out << ',' << wire_.bytes_in << ',' + << wire_.payload_out << ',' << wire_.payload_in << ',' + << wire_.frames_out << ',' << wire_.frames_in << ',' + << wire_.write_calls << ',' << log::invocation_id() << '\n'; + } + + void write_sym_(const std::string & dir) const + { + auto out = open_table_(dir, "sym.csv", + "name,party,run_id,purpose,primitive,blocks,invocation"); + for (std::size_t u = 0; u < prg::purpose_count; ++u) + for (std::size_t p = 0; p < prg::primitive_count; ++p) + { + const auto n = sym_[u * prg::primitive_count + p]; + if (n == 0) + continue; + out << csv_escape_(name_) << ',' << csv_escape_(party_) << ',' + << run_id_ << ',' + << prg::purpose_name(static_cast(u)) << ',' + << prg::primitive_name(static_cast(p)) << ',' + << n << ',' << log::invocation_id() << '\n'; + } + } + + void write_runs_(const std::string & dir) const + { + auto out = open_table_(dir, "runs.csv", + "name,party,run_id,invocation,seed_source,written_utc"); + out << csv_escape_(name_) << ',' << csv_escape_(party_) << ',' << run_id_ + << ',' << log::invocation_id() << ',' << origin_name(origin_) << ',' + << log::detail::utc_text(std::chrono::system_clock::now()) << '\n'; + } + + static std::string csv_escape_(const std::string & s) + { + if (s.find_first_of(",\"\n\r") == std::string::npos) + return s; + std::string out = "\""; + for (char c : s) + { + if (c == '"') + out += "\"\""; + else + out += c; + } + out += '"'; + return out; + } + + static std::size_t edge_get_(const std::map & m, int k) + { + auto it = m.find(k); + return it == m.end() ? 0 : it->second; + } + + std::string name_; + std::string party_; + std::uint64_t run_id_ = 0; + master_seed master_{}; + origin origin_ = origin::fresh; + prg::aes128::block_type aes_seed_{}; + std::uint32_t ctr_ = 0; + std::uint8_t buf_[16]{}; + std::size_t buf_pos_ = 16; + void (*prev_hook_)(void *, std::size_t) = nullptr; + void * prev_ctx_ = nullptr; + detail::experiment_seed_sink * prev_sink_ = nullptr; + bool installed_ = false; + std::vector seeds_; + std::vector rounds_; + std::map edge_in_; + std::map edge_out_; + std::map edge_plan_out_; + std::size_t interactive_rounds_ = 0; + std::size_t dag_depth_ = 0; + std::vector critical_path_; + std::uint64_t wall_ns_ = 0; + std::uint64_t cpu_ns_ = 0; + std::uint64_t prg_evals_ = 0; + prg::counts sym_{}; + std::uint64_t random_bytes_ = 0; + std::size_t bytes_in_ = 0; + std::size_t bytes_out_ = 0; + std::size_t plan_bytes_out_ = 0; + std::vector> config_; + std::vector trials_; + std::vector> party_trials_; + wire_counts wire_{}; + bool timing_started_ = false; + std::uint64_t wall0_ = 0; + std::uint64_t cpu0_ = 0; +}; + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_EXPERIMENT_HPP__ diff --git a/include/dpf/experiment_note.hpp b/include/dpf/experiment_note.hpp new file mode 100644 index 0000000..9d1c69f --- /dev/null +++ b/include/dpf/experiment_note.hpp @@ -0,0 +1,52 @@ +/// @file dpf/experiment_note.hpp +/// @brief Lightweight seed registry hook (no Asio / PRG includes). +#ifndef LIBDPF_INCLUDE_DPF_EXPERIMENT_NOTE_HPP__ +#define LIBDPF_INCLUDE_DPF_EXPERIMENT_NOTE_HPP__ + +#include +#include +#include + +#include "hedley/hedley.h" + +namespace dpf +{ +namespace detail +{ + +/// @brief Optional sink installed by `experiment` (TLS). +struct experiment_seed_sink +{ + virtual ~experiment_seed_sink() = default; + virtual void note(const char * name, const std::uint8_t * bytes, + std::size_t n) = 0; +}; + +inline thread_local experiment_seed_sink * experiment_seed_sink_tls = nullptr; + +} // namespace detail + +/// @brief Record a named seed when an `experiment` is installed on this thread. +HEDLEY_ALWAYS_INLINE +void note_experiment_seed(const char * name, const void * bytes, + std::size_t n) noexcept +{ + if (detail::experiment_seed_sink_tls == nullptr || bytes == nullptr + || n == 0 || name == nullptr) + return; + detail::experiment_seed_sink_tls->note(name, + static_cast(bytes), n); +} + +template +HEDLEY_ALWAYS_INLINE +void note_experiment_seed(const char * name, const T & seed) noexcept +{ + static_assert(std::is_trivially_copyable_v, + "note_experiment_seed requires a trivially copyable seed"); + note_experiment_seed(name, &seed, sizeof(seed)); +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_EXPERIMENT_NOTE_HPP__ diff --git a/include/dpf/factory_gadgets.hpp b/include/dpf/factory_gadgets.hpp new file mode 100644 index 0000000..5d76845 --- /dev/null +++ b/include/dpf/factory_gadgets.hpp @@ -0,0 +1,482 @@ +/// @file dpf/factory_gadgets.hpp +/// @brief Online MPC gadgets as `net::stream_array` round sequences. +/// @details These mirror the limb logic in `mpc::circuit` but speak only +/// `factory::detail::read_pod` / `exchange_pod` on dealer and peer +/// arrays. Higher-level circuit ops compose from them: +/// - `gt` — two `a2b_online` passes plus compare ANDs +/// - `trunc_exact` — open `x-r` then a carry AND chain (as in A2B) +/// - `mux` — Beaver mul on `(sel, a-b)` plus local add of `b` +#ifndef LIBDPF_INCLUDE_DPF_FACTORY_GADGETS_HPP__ +#define LIBDPF_INCLUDE_DPF_FACTORY_GADGETS_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/circuit.hpp" +#include "dpf/edabit.hpp" +#include "dpf/gilboa.hpp" +#include "dpf/net/round_sink.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/net/stream_mesh.hpp" +#include "dpf/ot_pack.hpp" +#include "dpf/protocol_factory.hpp" +#include "dpf/bit_inject.hpp" + +namespace dpf +{ +namespace factory +{ + +namespace detail +{ + +inline std::uint64_t limb_mask(std::uint16_t limb) +{ + if (limb == 0 || limb > 8) + throw std::invalid_argument("factory_gadgets limb"); + return limb >= 8 ? ~std::uint64_t{0} + : ((std::uint64_t{1} << (8u * limb)) - 1u); +} + +inline void ring_view_to_limbs(const ring_triple_view & v, std::uint16_t limb, + std::uint64_t & a, std::uint64_t & b, std::uint64_t & c) +{ + a = b = c = 0; + const std::uint16_t use = v.limb != 0 ? v.limb : limb; + std::memcpy(&a, v.a, use); + std::memcpy(&b, v.b, use); + std::memcpy(&c, v.c, use); + const auto mask = limb_mask(limb); + a &= mask; + b &= mask; + c &= mask; +} + +} // namespace detail + +/// @brief Sum-open one ring share on `peer[stream]` (additive declassify). +inline std::uint64_t open_sum_online(unsigned /*party*/, std::uint64_t mine, + net::stream_array & peer, std::size_t stream, std::uint16_t limb) +{ + const auto mask = detail::limb_mask(limb); + std::uint64_t theirs = 0; + detail::exchange_pod(peer, stream, mine & mask, theirs); + return (mine + theirs) & mask; +} + +/// @brief Beaver multiplication: triple on `dealer[dealer_stream]`, opens on +/// `peer[peer_d_stream]` and `peer[peer_e_stream]`. +inline std::uint64_t beaver_mul_online(unsigned party, std::uint64_t x, + std::uint64_t y, net::stream_array & peer, net::stream_array & dealer, + std::size_t dealer_stream = 0, std::size_t peer_d_stream = 0, + std::size_t peer_e_stream = 1, std::uint16_t limb = 8) +{ + const auto mask = detail::limb_mask(limb); + const auto view = + detail::read_pod(dealer, dealer_stream); + std::uint64_t a = 0, b = 0, c = 0; + detail::ring_view_to_limbs(view, limb, a, b, c); + const auto d = open_sum_online(party, (x - a) & mask, peer, peer_d_stream, + limb); + const auto e = open_sum_online(party, (y - b) & mask, peer, peer_e_stream, + limb); + std::uint64_t z = (c + d * b + e * a) & mask; + if (party == 0) + z = (z + d * e) & mask; + return z; +} + +/// @brief GMW AND on XOR bit shares; blind from `dealer[dealer_stream]`. +inline std::uint8_t gmw_and_online(unsigned party, std::uint8_t p, + std::uint8_t q, net::stream_array & peer, net::stream_array & dealer, + std::size_t dealer_stream = 0, std::size_t peer_stream = 0) +{ + const auto blind = detail::read_pod(dealer, dealer_stream); + gmw_and_msg mine{}; + mine.d = static_cast((p ^ blind.a) & 1u); + mine.e = static_cast((q ^ blind.b) & 1u); + gmw_and_msg theirs{}; + detail::exchange_pod(peer, peer_stream, mine, theirs); + const std::uint8_t d_open = + static_cast(mine.d ^ theirs.d); + const std::uint8_t e_open = + static_cast(mine.e ^ theirs.e); + ot::bit_triple t{blind.a, blind.b, blind.c}; + return edabit::and_finish(t, d_open, e_open, party); +} + +/// @brief Mux: `b + sel·(a-b)` via one Beaver mul of `(sel, a-b)`. +inline std::uint64_t mux_online(unsigned party, std::uint8_t sel, + std::uint64_t a, std::uint64_t b, net::stream_array & peer, + net::stream_array & dealer, std::size_t dealer_stream = 0, + std::size_t peer_d_stream = 0, std::size_t peer_e_stream = 1, + std::uint16_t limb = 8) +{ + const auto mask = detail::limb_mask(limb); + const auto diff = (a - b) & mask; + const auto prod = beaver_mul_online(party, sel & 1u, diff, peer, dealer, + dealer_stream, peer_d_stream, peer_e_stream, limb); + return (b + prod) & mask; +} + +/// @brief Exact trunc: open `x-r` (r from `s` dabits), then GMW wrap via +/// low-bit AND chain on the same shape as `a2b_online`'s carry. +inline std::uint64_t trunc_exact_online(unsigned party, std::uint64_t x_share, + unsigned n, unsigned s, net::stream_array & peer, net::stream_array & dealer, + std::uint16_t limb = 8, std::size_t dabit_stream = 0, + std::size_t and_blind_stream = 1, std::size_t open_stream = 0, + std::size_t and_peer_stream = 1) +{ + if (s >= n || n > 64) + throw std::invalid_argument("trunc_exact_online"); + const auto mask = detail::limb_mask(limb); + std::uint64_t r = 0; + std::vector r_bits(s); + for (unsigned i = 0; i < s; ++i) + { + const auto d = detail::read_pod(dealer, dabit_stream); + r_bits[i] = static_cast(d.bit & 1u); + std::uint64_t ar = 0; + const std::uint16_t use = d.limb != 0 ? d.limb : limb; + std::memcpy(&ar, d.arith, use); + r = (r + (ar << i)) & mask; + } + const auto delta = + open_sum_online(party, (x_share - r) & mask, peer, open_stream, limb); + // Wrap = carry out of the low `s` bits of delta + r (GMW chain). + std::uint8_t carry = 0; + for (unsigned i = 0; i < s; ++i) + { + const std::uint8_t di = + static_cast((delta >> i) & 1u); + const std::uint8_t ri = r_bits[i]; + const std::uint8_t rc = + gmw_and_online(party, ri, carry, peer, dealer, and_blind_stream, + and_peer_stream); + const std::uint8_t rd = static_cast(di & ri); + const std::uint8_t dc = static_cast(di & carry); + carry = static_cast((rd ^ dc ^ rc) & 1u); + } + const auto d_wrap = detail::read_pod(dealer, dabit_stream); + const std::uint8_t mine_mask = + static_cast(carry ^ (d_wrap.bit & 1u)); + std::uint8_t peer_mask = 0; + detail::exchange_pod(peer, open_stream, mine_mask, peer_mask); + const std::uint8_t mask_open = + static_cast(mine_mask ^ peer_mask); + ot::dabit dr{}; + dr.bit = d_wrap.bit; + const std::uint16_t use_wrap = + d_wrap.limb != 0 ? d_wrap.limb : limb; + std::memcpy(&dr.arith, d_wrap.arith, use_wrap); + const auto wrap = edabit::b2a_party_bit( + carry, dr, mask_open, party, 0); + const std::uint64_t high_m = ((n - s) >= 64) + ? ~std::uint64_t{0} + : ((std::uint64_t{1} << (n - s)) - 1u); + std::uint64_t out = wrap & mask; + if (party == 0) + out = (out + ((delta >> s) & high_m)) & mask; + return out; +} + +/// @brief A2B: `width` dabits on `dealer[dabit_stream]` (sequential reads), +/// `width` AND blinds on `dealer[and_blind_stream]`, open delta on +/// `peer[open_stream]`, AND masks on `peer[and_peer_stream]` (sequential). +inline std::uint64_t a2b_online(unsigned party, std::uint64_t x_share, + unsigned width, net::stream_array & peer, net::stream_array & dealer, + std::uint16_t limb = 8, std::size_t dabit_stream = 0, + std::size_t and_blind_stream = 1, std::size_t open_stream = 0, + std::size_t and_peer_stream = 1) +{ + if (width == 0 || width > 64) + throw std::invalid_argument("a2b_online width"); + const auto mask = detail::limb_mask(limb); + std::uint64_t r_arith = 0; + std::vector r_bits(width); + for (unsigned i = 0; i < width; ++i) + { + const auto d = detail::read_pod(dealer, dabit_stream); + r_bits[i] = static_cast(d.bit & 1u); + std::uint64_t ar = 0; + const std::uint16_t use = d.limb != 0 ? d.limb : limb; + std::memcpy(&ar, d.arith, use); + r_arith = (r_arith + (ar << i)) & mask; + } + const auto delta = open_sum_online(party, (x_share - r_arith) & mask, peer, + open_stream, limb); + std::uint8_t carry = 0; + std::uint64_t out = 0; + for (unsigned i = 0; i < width; ++i) + { + const auto blind = + detail::read_pod(dealer, and_blind_stream); + ot::bit_triple t{blind.a, blind.b, blind.c}; + const std::uint8_t di = + static_cast((delta >> i) & 1u); + const std::uint8_t ri = r_bits[i]; + gmw_and_msg mine{}; + mine.d = static_cast((ri ^ t.a) & 1u); + mine.e = static_cast((carry ^ t.b) & 1u); + gmw_and_msg peer_msg{}; + detail::exchange_pod(peer, and_peer_stream, mine, peer_msg); + const std::uint8_t d = + static_cast(mine.d ^ peer_msg.d); + const std::uint8_t e = + static_cast(mine.e ^ peer_msg.e); + const std::uint8_t rc = edabit::and_finish(t, d, e, party); + const std::uint8_t bi = static_cast( + ((party == 0 ? (ri ^ di ^ carry) : (ri ^ carry))) & 1u); + const std::uint8_t rd = static_cast(di & ri); + const std::uint8_t dc = static_cast(di & carry); + carry = static_cast((rd ^ dc ^ rc) & 1u); + out |= (static_cast(bi) << i); + } + return out; +} + +/// @brief Unsigned GT via two A2B passes plus MSB-first compare ANDs. +inline std::uint8_t gt_online(unsigned party, std::uint64_t x, std::uint64_t y, + unsigned width, net::stream_array & peer, net::stream_array & dealer, + std::uint16_t limb = 8) +{ + // Dealer layout: streams 0..1 dabits+ANDs for x, 2..3 for y, 4 for compare. + const auto bx = a2b_online(party, x, width, peer, dealer, limb, 0, 1, 0, 1); + const auto by = a2b_online(party, y, width, peer, dealer, limb, 2, 3, 2, 3); + std::uint8_t gt = 0; + std::uint8_t eq = static_cast(party == 0 ? 1 : 0); + for (unsigned k = width; k-- > 0; ) + { + const std::uint8_t xk = + static_cast((bx >> k) & 1u); + const std::uint8_t yk = + static_cast((by >> k) & 1u); + const std::uint8_t xny = gmw_and_online(party, xk, + static_cast(yk ^ (party == 0 ? 1u : 0u)), peer, + dealer, 4, 4); + const std::uint8_t both = gmw_and_online(party, eq, xny, peer, dealer, + 4, 4); + gt = static_cast(gt ^ both); + const std::uint8_t same = static_cast( + (xk ^ yk ^ (party == 0 ? 1u : 0u)) & 1u); + eq = gmw_and_online(party, eq, same, peer, dealer, 4, 4); + } + return gt; +} + +// --------------------------------------------------------------------------- +// RoundSink adapter: one peer stream index per circuit exchange round +// --------------------------------------------------------------------------- + +/// @brief Drive `mpc::party::run` with one `stream_array` index per slot. +class stream_array_circuit_sink : public net::RoundSink +{ +public: + stream_array_circuit_sink(net::stream_array & peer, + std::vector slot_bytes) + : peer_(&peer), slot_bytes_(std::move(slot_bytes)) + { + windows_.reserve(slot_bytes_.size()); + for (std::size_t sb : slot_bytes_) + windows_.emplace_back(1, sb); + if (peer_->size() < slot_bytes_.size()) + throw std::invalid_argument( + "stream_array_circuit_sink: peer too few streams"); + } + + std::size_t count() const noexcept override { return 1; } + std::size_t rounds() const noexcept override { return slot_bytes_.size(); } + + std::size_t slot_bytes(std::uint16_t round) const override + { + if (round >= slot_bytes_.size()) + throw std::out_of_range("stream_array_circuit_sink round"); + return slot_bytes_[round]; + } + + void submit(std::uint16_t round, std::size_t index, + const std::uint8_t * bytes, std::size_t n) override + { + if (index != 0) + throw std::out_of_range("stream_array_circuit_sink index"); + window(round).submit(0, bytes, n); + } + + bool peer_ready(std::uint16_t round, std::size_t index) const override + { + if (index != 0) + return false; + return window(round).peer_ready(0); + } + + void read_peer(std::uint16_t round, std::size_t index, std::uint8_t * out, + std::size_t n) const override + { + if (index != 0) + throw std::out_of_range("stream_array_circuit_sink read"); + window(round).read_peer(0, out, n); + } + + void flush() override + { + for (std::uint16_t r = 0; r < slot_bytes_.size(); ++r) + { + std::size_t begin = 0; + std::size_t n = 0; + window(r).pending_out(begin, n); + if (n != 0) + flush_round(r); + } + } + + void flush_round(std::uint16_t round) override + { + if (round >= slot_bytes_.size()) + throw std::out_of_range("stream_array_circuit_sink flush_round"); + auto & w = window(round); + std::size_t begin = 0; + std::size_t nslots = 0; + const auto * pend = w.pending_out(begin, nslots); + if (nslots == 0) + return; + const std::size_t nbyte = nslots * slot_bytes_[round]; + peer_->write(round, pend, nbyte); + peer_->flush(round); + w.mark_flushed(nslots); + std::vector peer_buf(nbyte); + peer_->read(round, peer_buf.data(), nbyte); + w.accept_peer_at(0, peer_buf.data(), nbyte); + } + + void poll() override {} + +private: + net::round_window & window(std::uint16_t round) + { + return windows_.at(round); + } + + const net::round_window & window(std::uint16_t round) const + { + return windows_.at(round); + } + + net::stream_array * peer_ = nullptr; + std::vector slot_bytes_; + std::vector windows_; +}; + +/// @brief Run a compiled circuit using stream indices for each online slot. +inline void run_circuit_stream_array(const mpc::circuit & circ, mpc::party & me, + net::stream_array & peer, net::stream_array & dealer, + std::size_t prep_bytes) +{ + stream_array_circuit_sink sink(peer, circ.slot_bytes()); + me.run(sink, dealer, prep_bytes); +} + +// --------------------------------------------------------------------------- +// Gilboa OT pads on stream arrays +// --------------------------------------------------------------------------- + +inline void write_ot_pack_wire(net::stream_array & dealer, std::size_t stream, + const ot::pack::wire & w) +{ + const std::uint64_t nb = static_cast(w.b2a.size()); + const std::uint64_t nt = static_cast(w.bits.size()); + const std::uint64_t nr = + w.bit_ring_elem != 0 + ? static_cast(w.bit_ring.size() / w.bit_ring_elem) + : 0u; + const std::uint64_t hdr[4] = {static_cast(w.me), nb, nt, nr}; + dealer.write(stream, hdr, sizeof(hdr)); + if (nb != 0) + dealer.write(stream, w.b2a.data(), nb * sizeof(ot::b2a_slot)); + if (nt != 0) + dealer.write(stream, w.bits.data(), nt * sizeof(ot::bit_triple)); + if (nr != 0) + dealer.write(stream, w.bit_ring.data(), w.bit_ring.size()); + dealer.flush(stream); +} + +inline ot::pack read_ot_pack_wire(net::stream_array & dealer, std::size_t stream) +{ + std::uint64_t hdr[4]{}; + dealer.read(stream, hdr, sizeof(hdr)); + ot::pack::wire w; + w.me = static_cast(hdr[0]); + const std::size_t nb = static_cast(hdr[1]); + const std::size_t nt = static_cast(hdr[2]); + const std::size_t nr = static_cast(hdr[3]); + w.b2a.resize(nb); + w.bits.resize(nt); + if (nb != 0) + dealer.read(stream, w.b2a.data(), nb * sizeof(ot::b2a_slot)); + if (nt != 0) + dealer.read(stream, w.bits.data(), nt * sizeof(ot::bit_triple)); + if (nr != 0) + { + w.bit_ring_elem = sizeof(ot::bit_ring_triple); + w.bit_ring.resize(nr * w.bit_ring_elem); + dealer.read(stream, w.bit_ring.data(), w.bit_ring.size()); + } + return ot::pack::from_wire(std::move(w)); +} + +/// @brief Sample correlated Gilboa/OT pads onto each party's dealer stream. +inline void deal_gilboa_mul_tape(net::stream_array & dealer0, + net::stream_array & dealer1, std::size_t bits) +{ + auto pr = ot::sample_dealer_pair(bits, 0, bits); + write_ot_pack_wire(dealer0, 0, pr.first.export_wire()); + write_ot_pack_wire(dealer1, 0, pr.second.export_wire()); +} + +/// @brief Online Gilboa mul: OT pads on `dealer`, `d`/`e` vectors on `peer`. +inline std::uint64_t gilboa_mul_online(unsigned party, std::uint64_t x, + std::uint64_t y, net::stream_array & peer, net::stream_array & dealer, + std::size_t bits = 16, std::size_t peer_stream = 0, + std::size_t dealer_stream = 0) +{ + auto pack = read_ot_pack_wire(dealer, dealer_stream); + auto r = gilboa::mul_from_ot_begin(pack, x, y, party, static_cast(bits)); + std::vector peer_d(r.d_share.size()); + std::vector peer_e(r.e_share.size()); + for (std::size_t i = 0; i < r.d_share.size(); ++i) + { + detail::exchange_pod(peer, peer_stream, r.d_share[i], peer_d[i]); + detail::exchange_pod(peer, peer_stream, r.e_share[i], peer_e[i]); + } + return gilboa::mul_from_ot_finish(r, peer_d, peer_e); +} + +// --------------------------------------------------------------------------- +// RSS ring refresh on a 3-party stream clique +// --------------------------------------------------------------------------- + +/// @brief Send `mine` to the next party; receive predecessor's payload. +/// @details Writes `(own, from_prev)` into `own_out` / `next_out` (RSS pair). +inline void rss_refresh_ring_online(net::memory_stream_clique & clique, + unsigned me, const std::uint8_t * mine, std::size_t n, + std::uint8_t * own_out, std::uint8_t * next_out, std::size_t stream = 0) +{ + if (clique.parties != 3 || me > 2) + throw std::invalid_argument("rss_refresh_ring_online"); + const unsigned next = static_cast((me + 1) % 3); + const unsigned prev = static_cast((me + 2) % 3); + clique.end(me, next).write(stream, mine, n); + clique.end(me, next).flush(stream); + clique.end(me, prev).read(stream, next_out, n); + std::memcpy(own_out, mine, n); +} + +} // namespace factory +} // namespace dpf + +#endif diff --git a/include/dpf/factory_tapes.hpp b/include/dpf/factory_tapes.hpp new file mode 100644 index 0000000..993a60b --- /dev/null +++ b/include/dpf/factory_tapes.hpp @@ -0,0 +1,107 @@ +/// @file dpf/factory_tapes.hpp +/// @brief Dealer stream layouts for `factory_gadgets` online tapes (A2B, trunc, GT). +#ifndef LIBDPF_INCLUDE_DPF_FACTORY_TAPES_HPP__ +#define LIBDPF_INCLUDE_DPF_FACTORY_TAPES_HPP__ + +#include +#include +#include +#include +#include + +#include "dpf/protocol_factory.hpp" + +namespace dpf +{ +namespace factory +{ + +namespace detail +{ + +inline std::pair deal_gmw_and_blind_pair() +{ + auto t = deal_bit_triple(); + gmw_and_blind v0{t.first.a, t.first.b, t.first.c}; + gmw_and_blind v1{t.second.a, t.second.b, t.second.c}; + return {v0, v1}; +} + +template +inline void deal_tape_pod(net::stream_array & party0, net::stream_array & party1, + std::size_t stream, std::size_t count, F && f) +{ + if (stream >= party0.size() || stream >= party1.size()) + throw std::invalid_argument("deal_tape_pod: stream index"); + for (std::size_t j = 0; j < count; ++j) + { + auto views = f(); + using V0 = std::decay_t; + using V1 = std::decay_t; + static_assert(std::is_trivially_copyable_v + && std::is_trivially_copyable_v, + "deal_tape_pod views must be trivially copyable"); + if (sizeof(V0) != sizeof(V1)) + throw std::logic_error("deal_tape_pod: unequal view sizes"); + detail::write_pod(party0, stream, views.first); + detail::write_pod(party1, stream, views.second); + } + party0.flush(stream); + party1.flush(stream); +} + +} // namespace detail + +/// @brief Sequential dabits then AND blinds for one `a2b_online` pass. +inline void deal_a2b_tape(unsigned width, std::uint16_t limb, + net::stream_array & party0, net::stream_array & party1, + std::size_t dabit_stream = 0, std::size_t and_blind_stream = 1) +{ + if (width == 0 || width > 64) + throw std::invalid_argument("deal_a2b_tape width"); + const std::size_t need = + 1 + (dabit_stream > and_blind_stream ? dabit_stream : and_blind_stream); + if (party0.size() < need || party1.size() < need) + throw std::invalid_argument("deal_a2b_tape: not enough streams"); + detail::deal_tape_pod(party0, party1, dabit_stream, width, + [limb] { return deal_dabit(limb); }); + detail::deal_tape_pod(party0, party1, and_blind_stream, width, + [] { return detail::deal_gmw_and_blind_pair(); }); +} + +/// @brief `s + 1` dabits (low mask + B2A wrap) and `s` AND blinds for trunc. +inline void deal_trunc_tape(unsigned n, unsigned s, std::uint16_t limb, + net::stream_array & party0, net::stream_array & party1, + std::size_t dabit_stream = 0, std::size_t and_blind_stream = 1) +{ + if (s >= n || n > 64) + throw std::invalid_argument("deal_trunc_tape"); + const std::size_t need = + 1 + (dabit_stream > and_blind_stream ? dabit_stream : and_blind_stream); + if (party0.size() < need || party1.size() < need) + throw std::invalid_argument("deal_trunc_tape: not enough streams"); + detail::deal_tape_pod(party0, party1, dabit_stream, s + 1u, + [limb] { return deal_dabit(limb); }); + detail::deal_tape_pod(party0, party1, and_blind_stream, s, + [] { return detail::deal_gmw_and_blind_pair(); }); +} + +/// @brief Dealer layout for `gt_online`: streams 0–1 (x A2B), 2–3 (y), 4 compare. +inline void deal_gt_tape(unsigned width, std::uint16_t limb, + net::stream_array & party0, net::stream_array & party1) +{ + if (width == 0 || width > 64) + throw std::invalid_argument("deal_gt_tape width"); + constexpr std::size_t k_gt_streams = 5; + if (party0.size() < k_gt_streams || party1.size() < k_gt_streams) + throw std::invalid_argument("deal_gt_tape: need 5 dealer streams"); + deal_a2b_tape(width, limb, party0, party1, 0, 1); + deal_a2b_tape(width, limb, party0, party1, 2, 3); + detail::deal_tape_pod(party0, party1, 4, 3u * width, + [] { return detail::deal_gmw_and_blind_pair(); }); +} + +} // namespace factory +} // namespace dpf + +#endif diff --git a/include/dpf/field128.hpp b/include/dpf/field128.hpp new file mode 100644 index 0000000..d18299a --- /dev/null +++ b/include/dpf/field128.hpp @@ -0,0 +1,492 @@ +/// @file dpf/field128.hpp +/// @brief Prime field of libprio's `Field128`, as a DPF output. +/// @details The modulus is 340282366920938462946865773367900766209. Pass +/// `dpf::field128{n}` as a `make_dpf` payload. Leaf addition and +/// scaling are the field operations. A raw PRG block is reduced into +/// the field on the first leaf operation. This is a point-function +/// output, not a comparison payload. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_FIELD128_HPP__ +#define LIBDPF_INCLUDE_DPF_FIELD128_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" +#include "simde/simde/x86/avx2.h" + +#include "dpf/leaf_arithmetic.hpp" +#include "dpf/random.hpp" +#include "dpf/utils.hpp" + +namespace dpf +{ + +/// @brief Element of the 128-bit libprio field. +class field128 +{ + public: + /// @brief Low limb of the modulus `2^128 - 0x1bffffffffffffffff`. + static constexpr std::uint64_t mod_lo = 0x0000000000000001ull; + /// @brief High limb of the modulus. + static constexpr std::uint64_t mod_hi = 0xffffffffffffffe4ull; + static constexpr bool dpf_point_group = true; + + /// @brief The zero element. + HEDLEY_ALWAYS_INLINE + constexpr field128() noexcept = default; + + /// @brief Reduce `v` into the field. A negative value is negated in the field. + /// @tparam T integral type, at most 128 bits + /// @param v the integer to reduce + template >> + HEDLEY_ALWAYS_INLINE + constexpr field128(T v) noexcept + { + assign_integer(v); + } + + /// @brief Reduce a PRG block into the field. Uses up to 16 bytes. + /// @param bytes the PRG output + /// @param n the number of bytes available + /// @return the field element + HEDLEY_ALWAYS_INLINE + static field128 from_seed(const void * bytes, std::size_t n) noexcept + { + unsigned char buf[16]{}; + if (n > sizeof(buf)) + n = sizeof(buf); + std::memcpy(buf, bytes, n); + std::uint64_t w[2]{}; + std::memcpy(w, buf, sizeof(w)); + return from_lane(w[0], w[1]); + } + + /// @brief Reduce an unreduced 128-bit lane `(hi << 64) + lo`. + /// @param lo the low limb, not necessarily reduced + /// @param hi the high limb, not necessarily reduced + /// @return the field element + HEDLEY_ALWAYS_INLINE + static constexpr field128 from_lane(std::uint64_t lo, std::uint64_t hi) noexcept + { + const std::uint64_t words[4] = {lo, hi, 0, 0}; + return reduce_words(words); + } + + /// @brief Canonical representative in `[0, mod)`. + HEDLEY_ALWAYS_INLINE + static constexpr field128 canonicalize(field128 a) noexcept + { + return from_lane(a.lo_, a.hi_); + } + + /// @brief Low 64 bits of the reduced representative. + /// @return the low limb + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + constexpr std::uint64_t lo() const noexcept { return lo_; } + + /// @brief High 64 bits of the reduced representative. + /// @return the high limb + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + constexpr std::uint64_t hi() const noexcept { return hi_; } + + /// @brief Field addition. + /// @param a left addend + /// @param b right addend + /// @return `a + b` in the field + HEDLEY_ALWAYS_INLINE + friend constexpr field128 operator+(field128 a, field128 b) noexcept + { + const unsigned __int128 low = + static_cast(a.lo_) + b.lo_; + const unsigned __int128 high = + static_cast(a.hi_) + b.hi_ + (low >> 64); + const std::uint64_t words[4] = { + static_cast(low), + static_cast(high), + static_cast(high >> 64), + 0}; + return reduce_words(words); + } + + /// @brief Field subtraction. + /// @param a minuend + /// @param b subtrahend + /// @return `a - b` in the field + HEDLEY_ALWAYS_INLINE + friend constexpr field128 operator-(field128 a, field128 b) noexcept + { + a = canonicalize(a); + b = canonicalize(b); + if (!less(a.hi_, a.lo_, b.hi_, b.lo_)) + { + std::uint64_t lo = 0, hi = 0; + sub_words(a.lo_, a.hi_, b.lo_, b.hi_, lo, hi); + return from_reduced(lo, hi); + } + std::uint64_t lo = 0, hi = 0; + sub_words(mod_lo, mod_hi, b.lo_, b.hi_, lo, hi); + return from_reduced(lo, hi) + a; + } + + /// @brief Field negation. + /// @param a the element to negate + /// @return `-a`, with `-0 = 0` + HEDLEY_ALWAYS_INLINE + friend constexpr field128 operator-(field128 a) noexcept + { + a = canonicalize(a); + if (a.lo_ == 0 && a.hi_ == 0) + return a; + std::uint64_t lo = 0, hi = 0; + sub_words(mod_lo, mod_hi, a.lo_, a.hi_, lo, hi); + return from_reduced(lo, hi); + } + + /// @brief Field multiplication. + /// @param a left factor + /// @param b right factor + /// @return `a * b` in the field + HEDLEY_ALWAYS_INLINE + friend constexpr field128 operator*(field128 a, field128 b) noexcept + { + std::uint64_t words[4]{}; + mul128(a.lo_, a.hi_, b.lo_, b.hi_, words); + return reduce_words(words); + } + + /// @brief Field equality. + /// @param a left element + /// @param b right element + /// @return `true` when the reduced values match + HEDLEY_ALWAYS_INLINE + friend constexpr bool operator==(field128 a, field128 b) noexcept + { + a = canonicalize(a); + b = canonicalize(b); + return a.lo_ == b.lo_ && a.hi_ == b.hi_; + } + + /// @brief Field inequality. + /// @param a left element + /// @param b right element + /// @return `true` when the reduced values differ + HEDLEY_ALWAYS_INLINE + friend constexpr bool operator!=(field128 a, field128 b) noexcept + { + return !(a == b); + } + + /// @brief Write the reduced representative in hexadecimal. + /// @param os the output stream + /// @param a the element to write + /// @return `os` + friend std::ostream & operator<<(std::ostream & os, field128 a) + { + const auto flags = os.flags(); + os << "0x" << std::hex << a.hi_ << std::setfill('0') << std::setw(16) << a.lo_; + os.flags(flags); + return os; + } + + private: + std::uint64_t lo_{}; + std::uint64_t hi_{}; + + HEDLEY_ALWAYS_INLINE + static constexpr field128 from_reduced(std::uint64_t lo, std::uint64_t hi) noexcept + { + field128 out; + out.lo_ = lo; + out.hi_ = hi; + return out; + } + + HEDLEY_ALWAYS_INLINE + static constexpr bool less(std::uint64_t hi, std::uint64_t lo, + std::uint64_t ohi, std::uint64_t olo) noexcept + { + return hi < ohi || (hi == ohi && lo < olo); + } + + HEDLEY_ALWAYS_INLINE + static constexpr bool ge_mod(std::uint64_t hi, std::uint64_t lo) noexcept + { + return hi > mod_hi || (hi == mod_hi && lo >= mod_lo); + } + + HEDLEY_ALWAYS_INLINE + static constexpr void sub_words(std::uint64_t al, std::uint64_t ah, + std::uint64_t bl, std::uint64_t bh, + std::uint64_t &ol, std::uint64_t &oh) noexcept + { + const unsigned borrow = al < bl ? 1u : 0u; + ol = static_cast(al - bl); + oh = static_cast(ah - bh - borrow); + } + + HEDLEY_ALWAYS_INLINE + static constexpr void add_c(std::uint64_t &lo, std::uint64_t &hi, + std::uint64_t &top) noexcept + { + const unsigned __int128 low = + static_cast(lo) + 0xffffffffffffffffull; + lo = static_cast(low); + const unsigned __int128 high = + static_cast(hi) + 0x1bull + static_cast(low >> 64); + hi = static_cast(high); + top = static_cast(high >> 64); + } + + /// @brief 128×128 → 256 multiply, little-endian limbs. + HEDLEY_ALWAYS_INLINE + static constexpr void mul128(std::uint64_t a0, std::uint64_t a1, + std::uint64_t b0, std::uint64_t b1, std::uint64_t out[4]) noexcept + { + const unsigned __int128 p00 = static_cast(a0) * b0; + const unsigned __int128 p01 = static_cast(a0) * b1; + const unsigned __int128 p10 = static_cast(a1) * b0; + const unsigned __int128 p11 = static_cast(a1) * b1; + out[0] = static_cast(p00); + const unsigned __int128 mid = (p00 >> 64) + + static_cast(p01) + static_cast(p10); + out[1] = static_cast(mid); + const unsigned __int128 high = (mid >> 64) + (p01 >> 64) + (p10 >> 64) + + static_cast(p11); + out[2] = static_cast(high); + out[3] = static_cast((high >> 64) + (p11 >> 64)); + } + + /// @brief Reduce a little-endian 256-bit integer. `2^128 ≡ C`. + HEDLEY_ALWAYS_INLINE + static constexpr field128 reduce_words(const std::uint64_t z[4]) noexcept + { + std::uint64_t lo = 0, hi = 0, top = 0; + for (int bit = 255; bit >= 0; --bit) + { + top = hi >> 63; + hi = (hi << 1) | (lo >> 63); + lo <<= 1; + const unsigned limb = static_cast(bit >> 6); + const unsigned off = static_cast(bit & 63); + if ((z[limb] >> off) & 1u) + { + const unsigned __int128 low = + static_cast(lo) + 1; + lo = static_cast(low); + const unsigned __int128 high = + static_cast(hi) + static_cast(low >> 64); + hi = static_cast(high); + top += static_cast(high >> 64); + } + while (top) + add_c(lo, hi, top); + if (ge_mod(hi, lo)) + sub_words(lo, hi, mod_lo, mod_hi, lo, hi); + } + return from_reduced(lo, hi); + } + + template + HEDLEY_ALWAYS_INLINE + constexpr void assign_integer(T v) noexcept + { + bool neg = false; + unsigned __int128 mag = 0; + if constexpr (std::is_signed_v) + { + if (v < 0) + { + neg = true; + using U = std::make_unsigned_t; + mag = static_cast(0) - static_cast(v); + } + else + { + mag = static_cast>(v); + } + } + else + { + mag = static_cast(v); + } + const std::uint64_t words[4] = { + static_cast(mag), + static_cast(mag >> 64), + 0, 0}; + *this = reduce_words(words); + if (neg) + *this = -*this; + } +}; + +namespace utils +{ + +template <> +struct bitlength_of + : std::integral_constant +{ }; + +template <> +struct has_characteristic_two : std::false_type +{ }; + +} // namespace utils + +namespace leaf_arithmetic +{ + +namespace detail +{ + +HEDLEY_ALWAYS_INLINE +field128 load_field128(const void *lane) noexcept +{ + std::uint64_t w[2]{}; + std::memcpy(w, lane, sizeof(w)); + return field128::from_lane(w[0], w[1]); +} + +HEDLEY_ALWAYS_INLINE +void store_field128(void *lane, field128 v) noexcept +{ + const std::uint64_t w[2] = {v.lo(), v.hi()}; + std::memcpy(lane, w, sizeof(w)); +} + +template +HEDLEY_ALWAYS_INLINE +void field128_lanes(const void *a, const void *b, void *out, + field128 (*op)(field128, field128)) noexcept +{ + auto *aa = static_cast(a); + auto *bb = static_cast(b); + auto *cc = static_cast(out); + for (std::size_t i = 0; i < Lanes; ++i) + { + const field128 y = op(load_field128(aa + i * 16), load_field128(bb + i * 16)); + store_field128(cc + i * 16, y); + } +} + +template +HEDLEY_ALWAYS_INLINE +void field128_scale(const void *a, field128 b, void *out) noexcept +{ + auto *aa = static_cast(a); + auto *cc = static_cast(out); + for (std::size_t i = 0; i < Lanes; ++i) + store_field128(cc + i * 16, load_field128(aa + i * 16) * b); +} + +} // namespace detail + +HEDLEY_PRAGMA(GCC diagnostic push) +HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + +template <> +struct add_t +{ + auto operator()(const simde__m128i &a, const simde__m128i &b) const + { + simde__m128i out; + detail::field128_lanes<1>(&a, &b, &out, [](field128 x, field128 y) { + return x + y; + }); + return out; + } +}; + +template <> +struct subtract_t +{ + auto operator()(const simde__m128i &a, const simde__m128i &b) const + { + simde__m128i out; + detail::field128_lanes<1>(&a, &b, &out, [](field128 x, field128 y) { + return x - y; + }); + return out; + } +}; + +template <> +struct multiply_t +{ + auto operator()(const simde__m128i &a, field128 b) const + { + simde__m128i out; + detail::field128_scale<1>(&a, b, &out); + return out; + } +}; + +template <> +struct add_t +{ + auto operator()(const simde__m256i &a, const simde__m256i &b) const + { + simde__m256i out; + detail::field128_lanes<2>(&a, &b, &out, [](field128 x, field128 y) { + return x + y; + }); + return out; + } +}; + +template <> +struct subtract_t +{ + auto operator()(const simde__m256i &a, const simde__m256i &b) const + { + simde__m256i out; + detail::field128_lanes<2>(&a, &b, &out, [](field128 x, field128 y) { + return x - y; + }); + return out; + } +}; + +template <> +struct multiply_t +{ + auto operator()(const simde__m256i &a, field128 b) const + { + simde__m256i out; + detail::field128_scale<2>(&a, b, &out); + return out; + } +}; + +HEDLEY_PRAGMA(GCC diagnostic pop) + +} // namespace leaf_arithmetic + +/// @brief Sample a uniform field element by rejection. +/// @return an element of the field +template <> +HEDLEY_NO_THROW +inline auto uniform_sample() noexcept +{ + for (;;) + { + const auto lo = uniform_sample(); + const auto hi = uniform_sample(); + if (hi < field128::mod_hi || (hi == field128::mod_hi && lo < field128::mod_lo)) + return field128::from_lane(lo, hi); + } +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_FIELD128_HPP__ diff --git a/include/dpf/field64.hpp b/include/dpf/field64.hpp new file mode 100644 index 0000000..eb97793 --- /dev/null +++ b/include/dpf/field64.hpp @@ -0,0 +1,362 @@ +/// @file dpf/field64.hpp +/// @brief Prime field GF(2^64 − 2^32 + 1), as a DPF output. +/// @details The modulus is libprio's `Field64` (the Goldilocks prime). Pass +/// `dpf::field64{n}` as a `make_dpf` payload. Leaf addition and +/// scaling are the field operations. A raw PRG block is reduced into +/// the field on the first leaf operation. This is a point-function +/// output, not a comparison payload. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_FIELD64_HPP__ +#define LIBDPF_INCLUDE_DPF_FIELD64_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" +#include "simde/simde/x86/avx2.h" + +#include "dpf/leaf_arithmetic.hpp" +#include "dpf/random.hpp" +#include "dpf/utils.hpp" + +namespace dpf +{ + +/// @brief Element of GF(2^64 − 2^32 + 1). +class field64 +{ + public: + /// @brief Modulus \f$2^{64}-2^{32}+1\f$. + static constexpr std::uint64_t mod = 0xffffffff00000001ull; + using integral_type = std::uint64_t; + static constexpr bool dpf_point_group = true; + + /// @brief Reduce `v` into the field. A negative value is negated in the field. + /// @tparam T integral type + /// @param v the integer to reduce + template >> + HEDLEY_ALWAYS_INLINE + constexpr field64(T v) noexcept + { + val = from_integer(v); + } + + /// @brief The zero element. + HEDLEY_ALWAYS_INLINE + constexpr field64() noexcept = default; + + /// @brief Reduce a PRG block into the field. Uses up to 16 bytes. + /// @param bytes the PRG output + /// @param n the number of bytes available + /// @return the field element + HEDLEY_ALWAYS_INLINE + static field64 from_seed(const void * bytes, std::size_t n) noexcept + { + unsigned char buf[16]{}; + if (n > sizeof(buf)) + n = sizeof(buf); + std::memcpy(buf, bytes, n); + std::uint64_t w[2]{}; + std::memcpy(w, buf, sizeof(w)); + const unsigned __int128 wide = static_cast(w[0]) + | (static_cast(w[1]) << 64); + return from_reduced(reduce_u128(wide)); + } + + /// @brief Reduced representative in `[0, mod)`. + /// @return the stored field element + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + constexpr integral_type raw() const noexcept { return reduce(val); } + + /// @brief Same value as `raw()`. + /// @return the stored field element + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + explicit constexpr operator integral_type() const noexcept { return raw(); } + + /// @brief Fold a 128-bit integer into the field. + /// @param x the integer to reduce + /// @return `x` modulo `mod` + HEDLEY_ALWAYS_INLINE + static constexpr integral_type reduce_u128(unsigned __int128 x) noexcept + { + // 2^64 ≡ 2^32 − 1, so each step replaces the high half. + while (x >> 64) + { + const auto lo = static_cast(x); + const auto hi = static_cast(x >> 64); + x = static_cast(lo) + + (static_cast(hi) << 32) - hi; + } + auto lo = static_cast(x); + if (lo >= mod) + lo -= mod; + return lo; + } + + /// @brief Reduce a 64-bit word. `mod` itself fits in the word. + /// @param x the integer to reduce + /// @return `x` modulo `mod` + HEDLEY_ALWAYS_INLINE + static constexpr integral_type reduce(integral_type x) noexcept + { + return x >= mod ? static_cast(x - mod) : x; + } + + /// @brief Field addition. + /// @param a left addend + /// @param b right addend + /// @return `a + b` in the field + HEDLEY_ALWAYS_INLINE + friend constexpr field64 operator+(field64 a, field64 b) noexcept + { + return from_reduced(reduce_u128( + static_cast(reduce(a.val)) + reduce(b.val))); + } + + /// @brief Field subtraction. + /// @param a minuend + /// @param b subtrahend + /// @return `a - b` in the field + HEDLEY_ALWAYS_INLINE + friend constexpr field64 operator-(field64 a, field64 b) noexcept + { + a.val = reduce(a.val); + b.val = reduce(b.val); + if (a.val >= b.val) + return from_reduced(static_cast(a.val - b.val)); + return from_reduced(static_cast(mod - (b.val - a.val))); + } + + /// @brief Field negation. + /// @param a the element to negate + /// @return `-a`, with `-0 = 0` + HEDLEY_ALWAYS_INLINE + friend constexpr field64 operator-(field64 a) noexcept + { + a.val = reduce(a.val); + return from_reduced(a.val == 0 ? 0 : static_cast(mod - a.val)); + } + + /// @brief Field multiplication. + /// @param a left factor + /// @param b right factor + /// @return `a * b` in the field + HEDLEY_ALWAYS_INLINE + friend constexpr field64 operator*(field64 a, field64 b) noexcept + { + return from_reduced(reduce_u128( + static_cast(reduce(a.val)) * reduce(b.val))); + } + + /// @brief Field equality. + /// @param a left element + /// @param b right element + /// @return `true` when the reduced values match + HEDLEY_ALWAYS_INLINE + friend constexpr bool operator==(field64 a, field64 b) noexcept + { + return reduce(a.val) == reduce(b.val); + } + + /// @brief Field inequality. + /// @param a left element + /// @param b right element + /// @return `true` when the reduced values differ + HEDLEY_ALWAYS_INLINE + friend constexpr bool operator!=(field64 a, field64 b) noexcept + { + return reduce(a.val) != reduce(b.val); + } + + /// @brief Write the reduced representative in decimal. + /// @param os the output stream + /// @param a the element to write + /// @return `os` + friend std::ostream & operator<<(std::ostream & os, field64 a) + { + return os << a.raw(); + } + + private: + integral_type val{}; + + HEDLEY_ALWAYS_INLINE + static constexpr field64 from_reduced(integral_type v) noexcept + { + field64 out; + out.val = v; + return out; + } + + template + HEDLEY_ALWAYS_INLINE + static constexpr integral_type from_integer(T v) noexcept + { + if constexpr (std::is_signed_v) + { + if (v < 0) + { + using U = std::make_unsigned_t; + const auto mag = static_cast(0) - static_cast(v); + return reduce_u128(static_cast(mag)) == 0 + ? 0 + : static_cast( + mod - reduce_u128(static_cast(mag))); + } + } + return reduce_u128(static_cast(v)); + } +}; + +namespace utils +{ + +template <> +struct bitlength_of + : std::integral_constant +{ }; + +template <> +struct has_characteristic_two : std::false_type +{ }; + +} // namespace utils + +namespace leaf_arithmetic +{ + +namespace detail +{ + +template +HEDLEY_ALWAYS_INLINE +void field64_lanes(const void *a, const void *b, void *out, + field64 (*op)(field64, field64)) noexcept +{ + std::uint64_t aa[Lanes], bb[Lanes], cc[Lanes]; + std::memcpy(aa, a, sizeof(aa)); + std::memcpy(bb, b, sizeof(bb)); + for (std::size_t i = 0; i < Lanes; ++i) + cc[i] = op(field64{aa[i]}, field64{bb[i]}).raw(); + std::memcpy(out, cc, sizeof(cc)); +} + +template +HEDLEY_ALWAYS_INLINE +void field64_scale(const void *a, field64 b, void *out) noexcept +{ + std::uint64_t aa[Lanes], cc[Lanes]; + std::memcpy(aa, a, sizeof(aa)); + for (std::size_t i = 0; i < Lanes; ++i) + cc[i] = (field64{aa[i]} * b).raw(); + std::memcpy(out, cc, sizeof(cc)); +} + +} // namespace detail + +HEDLEY_PRAGMA(GCC diagnostic push) +HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + +template <> +struct add_t +{ + auto operator()(const simde__m128i &a, const simde__m128i &b) const + { + simde__m128i out; + detail::field64_lanes<2>(&a, &b, &out, [](field64 x, field64 y) { + return x + y; + }); + return out; + } +}; + +template <> +struct subtract_t +{ + auto operator()(const simde__m128i &a, const simde__m128i &b) const + { + simde__m128i out; + detail::field64_lanes<2>(&a, &b, &out, [](field64 x, field64 y) { + return x - y; + }); + return out; + } +}; + +template <> +struct multiply_t +{ + auto operator()(const simde__m128i &a, field64 b) const + { + simde__m128i out; + detail::field64_scale<2>(&a, b, &out); + return out; + } +}; + +template <> +struct add_t +{ + auto operator()(const simde__m256i &a, const simde__m256i &b) const + { + simde__m256i out; + detail::field64_lanes<4>(&a, &b, &out, [](field64 x, field64 y) { + return x + y; + }); + return out; + } +}; + +template <> +struct subtract_t +{ + auto operator()(const simde__m256i &a, const simde__m256i &b) const + { + simde__m256i out; + detail::field64_lanes<4>(&a, &b, &out, [](field64 x, field64 y) { + return x - y; + }); + return out; + } +}; + +template <> +struct multiply_t +{ + auto operator()(const simde__m256i &a, field64 b) const + { + simde__m256i out; + detail::field64_scale<4>(&a, b, &out); + return out; + } +}; + +HEDLEY_PRAGMA(GCC diagnostic pop) + +} // namespace leaf_arithmetic + +/// @brief Sample a uniform field element by rejection. +/// @return an element of the field +template <> +HEDLEY_NO_THROW +inline auto uniform_sample() noexcept +{ + for (;;) + { + const auto x = uniform_sample(); + if (x < field64::mod) + return field64{x}; + } +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_FIELD64_HPP__ diff --git a/include/dpf/fixed_share.hpp b/include/dpf/fixed_share.hpp new file mode 100644 index 0000000..5c358d6 --- /dev/null +++ b/include/dpf/fixed_share.hpp @@ -0,0 +1,87 @@ +/// @file dpf/fixed_share.hpp +/// @brief Fixed-point arithmetic shares: `fixed`. +#ifndef LIBDPF_INCLUDE_DPF_FIXED_SHARE_HPP__ +#define LIBDPF_INCLUDE_DPF_FIXED_SHARE_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/share_vec.hpp" +#include "dpf/trunc.hpp" + +namespace dpf +{ + +template +struct fixed +{ + static constexpr unsigned int_bits = IntBits; + static constexpr unsigned frac_bits = FracBits; + static constexpr unsigned width = IntBits + FracBits; + static_assert(width > 0 && width <= 128, "fixed width 1..128"); + + using ring = std::conditional_t<(width > 64), unsigned __int128, std::uint64_t>; + + ring raw{}; + + fixed() = default; + explicit fixed(ring v) : raw(v) {} + + static fixed from_integer(ring i) + { + return fixed{static_cast(i << FracBits)}; + } + + static fixed mul_clear(fixed a, fixed b) + { + const ring prod = static_cast(a.raw * b.raw); + return fixed{static_cast(prod >> FracBits)}; + } + + friend fixed operator+(fixed a, fixed b) + { + return fixed{static_cast(a.raw + b.raw)}; + } + + friend fixed operator-(fixed a, fixed b) + { + return fixed{static_cast(a.raw - b.raw)}; + } +}; + +template +using fixed_vec = share_vec::ring>; + +/// @brief Fixed-point product via mul_trunc by FracBits (Beaver, both parties). +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, fixed_vec> +fixed_mul_share(const fixed_vec & x0, + const fixed_vec & x1, + const fixed_vec & y0, + const fixed_vec & y1) +{ + if (x0.size() != x1.size() || x0.size() != y0.size() + || y0.size() != y1.size()) + throw std::invalid_argument("fixed_mul_share size"); + fixed_vec z0(x0.size(), protocol::domain::a, 0); + fixed_vec z1(x0.size(), protocol::domain::a, 1); + for (std::size_t i = 0; i < x0.size(); ++i) + { + // Widen so IntBits+FracBits products do not wrap before the shift. + auto mt = trunc::mul_exact_trunc(x0[i], x1[i], y0[i], y1[i], FracBits); + z0[i] = mt.z0; + z1[i] = mt.z1; + } + return {std::move(z0), std::move(z1)}; +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_FIXED_SHARE_HPP__ diff --git a/include/dpf/flute.hpp b/include/dpf/flute.hpp new file mode 100644 index 0000000..11866cc --- /dev/null +++ b/include/dpf/flute.hpp @@ -0,0 +1,260 @@ +/// @file dpf/flute.hpp +/// @brief Lookup tables as a multi-fan-in inner product. +/// @details A public table `f : {0,1}^δ → {0,1}^σ` is the OR of the input +/// rows whose output bit is 1. Those terms are disjoint, so the OR +/// is an XOR, and the XOR of ANDs is an inner product of one vector +/// per input bit (and the public output column). Complements flip the +/// already-opened masked bit and leave the mask λ alone, so setup +/// builds subset products of the δ input masks once, not once per row. +/// +/// Online, each party XORs the public terms into a share of `v` and +/// the parties exchange that share. Two parties send two bits per +/// output bit, independent of δ. The masked output `m_z` is then +/// local, and the semantic bit is `m_z XOR λ_z`. +/// +/// The two-party exchange is ΠLUT. The three-party function is the +/// same algebra on three XOR shares of each mask: the paper's +/// construction is the inner product, and the share count is the +/// underlying MPC. This is not a new share domain. +/// @note Andreas Brüggemann, Robin Hundt, Thomas Schneider, Ajith Suresh, and +/// Hossein Yalame, "FLUTE: Fast and Secure Lookup Table Evaluations," +/// IEEE S&P 2023 (ePrint 2023/499). The masked bits are the ABY2.0 wire +/// (Patra, Schneider, Suresh, and Yalame, USENIX Security 2021). +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_FLUTE_HPP__ +#define LIBDPF_INCLUDE_DPF_FLUTE_HPP__ + +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/random.hpp" + +namespace dpf +{ +namespace flute +{ + +inline constexpr unsigned k_max_delta = 8; + +/// @brief One evaluation. `opened[w] = masked[w] XOR` the mask shares. +struct result +{ + std::vector opened; + std::vector masked; + /// @brief XOR shares of `λ_z`, one vector per party. Size 2 or 3. + std::vector> mask; + /// @brief Bits exchanged online: one bit per party per output bit. + std::size_t online_bits = 0; +}; + +namespace detail +{ + +inline std::uint8_t bit_of(std::uint32_t row, unsigned i) +{ + return static_cast((row >> i) & 1u); +} + +/// @brief Masked literal of input `i` on row `j`. Complement flips `m` only. +inline std::uint8_t masked_lit(std::uint8_t m, std::uint8_t encoding) +{ + return encoding ? m : static_cast(m ^ 1u); +} + +inline std::uint8_t and_subset(std::uint32_t subset, std::uint32_t row, + unsigned delta, const std::uint8_t * m) +{ + std::uint8_t acc = 1; + for (unsigned i = 0; i < delta; ++i) + { + if (((subset >> i) & 1u) == 0) + continue; + acc = static_cast( + acc & masked_lit(m[i], bit_of(row, i))); + } + return acc; +} + +inline std::uint8_t dot_column(std::uint32_t subset, unsigned delta, + const std::uint8_t * m, const std::uint8_t * column) +{ + const std::uint32_t rows = 1u << delta; + std::uint8_t acc = 0; + for (std::uint32_t j = 0; j < rows; ++j) + { + if (column[j] == 0) + continue; + acc = static_cast( + acc ^ and_subset(subset, j, delta, m)); + } + return acc; +} + +inline std::uint8_t rand_bit() +{ + return static_cast(dpf::uniform_sample() & 1u); +} + +struct setup +{ + std::vector m; + std::vector lam; + /// @brief `share[party][subset] =` that party's XOR share of AND_{i in subset} λ_i. + std::vector> share; + std::vector> lamz; +}; + +inline setup make_setup(unsigned delta, unsigned n_out, unsigned parties, + const std::uint8_t * x) +{ + if (parties != 2 && parties != 3) + throw std::invalid_argument("flute: parties"); + setup s; + s.m.resize(delta); + s.lam.resize(delta); + s.share.assign(parties, std::vector(1u << delta, 0)); + s.lam.resize(delta); + for (unsigned i = 0; i < delta; ++i) + { + if (x[i] > 1) + throw std::invalid_argument("flute: input bit"); + std::uint8_t lam = 0; + for (unsigned p = 0; p < parties; ++p) + { + const std::uint8_t sh = rand_bit(); + s.share[p][1u << i] = sh; + lam = static_cast(lam ^ sh); + } + s.lam[i] = lam; + s.m[i] = static_cast(x[i] ^ lam); + } + s.share[0][0] = 1; + const std::uint32_t nsub = 1u << delta; + for (std::uint32_t subset = 1; subset < nsub; ++subset) + { + if ((subset & (subset - 1u)) == 0) + continue; + for (unsigned p = 0; p < parties; ++p) + { + // Dealer shares the AND. Party 0 holds the product of the full + // masks adjusted by the other parties' shares of this subset. + s.share[p][subset] = 0; + } + std::uint8_t prod = 1; + for (unsigned i = 0; i < delta; ++i) + if (((subset >> i) & 1u) != 0) + prod = static_cast(prod & s.lam[i]); + for (unsigned p = 1; p < parties; ++p) + s.share[p][subset] = rand_bit(); + std::uint8_t rest = prod; + for (unsigned p = 1; p < parties; ++p) + rest = static_cast(rest ^ s.share[p][subset]); + s.share[0][subset] = rest; + } + s.lamz.assign(parties, std::vector(n_out, 0)); + for (unsigned w = 0; w < n_out; ++w) + for (unsigned p = 0; p < parties; ++p) + s.lamz[p][w] = rand_bit(); + return s; +} + +inline std::uint8_t party_v(const setup & s, unsigned party, unsigned delta, + std::uint32_t full, const std::uint8_t * column, std::uint8_t lamz_share) +{ + std::uint8_t v = lamz_share; + for (std::uint32_t subset = 0; subset < full; ++subset) + { + const std::uint32_t rest = full ^ subset; + const std::uint8_t t = dot_column(subset, delta, s.m.data(), column); + v = static_cast( + v ^ (t & s.share[party][rest])); + } + return v; +} + +inline result run(unsigned delta, unsigned n_out, unsigned parties, + const std::uint8_t * columns, const std::uint8_t * x) +{ + if (delta < 1 || delta > k_max_delta) + throw std::invalid_argument("flute: delta"); + if (n_out == 0 || columns == nullptr || x == nullptr) + throw std::invalid_argument("flute: table"); + const std::uint32_t rows = 1u << delta; + const std::uint32_t full = rows - 1u; + auto s = make_setup(delta, n_out, parties, x); + result out; + out.mask.assign(parties, std::vector(n_out, 0)); + out.masked.resize(n_out); + out.opened.resize(n_out); + out.online_bits = static_cast(parties) * n_out; + for (unsigned w = 0; w < n_out; ++w) + { + const std::uint8_t * column = columns + static_cast(w) * rows; + std::uint8_t v = 0; + for (unsigned p = 0; p < parties; ++p) + { + const std::uint8_t share = party_v(s, p, delta, full, column, s.lamz[p][w]); + v = static_cast(v ^ share); + out.mask[p][w] = s.lamz[p][w]; + } + const std::uint8_t t_full = dot_column(full, delta, s.m.data(), column); + out.masked[w] = static_cast(v ^ t_full); + std::uint8_t lam = 0; + for (unsigned p = 0; p < parties; ++p) + lam = static_cast(lam ^ out.mask[p][w]); + out.opened[w] = static_cast(out.masked[w] ^ lam); + } + return out; +} + +} // namespace detail + +/// @brief Clear table. `x` is δ bits, least-significant bit first. +/// `columns[w * 2^δ + row]` is output bit `w` on that row. +HEDLEY_WARN_UNUSED_RESULT +inline std::vector eval_plain(unsigned delta, unsigned n_out, + const std::uint8_t * columns, const std::uint8_t * x) +{ + if (delta < 1 || delta > k_max_delta) + throw std::invalid_argument("flute: delta"); + std::uint32_t row = 0; + for (unsigned i = 0; i < delta; ++i) + { + if (x[i] > 1) + throw std::invalid_argument("flute: input bit"); + row |= static_cast(x[i]) << i; + } + const std::uint32_t rows = 1u << delta; + std::vector out(n_out); + for (unsigned w = 0; w < n_out; ++w) + out[w] = columns[static_cast(w) * rows + row] & 1u; + return out; +} + +/// @brief Two-party ΠLUT. Online cost is two bits per output bit. +HEDLEY_WARN_UNUSED_RESULT +inline result eval_pair(unsigned delta, unsigned n_out, + const std::uint8_t * columns, const std::uint8_t * x) +{ + return detail::run(delta, n_out, 2, columns, x); +} + +/// @brief The same ΠLUT inner product on three XOR shares of each mask. +HEDLEY_WARN_UNUSED_RESULT +inline result eval_trio(unsigned delta, unsigned n_out, + const std::uint8_t * columns, const std::uint8_t * x) +{ + return detail::run(delta, n_out, 3, columns, x); +} + +} // namespace flute +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_FLUTE_HPP__ diff --git a/include/dpf/fp61.hpp b/include/dpf/fp61.hpp index 96e61f0..03a3f8e 100644 --- a/include/dpf/fp61.hpp +++ b/include/dpf/fp61.hpp @@ -11,17 +11,19 @@ #include #include #include +#include #include #include "hedley/hedley.h" #include "dpf/utils.hpp" #include "dpf/leaf_arithmetic.hpp" +#include "dpf/random.hpp" namespace dpf { -/// @brief Modulus \(p = 2^{61}-1\). `p` itself reduces to 0. +/// @brief Modulus \f$p = 2^{61}-1\f$. `p` itself reduces to 0. inline constexpr std::uint64_t fp61_mod = (std::uint64_t{1} << 61) - 1; /// @brief Additive element of the field of order `2^61 - 1`. @@ -66,7 +68,29 @@ class fp61 HEDLEY_NO_THROW HEDLEY_ALWAYS_INLINE HEDLEY_PURE - constexpr integral_type raw() const noexcept { return val; } + constexpr integral_type raw() const noexcept { return reduce(val); } + + /// @brief Build a field element from PRG bytes (Mersenne reduction). + /// @param bytes the PRG output + /// @param n the number of bytes available + /// @return the field element + HEDLEY_ALWAYS_INLINE + static fp61 from_seed(const void * bytes, std::size_t n) noexcept + { + unsigned char buf[16]{}; + if (n > sizeof(buf)) + n = sizeof(buf); + std::memcpy(buf, bytes, n); + std::uint64_t w[2]{}; + std::memcpy(w, buf, sizeof(w)); + using u128 = unsigned __int128; + const u128 wide = static_cast(w[0]) + | (static_cast(w[1]) << 64); + const auto lo = static_cast(wide) & fp61_mod; + const auto mid = static_cast(wide >> 61) & fp61_mod; + const auto hi = static_cast(wide >> 122); + return fp61{lo + mid + hi}; + } /// @brief Same value as `raw()`. /// @return the stored field element @@ -98,7 +122,7 @@ class fp61 HEDLEY_CONST friend constexpr fp61 operator+(fp61 a, fp61 b) noexcept { - return fp61{a.val + b.val}; + return fp61{reduce(a.val) + reduce(b.val)}; } /// @brief Field subtraction. @@ -110,7 +134,7 @@ class fp61 HEDLEY_CONST friend constexpr fp61 operator-(fp61 a, fp61 b) noexcept { - return fp61{a.val + fp61_mod - b.val}; + return fp61{reduce(a.val) + fp61_mod - reduce(b.val)}; } /// @brief Field negation. @@ -121,7 +145,8 @@ class fp61 HEDLEY_CONST friend constexpr fp61 operator-(fp61 a) noexcept { - return fp61{a.val == 0 ? 0 : fp61_mod - a.val}; + const auto v = reduce(a.val); + return fp61{v == 0 ? 0 : fp61_mod - v}; } /// @brief Field multiplication. @@ -134,7 +159,7 @@ class fp61 friend constexpr fp61 operator*(fp61 a, fp61 b) noexcept { using u128 = unsigned __int128; - const u128 p = static_cast(a.val) * static_cast(b.val); + const u128 p = static_cast(reduce(a.val)) * static_cast(reduce(b.val)); const auto lo = static_cast(p) & fp61_mod; const auto mid = static_cast(p >> 61) & fp61_mod; const auto hi = static_cast(p >> 122); @@ -150,7 +175,7 @@ class fp61 HEDLEY_CONST friend constexpr bool operator==(fp61 a, fp61 b) noexcept { - return a.val == b.val; + return reduce(a.val) == reduce(b.val); } /// @brief Field inequality. @@ -162,7 +187,7 @@ class fp61 HEDLEY_CONST friend constexpr bool operator!=(fp61 a, fp61 b) noexcept { - return a.val != b.val; + return reduce(a.val) != reduce(b.val); } /// @brief Write the reduced representative in decimal. @@ -195,6 +220,35 @@ struct has_characteristic_two : std::false_type namespace leaf_arithmetic { +namespace detail +{ + +template +HEDLEY_ALWAYS_INLINE +void fp61_lanes(const void * a, const void * b, void * out, + fp61 (*op)(fp61, fp61)) noexcept +{ + std::uint64_t aa[Lanes], bb[Lanes], cc[Lanes]; + std::memcpy(aa, a, sizeof(aa)); + std::memcpy(bb, b, sizeof(bb)); + for (std::size_t i = 0; i < Lanes; ++i) + cc[i] = op(fp61{aa[i]}, fp61{bb[i]}).raw(); + std::memcpy(out, cc, sizeof(cc)); +} + +template +HEDLEY_ALWAYS_INLINE +void fp61_scale(const void * a, fp61 b, void * out) noexcept +{ + std::uint64_t aa[Lanes], cc[Lanes]; + std::memcpy(aa, a, sizeof(aa)); + for (std::size_t i = 0; i < Lanes; ++i) + cc[i] = (fp61{aa[i]} * b).raw(); + std::memcpy(out, cc, sizeof(cc)); +} + +} // namespace detail + HEDLEY_PRAGMA(GCC diagnostic push) HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") template <> @@ -202,7 +256,11 @@ struct add_t { auto operator()(const simde__m128i & a, const simde__m128i & b) const { - return add_t{}(a, b); + simde__m128i out; + detail::fp61_lanes<2>(&a, &b, &out, [](fp61 x, fp61 y) { + return x + y; + }); + return out; } }; @@ -211,7 +269,22 @@ struct subtract_t { auto operator()(const simde__m128i & a, const simde__m128i & b) const { - return subtract_t{}(a, b); + simde__m128i out; + detail::fp61_lanes<2>(&a, &b, &out, [](fp61 x, fp61 y) { + return x - y; + }); + return out; + } +}; + +template <> +struct multiply_t +{ + auto operator()(const simde__m128i & a, fp61 b) const + { + simde__m128i out; + detail::fp61_scale<2>(&a, b, &out); + return out; } }; @@ -220,7 +293,11 @@ struct add_t { auto operator()(const simde__m256i & a, const simde__m256i & b) const { - return add_t{}(a, b); + simde__m256i out; + detail::fp61_lanes<4>(&a, &b, &out, [](fp61 x, fp61 y) { + return x + y; + }); + return out; } }; @@ -229,13 +306,72 @@ struct subtract_t { auto operator()(const simde__m256i & a, const simde__m256i & b) const { - return subtract_t{}(a, b); + simde__m256i out; + detail::fp61_lanes<4>(&a, &b, &out, [](fp61 x, fp61 y) { + return x - y; + }); + return out; + } +}; + +template <> +struct multiply_t +{ + auto operator()(const simde__m256i & a, fp61 b) const + { + simde__m256i out; + detail::fp61_scale<4>(&a, b, &out); + return out; } }; HEDLEY_PRAGMA(GCC diagnostic pop) } // namespace leaf_arithmetic +/// @brief Sample a uniformly reduced field element by rejection. +/// @return an element of the field +template <> +HEDLEY_NO_THROW +inline auto uniform_sample() noexcept +{ + for (;;) + { + const auto v = uniform_sample() & fp61_mod; + if (v < fp61_mod) + return fp61{v}; + } +} + +namespace detail +{ + +template <> +struct shamir_field : std::true_type +{ + /// @brief `a^{-1}` by Fermat, `a^{p-2}`. + /// @param a a non-zero field element + /// @return `a^{-1}` + /// @throws std::invalid_argument if `a` is zero + static fp61 inv(fp61 a) + { + if (a.raw() == 0) + throw std::invalid_argument("shamir: inverse of zero"); + fp61 base = a; + fp61 out{1}; + auto e = fp61_mod - 2; + while (e != 0) + { + if (e & 1u) + out = out * base; + base = base * base; + e >>= 1; + } + return out; + } +}; + +} // namespace detail + } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_FP61_HPP__ diff --git a/include/dpf/geneval.hpp b/include/dpf/geneval.hpp index 1e0791d..31bc6d4 100644 --- a/include/dpf/geneval.hpp +++ b/include/dpf/geneval.hpp @@ -11,9 +11,10 @@ /// cancels. /// /// Default calls take XOR shares of the point. Tagged with -/// `arith_input`, the point is the ring sum of the two shares; path -/// bits are opened by a carry chain inside the local CW protocol so -/// the words match `make_dpf(x0 + x1)` at the caller's query. +/// `arith_input`, the point is the ring sum of the two shares. A +/// beaver ripple-carry converts those shares to XOR shares of the +/// sum bits before the walk, so the words match `make_dpf` on that +/// sum. The sum is not opened. /// /// `geneval_cmp` is the comparison-channel form. The value-correction /// word is a function of the secret path at every level, so the walk @@ -21,6 +22,7 @@ /// Doerner–Shelat comparison key. Prefix shares are /// `eval_point(cmp, ...)` at each endpoint. Piecewise-cubic evaluation /// on top of that is `grotto::geneval_offset_horner`. +/// @note The per-level correction opening follows Jack Doerner and abhi shelat, CCS 2017 (ePrint 2017/827). They return a reusable key. This function opens a word only for nodes on the public query trie and, with a local pad tape, sends nothing. /// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license; /// see [LICENSE.md](@ref license) for details. @@ -46,6 +48,7 @@ #include "dpf/doerner_shelat.hpp" #include "dpf/eval_target.hpp" #include "dpf/leaf_node.hpp" +#include "dpf/verifiable.hpp" namespace dpf { @@ -69,6 +72,9 @@ struct geneval_result std::size_t live_levels = 0; bool leaf_live = false; Leaf leaf{}; + /// @brief Party 0 / 1 VDPF tokens over the live eval trie (empty when unused). + proof_token proof0{}; + proof_token proof1{}; }; namespace detail @@ -172,7 +178,8 @@ auto geneval_run(bool arith, bool arith_out, InputT x0, InputT x1, InputT x0c = x0; InputT x1c = x1; proto.encode_walk_shares(x0c, x1c, arith); - const InputT alpha = utils::xor_input_shares(x0c, x1c); + // Keep the secret path on share-bits. Do not form a clear alpha for leaf + // placement, live levels, or correction seeds. std::vector flipped; flipped.reserve(queries.size()); @@ -191,8 +198,6 @@ auto geneval_run(bool arith, bool arith_out, InputT x0, InputT x1, if (unique_leaves.size() > (std::size_t{1} << 20)) throw std::length_error("geneval trie is too large"); - const uint64_t secret_leaf = geneval_leaf_id(alpha); - constexpr auto to_int = utils::to_integral_type{}; using tree = dpf::tree_traits; @@ -222,14 +227,17 @@ HEDLEY_PRAGMA(GCC diagnostic pop) std::memset(&result.leaf, 0, sizeof(result.leaf)); result.correction_words.reserve(depth); result.correction_advice.reserve(depth); + result.proof0 = detail::vdpf::zero_proof(); + result.proof1 = detail::vdpf::zero_proof(); auto mask = dpf_type::msb_mask; bool still_live = true; + uint64_t secret_prefix = 0; for (std::size_t level = 0; level < depth; ++level, mask >>= 1) { const uint8_t bit0 = static_cast(!!(to_int(mask) & to_int(x0c))); const uint8_t bit1 = static_cast(!!(to_int(mask) & to_int(x1c))); - const uint64_t parent_id = geneval_prefix(secret_leaf, depth, level); + const uint64_t parent_id = secret_prefix; const bool is_last = tree::is_last_level(level, depth); node L0 = simde_mm_setzero_si128(); @@ -303,6 +311,8 @@ HEDLEY_PRAGMA(GCC diagnostic pop) const node cw0 = tree::pack_cw(cw, advice, false, is_last); const node cw1 = tree::pack_cw(cw, advice, true, is_last); const std::size_t child_bits = level + 1; + const uint8_t secret_bit = static_cast((bit0 ^ bit1) & 1u); + secret_prefix = (secret_prefix << 1) | secret_bit; std::vector next; next.reserve(exps.size() * 2); for (const exp & e : exps) @@ -322,9 +332,37 @@ HEDLEY_PRAGMA(GCC diagnostic pop) dpf::xor_if_lo_bit(e.R1, cw1, e.s1)}); } } + + // Fold every live child into both parties' VDPF tokens. + if (!next.empty()) + { + cs_block cs{}; + bool have_cs = false; + for (const slot & c : next) + { + if (c.id == secret_prefix) + { + // Prefix is the share-bit path accumulated above — not a + // fresh xor_input_shares of the point for leaf placement. + cs = detail::vdpf::make_cs(level, c.id, c.s0, c.s1); + have_cs = true; + break; + } + } + if (!have_cs) + cs = detail::vdpf::make_cs(level, next[0].id, next[0].s0, + next[0].s1); + for (const slot & c : next) + { + detail::vdpf::fold_node(result.proof0, level, c.id, c.s0, cs); + detail::vdpf::fold_node(result.proof1, level, c.id, c.s1, cs); + } + } + frontier = std::move(next); } + const uint64_t secret_leaf = secret_prefix; result.leaf_live = geneval_any_prefix(unique_leaves, depth, secret_leaf, depth); if (result.leaf_live) { @@ -343,18 +381,21 @@ HEDLEY_PRAGMA(GCC diagnostic pop) { const uint8_t t0 = static_cast(dpf::get_lo_bit(on->s0)); const uint8_t t1 = static_cast(dpf::get_lo_bit(on->s1)); - const std::size_t lane = static_cast(to_int(alpha)); result.leaf = proto.template open_arith_leaf( dpf::unset_lo_2bits(on->s0), dpf::unset_lo_2bits(on->s1), t0, t1, - y0, y1, std::size_t{0}, lane); + y0, y1, std::size_t{0}, x0c, x1c); } else { - const bool sign0 = dpf::get_lo_bit(on->s0); - auto built = dpf::make_leaves(alpha, - dpf::unset_lo_2bits(on->s0), dpf::unset_lo_2bits(on->s1), sign0, - std::size_t{0}, y0); - result.leaf = std::get<0>(built.first.first); + // Mux / reconstruct only inside the leaf protocol hook. + proto.open_leaf_group(x0c, x1c, [&](InputT sx0, InputT sx1) { + const InputT x = utils::xor_input_shares(sx0, sx1); + const bool sign0 = dpf::get_lo_bit(on->s0); + auto built = dpf::make_leaves(x, + dpf::unset_lo_2bits(on->s0), dpf::unset_lo_2bits(on->s1), + sign0, std::size_t{0}, y0); + result.leaf = std::get<0>(built.first.first); + }); } } @@ -491,6 +532,10 @@ std::vector geneval_inclusive(InputT from, InputT to) /// @param rng the Doerner–Shelat randomness tapes /// @param y the payload /// @return the opened shares and correction words +/// \complexity O(n F) PRG expansions. n is `depth`. Each level expands every frontier node (two `expand` calls, one per share) and, while the secret path is live, one `prepare_level`. F is at most the number of distinct query leaves; the function rejects more than 2^20. Setup sorts the q query ids. +/// \rounds No sockets. While the path is live, each level calls `prepare_level`, which samples one `ds_cw_pads` and two `ds_and_pads` and then `open_cw`. +/// \communication none in this function. +/// \preprocessing The `ds_randomness` tape: per live level, `ds_sample_cw` draws two 128-bit blocks and two bits, and each of the two AND pads is one `ds_sample_and`. template (), rng.root, rng.pad, y); } +/// \complexity O(n F) PRG expansions. n is `depth`. Each level expands every frontier node (two `expand` calls, one per share) and, while the secret path is live, one `prepare_level`. F is at most the number of distinct query leaves; the function rejects more than 2^20. Setup sorts the q query ids. +/// \rounds No sockets. While the path is live, each level calls `prepare_level`, which samples one `ds_cw_pads` and two `ds_and_pads` and then `open_cw`. +/// \communication none in this function. +/// \preprocessing The `ds_randomness` tape: per live level, `ds_sample_cw` draws two 128-bit blocks and two bits, and each of the two AND pads is one `ds_sample_and`. template ; @@ -792,11 +878,19 @@ geneval_cmp_result geneval_cmp(InputT x0, InputT x1, if constexpr (key_type::cmp_block == 0) out.value_cw[level] = k0.value_cw(level); } + detail::vdpf::init_proof(out.proof0, k0); + detail::vdpf::init_proof(out.proof1, k1); + auto path0 = make_basic_path_memoizer(k0); + auto path1 = make_basic_path_memoizer(k1); for (auto it = begin; it != end; ++it) { - out.party0.push_back(eval_point(dpf::cmp, k0, *it).raw()); - out.party1.push_back(eval_point(dpf::cmp, k1, *it).raw()); + out.party0.push_back( + detail::incr::eval_cmp_point_impl(k0, *it, path0, &out.proof0).raw()); + out.party1.push_back( + detail::incr::eval_cmp_point_impl(k1, *it, path1, &out.proof1).raw()); } + detail::vdpf::fold_output_binding(out.proof0, k0); + detail::vdpf::fold_output_binding(out.proof1, k1); return out; } @@ -823,7 +917,7 @@ geneval_cmp_result geneval_cmp(arith_input_t, InputT x0, InputT x1, return out; auto keys = make_dpf_doerner_shelat(arith_input, std::move(x0), std::move(x1), - std::move(rng), std::move(spec)); + std::move(rng), std::move(spec), dpf::verifiable{}); const auto & k0 = keys.first; const auto & k1 = keys.second; using key_type = std::decay_t; @@ -853,11 +947,19 @@ geneval_cmp_result geneval_cmp(arith_input_t, InputT x0, InputT x1, if constexpr (key_type::cmp_block == 0) out.value_cw[level] = k0.value_cw(level); } + detail::vdpf::init_proof(out.proof0, k0); + detail::vdpf::init_proof(out.proof1, k1); + auto path0 = make_basic_path_memoizer(k0); + auto path1 = make_basic_path_memoizer(k1); for (auto it = begin; it != end; ++it) { - out.party0.push_back(eval_point(dpf::cmp, k0, *it).raw()); - out.party1.push_back(eval_point(dpf::cmp, k1, *it).raw()); + out.party0.push_back( + detail::incr::eval_cmp_point_impl(k0, *it, path0, &out.proof0).raw()); + out.party1.push_back( + detail::incr::eval_cmp_point_impl(k1, *it, path1, &out.proof1).raw()); } + detail::vdpf::fold_output_binding(out.proof0, k0); + detail::vdpf::fold_output_binding(out.proof1, k1); return out; } @@ -903,6 +1005,124 @@ geneval_cmp_result geneval_cmp(arith_input_t, InputT x0, InputT x1, /// @} +namespace detail +{ + +/// @brief Copy party shares from a geneval result into caller buffers. +template +void geneval_fill_buffers(const Result & r, Buf0 & buf0, Buf1 & buf1) +{ + const std::size_t n = r.party0.size(); + if (utils::size(buf0) < n || utils::size(buf1) < n) + throw std::length_error("geneval: output buffer is too small"); + for (std::size_t i = 0; i < n; ++i) + { + buf0[i] = r.party0[i]; + buf1[i] = r.party1[i]; + } +} + +} // namespace detail + +/// @name Geneval into caller buffers +/// @details Thin overloads that run the same trie walk, then copy party shares +/// into `buf0` / `buf1` (same layout as `eval_interval` / `eval_sequence` +/// output buffers). Memoizer arguments for the fused trie are internal; +/// path memoizers live on `geneval_cmp` / `geneval_ic`. +/// @{ + +/// \complexity O(n F) PRG expansions. n is `depth`. Each level expands every frontier node (two `expand` calls, one per share) and, while the secret path is live, one `prepare_level`. F is at most the number of distinct query leaves; the function rejects more than 2^20. Setup sorts the q query ids. +/// \rounds No sockets. While the path is live, each level calls `prepare_level`, which samples one `ds_cw_pads` and two `ds_and_pads` and then `open_cw`. +/// \communication none in this function. +/// \preprocessing The `ds_randomness` tape: per live level, `ds_sample_cw` draws two 128-bit blocks and two bits, and each of the two AND pads is one `ds_sample_and`. +template +HEDLEY_WARN_UNUSED_RESULT +auto geneval_point(InputT x0, InputT x1, InputT query, + ds_randomness rng, OutputT y, Buf0 & buf0, Buf1 & buf1) +{ + auto r = geneval_point(std::move(x0), + std::move(x1), query, std::move(rng), std::move(y)); + detail::geneval_fill_buffers(r, buf0, buf1); + return r; +} + +/// \complexity O(n F) PRG expansions. n is `depth`. Each level expands every frontier node (two `expand` calls, one per share) and, while the secret path is live, one `prepare_level`. F is at most the number of distinct query leaves; the function rejects more than 2^20. Setup sorts the q query ids. +/// \rounds No sockets. While the path is live, each level calls `prepare_level`, which samples one `ds_cw_pads` and two `ds_and_pads` and then `open_cw`. +/// \communication none in this function. +/// \preprocessing The `ds_randomness` tape: per live level, `ds_sample_cw` draws two 128-bit blocks and two bits, and each of the two AND pads is one `ds_sample_and`. +template +HEDLEY_WARN_UNUSED_RESULT +auto geneval_interval(InputT x0, InputT x1, InputT from, InputT to, + ds_randomness rng, OutputT y, Buf0 & buf0, Buf1 & buf1) +{ + auto r = geneval_interval(std::move(x0), + std::move(x1), from, to, std::move(rng), std::move(y)); + detail::geneval_fill_buffers(r, buf0, buf1); + return r; +} + +/// \complexity O(n F) PRG expansions. n is `depth`. Each level expands every frontier node (two `expand` calls, one per share) and, while the secret path is live, one `prepare_level`. F is at most the number of distinct query leaves; the function rejects more than 2^20. Setup sorts the q query ids. +/// \rounds No sockets. While the path is live, each level calls `prepare_level`, which samples one `ds_cw_pads` and two `ds_and_pads` and then `open_cw`. +/// \communication none in this function. +/// \preprocessing The `ds_randomness` tape: per live level, `ds_sample_cw` draws two 128-bit blocks and two bits, and each of the two AND pads is one `ds_sample_and`. +template +HEDLEY_WARN_UNUSED_RESULT +auto geneval_full(InputT x0, InputT x1, + ds_randomness rng, OutputT y, Buf0 & buf0, Buf1 & buf1) +{ + auto r = geneval_full(std::move(x0), + std::move(x1), std::move(rng), std::move(y)); + detail::geneval_fill_buffers(r, buf0, buf1); + return r; +} + +/// \complexity O(n F) PRG expansions. n is `depth`. Each level expands every frontier node (two `expand` calls, one per share) and, while the secret path is live, one `prepare_level`. F is at most the number of distinct query leaves; the function rejects more than 2^20. Setup sorts the q query ids. +/// \rounds No sockets. While the path is live, each level calls `prepare_level`, which samples one `ds_cw_pads` and two `ds_and_pads` and then `open_cw`. +/// \communication none in this function. +/// \preprocessing The `ds_randomness` tape: per live level, `ds_sample_cw` draws two 128-bit blocks and two bits, and each of the two AND pads is one `ds_sample_and`. +template +HEDLEY_WARN_UNUSED_RESULT +auto geneval_sequence(InputT x0, InputT x1, ForwardIterator begin, + ForwardIterator end, ds_randomness rng, OutputT y, + Buf0 & buf0, Buf1 & buf1) +{ + auto r = geneval_sequence(std::move(x0), + std::move(x1), begin, end, std::move(rng), std::move(y)); + detail::geneval_fill_buffers(r, buf0, buf1); + return r; +} + +/// @} + } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_GENEVAL_HPP__ diff --git a/include/dpf/gf2.hpp b/include/dpf/gf2.hpp new file mode 100644 index 0000000..9099320 --- /dev/null +++ b/include/dpf/gf2.hpp @@ -0,0 +1,924 @@ +/// @file dpf/gf2.hpp +/// @brief Characteristic-2 field elements as DPF output types. +/// @details `dpf::gf2`, `gf22`, `gf24`, `gf28`, `gf216`, `gf232`, and `gf264` +/// are GF(2^k) for k = 1, 2, 4, 8, 16, 32, 64. Addition and +/// subtraction are XOR. Multiplication is the polynomial product +/// in the standard basis (low bit is the coefficient of 1). +/// +/// The moduli match laneint on mocha2. Widths 1, 2, 4, and 16 are +/// the sparse irreducibles in `laneint/gf2_poly_basis.hpp` and the +/// epi multipliers. GF(2^8) is the AES polynomial that +/// `gf256_mul_u8` uses (`0x11B`), not the sparse `0x11D` alternative. +/// GF(2^32) and GF(2^64) use the irreducible basis polynomials. +/// The epi “default” reducers `x^32+x^7+1` and `x^64+x^4+1` factor, +/// so they are not the field. Leaf scaling of `gf28` and `gf216` +/// is the FAST'13 nibble `pshufb` (Plank, Greenan, Miller): one +/// constant builds 16-byte tables, and every lane is a shuffle. +/// `detail::shamir_field` inverts a +/// nonzero element by Fermat, `a^{2^k - 2}`. Shamir points are the +/// integers `1 .. N` as bit patterns, so `N` must be less than `2^k` +/// or two parties land on the same element. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_GF2_HPP__ +#define LIBDPF_INCLUDE_DPF_GF2_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" +#include "simde/simde/x86/avx2.h" + +#include "dpf/leaf_arithmetic.hpp" +#include "dpf/utils.hpp" + +namespace dpf +{ +namespace gf2_detail +{ + +template +struct field; + +template <> +struct field<1> +{ + using word = std::uint8_t; + using wide = std::uint16_t; + static constexpr unsigned bits = 1; + /// `x + 1` + static constexpr wide modulus = 0x3u; +}; + +template <> +struct field<2> +{ + using word = std::uint8_t; + using wide = std::uint16_t; + static constexpr unsigned bits = 2; + /// `x^2 + x + 1` + static constexpr wide modulus = 0x7u; +}; + +template <> +struct field<4> +{ + using word = std::uint8_t; + using wide = std::uint16_t; + static constexpr unsigned bits = 4; + /// `x^4 + x + 1` + static constexpr wide modulus = 0x13u; +}; + +template <> +struct field<8> +{ + using word = std::uint8_t; + using wide = std::uint16_t; + static constexpr unsigned bits = 8; + /// AES: `x^8 + x^4 + x^3 + x + 1` + static constexpr wide modulus = 0x11bu; +}; + +template <> +struct field<16> +{ + using word = std::uint16_t; + using wide = std::uint32_t; + static constexpr unsigned bits = 16; + /// `x^16 + x^5 + x^3 + x^2 + 1` + static constexpr wide modulus = 0x1002du; +}; + +template <> +struct field<32> +{ + using word = std::uint32_t; + using wide = std::uint64_t; + static constexpr unsigned bits = 32; + /// `x^32 + x^31 + x^28 + x^21 + 1` + static constexpr wide modulus = 0x190200001ull; +}; + +template <> +struct field<64> +{ + using word = std::uint64_t; + using wide = unsigned __int128; + static constexpr unsigned bits = 64; + /// `x^64 + x^63 + x^62 + x^53 + 1` + static constexpr wide modulus = + (wide{1} << 64) | (wide{1} << 63) | (wide{1} << 62) | (wide{1} << 53) | wide{1}; +}; + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +constexpr typename field::word mask() noexcept +{ + using word = typename field::word; + if constexpr (Bits >= sizeof(word) * 8u) + return static_cast(~word{0}); + else + return static_cast((word{1} << Bits) - word{1}); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +constexpr typename field::word reduce(typename field::wide p) noexcept +{ + using wide = typename field::wide; + constexpr wide mod = field::modulus; + for (int bit = static_cast(2u * Bits) - 2; bit >= static_cast(Bits); --bit) + { + if (((p >> bit) & wide{1}) != 0) + p ^= mod << (bit - static_cast(Bits)); + } + return static_cast::word>(p); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +constexpr typename field::word mul(typename field::word a, + typename field::word b) noexcept +{ + using wide = typename field::wide; + a = static_cast::word>(a & mask()); + b = static_cast::word>(b & mask()); + wide p = 0; + for (unsigned i = 0; i < Bits; ++i) + { + if (((b >> i) & 1u) != 0u) + p ^= static_cast(a) << i; + } + return reduce(p); +} + +/// @brief Multiplicative inverse, `a^{2^Bits - 2}`. +/// @param a a nonzero field element +/// @return `a^{-1}` +/// @throws std::invalid_argument if `a` is zero +template +typename field::word inv(typename field::word a) +{ + using word = typename field::word; + a = static_cast(a & mask()); + if (a == 0) + throw std::invalid_argument("shamir: inverse of zero"); + // Exponent 2^Bits - 2 is Bits-1 ones followed by a zero. + word result{1}; + for (int bit = static_cast(Bits) - 1; bit >= 0; --bit) + { + result = mul(result, result); + if (bit != 0) + result = mul(result, a); + } + return result; +} + +/// @brief Multiply by `x` in AES GF(2^8), modulus `0x11B`. +HEDLEY_ALWAYS_INLINE +constexpr std::uint8_t gf28_mul_x(std::uint8_t a) noexcept +{ + const std::uint8_t hi = static_cast(a & 0x80u); + a = static_cast(static_cast(a << 1) ^ (hi != 0 ? 0x1bu : 0)); + return a; +} + +/// @brief Multiply by `x` in GF(2^16), modulus `x^16+x^5+x^3+x^2+1`. +HEDLEY_ALWAYS_INLINE +constexpr std::uint16_t gf216_mul_x(std::uint16_t a) noexcept +{ + const std::uint16_t hi = static_cast(a & 0x8000u); + a = static_cast(static_cast(a << 1) ^ (hi != 0 ? 0x2du : 0)); + return a; +} + +/// @brief 16 products of `base` with a nibble, built from four multiplies by `x`. +HEDLEY_ALWAYS_INLINE +void nibble_products_u8(std::uint8_t base, std::uint8_t out[16]) noexcept +{ + const std::uint8_t b0 = base; + const std::uint8_t b1 = gf28_mul_x(b0); + const std::uint8_t b2 = gf28_mul_x(b1); + const std::uint8_t b3 = gf28_mul_x(b2); + out[0] = 0; + for (unsigned n = 1; n < 16u; ++n) + { + std::uint8_t r = 0; + if ((n & 1u) != 0) r = static_cast(r ^ b0); + if ((n & 2u) != 0) r = static_cast(r ^ b1); + if ((n & 4u) != 0) r = static_cast(r ^ b2); + if ((n & 8u) != 0) r = static_cast(r ^ b3); + out[n] = r; + } +} + +HEDLEY_ALWAYS_INLINE +void nibble_products_u16(std::uint16_t base, std::uint8_t lo[16], std::uint8_t hi[16]) noexcept +{ + const std::uint16_t b0 = base; + const std::uint16_t b1 = gf216_mul_x(b0); + const std::uint16_t b2 = gf216_mul_x(b1); + const std::uint16_t b3 = gf216_mul_x(b2); + lo[0] = 0; + hi[0] = 0; + for (unsigned n = 1; n < 16u; ++n) + { + std::uint16_t r = 0; + if ((n & 1u) != 0) r = static_cast(r ^ b0); + if ((n & 2u) != 0) r = static_cast(r ^ b1); + if ((n & 4u) != 0) r = static_cast(r ^ b2); + if ((n & 8u) != 0) r = static_cast(r ^ b3); + lo[n] = static_cast(r); + hi[n] = static_cast(r >> 8); + } +} + +/// @brief FAST'13 nibble tables for one GF(2^8) constant. +/// @details Plank, Greenan, Miller, "Screaming Fast Galois Field Arithmetic +/// Using Intel SIMD Instructions". `y * a = (y * a_lo) XOR (y * (a_hi << 4))`, +/// each half a 16-entry `pshufb`. +struct gf28_shufb +{ + simde__m128i lo; + simde__m128i hi; +}; + +inline const gf28_shufb & gf28_shufb_for(std::uint8_t y) noexcept +{ + struct tables + { + gf28_shufb t[256]; + tables() noexcept + { + for (unsigned yy = 0; yy < 256u; ++yy) + { + alignas(16) std::uint8_t lo[16]; + alignas(16) std::uint8_t hi[16]; + nibble_products_u8(static_cast(yy), lo); + const std::uint8_t x4 = gf28_mul_x(gf28_mul_x(gf28_mul_x(gf28_mul_x( + static_cast(yy))))); + nibble_products_u8(x4, hi); + t[yy].lo = simde_mm_load_si128(reinterpret_cast(lo)); + t[yy].hi = simde_mm_load_si128(reinterpret_cast(hi)); + } + } + }; + static const tables all; + return all.t[y]; +} + +HEDLEY_ALWAYS_INLINE +simde__m128i gf28_scale_m128(simde__m128i lut_lo, simde__m128i lut_hi, simde__m128i a) noexcept +{ + const simde__m128i m0f = simde_mm_set1_epi8(0x0f); + const simde__m128i lo = simde_mm_and_si128(a, m0f); + const simde__m128i hi = simde_mm_and_si128(simde_mm_srli_epi16(a, 4), m0f); + return simde_mm_xor_si128(simde_mm_shuffle_epi8(lut_lo, lo), + simde_mm_shuffle_epi8(lut_hi, hi)); +} + +/// @brief Four nibble positions of one GF(2^16) constant. Each position is a +/// low-byte table and a high-byte table. +struct gf216_shufb +{ + simde__m128i lo[4]; + simde__m128i hi[4]; +}; + +HEDLEY_ALWAYS_INLINE +gf216_shufb gf216_shufb_prepare(std::uint16_t k) noexcept +{ + gf216_shufb L{}; + std::uint16_t base = k; + for (unsigned nib = 0; nib < 4u; ++nib) + { + alignas(16) std::uint8_t lo[16]; + alignas(16) std::uint8_t hi[16]; + nibble_products_u16(base, lo, hi); + L.lo[nib] = simde_mm_load_si128(reinterpret_cast(lo)); + L.hi[nib] = simde_mm_load_si128(reinterpret_cast(hi)); + base = gf216_mul_x(gf216_mul_x(gf216_mul_x(gf216_mul_x(base)))); + } + return L; +} + +HEDLEY_ALWAYS_INLINE +simde__m128i gf216_scale_m128(const gf216_shufb & L, simde__m128i x) noexcept +{ + const simde__m128i m4 = simde_mm_set1_epi16(0x000f); + const simde__m128i pick_ev = simde_mm_setr_epi8( + 0, static_cast(0x80), 2, static_cast(0x80), + 4, static_cast(0x80), 6, static_cast(0x80), + 8, static_cast(0x80), 10, static_cast(0x80), + 12, static_cast(0x80), 14, static_cast(0x80)); + const simde__m128i ix0 = simde_mm_shuffle_epi8(simde_mm_and_si128(x, m4), pick_ev); + const simde__m128i ix1 = simde_mm_shuffle_epi8( + simde_mm_and_si128(simde_mm_srli_epi16(x, 4), m4), pick_ev); + const simde__m128i ix2 = simde_mm_shuffle_epi8( + simde_mm_and_si128(simde_mm_srli_epi16(x, 8), m4), pick_ev); + const simde__m128i ix3 = simde_mm_shuffle_epi8( + simde_mm_and_si128(simde_mm_srli_epi16(x, 12), m4), pick_ev); + auto part = [](simde__m128i tl, simde__m128i th, simde__m128i ix) noexcept { + const simde__m128i pl = simde_mm_shuffle_epi8(tl, ix); + const simde__m128i ph = simde_mm_shuffle_epi8(th, ix); + return simde_mm_or_si128(pl, simde_mm_slli_epi16(ph, 8)); + }; + return simde_mm_xor_si128( + simde_mm_xor_si128(part(L.lo[0], L.hi[0], ix0), part(L.lo[1], L.hi[1], ix1)), + simde_mm_xor_si128(part(L.lo[2], L.hi[2], ix2), part(L.lo[3], L.hi[3], ix3))); +} + +HEDLEY_ALWAYS_INLINE +void scale_gf28(unsigned char * dst, const unsigned char * src, std::size_t n, + std::uint8_t k) noexcept +{ + if (k == 0) + { + std::memset(dst, 0, n); + return; + } + if (k == 1) + { + if (dst != src) + std::memcpy(dst, src, n); + return; + } + const gf28_shufb & lut = gf28_shufb_for(k); + const simde__m256i lo256 = simde_mm256_broadcastsi128_si256(lut.lo); + const simde__m256i hi256 = simde_mm256_broadcastsi128_si256(lut.hi); + const simde__m256i m0f = simde_mm256_set1_epi8(0x0f); + std::size_t i = 0; + for (; i + 32 <= n; i += 32) + { + const simde__m256i a = simde_mm256_loadu_si256(src + i); + const simde__m256i lo = simde_mm256_and_si256(a, m0f); + const simde__m256i hi = simde_mm256_and_si256(simde_mm256_srli_epi16(a, 4), m0f); + const simde__m256i r = simde_mm256_xor_si256( + simde_mm256_shuffle_epi8(lo256, lo), + simde_mm256_shuffle_epi8(hi256, hi)); + simde_mm256_storeu_si256(dst + i, r); + } + for (; i + 16 <= n; i += 16) + { + const simde__m128i a = simde_mm_loadu_si128(src + i); + simde_mm_storeu_si128(dst + i, gf28_scale_m128(lut.lo, lut.hi, a)); + } + for (; i < n; ++i) + dst[i] = mul<8>(src[i], k); +} + +HEDLEY_ALWAYS_INLINE +void scale_gf216(unsigned char * dst, const unsigned char * src, std::size_t n, + std::uint16_t k) noexcept +{ + if (k == 0) + { + std::memset(dst, 0, n); + return; + } + if (k == 1) + { + if (dst != src) + std::memcpy(dst, src, n); + return; + } + const gf216_shufb L = gf216_shufb_prepare(k); + std::size_t i = 0; + for (; i + 16 <= n; i += 16) + { + const simde__m128i a = simde_mm_loadu_si128(src + i); + simde_mm_storeu_si128(dst + i, gf216_scale_m128(L, a)); + } + for (; i + sizeof(std::uint16_t) <= n; i += sizeof(std::uint16_t)) + { + std::uint16_t a{}; + std::memcpy(&a, src + i, sizeof(a)); + const std::uint16_t c = mul<16>(a, k); + std::memcpy(dst + i, &c, sizeof(c)); + } + for (; i < n; ++i) + dst[i] = 0; +} + +HEDLEY_ALWAYS_INLINE +void xor_bytes(unsigned char * dst, const unsigned char * a, + const unsigned char * b, std::size_t n) noexcept +{ + for (std::size_t i = 0; i < n; ++i) + dst[i] = static_cast(a[i] ^ b[i]); +} + +template +HEDLEY_ALWAYS_INLINE +void scale_bytes(unsigned char * dst, const unsigned char * src, std::size_t n, + typename field::word k) noexcept +{ + using word = typename field::word; + k = static_cast(k & mask()); + if constexpr (Bits == 1) + { + const unsigned char fill = (k & 1u) ? static_cast(0xffu) : 0; + for (std::size_t i = 0; i < n; ++i) + dst[i] = static_cast(src[i] & fill); + } + else if constexpr (Bits < 8) + { + constexpr unsigned per_byte = 8u / Bits; + constexpr unsigned lane_mask = (1u << Bits) - 1u; + for (std::size_t i = 0; i < n; ++i) + { + unsigned out = 0; + const unsigned in = src[i]; + for (unsigned lane = 0; lane < per_byte; ++lane) + { + const auto a = static_cast((in >> (lane * Bits)) & lane_mask); + out |= static_cast(mul(a, k)) << (lane * Bits); + } + dst[i] = static_cast(out); + } + } + else if constexpr (Bits == 8) + { + scale_gf28(dst, src, n, static_cast(k)); + } + else if constexpr (Bits == 16) + { + scale_gf216(dst, src, n, static_cast(k)); + } + else + { + std::size_t i = 0; + for (; i + sizeof(word) <= n; i += sizeof(word)) + { + word a{}; + std::memcpy(&a, src + i, sizeof(word)); + const word c = mul(a, k); + std::memcpy(dst + i, &c, sizeof(word)); + } + for (; i < n; ++i) + dst[i] = 0; + } +} + +template +HEDLEY_ALWAYS_INLINE +NodeT xor_node(const NodeT & a, const NodeT & b) noexcept +{ + unsigned char aa[sizeof(NodeT)]; + unsigned char bb[sizeof(NodeT)]; + unsigned char cc[sizeof(NodeT)]; + std::memcpy(aa, std::addressof(a), sizeof(NodeT)); + std::memcpy(bb, std::addressof(b), sizeof(NodeT)); + xor_bytes(cc, aa, bb, sizeof(NodeT)); + NodeT out; + std::memcpy(std::addressof(out), cc, sizeof(NodeT)); + return out; +} + +template +HEDLEY_ALWAYS_INLINE +NodeT scale_node(const NodeT & a, typename field::word k) noexcept +{ + unsigned char src[sizeof(NodeT)]; + unsigned char dst[sizeof(NodeT)]; + std::memcpy(src, std::addressof(a), sizeof(NodeT)); + scale_bytes(dst, src, sizeof(NodeT), k); + NodeT out; + std::memcpy(std::addressof(out), dst, sizeof(NodeT)); + return out; +} + +} // namespace gf2_detail + +/// @brief Element of GF(2^Bits) in the standard polynomial basis. +/// @tparam Bits field degree. One of 1, 2, 4, 8, 16, 32, 64. +template +class gf2n +{ + public: + using integral_type = typename gf2_detail::field::word; + static constexpr unsigned bits = Bits; + static constexpr bool dpf_gf2n = true; + static constexpr bool dpf_point_group = true; + + /// @brief The zero element. + HEDLEY_ALWAYS_INLINE + constexpr gf2n() noexcept = default; + + /// @brief Bit embedding of an integer. A negative value is the field + /// negation of its magnitude, which is the same element: every + /// element is its own additive inverse. + /// @tparam T integral type + /// @param v the integer to embed + template >> + HEDLEY_ALWAYS_INLINE + constexpr gf2n(T v) noexcept + { + if constexpr (std::is_signed_v) + { + if (v < 0) + { + using unsigned_type = std::make_unsigned_t; + const auto mag = static_cast(0) + - static_cast(v); + val = static_cast(mag) & gf2_detail::mask(); + } + else + { + val = static_cast(v) & gf2_detail::mask(); + } + } + else + { + val = static_cast(v) & gf2_detail::mask(); + } + } + + /// @brief Low `Bits` of a PRG block. Every bit string is a field element. + /// @param bytes the PRG output + /// @param n the number of bytes available + /// @return the field element + HEDLEY_ALWAYS_INLINE + static gf2n from_seed(const void * bytes, std::size_t n) noexcept + { + integral_type w{}; + if (bytes != nullptr && n != 0) + { + const std::size_t take = n < sizeof(w) ? n : sizeof(w); + std::memcpy(&w, bytes, take); + } + return gf2n{w}; + } + + /// @brief Reduced representative in `0 .. 2^Bits - 1`. + /// @return the stored field element + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + constexpr integral_type raw() const noexcept + { + return static_cast(val & gf2_detail::mask()); + } + + /// @brief Same value as `raw()`. + /// @return the stored field element + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + explicit constexpr operator integral_type() const noexcept { return raw(); } + + private: + integral_type val{}; +}; + +/// @brief GF(2). +using gf2 = gf2n<1>; +/// @brief GF(4) = GF(2^2), modulus `x^2 + x + 1`. +using gf22 = gf2n<2>; +/// @brief GF(16) = GF(2^4), modulus `x^4 + x + 1`. +using gf24 = gf2n<4>; +/// @brief GF(256) = GF(2^8), AES modulus `x^8 + x^4 + x^3 + x + 1`. +using gf28 = gf2n<8>; +/// @brief GF(2^16), modulus `x^16 + x^5 + x^3 + x^2 + 1`. +using gf216 = gf2n<16>; +/// @brief GF(2^32), modulus `x^32 + x^31 + x^28 + x^21 + 1`. +using gf232 = gf2n<32>; +/// @brief GF(2^64), modulus `x^64 + x^63 + x^62 + x^53 + 1`. +using gf264 = gf2n<64>; + +/// @brief Field addition. XOR of the reduced representatives. +template +HEDLEY_ALWAYS_INLINE +constexpr gf2n operator+(gf2n a, gf2n b) noexcept +{ + using word = typename gf2n::integral_type; + return gf2n{static_cast(a.raw() ^ b.raw())}; +} + +/// @brief Field subtraction. Identical to addition. +template +HEDLEY_ALWAYS_INLINE +constexpr gf2n operator-(gf2n a, gf2n b) noexcept +{ + return a + b; +} + +/// @brief Additive inverse. Identical to `a` in characteristic 2. +template +HEDLEY_ALWAYS_INLINE +constexpr gf2n operator-(gf2n a) noexcept +{ + return a; +} + +/// @brief Field XOR. Identical to addition. +template +HEDLEY_ALWAYS_INLINE +constexpr gf2n operator^(gf2n a, gf2n b) noexcept +{ + return a + b; +} + +/// @brief Field multiplication. +template +HEDLEY_ALWAYS_INLINE +constexpr gf2n operator*(gf2n a, gf2n b) noexcept +{ + return gf2n{gf2_detail::mul(a.raw(), b.raw())}; +} + +/// @brief Equality of the reduced representatives. +template +HEDLEY_ALWAYS_INLINE +constexpr bool operator==(gf2n a, gf2n b) noexcept +{ + return a.raw() == b.raw(); +} + +/// @brief Inequality of the reduced representatives. +template +HEDLEY_ALWAYS_INLINE +constexpr bool operator!=(gf2n a, gf2n b) noexcept +{ + return a.raw() != b.raw(); +} + +/// @brief Write the reduced representative in decimal. +template +std::ostream & operator<<(std::ostream & os, gf2n a) +{ + return os << static_cast(a.raw()); +} + +/// @brief Non-template operators so a packed-lane proxy converts to the field +/// and finds `+` / `-` the same way `nyble` and `twobit` do. +#define DPF_GF_LANE_OPS(Type) \ +HEDLEY_ALWAYS_INLINE constexpr Type operator+(Type a, Type b) noexcept \ +{ \ + using word = typename Type::integral_type; \ + return Type{static_cast(a.raw() ^ b.raw())}; \ +} \ +HEDLEY_ALWAYS_INLINE constexpr Type operator-(Type a, Type b) noexcept \ +{ \ + return a + b; \ +} \ +HEDLEY_ALWAYS_INLINE constexpr Type operator-(Type a) noexcept { return a; } \ +HEDLEY_ALWAYS_INLINE constexpr Type operator^(Type a, Type b) noexcept \ +{ \ + return a + b; \ +} \ +HEDLEY_ALWAYS_INLINE constexpr Type operator*(Type a, Type b) noexcept \ +{ \ + return Type{gf2_detail::mul(a.raw(), b.raw())}; \ +} \ +HEDLEY_ALWAYS_INLINE constexpr bool operator==(Type a, Type b) noexcept \ +{ \ + return a.raw() == b.raw(); \ +} \ +HEDLEY_ALWAYS_INLINE constexpr bool operator!=(Type a, Type b) noexcept \ +{ \ + return !(a == b); \ +} \ +inline std::ostream & operator<<(std::ostream & os, Type a) \ +{ \ + return os << static_cast(a.raw()); \ +} + +DPF_GF_LANE_OPS(gf2) +DPF_GF_LANE_OPS(gf22) +DPF_GF_LANE_OPS(gf24) +DPF_GF_LANE_OPS(gf28) +DPF_GF_LANE_OPS(gf216) +DPF_GF_LANE_OPS(gf232) +DPF_GF_LANE_OPS(gf264) +#undef DPF_GF_LANE_OPS + +namespace utils +{ + +template +struct bitlength_of> + : std::integral_constant +{ }; + +template +struct bitlength_of_output, NodeT> + : std::integral_constant +{ }; + +template +struct is_packed_subbyte> : std::bool_constant<(Bits < 8)> {}; + +template +struct packed_lane_bits> + : std::integral_constant {}; + +template +struct has_characteristic_two> : std::true_type {}; + +} // namespace utils + +namespace leaf_arithmetic +{ + +template +struct add_t, NodeT, std::enable_if_t>> +{ + HEDLEY_ALWAYS_INLINE + auto operator()(const NodeT & a, const NodeT & b) const noexcept + { + return gf2_detail::xor_node(a, b); + } +}; + +template +struct subtract_t, NodeT, std::enable_if_t>> +{ + HEDLEY_ALWAYS_INLINE + auto operator()(const NodeT & a, const NodeT & b) const noexcept + { + return gf2_detail::xor_node(a, b); + } +}; + +template +struct multiply_t, NodeT, std::enable_if_t>> +{ + HEDLEY_ALWAYS_INLINE + auto operator()(const NodeT & a, gf2n b) const noexcept + { + return gf2_detail::scale_node(a, b.raw()); + } +}; + +} // namespace leaf_arithmetic + +} // namespace dpf + +#include "dpf/output_buffer.hpp" + +namespace dpf +{ + +template <> +class output_buffer : public dynamic_packed_array +{ + using base = dynamic_packed_array; + public: + using size_type = typename base::size_type; + explicit output_buffer(size_type size) : base(size) { } + output_buffer(output_buffer &&) noexcept = default; + output_buffer(const output_buffer &) = delete; + output_buffer & operator=(output_buffer &&) noexcept = default; + output_buffer & operator=(const output_buffer &) = delete; + ~output_buffer() noexcept = default; +}; + +template <> +class output_buffer : public dynamic_packed_array +{ + using base = dynamic_packed_array; + public: + using size_type = typename base::size_type; + explicit output_buffer(size_type size) : base(size) { } + output_buffer(output_buffer &&) noexcept = default; + output_buffer(const output_buffer &) = delete; + output_buffer & operator=(output_buffer &&) noexcept = default; + output_buffer & operator=(const output_buffer &) = delete; + ~output_buffer() noexcept = default; +}; + +template <> +class output_buffer : public dynamic_packed_array +{ + using base = dynamic_packed_array; + public: + using size_type = typename base::size_type; + explicit output_buffer(size_type size) : base(size) { } + output_buffer(output_buffer &&) noexcept = default; + output_buffer(const output_buffer &) = delete; + output_buffer & operator=(output_buffer &&) noexcept = default; + output_buffer & operator=(const output_buffer &) = delete; + ~output_buffer() noexcept = default; +}; + +template <> +class output_buffer> : public packed_share_output +{ + using base = packed_share_output; + public: + using size_type = typename base::size_type; + explicit output_buffer(size_type size) : base(size) { } + output_buffer(output_buffer &&) noexcept = default; + output_buffer(const output_buffer &) = delete; + output_buffer & operator=(output_buffer &&) noexcept = default; + output_buffer & operator=(const output_buffer &) = delete; + ~output_buffer() noexcept = default; +}; + +template <> +class output_buffer> : public packed_share_output +{ + using base = packed_share_output; + public: + using size_type = typename base::size_type; + explicit output_buffer(size_type size) : base(size) { } + output_buffer(output_buffer &&) noexcept = default; + output_buffer(const output_buffer &) = delete; + output_buffer & operator=(output_buffer &&) noexcept = default; + output_buffer & operator=(const output_buffer &) = delete; + ~output_buffer() noexcept = default; +}; + +template <> +class output_buffer> : public packed_share_output +{ + using base = packed_share_output; + public: + using size_type = typename base::size_type; + explicit output_buffer(size_type size) : base(size) { } + output_buffer(output_buffer &&) noexcept = default; + output_buffer(const output_buffer &) = delete; + output_buffer & operator=(output_buffer &&) noexcept = default; + output_buffer & operator=(const output_buffer &) = delete; + ~output_buffer() noexcept = default; +}; + +template <> +class output_buffer> : public packed_share_output +{ + using base = packed_share_output; + public: + using size_type = typename base::size_type; + explicit output_buffer(size_type size) : base(size) { } + output_buffer(output_buffer &&) noexcept = default; + output_buffer(const output_buffer &) = delete; + output_buffer & operator=(output_buffer &&) noexcept = default; + output_buffer & operator=(const output_buffer &) = delete; + ~output_buffer() noexcept = default; +}; + +template <> +class output_buffer> : public packed_share_output +{ + using base = packed_share_output; + public: + using size_type = typename base::size_type; + explicit output_buffer(size_type size) : base(size) { } + output_buffer(output_buffer &&) noexcept = default; + output_buffer(const output_buffer &) = delete; + output_buffer & operator=(output_buffer &&) noexcept = default; + output_buffer & operator=(const output_buffer &) = delete; + ~output_buffer() noexcept = default; +}; + +template <> +class output_buffer> : public packed_share_output +{ + using base = packed_share_output; + public: + using size_type = typename base::size_type; + explicit output_buffer(size_type size) : base(size) { } + output_buffer(output_buffer &&) noexcept = default; + output_buffer(const output_buffer &) = delete; + output_buffer & operator=(output_buffer &&) noexcept = default; + output_buffer & operator=(const output_buffer &) = delete; + ~output_buffer() noexcept = default; +}; + +} // namespace dpf + +#include "dpf/shamir.hpp" + +namespace dpf +{ +namespace detail +{ + +/// @brief Shamir inverse for `gf2n`. Points `1 .. N` must stay distinct, so +/// `N < 2^Bits`. +template +struct shamir_field> : std::true_type +{ + /// @brief `a^{-1}` by Fermat, `a^{2^Bits - 2}`. + /// @param a a nonzero field element + /// @return `a^{-1}` + /// @throws std::invalid_argument if `a` is zero + static gf2n inv(gf2n a) + { + return gf2n{gf2_detail::inv(a.raw())}; + } +}; + +} // namespace detail +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_GF2_HPP__ diff --git a/include/dpf/gilboa.hpp b/include/dpf/gilboa.hpp new file mode 100644 index 0000000..7a2d510 --- /dev/null +++ b/include/dpf/gilboa.hpp @@ -0,0 +1,277 @@ +/// @file dpf/gilboa.hpp +/// @brief One-off Gilboa multiplication from correlated bit×ring triples. +#ifndef LIBDPF_INCLUDE_DPF_GILBOA_HPP__ +#define LIBDPF_INCLUDE_DPF_GILBOA_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/beaver.hpp" +#include "dpf/edabit.hpp" +#include "dpf/ot_pack.hpp" +#include "dpf/random.hpp" + +namespace dpf +{ +namespace gilboa +{ + +/// @brief Clear product of additive shares (oracle only). +template +HEDLEY_WARN_UNUSED_RESULT +Ring mul_clear(Ring x0, Ring x1, Ring y0, Ring y1) +{ + return static_cast((x0 + x1) * (y0 + y1)); +} + +template +struct product_shares +{ + Ring z0{}; + Ring z1{}; +}; + +/// @brief Oracle: reconstruct, multiply, re-share. Not a party protocol. +template +HEDLEY_WARN_UNUSED_RESULT +product_shares mul_dealer(Ring x0, Ring x1, Ring y0, Ring y1) +{ + const Ring z = mul_clear(x0, x1, y0, y1); + const Ring m = dpf::uniform_sample(); + return product_shares{m, static_cast(z - m)}; +} + +/// @brief Per-bit messages one party produces before the peer exchange. +/// @details Factor `x` must be held as bits (party 1 share 0, or XOR bit +/// shares). Additive `x` shares are bit-sliced locally — correct when +/// one party holds the clear factor. +template +struct gilboa_round +{ + std::vector d_share; ///< additive share of x_bit - a + std::vector e_share; ///< additive share of y - b + std::vector> triples; + Ring x_share{}; + Ring y_share{}; + unsigned party = 0; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +gilboa_round mul_from_ot_begin(ot::pack & pack, Ring x_share, Ring y_share, + unsigned party, unsigned bits = 64) +{ + if (bits == 0 || bits > 8u * sizeof(Ring)) + throw std::invalid_argument("gilboa bits"); + if (pack.remaining_bit_ring() < bits) + throw std::runtime_error("gilboa::mul_from_ot: need bit×ring triples"); + gilboa_round r; + r.x_share = x_share; + r.y_share = y_share; + r.party = party; + r.d_share.resize(bits); + r.e_share.resize(bits); + r.triples.reserve(bits); + for (unsigned i = 0; i < bits; ++i) + { + auto t = pack.take_bit_ring(); + const Ring x_bit = static_cast( + (static_cast(x_share) >> i) & 1u); + r.d_share[i] = static_cast(x_bit - Ring{t.a}); + r.e_share[i] = static_cast(y_share - t.b); + r.triples.push_back(t); + } + return r; +} + +/// @brief Finish after exchanging additive `d` and `e` with the peer. +template +HEDLEY_WARN_UNUSED_RESULT +Ring mul_from_ot_finish(const gilboa_round & r, + const std::vector & peer_d, const std::vector & peer_e) +{ + if (peer_d.size() != r.d_share.size() || peer_e.size() != r.e_share.size()) + throw std::invalid_argument("gilboa finish size"); + Ring acc{}; + for (std::size_t i = 0; i < r.d_share.size(); ++i) + { + const auto & t = r.triples[i]; + const Ring d = static_cast(r.d_share[i] + peer_d[i]); + const Ring e = static_cast(r.e_share[i] + peer_e[i]); + Ring z = t.c; + z = static_cast(z + d * t.b); + z = static_cast(z + e * Ring{t.a}); + if (r.party == 0) + z = static_cast(z + d * e); + acc = static_cast(acc + (z << i)); + } + return acc; +} + +/// @brief One bit×ring product of an additive 0/1 value with `y`. +template +HEDLEY_WARN_UNUSED_RESULT +product_shares mul_bit_from_ot(ot::pack & pack0, ot::pack & pack1, + Ring bit0, Ring bit1, Ring y0, Ring y1) +{ + auto t0 = pack0.template take_bit_ring(); + auto t1 = pack1.template take_bit_ring(); + const Ring d0 = static_cast(bit0 - Ring{t0.a}); + const Ring d1 = static_cast(bit1 - Ring{t1.a}); + const Ring e0 = static_cast(y0 - t0.b); + const Ring e1 = static_cast(y1 - t1.b); + const Ring d = static_cast(d0 + d1); + const Ring e = static_cast(e0 + e1); + auto acc = [&](const ot::bit_ring_triple & t, unsigned party) { + Ring z = t.c; + z = static_cast(z + d * t.b); + z = static_cast(z + e * Ring{t.a}); + if (party == 0) + z = static_cast(z + d * e); + return z; + }; + return product_shares{acc(t0, 0), acc(t1, 1)}; +} + +/// @brief General additive `x`: A2B, daBit B2A per bit, then bit×ring Gilboa. +template +HEDLEY_WARN_UNUSED_RESULT +product_shares mul_from_ot_pair(ot::pack & pack0, ot::pack & pack1, + Ring x0, Ring x1, Ring y0, Ring y1, unsigned bits = 64) +{ + if (pack0.remaining_b2a() < bits || pack1.remaining_b2a() < bits + || pack0.remaining_bit_ring() < bits || pack1.remaining_bit_ring() < bits) + throw std::runtime_error("gilboa::mul_from_ot_pair: need dabits and bit×ring"); + auto eda = edabit::sample_edabit_pair(bits); + auto bits_xy = edabit::a2b_gmw_pair(eda, x0, x1); + const auto & bx0 = bits_xy.first; + const auto & bx1 = bits_xy.second; + Ring z0{}, z1{}; + for (unsigned i = 0; i < bits; ++i) + { + auto d0 = pack0.template take_dabit(); + auto d1 = pack1.template take_dabit(); + const std::uint8_t b0 = edabit::detail::get_bit(bx0, i); + const std::uint8_t b1 = edabit::detail::get_bit(bx1, i); + const std::uint8_t mask = static_cast( + (b0 ^ d0.bit) ^ (b1 ^ d1.bit)); + const Ring a0 = edabit::b2a_party_bit(b0, d0, mask, 0, 0); + const Ring a1 = edabit::b2a_party_bit(b1, d1, mask, 1, 0); + auto part = mul_bit_from_ot(pack0, pack1, a0, a1, y0, y1); + z0 = static_cast(z0 + (part.z0 << i)); + z1 = static_cast(z1 + (part.z1 << i)); + } + return product_shares{z0, z1}; +} + +/// @brief Convenience: one party after peer messages are known (same as finish). +template +HEDLEY_WARN_UNUSED_RESULT +Ring mul_from_ot(ot::pack & pack, Ring x_share, Ring y_share, unsigned party, + const std::vector & peer_d, const std::vector & peer_e, + unsigned bits = 64) +{ + auto r = mul_from_ot_begin(pack, x_share, y_share, party, bits); + return mul_from_ot_finish(r, peer_d, peer_e); +} + +/// @brief Honest-dealer tape: `session::sample` then `export_party`. +template +HEDLEY_WARN_UNUSED_RESULT +beavers::party_tape fill_tape_dealer(beavers::session & s, + unsigned party) +{ + s.sample(); + return s.export_party(party); +} + +/// @brief Sample λ from correlated bit×ring `b` shares; monomials are Π λ^e. +/// @details One λ per wire (repeated factors share it). Both packs are consumed +/// in lockstep. `sample` is driven by those triples, not overwritten after. +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, beavers::party_tape> +fill_tape_ot_pair(beavers::session & s, ot::pack & pack0, ot::pack & pack1) +{ + std::size_t calls = 0; + s.sample([&]() { + ++calls; + return Ring{1}; + }); + std::size_t nblind = 0; + { + const auto probe = s.export_party(0); + for (auto ready : probe.lambda_ready) + nblind += ready ? 1u : 0u; + } + s.clear_sample(); + struct sampler + { + ot::pack * p0; + ot::pack * p1; + std::size_t nblind; + std::size_t call = 0; + Ring saved{}; + Ring operator()() + { + if (p0->remaining_bit_ring() == 0 || p1->remaining_bit_ring() == 0) + throw std::runtime_error("fill_tape_ot: need bit×ring triples"); + if (call < nblind * 2) + { + if ((call & 1u) == 0) + { + auto t0 = p0->template take_bit_ring(); + auto t1 = p1->template take_bit_ring(); + saved = t0.b; + ++call; + return static_cast(t0.b + t1.b); + } + ++call; + return saved; + } + auto t0 = p0->template take_bit_ring(); + auto t1 = p1->template take_bit_ring(); + ++call; + (void)t1; + return t0.c; + } + }; + s.sample(sampler{&pack0, &pack1, nblind}); + (void)calls; + auto t0 = s.export_party(0); + auto t1 = s.export_party(1); + pack0.stash_party_tape(t0); + pack1.stash_party_tape(t1); + return {t0, t1}; +} + +/// @brief Read the party view `fill_tape_ot_pair` stashed in `pack`. +/// @details Does not sample. A pack that was not produced by the pair sampler +/// has no view to read. +template +HEDLEY_WARN_UNUSED_RESULT +beavers::party_tape fill_tape_ot(beavers::session & s, ot::pack & pack, + unsigned party) +{ + if (party > 1) + throw std::invalid_argument("fill_tape_ot party"); + if (!pack.has_party_tape()) + throw std::runtime_error( + "fill_tape_ot: pack has no party view; call fill_tape_ot_pair"); + auto tape = pack.template load_party_tape(); + if (tape.lambda.size() != s.wire_count()) + throw std::invalid_argument("fill_tape_ot: tape does not match session"); + (void)party; + return tape; +} + +} // namespace gilboa +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_GILBOA_HPP__ diff --git a/include/dpf/grow.hpp b/include/dpf/grow.hpp new file mode 100644 index 0000000..9b75b27 --- /dev/null +++ b/include/dpf/grow.hpp @@ -0,0 +1,1143 @@ +/// @file dpf/grow.hpp +/// @brief Dealer-side growth of an existing `dpf_key`: one more level, or one +/// more output on a level the tree already has. +/// @details `extend` and `add_output` take both parties' keys (same dealer view +/// as `make_dpf`), return a new `party_key` pair whose type is the old +/// key plus the new material, and keep earlier correction words / +/// leaves / comparison words. Specs are the same objects `make_dpf` +/// accepts. Memoizer overloads skip the rewalk when both path +/// memoizers are already filled through the frontier. Interactive +/// Doerner–Shelat growth is `extend_ds` / `add_output_ds` in +/// grow_ds.hpp. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_GROW_HPP__ +#define LIBDPF_INCLUDE_DPF_GROW_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/dpf_key.hpp" +#include "dpf/incremental.hpp" +#include "dpf/path_memoizer.hpp" +#include "dpf/placement.hpp" +#include "dpf/secret_share.hpp" +#include "dpf/tree_traits.hpp" +#include "dpf/twiddle.hpp" +#include "dpf/utils.hpp" +#include "dpf/verifiable.hpp" + +namespace dpf +{ +namespace detail +{ +namespace grow_impl +{ + +template +struct has_placed_tuple : std::false_type +{ +}; + +template +struct has_placed_tuple> + : std::true_type +{ +}; + +template +inline constexpr bool has_placed_tuple_v = + has_placed_tuple>::value; + +template +using bare_key_t = unwrap_party_key_t; + +template +HEDLEY_ALWAYS_INLINE +bool try_advance(Node & s0, Node & s1, Node cw, psnip_uint8_t advice, bool bit) +{ + const bool t0 = static_cast(get_lo_bit(s0)); + const bool t1 = static_cast(get_lo_bit(s1)); + const bool is_last = false; + const auto kids0 = Tree::expand(s0, is_last); + const auto kids1 = Tree::expand(s1, is_last); + const Node n0 = Tree::advance(s0, kids0, cw, advice, bit, t0, is_last); + const Node n1 = Tree::advance(s1, kids1, cw, advice, bit, t1, is_last); + if (get_lo_bit(n0) == get_lo_bit(n1)) + return false; + s0 = n0; + s1 = n1; + return true; +} + +/// @brief Rewalk Gen to `stop` using stored CWs. Path bits are recovered: only +/// the programmed direction keeps the parties' control bits distinct. +template +void rewalk_to(const Key & k0, const Key & k1, + typename Key::interior_node & s0, typename Key::interior_node & s1, + std::size_t stop, bool * path_out = nullptr) +{ + using tree = typename Key::tree; + using node = typename Key::interior_node; + s0 = k0.root(); + s1 = k1.root(); + const auto & cws = k0.correction_words(); + const auto & adv = k0.correction_advice(); + for (std::size_t level = 0; level < stop; ++level) + { + bool found = false; + node a0 = s0; + node a1 = s1; + if (try_advance(a0, a1, cws[level], adv[level], false)) + { + s0 = a0; + s1 = a1; + if (path_out) + path_out[level] = false; + found = true; + } + else + { + a0 = s0; + a1 = s1; + if (try_advance(a0, a1, cws[level], adv[level], true)) + { + s0 = a0; + s1 = a1; + if (path_out) + path_out[level] = true; + found = true; + } + } + if (!found) + throw std::logic_error("grow: path bit recovery failed"); + } +} + +template +HEDLEY_NO_THROW +constexpr bool bit_at(InputT x, std::size_t level) noexcept +{ + constexpr auto bitlen = utils::bitlength_of_v; + const auto to_int = utils::to_integral_type{}; + using I = typename utils::to_integral_type::integral_type; + const I xi = static_cast(to_int(x)); + return static_cast( + utils::shift_right(xi, bitlen - 1 - level) & I{1}); +} + +/// @brief Read both parties' seeds at `need` from path memoizers. The caller +/// must already have filled each memo through `need` (e.g. via +/// `eval_point` / `ensure_level`); this does not walk the tree. +template +void frontier_from_memos(const Key & k0, const Key & k1, Memo0 & m0, Memo1 & m1, + typename Key::input_type xx, std::size_t need, + typename Key::interior_node & s0, typename Key::interior_node & s1, + bool * path_out) +{ + if (need > Key::depth) + throw std::invalid_argument("grow: memoizer level past key depth"); + static_assert(detail::has_path_high_water::value + && detail::has_path_high_water::value, + "grow: memoizer overloads require a path memoizer with filled_to"); + if (m0.filled_to() < need) + throw std::invalid_argument( + "grow: party-0 memoizer is not filled to the required level"); + if (m1.filled_to() < need) + throw std::invalid_argument( + "grow: party-1 memoizer is not filled to the required level"); + (void)k0; + (void)k1; + for (std::size_t level = 0; level < Key::depth && path_out != nullptr; + ++level) + path_out[level] = bit_at(xx, level); + s0 = m0[need]; + s1 = m1[need]; +} + +template +void read_snap_from_memos(Memo0 & m0, Memo1 & m1, std::size_t depth, Node * snap0, + Node * snap1, bool * snap_sign) +{ + for (std::size_t lvl = 0; lvl <= depth; ++lvl) + { + snap0[lvl] = m0[lvl]; + snap1[lvl] = m1[lvl]; + snap_sign[lvl] = static_cast(get_lo_bit(snap0[lvl])); + } +} + +template +auto cat_placed(const OldPlaced &, NewPlaced && neu, + std::index_sequence, std::index_sequence) +{ + // Old payload values are not stored on the key; only types matter for the + // concatenated placed tuple used to name the new key. Dummy defaults. + return std::tuple_cat( + std::make_tuple(std::tuple_element_t{}...), + std::make_tuple(std::get(std::forward(neu))...)); +} + +template +auto cat_wrappers(OldWraps && old_w, NewWraps && new_w, + std::index_sequence, std::index_sequence) +{ + return std::make_tuple( + std::get(std::forward(old_w))..., + std::get(std::forward(new_w))...); +} + +template +auto cat_addends(const OldAdds & old_a, NewAdds && new_a, + std::index_sequence, std::index_sequence) +{ + return std::make_tuple( + std::get(old_a)..., + std::get(std::forward(new_a))...); +} + +template +void copy_cmp_common(const OldKey & src, typename NewKey::value_cw_array & vcw, + typename NewKey::value_cw_array & vcoeff, + typename NewKey::tail_array & tail, + typename NewKey::tail_array & tcoeff, + typename NewKey::prefix_cw_array & prefix, + typename NewKey::prefix_cw_array & pcoeff, + typename NewKey::value_cw_word & cw_last, + typename NewKey::value_cw_word & cw_last_coeff) +{ + if constexpr (OldKey::cmp_depth > 0 && NewKey::cmp_depth > 0) + { + const auto & old_vcw = src.value_cw(); + const auto & old_coeff = src.value_cw_coeff(); + constexpr std::size_t ncopy = + OldKey::value_cw_len < NewKey::value_cw_len + ? OldKey::value_cw_len + : NewKey::value_cw_len; + for (std::size_t i = 0; i < ncopy; ++i) + { + vcw[i] = old_vcw[i]; + if constexpr (OldKey::cmp_is_wildcard && NewKey::cmp_is_wildcard) + vcoeff[i] = old_coeff[i]; + } + const auto & ot = src.tail_cw(); + const auto & otc = src.tail_coeff(); + constexpr std::size_t nt = + OldKey::cmp_tail < NewKey::cmp_tail ? OldKey::cmp_tail + : NewKey::cmp_tail; + for (std::size_t i = 0; i < nt; ++i) + { + tail[i] = ot[i]; + if constexpr (OldKey::cmp_is_wildcard && NewKey::cmp_is_wildcard) + tcoeff[i] = otc[i]; + } + if constexpr (OldKey::cmp_idcf && NewKey::cmp_idcf) + { + const auto & op = src.prefix_cws(); + const auto & opc = src.prefix_cw_coeff(); + constexpr std::size_t np = + OldKey::prefix_cw_len < NewKey::prefix_cw_len + ? OldKey::prefix_cw_len + : NewKey::prefix_cw_len; + for (std::size_t i = 0; i < np; ++i) + { + prefix[i] = op[i]; + if constexpr (OldKey::cmp_is_wildcard && NewKey::cmp_is_wildcard) + pcoeff[i] = opc[i]; + } + } + cw_last = src.cw_last_word(); + cw_last_coeff = src.cw_last_coeff_word(); + } +} + +template +struct grown_key_type +{ + using old_placed = typename OldKey::placed_tuple; + using new_placed = decltype(std::tuple_cat( + std::declval(), std::declval())); + static constexpr std::size_t cmp_depth = + NewCmpDepth > 0 ? NewCmpDepth : OldKey::cmp_depth; + static constexpr std::size_t cmp_out_bits = + NewCmpDepth > 0 ? NewCmpOutBits : OldKey::cmp_out_bits; + static constexpr bool cmp_wild = + NewCmpDepth > 0 ? NewCmpWild : OldKey::cmp_is_wildcard; + static constexpr std::size_t cmp_block = + NewCmpDepth > 0 ? NewCmpBlock : OldKey::cmp_block; + static constexpr bool cmp_idcf = + NewCmpDepth > 0 ? NewCmpIdcf : OldKey::cmp_idcf; + static constexpr bool is_verifiable = + NewVerifiable || OldKey::is_verifiable; + static constexpr bool is_extractable = + NewExtractable || OldKey::is_extractable; + using type = incr::incr_dpf_key_of_t; +}; + +template +auto grow_impl(const K0 & pk0, const K1 & pk1, Memo0 * m0, Memo1 * m1, bool bit, + InputT x, bool have_pre, + typename bare_key_t::interior_node * pre_cw, psnip_uint8_t * pre_advice, + typename bare_key_t::interior_node * pre_s0, + typename bare_key_t::interior_node * pre_s1, Specs &&... specs) +{ + using old_key = bare_key_t; + static_assert(std::is_same_v>, + "grow: both keys must have the same type"); + static_assert(has_placed_tuple_v, + "grow: key must be a multi-level / incremental dpf_key"); + static_assert(old_key::num_outputs > 0 || old_key::cmp_depth > 0, + "grow: empty key"); + + using input_type = typename old_key::input_type; + static_assert(std::is_same_v, input_type> + || std::is_convertible_v, + "grow: programmed point type mismatch"); + constexpr auto bitlen = utils::bitlength_of_v; + + const old_key & k0 = static_cast(pk0); + const old_key & k1 = static_cast(pk1); + + if constexpr (old_key::depth > 0) + { + if (std::memcmp(k0.correction_words().data(), + k1.correction_words().data(), + sizeof(typename old_key::correction_words_array)) != 0 + || std::memcmp(k0.correction_advice().data(), + k1.correction_advice().data(), + sizeof(typename old_key::correction_advice_array)) != 0) + throw std::invalid_argument("grow: keys are not a matching pair"); + } + + dcf_runtime_spec dcf_spec{}; + bool has_cmp = false; + auto new_placed_part = detail::incr::flatten_args_and_cmp(dcf_spec, + has_cmp, std::forward(specs)...); + using new_placed_part_t = decltype(new_placed_part); + + constexpr std::size_t arg_cmp_depth = + forced_cmp_depth_v; + constexpr std::size_t arg_cmp_bits = + forced_cmp_out_bits_v; + constexpr bool arg_cmp_wild = forced_cmp_wild_v; + constexpr std::size_t arg_cmp_block = forced_cmp_block_v; + constexpr bool arg_cmp_idcf = forced_cmp_idcf_v; + constexpr bool arg_verifiable = args_have_verifiable_v; + constexpr bool arg_extractable = args_have_extractable_v; + + if constexpr (old_key::cmp_depth > 0 && arg_cmp_depth > 0) + { + static_assert(old_key::cmp_depth == arg_cmp_depth + && old_key::cmp_block == arg_cmp_block + && old_key::cmp_idcf == arg_cmp_idcf, + "grow: comparison channel already present with a different shape"); + } + + using grown = grown_key_type; + using new_key = typename grown::type; + using new_placed = typename grown::new_placed; + using node = typename new_key::interior_node; + using tree = typename new_key::tree; + + constexpr std::size_t old_n = old_key::num_outputs; + constexpr std::size_t new_n = new_key::num_outputs; + constexpr std::size_t added = new_n - old_n; + if constexpr (DoExtend) + { + static_assert(new_key::depth == old_key::depth + 1, + "extend: expected depth to grow by exactly one"); + } + else + { + static_assert(new_key::depth == old_key::depth, + "add_output: comparison or output would deepen the tree; " + "use extend or a shorter lt_at/gt_at/eq_at prefix"); + } + + if constexpr (!DoExtend) + { + if constexpr (added == 0 && arg_cmp_depth == 0 && !arg_verifiable + && !arg_extractable) + throw std::invalid_argument("add_output: no new material"); + } + else + { + if (old_key::depth + 1 >= bitlen) + throw std::invalid_argument( + "extend: key is already as deep as the input type"); + if (bit != bit_at(static_cast(x), old_key::depth)) + throw std::invalid_argument( + "extend: bit does not match the programmed point"); + } + + // Reject specs that belong on an older level (extend) or on a missing + // level (add_output). + if constexpr (added > 0) + { + constexpr auto new_meta = new_key::meta; + for (std::size_t i = old_n; i < new_n; ++i) + { + const auto lvl = new_meta[i].tree_level; + if constexpr (DoExtend) + { + if (lvl != new_key::depth) + throw std::invalid_argument( + "extend: output prefix is not the new depth"); + } + else + { + if (lvl > old_key::depth) + throw std::invalid_argument( + "add_output: prefix needs a deeper tree"); + } + } + } + + input_type xx = static_cast(x); + utils::flip_msb_if_signed_integral(xx); + + node s0{}; + node s1{}; + std::array path{}; + if constexpr (UseMemo) + { + static_assert(!std::is_void_v && !std::is_void_v, + "grow: memoizer overload requires two memoizers"); + frontier_from_memos(k0, k1, *m0, *m1, xx, old_key::depth, s0, s1, + old_key::depth == 0 ? nullptr : path.data()); + } + else + { + rewalk_to(k0, k1, s0, s1, old_key::depth, + old_key::depth == 0 ? nullptr : path.data()); + (void)m0; + (void)m1; + } + + typename new_key::correction_words_array correction_words{}; + typename new_key::correction_advice_array correction_advice{}; + typename new_key::correction_seeds_array correction_seeds{}; + + for (std::size_t i = 0; i < old_key::depth; ++i) + { + correction_words[i] = k0.correction_words()[i]; + correction_advice[i] = k0.correction_advice()[i]; + } + if constexpr (old_key::is_verifiable && new_key::is_verifiable) + { + for (std::size_t i = 0; i < old_key::depth; ++i) + correction_seeds[i] = k0.correction_seeds()[i]; + } + else if constexpr (!old_key::is_verifiable && new_key::is_verifiable) + { + // Opting in: sample seeds for levels that already exist. + node p0 = k0.root(); + node p1 = k1.root(); + for (std::size_t level = 0; level < old_key::depth; ++level) + { + const bool pb = path[level]; + const bool is_last = tree::is_last_level(level, new_key::depth); + const bool a0 = static_cast(get_lo_bit(p0)); + const bool a1 = static_cast(get_lo_bit(p1)); + auto c0 = tree::expand(p0, is_last); + auto c1 = tree::expand(p1, is_last); + p0 = tree::advance(p0, c0, correction_words[level], + correction_advice[level], pb, a0, is_last); + p1 = tree::advance(p1, c1, correction_words[level], + correction_advice[level], pb, a1, is_last); + const auto prefix = static_cast( + utils::to_integral_type{}(xx) + >> (bitlen - (level + 1))); + if constexpr (new_key::cmp_block > 0) + { + correction_seeds[level] = detail::vdpf::make_cs( + detail::blocked::fold_spine_tag | level, prefix, p0, p1); + } + else + { + correction_seeds[level] = + detail::vdpf::make_cs(level, prefix, p0, p1); + } + } + s0 = p0; + s1 = p1; + } + + if constexpr (DoExtend) + { + const std::size_t level = old_key::depth; + if (have_pre) + { + correction_words[level] = *pre_cw; + correction_advice[level] = *pre_advice; + s0 = *pre_s0; + s1 = *pre_s1; + } + else + { + const bool is_last = tree::is_last_level(level, new_key::depth); + const bool a0 = static_cast(get_lo_bit(s0)); + const bool a1 = static_cast(get_lo_bit(s1)); + auto c0 = tree::expand(s0, is_last); + auto c1 = tree::expand(s1, is_last); + node cw{}; + psnip_uint8_t advice = 0; + tree::make_cw(cw, advice, c0, c1, s0, s1, bit, is_last); + s0 = tree::advance(s0, c0, cw, advice, bit, a0, is_last); + s1 = tree::advance(s1, c1, cw, advice, bit, a1, is_last); + correction_words[level] = cw; + correction_advice[level] = advice; + } + if constexpr (new_key::is_verifiable) + { + const auto prefix = static_cast( + utils::to_integral_type{}(xx) + >> (bitlen - (level + 1))); + if constexpr (new_key::cmp_block > 0) + { + correction_seeds[level] = detail::vdpf::make_cs( + detail::blocked::fold_spine_tag | level, prefix, s0, s1); + } + else + { + correction_seeds[level] = + detail::vdpf::make_cs(level, prefix, s0, s1); + } + } + } + else + { + (void)have_pre; + (void)pre_cw; + (void)pre_advice; + (void)pre_s0; + (void)pre_s1; + } + + // Full placed tuple for naming / meta; only the new slots' values are used + // when planting leaves. + new_placed placed = cat_placed(typename old_key::placed_tuple{}, + std::move(new_placed_part), std::make_index_sequence{}, + std::make_index_sequence{}); + + auto leaves0 = detail::incr::empty_leaves(std::make_index_sequence{}); + auto beavers0 = detail::incr::empty_beavers(std::make_index_sequence{}); + auto leaves1 = detail::incr::empty_leaves(std::make_index_sequence{}); + auto beavers1 = detail::incr::empty_beavers(std::make_index_sequence{}); + + // Copy old raw leaves / beavers into the front slots. + if constexpr (old_n > 0) + { + [&](std::index_sequence) { + ((std::get(leaves0) = k0.template leaf(), + std::get(beavers0) = k0.template beaver(), + std::get(leaves1) = k1.template leaf(), + std::get(beavers1) = k1.template beaver()), + ...); + }(std::make_index_sequence{}); + } + + // When depth grows, groups that sat at the old deepest level move from + // pos_base-start-0 to pos_base-start-2. Retarget their shared correction + // words so eval of those slots stays share-identical. + if constexpr (DoExtend && old_n > 0) + { + using exterior = typename new_key::exterior_prg; + using node_ex = typename exterior::block_type; + node p0 = k0.root(); + node p1 = k1.root(); + // Walk to each old-deepest group's level once. + for (std::size_t level = 0; level < old_key::depth; ++level) + { + const bool pb = path[level]; + const bool is_last = tree::is_last_level(level, new_key::depth); + const bool a0 = static_cast(get_lo_bit(p0)); + const bool a1 = static_cast(get_lo_bit(p1)); + auto c0 = tree::expand(p0, is_last); + auto c1 = tree::expand(p1, is_last); + p0 = tree::advance(p0, c0, correction_words[level], + correction_advice[level], pb, a0, is_last); + p1 = tree::advance(p1, c1, correction_words[level], + correction_advice[level], pb, a1, is_last); + } + const auto seed0 = dpf::unset_lo_2bits(p0); + const auto seed1 = dpf::unset_lo_2bits(p1); + const bool sign0 = static_cast(get_lo_bit(p0)); + + [&](std::index_sequence) { + (([&] { + constexpr std::size_t old_pos = old_key::meta[Is].pos_base; + constexpr std::size_t new_pos = new_key::meta[Is].pos_base; + if constexpr (old_pos == new_pos) + return; + using Out = typename new_key::template output_type_t; + using Concrete = concrete_type_t; + // Build a one-slot outputs tuple so make_leaf_mask indices match. + using outs = std::tuple; + const auto mask_old = + dpf::make_leaf_mask( + seed0, seed1, old_pos); + const auto mask_new = + dpf::make_leaf_mask( + seed0, seed1, new_pos); + auto & L0 = std::get(leaves0); + auto & L1 = std::get(leaves1); + if (sign0) + { + // L = naked - mask => L' = L + mask_old - mask_new + L0 = dpf::subtract_leaf( + dpf::add_leaf(L0, mask_old), mask_new); + L1 = dpf::subtract_leaf( + dpf::add_leaf(L1, mask_old), mask_new); + } + else + { + // L = mask - naked => L' = L - mask_old + mask_new + L0 = dpf::add_leaf( + dpf::subtract_leaf(L0, mask_old), mask_new); + L1 = dpf::add_leaf( + dpf::subtract_leaf(L1, mask_old), mask_new); + } + }()), ...); + }(std::make_index_sequence{}); + (void)sign0; + } + + // Plant only groups that contain a newly added slot. A group that also + // holds an older slot would need that slot's payload to rebuild the + // packed leaf; reject that case. + if constexpr (added > 0) + { + using MetaHolder = detail::incr::meta_holder; + constexpr auto meta = new_key::meta; + constexpr std::size_t ngroups = [] { + std::size_t m = 0; + for (std::size_t i = 0; i < new_n; ++i) + m = std::max(m, new_key::meta[i].group_id + 1); + return m; + }(); + constexpr auto order = + detail::incr::build_group_order(meta, + new_n); + + std::array snap0{}; + std::array snap1{}; + std::array snap_sign{}; + if constexpr (UseMemo) + { + // Seeds through the old frontier come from the memoizers. After an + // extend the new depth's node is already in s0/s1. + read_snap_from_memos(*m0, *m1, old_key::depth, snap0.data(), + snap1.data(), snap_sign.data()); + if constexpr (DoExtend) + { + snap0[new_key::depth] = s0; + snap1[new_key::depth] = s1; + snap_sign[new_key::depth] = + static_cast(get_lo_bit(s0)); + } + } + else + { + node p0 = k0.root(); + node p1 = k1.root(); + snap0[0] = p0; + snap1[0] = p1; + snap_sign[0] = static_cast(get_lo_bit(p0)); + for (std::size_t level = 0; level < new_key::depth; ++level) + { + const bool pb = (level < old_key::depth) ? path[level] : bit; + const bool is_last = + tree::is_last_level(level, new_key::depth); + const bool a0 = static_cast(get_lo_bit(p0)); + const bool a1 = static_cast(get_lo_bit(p1)); + auto c0 = tree::expand(p0, is_last); + auto c1 = tree::expand(p1, is_last); + p0 = tree::advance(p0, c0, correction_words[level], + correction_advice[level], pb, a0, is_last); + p1 = tree::advance(p1, c1, correction_words[level], + correction_advice[level], pb, a1, is_last); + snap0[level + 1] = p0; + snap1[level + 1] = p1; + snap_sign[level + 1] = static_cast(get_lo_bit(p0)); + } + } + + detail::incr::for_each_index(std::make_index_sequence{}, + [&](auto oi) { + constexpr std::size_t G = order[decltype(oi)::value]; + constexpr bool touches_new = [] { + for (std::size_t i = old_n; i < new_n; ++i) + if (new_key::meta[i].group_id == G) + return true; + return false; + }(); + constexpr bool touches_old = [] { + for (std::size_t i = 0; i < old_n; ++i) + if (new_key::meta[i].group_id == G) + return true; + return false; + }(); + if constexpr (!touches_new) + return; + if constexpr (touches_old) + { + throw std::invalid_argument( + "grow: new output shares a packing group with an " + "existing slot; use make_dpf for that pack"); + } + constexpr std::size_t lvl = [] { + for (std::size_t i = 0; i < new_n; ++i) + if (new_key::meta[i].group_id == G) + return new_key::meta[i].tree_level; + return std::size_t{0}; + }(); + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + using leaf_prg = std::conditional_t, + typename new_key::exterior_prg>; + detail::incr::gen_group(xx, + dpf::unset_lo_2bits(snap0[lvl]), + dpf::unset_lo_2bits(snap1[lvl]), + static_cast(snap_sign[lvl]), + static_cast(dpf::get_lo_bit(snap1[lvl])), placed, + leaves0, beavers0, leaves1, beavers1); + HEDLEY_PRAGMA(GCC diagnostic pop) + }); + } + + if constexpr (!old_key::is_extractable && new_key::is_extractable + && old_n > 0 && added == 0) + { + throw std::invalid_argument( + "grow: opting into extractable requires new outputs or a full " + "rebuild via make_dpf"); + } + + auto wrap0 = detail::incr::wrap_leaves(leaves0, + beavers0, std::make_index_sequence{}); + auto wrap1 = detail::incr::wrap_leaves(leaves1, + beavers1, std::make_index_sequence{}); + + typename new_key::value_cw_array value_cws{}; + typename new_key::value_cw_array value_cw_coeff{}; + typename new_key::tail_array tail{}; + typename new_key::tail_array tail_coeff{}; + typename new_key::prefix_cw_array prefix_cw{}; + typename new_key::prefix_cw_array prefix_coeff{}; + typename new_key::value_cw_word cw_last{}; + typename new_key::value_cw_word cw_last_coeff{}; + typename new_key::value_cw_word cmp_add0{}; + typename new_key::value_cw_word cmp_add1{}; + + copy_cmp_common(k0, value_cws, value_cw_coeff, tail, + tail_coeff, prefix_cw, prefix_coeff, cw_last, cw_last_coeff); + if constexpr (old_key::cmp_depth > 0) + { + cmp_add0 = k0.cmp_addend_word(); + cmp_add1 = k1.cmp_addend_word(); + } + + detail::cmp_meta cmp = k0.cmp(); + + // Add a comparison onto a key that had none (integral per-level path). + if (has_cmp && old_key::cmp_depth == 0) + { + using namespace detail::dcf_impl; + cmp.nbits = static_cast(dcf_spec.prefix ? dcf_spec.prefix + : bitlen); + cmp.mask = dcf_spec.mask; + cmp.kind = dcf_spec.kind; + cmp.active = true; + cmp.incremental = dcf_spec.incremental; + cmp.eval_as_ge = false; + cmp.trivial = cmp_trivial::none; + cmp.block_width = static_cast(new_key::cmp_block); + cmp.tail_bits = static_cast(new_key::cmp_q); + cmp.include_eq = false; + const uint64_t delta = dcf_spec.beta & dcf_spec.mask; + const uint64_t false_value = dcf_spec.false_value & dcf_spec.mask; + unsigned __int128 thresh = + static_cast( + utils::to_integral_type{}(xx)); + if (dcf_spec.prefix) + thresh >>= (bitlen - dcf_spec.prefix); + detail::incr::adjust_cmp_threshold(cmp, thresh, + static_cast(cmp.nbits)); + const std::size_t cmp_nbits = static_cast(cmp.nbits); + + if (cmp.trivial != cmp_trivial::none || new_key::cmp_block > 0 + || dcf_spec.custom || dcf_spec.use_payload_group + || is_paint_kind(dcf_spec.kind)) + { + throw std::invalid_argument( + "add_output: comparison shape not supported on grow yet"); + } + + uint64_t Va = 0; + uint64_t Va1 = 0; + node p0 = k0.root(); + node p1 = k1.root(); + for (std::size_t level = 0; level < new_key::depth; ++level) + { + const bool pb = (level < old_key::depth) ? path[level] + : (DoExtend ? bit : bit_at(xx, level)); + const bool is_last = tree::is_last_level(level, new_key::depth); + const bool advice0 = static_cast(get_lo_bit(p0)); + const bool advice1 = static_cast(get_lo_bit(p1)); + const auto val0 = tree::expand_value(p0); + const auto val1 = tree::expand_value(p1); + auto c0 = tree::expand(p0, is_last); + auto c1 = tree::expand(p1, is_last); + if (level < cmp_nbits) + { + const int ai = static_cast( + (thresh >> (cmp_nbits - 1 - level)) & 1); + const uint64_t base = make_value_cw(val0[0], val0[1], + val1[0], val1[1], static_cast(advice0), + static_cast(advice1), ai, Va, delta, cmp.mask); + value_cws[level] = + static_cast(base); + if constexpr (new_key::cmp_is_wildcard) + { + const uint64_t v1 = make_value_cw(val0[0], val0[1], + val1[0], val1[1], static_cast(advice0), + static_cast(advice1), ai, Va1, 1ULL, + cmp.mask); + value_cw_coeff[level] = + static_cast( + (v1 + neg_m(base, cmp.mask)) & cmp.mask); + } + } + p0 = tree::advance(p0, c0, correction_words[level], + correction_advice[level], pb, advice0, is_last); + p1 = tree::advance(p1, c1, correction_words[level], + correction_advice[level], pb, advice1, is_last); + if (level + 1 == cmp_nbits) + { + cw_last = static_cast( + make_final_cw(p0, p1, + static_cast(get_lo_bit(p1)), Va, cmp.mask, + true)); + if constexpr (new_key::cmp_is_wildcard) + { + const uint64_t l1 = make_final_cw(p0, p1, + static_cast(get_lo_bit(p1)), Va1, cmp.mask, + true); + cw_last_coeff = + static_cast( + (l1 + neg_m(static_cast(cw_last), + cmp.mask)) + & cmp.mask); + } + } + } + uint64_t target = false_value; + if (cmp.eval_as_ge) + target = (delta + false_value) & cmp.mask; + const uint64_t rblind = sample_addend_blind(cmp.mask, + [] { return dpf::uniform_sample(); }); + uint64_t a0 = 0, a1 = 0; + detail::incr::split_cmp_addend(target, cmp.mask, rblind, a0, a1); + cmp_add0 = static_cast(a0); + cmp_add1 = static_cast(a1); + } + else if constexpr (DoExtend && old_key::cmp_depth > 0 + && new_key::cmp_block == 0 && new_key::depth > old_key::depth) + { + // Extending a key that already has a comparison: append a value word + // when the new level is still inside the comparison. Requires the + // caller to re-pass the comparison spec so δ is known. + if (has_cmp && cmp.active && cmp.trivial == cmp_trivial::none) + { + using namespace detail::dcf_impl; + const std::size_t level = old_key::depth; + const std::size_t cmp_nbits = static_cast(cmp.nbits); + if (level < cmp_nbits) + { + const uint64_t delta = dcf_spec.beta & dcf_spec.mask; + unsigned __int128 thresh = + static_cast( + utils::to_integral_type{}(xx)); + if (cmp_nbits < bitlen) + thresh >>= (bitlen - cmp_nbits); + uint64_t Va = 0; + uint64_t Va1 = 0; + node p0 = k0.root(); + node p1 = k1.root(); + for (std::size_t L = 0; L < level; ++L) + { + const bool advice0 = + static_cast(get_lo_bit(p0)); + const bool advice1 = + static_cast(get_lo_bit(p1)); + const auto val0 = tree::expand_value(p0); + const auto val1 = tree::expand_value(p1); + const int ai = static_cast( + (thresh >> (cmp_nbits - 1 - L)) & 1); + (void)make_value_cw(val0[0], val0[1], val1[0], val1[1], + static_cast(advice0), + static_cast(advice1), ai, Va, delta, + cmp.mask); + if constexpr (new_key::cmp_is_wildcard) + { + (void)make_value_cw(val0[0], val0[1], val1[0], + val1[1], static_cast(advice0), + static_cast(advice1), ai, Va1, 1ULL, + cmp.mask); + } + const bool pb = path[L]; + const bool is_last = + tree::is_last_level(L, new_key::depth); + auto c0 = tree::expand(p0, is_last); + auto c1 = tree::expand(p1, is_last); + p0 = tree::advance(p0, c0, correction_words[L], + correction_advice[L], pb, advice0, is_last); + p1 = tree::advance(p1, c1, correction_words[L], + correction_advice[L], pb, advice1, is_last); + } + const bool advice0 = static_cast(get_lo_bit(p0)); + const bool advice1 = static_cast(get_lo_bit(p1)); + const auto val0 = tree::expand_value(p0); + const auto val1 = tree::expand_value(p1); + const int ai = static_cast( + (thresh >> (cmp_nbits - 1 - level)) & 1); + const uint64_t base = make_value_cw(val0[0], val0[1], + val1[0], val1[1], static_cast(advice0), + static_cast(advice1), ai, Va, delta, cmp.mask); + value_cws[level] = + static_cast(base); + if constexpr (new_key::cmp_is_wildcard) + { + const uint64_t v1 = make_value_cw(val0[0], val0[1], + val1[0], val1[1], static_cast(advice0), + static_cast(advice1), ai, Va1, 1ULL, + cmp.mask); + value_cw_coeff[level] = + static_cast( + (v1 + neg_m(base, cmp.mask)) & cmp.mask); + } + if (level + 1 == cmp_nbits) + { + const bool is_last = + tree::is_last_level(level, new_key::depth); + auto c0 = tree::expand(p0, is_last); + auto c1 = tree::expand(p1, is_last); + p0 = tree::advance(p0, c0, correction_words[level], + correction_advice[level], bit, advice0, is_last); + p1 = tree::advance(p1, c1, correction_words[level], + correction_advice[level], bit, advice1, is_last); + cw_last = static_cast( + make_final_cw(p0, p1, + static_cast(get_lo_bit(p1)), Va, + cmp.mask, true)); + } + } + } + } + + auto adds_new = detail::incr::extract_addends(placed, + std::make_index_sequence{}); + if constexpr (old_n > 0) + { + [&](std::index_sequence) { + ((std::get(adds_new) = std::get(k0.public_addends)), ...); + }(std::make_index_sequence{}); + } + + input_type off0 = k0.offset_x.raw(); + input_type off1 = k1.offset_x.raw(); + + new_key key0{k0.root(), correction_words, correction_advice, + std::move(wrap0), off0, cmp, value_cws, + static_cast(cw_last), static_cast(cmp_add0), + adds_new, value_cw_coeff, static_cast(cw_last_coeff), tail, + tail_coeff, prefix_cw, prefix_coeff, correction_seeds}; + new_key key1{k1.root(), correction_words, correction_advice, + std::move(wrap1), off1, cmp, value_cws, + static_cast(cw_last), static_cast(cmp_add1), + adds_new, value_cw_coeff, static_cast(cw_last_coeff), tail, + tail_coeff, prefix_cw, prefix_coeff, correction_seeds}; + + if constexpr (old_key::cmp_depth > 0 || (arg_cmp_depth > 0)) + { + key0.set_cmp_scalars(cw_last, cmp_add0, cw_last_coeff); + key1.set_cmp_scalars(cw_last, cmp_add1, cw_last_coeff); + if constexpr (old_key::cmp_depth > 0) + { + key0.set_cmp_assigned(k0.cmp_assigned()); + key1.set_cmp_assigned(k1.cmp_assigned()); + } + } + + return dpf::make_party_key_pair(std::move(key0), std::move(key1)); +} + +} // namespace grow_impl +} // namespace detail + +/// @brief Append one interior level and plant specs whose prefix is the new +/// depth. `bit` is the next MSB-side path bit; `x` is the programmed +/// point (must agree with `bit` at the new level) used for leaf lanes. +/// \complexity O(d) rewalk of the existing spine plus one `make_cw` / `advance` +/// and one exterior leaf plant per new packing group. d is the old +/// depth. Copying prior correction words and leaves is O(d + m) for +/// m existing outputs. +/// \rounds none (dealer / joint view) +/// \communication none +template +HEDLEY_WARN_UNUSED_RESULT +auto extend(const K0 & k0, const K1 & k1, bool bit, InputT x, + Specs &&... specs) +{ + return detail::grow_impl::grow_impl(k0, k1, + static_cast(nullptr), static_cast(nullptr), bit, x, + false, static_cast::interior_node *>( + nullptr), + static_cast(nullptr), + static_cast::interior_node *>( + nullptr), + static_cast::interior_node *>( + nullptr), + std::forward(specs)...); +} + +/// @brief Append one interior level. Path bit taken from `x` at the old depth. +template , bool> + && !is_at_v> + && !is_cmp_spec_v> + && !is_verifiable_tag_v> + && !is_extractable_tag_v>>> +HEDLEY_WARN_UNUSED_RESULT +auto extend(const K0 & k0, const K1 & k1, InputT x, Specs &&... specs) +{ + using old_key = detail::grow_impl::bare_key_t; + const bool bit = + detail::grow_impl::bit_at(static_cast(x), + old_key::depth); + return extend(k0, k1, bit, x, std::forward(specs)...); +} + +/// @brief Plant outputs on levels the tree already has. No new correction word. +/// \complexity O(d) rewalk (or O(1) seed reads with filled memoizers) plus one +/// exterior leaf plant per new packing group. No new interior CW. +/// \rounds none +/// \communication none +template +HEDLEY_WARN_UNUSED_RESULT +auto add_output(const K0 & k0, const K1 & k1, InputT x, Specs &&... specs) +{ + return detail::grow_impl::grow_impl(k0, k1, + static_cast(nullptr), static_cast(nullptr), + /*bit=*/false, x, false, + static_cast::interior_node *>( + nullptr), + static_cast(nullptr), + static_cast::interior_node *>( + nullptr), + static_cast::interior_node *>( + nullptr), + std::forward(specs)...); +} + +/// @brief Like `extend`, but on-path seeds come from path memoizers (joint / +/// 2+1 view). Memoizers must already be filled through the old depth +/// for `x` (e.g. after `eval_point`); they are not walked here. +/// \complexity O(1) seed reads at the frontier, then the same `make_cw` and +/// leaf work as dealer `extend`. No O(d) rewalk. +/// \rounds none +/// \communication none +template +HEDLEY_WARN_UNUSED_RESULT +auto extend(const K0 & k0, const K1 & k1, Memo0 & m0, Memo1 & m1, bool bit, + InputT x, Specs &&... specs) +{ + return detail::grow_impl::grow_impl(k0, k1, &m0, &m1, bit, x, + false, + static_cast::interior_node *>( + nullptr), + static_cast(nullptr), + static_cast::interior_node *>( + nullptr), + static_cast::interior_node *>( + nullptr), + std::forward(specs)...); +} + +template , bool> + && !is_at_v> + && !is_cmp_spec_v> + && !is_verifiable_tag_v> + && !is_extractable_tag_v>>> +HEDLEY_WARN_UNUSED_RESULT +auto extend(const K0 & k0, const K1 & k1, Memo0 & m0, Memo1 & m1, InputT x, + Specs &&... specs) +{ + using old_key = detail::grow_impl::bare_key_t; + const bool bit = + detail::grow_impl::bit_at(static_cast(x), + old_key::depth); + return extend(k0, k1, m0, m1, bit, x, std::forward(specs)...); +} + +/// @brief Like `add_output`, reading on-path seeds from path memoizers. +/// \complexity O(1) seed reads per planted level plus leaf plants. Memoizers +/// must already be filled through each new slot's tree level. +/// \rounds none +/// \communication none +template +HEDLEY_WARN_UNUSED_RESULT +auto add_output(const K0 & k0, const K1 & k1, Memo0 & m0, Memo1 & m1, InputT x, + Specs &&... specs) +{ + return detail::grow_impl::grow_impl(k0, k1, &m0, &m1, + /*bit=*/false, x, false, + static_cast::interior_node *>( + nullptr), + static_cast(nullptr), + static_cast::interior_node *>( + nullptr), + static_cast::interior_node *>( + nullptr), + std::forward(specs)...); +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_GROW_HPP__ diff --git a/include/dpf/grow_ds.hpp b/include/dpf/grow_ds.hpp new file mode 100644 index 0000000..d02116b --- /dev/null +++ b/include/dpf/grow_ds.hpp @@ -0,0 +1,132 @@ +/// @file dpf/grow_ds.hpp +/// @brief Doerner–Shelat interactive / joint grow: `extend_ds` and +/// `add_output_ds` on path-memoizer frontiers. +/// @details Joint (2+1 / local) view holds both keys and both memoizers. One +/// correction-word round uses `ds_advance_level`; leaf planting reuses +/// dealer `grow_impl` with the opened CW. A socket backend swaps in a +/// `CwProtocol` that exchanges blinds without revealing the peer seed. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_GROW_DS_HPP__ +#define LIBDPF_INCLUDE_DPF_GROW_DS_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/doerner_shelat.hpp" +#include "dpf/grow.hpp" +#include "dpf/path_memoizer.hpp" +#include "dpf/utils.hpp" + +namespace dpf +{ + +/// @brief One interactive interior level from memoizer frontiers, then plant +/// `specs` via the same assembly as dealer `extend`. +/// @details `x0` / `x1` are XOR shares of the programmed point (use `(x, 0)` in +/// a local joint test). Memoizers must already be filled for the clear +/// point `x0 ⊕ x1` through the old depth. +/// \complexity One `ds_advance_level` (two PRG expands + `prepare_level` / +/// `open_cw` / AND opens) plus the same leaf plants as dealer +/// `extend`. No O(d) rewalk when memoizers are warm. +/// \rounds One interactive CW round for the new level (local_cw_protocol opens +/// in-process; a socket `CwProtocol` is one peer exchange round). +/// \communication Local: none on the wire. Networked: one level's blinds, CW +/// shares, and advice (same shape as one `point_party` level), +/// plus leaf pads when planting. +template +HEDLEY_WARN_UNUSED_RESULT +auto extend_ds(const K0 & k0, const K1 & k1, Memo0 & m0, Memo1 & m1, InputT x0, + InputT x1, CwProtocol & proto, Specs &&... specs) +{ + using old_key = detail::grow_impl::bare_key_t; + static_assert(std::is_same_v>, + "extend_ds: both keys must have the same type"); + using input_type = typename old_key::input_type; + using node = typename old_key::interior_node; + using interior = typename old_key::interior_prg; + + input_type xx0 = static_cast(x0); + input_type xx1 = static_cast(x1); + utils::flip_msb_if_signed_integral(xx0); + // Party 1 share is not MSB-flipped in DS (same as make_dpf_doerner_shelat). + const input_type x = utils::xor_input_shares(xx0, xx1); + + const old_key & bk0 = static_cast(k0); + const old_key & bk1 = static_cast(k1); + + const bool bit = detail::grow_impl::bit_at(x, old_key::depth); + + node s0{}; + node s1{}; + std::array path{}; + detail::grow_impl::frontier_from_memos(bk0, bk1, m0, m1, x, old_key::depth, s0, + s1, old_key::depth == 0 ? nullptr : path.data()); + + detail::ds_gen_state st; + st.init(s0, s1); + + const std::size_t level = old_key::depth; + const std::size_t new_depth = old_key::depth + 1; + auto mask = old_key::msb_mask; + for (std::size_t i = 0; i < level; ++i) + mask >>= 1; + + node cw{}; + psnip_uint8_t advice = 0; + detail::ds_advance_level(st, xx0, xx1, mask, level, new_depth, + proto, cw, advice); + + node ns0 = st.seed0(); + node ns1 = st.seed1(); + + return detail::grow_impl::grow_impl(bk0, bk1, &m0, &m1, bit, x, + true, &cw, &advice, &ns0, &ns1, std::forward(specs)...); +} + +/// @brief Plant outputs on existing levels using memoizer seeds. Joint leaf +/// construction matches dealer `add_output`; `proto.open_leaf_group` is +/// invoked so a non-local protocol can hide the clear point. +/// \complexity O(1) frontier reads plus leaf plants. No new interior CW. +/// \rounds Leaf-open only (local: one `open_leaf_group` callback; networked: +/// the leaf pad / mux pattern of `point_party`). +/// \communication none for `local_cw_protocol`; otherwise leaf pads and the +/// leaf CW open. +template +HEDLEY_WARN_UNUSED_RESULT +auto add_output_ds(const K0 & k0, const K1 & k1, Memo0 & m0, Memo1 & m1, + InputT x0, InputT x1, CwProtocol & proto, Specs &&... specs) +{ + using old_key = detail::grow_impl::bare_key_t; + using input_type = typename old_key::input_type; + const old_key & bk0 = static_cast(k0); + const old_key & bk1 = static_cast(k1); + + input_type xx0 = static_cast(x0); + input_type xx1 = static_cast(x1); + utils::flip_msb_if_signed_integral(xx0); + input_type x{}; + proto.open_leaf_group(xx0, xx1, [&](input_type sx0, input_type sx1) { + x = utils::xor_input_shares(sx0, sx1); + }); + + return detail::grow_impl::grow_impl(bk0, bk1, &m0, &m1, + /*bit=*/false, x, false, + static_cast(nullptr), + static_cast(nullptr), + static_cast(nullptr), + static_cast(nullptr), + std::forward(specs)...); +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_GROW_DS_HPP__ diff --git a/include/dpf/idpf_agg.hpp b/include/dpf/idpf_agg.hpp new file mode 100644 index 0000000..fc307a2 --- /dev/null +++ b/include/dpf/idpf_agg.hpp @@ -0,0 +1,202 @@ +/// @file dpf/idpf_agg.hpp +/// @brief Max and k-th order statistic on a list of incremental DPF keys. +/// @details Each secret value is one `idpf` with a unit payload on every +/// prefix length. Servers add prefix shares along the live spine +/// with `eval_until`. Communication tracks the bit length of the +/// domain, not how many secret inputs were summed +/// (Cheng–Mitrokotsa–Zhang–Hartmann, ePrint 2024/1190, on the +/// S&P 2021 incremental DPF / Poplar walk). +/// @see dpf/eval_until.hpp, dpf/placement.hpp (`idpf`), examples/applications/idpf_agg.cpp +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_IDPF_AGG_HPP__ +#define LIBDPF_INCLUDE_DPF_IDPF_AGG_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/eval_until.hpp" +#include "dpf/placement.hpp" +#include "dpf/secret_share.hpp" +#include "dpf/utils.hpp" + +namespace dpf +{ + +/// @brief Unit payload on every prefix length `1 .. N`. +template +HEDLEY_ALWAYS_INLINE +constexpr auto idpf_ones_impl(std::index_sequence) +{ + return idpf(((void)Is, Beta{1})...); +} + +/// @brief `idpf(1, 1, …, 1)` of length `N` (one unit per prefix length). +template +HEDLEY_ALWAYS_INLINE +constexpr auto idpf_ones() +{ + static_assert(N > 0, "idpf_ones: N must be positive"); + return idpf_ones_impl(std::make_index_sequence{}); +} + +namespace detail +{ +namespace idpf_agg_detail +{ + +template +struct has_raw_member : std::false_type {}; +template +struct has_raw_member().raw())>> + : std::true_type {}; + +template +HEDLEY_ALWAYS_INLINE +auto share_raw(const Share & s) +{ + if constexpr (has_raw_member::value) + return s.raw(); + else + return s; +} + +template +auto open_prefix_counts(std::vector> & ctx0, + std::vector> & ctx1, std::size_t level, + const std::vector::input_type> & prefs) +{ + std::vector counts(prefs.size(), 0); + for (std::size_t i = 0; i < ctx0.size(); ++i) + { + auto s0 = eval_until(ctx0[i], level, prefs); + auto s1 = eval_until(ctx1[i], level, prefs); + for (std::size_t j = 0; j < prefs.size(); ++j) + { + const auto opened = reconstruct(s0[j], s1[j]); + counts[j] += static_cast(share_raw(opened)); + } + } + return counts; +} + +template +void retain_all(std::vector> & ctx0, + std::vector> & ctx1, InputT prefix) +{ + for (std::size_t i = 0; i < ctx0.size(); ++i) + { + ctx0[i].retain(prefix); + ctx1[i].retain(prefix); + } +} + +} // namespace idpf_agg_detail +} // namespace detail + +/// @brief Walk both parties' idpf contexts to the numeric maximum. +/// @details At each bit, keep the `1`-child when it holds any mass; otherwise +/// keep the `0`-child. That is the MSB-first spine of the max value. +/// \complexity O(n · N · depth) party work for `n` keys on an `N`-bit domain: +/// two `eval_until` calls per key per level (both children), then +/// `retain`. Communication of opened counts is O(depth), independent +/// of `n` (ePrint 2024/1190). +template +HEDLEY_WARN_UNUSED_RESULT +auto idpf_agg_max(const std::vector & keys0, + const std::vector & keys1) +{ + using key_type = unwrap_party_key_t; + using input_type = typename key_type::input_type; + constexpr auto bits = key_type::input_bits; + static_assert(std::is_same_v>, + "idpf_agg_max: party keys must unwrap to the same DPF type"); + if (keys0.size() != keys1.size() || keys0.empty()) + throw std::invalid_argument("idpf_agg_max: nonempty equal key lists"); + + std::vector> ctx0; + std::vector> ctx1; + ctx0.reserve(keys0.size()); + ctx1.reserve(keys1.size()); + for (std::size_t i = 0; i < keys0.size(); ++i) + { + ctx0.emplace_back(keys0[i]); + ctx1.emplace_back(keys1[i]); + } + + input_type prefix{0}; + for (std::size_t level = 1; level <= bits; ++level) + { + const input_type left = static_cast(prefix << 1); + const input_type right = static_cast((prefix << 1) | 1); + std::vector prefs{left, right}; + auto counts = detail::idpf_agg_detail::open_prefix_counts(ctx0, ctx1, + level, prefs); + prefix = (counts[1] > 0) ? right : left; + detail::idpf_agg_detail::retain_all(ctx0, ctx1, prefix); + } + return prefix; +} + +/// @brief Walk both parties' idpf contexts to the k-th largest (1-based). +/// @details `k == 1` is the maximum; `k == n` is the minimum. At each bit, +/// take the `1`-child when its count is at least `k`; otherwise +/// subtract that count and take the `0`-child. +/// \complexity Same as `idpf_agg_max`: O(n · N · depth) local work, +/// O(depth) opened counts. +template +HEDLEY_WARN_UNUSED_RESULT +auto idpf_agg_kth(const std::vector & keys0, + const std::vector & keys1, std::size_t k) +{ + using key_type = unwrap_party_key_t; + using input_type = typename key_type::input_type; + constexpr auto bits = key_type::input_bits; + static_assert(std::is_same_v>, + "idpf_agg_kth: party keys must unwrap to the same DPF type"); + if (keys0.size() != keys1.size() || keys0.empty()) + throw std::invalid_argument("idpf_agg_kth: nonempty equal key lists"); + if (k == 0 || k > keys0.size()) + throw std::invalid_argument("idpf_agg_kth: k out of range"); + + std::vector> ctx0; + std::vector> ctx1; + ctx0.reserve(keys0.size()); + ctx1.reserve(keys1.size()); + for (std::size_t i = 0; i < keys0.size(); ++i) + { + ctx0.emplace_back(keys0[i]); + ctx1.emplace_back(keys1[i]); + } + + input_type prefix{0}; + for (std::size_t level = 1; level <= bits; ++level) + { + const input_type left = static_cast(prefix << 1); + const input_type right = static_cast((prefix << 1) | 1); + std::vector prefs{left, right}; + auto counts = detail::idpf_agg_detail::open_prefix_counts(ctx0, ctx1, + level, prefs); + if (counts[1] >= k) + prefix = right; + else + { + k -= counts[1]; + prefix = left; + } + detail::idpf_agg_detail::retain_all(ctx0, ctx1, prefix); + } + return prefix; +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_IDPF_AGG_HPP__ diff --git a/include/dpf/iknp.hpp b/include/dpf/iknp.hpp new file mode 100644 index 0000000..a8535bd --- /dev/null +++ b/include/dpf/iknp.hpp @@ -0,0 +1,700 @@ +/// @file dpf/iknp.hpp +/// @brief Semi-honest IKNP OT extension and the pads a DPF dealer would sample. +/// @details Base OTs are Chou–Orlandi (LATINCRYPT 2015, ePrint 2015/267) on +/// P-256. Extension follows Ishai, Kilian, Nissim, and Petrank, +/// CRYPTO 2003, with fixed-key AES as the correlation-robust hash. +/// `sample` returns this party's shares of random bit triples, +/// bit×block triples, comparison B2A pads, and Doerner–Shelat +/// correction-word pads. +/// +/// Ideal functionality of `sample` (semi-honest, two parties): +/// - **Inputs.** Both parties pass the same lengths `(nblock, nbit, nb2a, ncw)` +/// and call on the peer link before any other walk traffic. +/// - **Outputs.** Party `i` receives shares such that +/// - blocks: `(a0⊕a1)·(b0⊕b1) = c0⊕c1` (bit × 128-bit block); +/// - bits: `(a0⊕a1)∧(b0⊕b1) = c0⊕c1`; +/// - b2a: `(add0+add1) mod 2^64 = r0⊕r1` (0 or 1); +/// - cw: `gamma0⊕gamma1 = (bit1·rand0)⊕(bit0·rand1)` (XOR shares — neither +/// party learns the peer pad bit; see `ds_sample_cw`). +/// - **Hidden.** Peer seeds, peer choice bits used only as OT choice, and the +/// peer's pad bit (so an opened blind `path⊕pad` does not open the path). +/// +/// Cost of `sample` with tape `T = nblock + nbit + ncw` and security +/// parameter `κ = 128`: two Chou–Orlandi base sessions of `κ` OTs (P-256 +/// points, `Θ(κ)` scalar muls), then two OT-extension directions each +/// sending `κ ⌈T/8⌉` bytes of U and `T · 16` bytes of correction, plus +/// `ncw · 16` bytes of `gamma` and an optional B2A extension of length +/// `nb2a`. See [tour_iknp](@ref tour_iknp) for the comparison with a p2 +/// dealer tape and with Half-Tree §5.2. + +#ifndef LIBDPF_INCLUDE_DPF_IKNP_HPP__ +#define LIBDPF_INCLUDE_DPF_IKNP_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" +#include "simde/simde/x86/avx2.h" + +#include "dpf/net/channel.hpp" +#include "dpf/p256.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" + +namespace dpf +{ +namespace iknp +{ + +struct block_share +{ + std::uint8_t a = 0; + simde__m128i b{}; + simde__m128i c{}; +}; + +struct bit_share +{ + std::uint8_t a = 0; + std::uint8_t b = 0; + std::uint8_t c = 0; +}; + +struct b2a_share +{ + std::uint8_t r = 0; + std::uint64_t add = 0; +}; + +struct cw_share +{ + simde__m128i rand{}; + simde__m128i gamma{}; + std::uint8_t bit = 0; +}; + +struct material +{ + std::vector blocks; + std::vector bits; + std::vector b2a; + std::vector cws; +}; + +namespace detail +{ + +inline constexpr std::size_t kappa = 128; +inline constexpr std::size_t chunk_rows = 8192; + +struct point_msg +{ + std::uint8_t enc[33]; +}; + +struct role_state +{ + bool ready = false; + simde__m128i k0[kappa]{}; + simde__m128i k1[kappa]{}; + simde__m128i seed[kappa]{}; + std::uint8_t delta_bits[kappa]{}; + simde__m128i delta{}; + std::uint64_t rows = 0; +}; + +inline simde__m128i xor_block(simde__m128i a, simde__m128i b) +{ + return simde_mm_xor_si128(a, b); +} + +inline std::uint8_t lsb(simde__m128i x) +{ + unsigned char b = 0; + std::memcpy(&b, &x, 1); + return static_cast(b & 1u); +} + +inline simde__m128i bit_block(std::uint8_t bit) +{ + simde__m128i z = simde_mm_setzero_si128(); + const unsigned char b = static_cast(bit & 1u); + std::memcpy(&z, &b, 1); + return z; +} + +inline simde__m128i gate(std::uint8_t bit, simde__m128i block) +{ + return (bit & 1u) ? block : simde_mm_setzero_si128(); +} + +inline std::uint64_t low64(simde__m128i x) +{ + std::uint64_t v = 0; + std::memcpy(&v, &x, sizeof(v)); + return v; +} + +inline simde__m128i ot_hash(std::uint64_t index, simde__m128i row) +{ + const prg::purpose_scope counted(prg::purpose::hash); + const auto mixed = xor_block(row, + simde_mm_set_epi64x(static_cast(index >> 32), + static_cast(index))); + return prg::aes128::eval(mixed, + static_cast(index * 0x9E3779B9u) ^ 0xA5A5u); +} + +inline void sample_scalar(std::uint64_t k[4]) +{ + for (;;) + { + for (int i = 0; i < 4; ++i) + k[i] = dpf::uniform_sample(); + const bool zero = (k[0] | k[1] | k[2] | k[3]) == 0; + if (!zero && p256_detail::limbs_cmp(k, p256_detail::N, 4) < 0) + return; + } +} + +inline simde__m128i hash_point(const p256_detail::affine & p) +{ + std::uint8_t enc[33]{}; + p256_detail::encode_point(enc, p); + simde__m128i b0 = simde_mm_setzero_si128(); + simde__m128i b1 = simde_mm_setzero_si128(); + std::memcpy(&b0, enc, 16); + std::memcpy(&b1, enc + 16, 16); + const simde__m128i b2 = simde_mm_set_epi64x(0, enc[32]); + const prg::purpose_scope counted(prg::purpose::hash); + auto h = prg::aes128::eval(b0, 1); + h = xor_block(h, prg::aes128::eval(b1, 2)); + return xor_block(h, prg::aes128::eval(b2, 3)); +} + +inline simde__m128i pack_bits(const std::uint8_t * bits) +{ + std::uint8_t packed[16]{}; + for (int i = 0; i < static_cast(kappa); ++i) + { + if (bits[i] & 1u) + packed[static_cast(i) >> 3] |= + static_cast(1u << (i & 7)); + } + simde__m128i out = simde_mm_setzero_si128(); + std::memcpy(&out, packed, 16); + return out; +} + +inline void expand_column(simde__m128i seed, std::uint64_t domain, + std::uint8_t * dst, std::size_t nbytes) +{ + const auto tweaked = xor_block(seed, + simde_mm_set_epi64x(static_cast(domain), 0)); + const std::size_t nblocks = (nbytes + 15) / 16; + std::vector buf(nblocks); + if (nblocks > 0) + prg::aes128::eval(tweaked, buf.data(), + static_cast(nblocks), 0); + std::memcpy(dst, buf.data(), nbytes); +} + +/// @brief Transpose a `kappa × nrows` bit matrix packed by columns into rows. +inline void transpose_rows(const std::uint8_t * cols, std::size_t nbytes, + std::size_t nrows, simde__m128i * rows) +{ + // Process 8 row-bits at a time when possible via byte gathers; fall back + // per-row for the tail. Still O(kappa · nrows) but with tight inner loops. + for (std::size_t j = 0; j < nrows; ++j) + { + std::uint8_t packed[16]{}; + const std::size_t byte = j >> 3; + const auto mask = static_cast(1u << (j & 7)); + for (int i = 0; i < static_cast(kappa); ++i) + { + if (cols[static_cast(i) * nbytes + byte] & mask) + packed[static_cast(i) >> 3] |= + static_cast(1u << (i & 7)); + } + std::memcpy(&rows[j], packed, 16); + } +} + +inline void base_sender(net::channel & ch, simde__m128i k0[kappa], + simde__m128i k1[kappa]) +{ + std::uint64_t a[4]; + sample_scalar(a); + const auto A = p256_detail::point_scalarmul_limbs( + p256_detail::generator_point(), a); + point_msg am{}; + p256_detail::encode_point(am.enc, A); + ch.send(net::msg::bytes, am); + const auto bs = ch.recv_vec(net::msg::bytes); + if (bs.size() != kappa) + throw std::runtime_error("iknp base OT count"); + for (std::size_t i = 0; i < kappa; ++i) + { + const auto B = p256_detail::decode_strict(bs[i].enc, 33); + k0[i] = hash_point(p256_detail::point_scalarmul_limbs(B, a)); + k1[i] = hash_point(p256_detail::point_scalarmul_limbs( + p256_detail::point_sub(B, A), a)); + } +} + +inline void base_receiver(net::channel & ch, simde__m128i seed[kappa], + std::uint8_t delta_bits[kappa], simde__m128i & delta) +{ + const auto am = ch.recv(net::msg::bytes); + const auto A = p256_detail::decode_strict(am.enc, 33); + std::vector bs(kappa); + for (std::size_t i = 0; i < kappa; ++i) + { + delta_bits[i] = static_cast( + dpf::uniform_sample() & 1u); + std::uint64_t r[4]; + sample_scalar(r); + const auto R = p256_detail::point_scalarmul_limbs( + p256_detail::generator_point(), r); + const auto B = delta_bits[i] + ? p256_detail::point_add(A, R) : R; + p256_detail::encode_point(bs[i].enc, B); + seed[i] = hash_point(p256_detail::point_scalarmul_limbs(A, r)); + } + delta = pack_bits(delta_bits); + ch.send_vec(bs, net::msg::bytes); +} + +inline void ensure_sender(net::channel & ch, role_state & st) +{ + if (st.ready) + return; + base_receiver(ch, st.seed, st.delta_bits, st.delta); + st.ready = true; +} + +inline void ensure_receiver(net::channel & ch, role_state & st) +{ + if (st.ready) + return; + base_sender(ch, st.k0, st.k1); + st.ready = true; +} + +inline void extend_send(net::channel & ch, role_state & st, std::size_t n, + std::vector & m0, std::vector & m1) +{ + if (n == 0) + return; + ensure_sender(ch, st); + m0.resize(n); + m1.resize(n); + std::size_t off = 0; + while (off < n) + { + const std::size_t rows = std::min(chunk_rows, n - off); + const std::size_t nbytes = (rows + 7) / 8; + const auto u = ch.recv_bytes(net::msg::bytes); + if (u.size() != kappa * nbytes) + throw std::runtime_error("iknp extension length"); + std::vector cols(kappa * nbytes); + for (std::size_t i = 0; i < kappa; ++i) + { + expand_column(st.seed[i], st.rows, cols.data() + i * nbytes, nbytes); + if (st.delta_bits[i]) + { + for (std::size_t b = 0; b < nbytes; ++b) + cols[i * nbytes + b] = static_cast( + cols[i * nbytes + b] ^ u[i * nbytes + b]); + } + } + std::vector q(rows); + transpose_rows(cols.data(), nbytes, rows, q.data()); + for (std::size_t j = 0; j < rows; ++j) + { + const auto index = st.rows + j; + m0[off + j] = ot_hash(index, q[j]); + m1[off + j] = ot_hash(index, xor_block(q[j], st.delta)); + } + st.rows += rows; + off += rows; + } +} + +inline void extend_recv(net::channel & ch, role_state & st, + const std::uint8_t * choices, std::size_t n, + std::vector & masks) +{ + if (n == 0) + return; + ensure_receiver(ch, st); + masks.resize(n); + std::size_t off = 0; + while (off < n) + { + const std::size_t rows = std::min(chunk_rows, n - off); + const std::size_t nbytes = (rows + 7) / 8; + std::vector xbytes(nbytes); + for (std::size_t j = 0; j < rows; ++j) + { + if (choices[off + j] & 1u) + xbytes[j >> 3] = static_cast( + xbytes[j >> 3] | (1u << (j & 7))); + } + std::vector u(kappa * nbytes); + std::vector t0cols(kappa * nbytes); + for (std::size_t i = 0; i < kappa; ++i) + { + std::vector t1(nbytes); + expand_column(st.k0[i], st.rows, t0cols.data() + i * nbytes, nbytes); + expand_column(st.k1[i], st.rows, t1.data(), nbytes); + for (std::size_t b = 0; b < nbytes; ++b) + u[i * nbytes + b] = static_cast( + t0cols[i * nbytes + b] ^ t1[b] ^ xbytes[b]); + } + ch.send_bytes(net::msg::bytes, u.data(), u.size()); + std::vector t(rows); + transpose_rows(t0cols.data(), nbytes, rows, t.data()); + for (std::size_t j = 0; j < rows; ++j) + masks[off + j] = ot_hash(st.rows + j, t[j]); + st.rows += rows; + off += rows; + } +} + +/// @brief Correlated OT correction: sender holds (m0,m1), payload Δ; receiver +/// with choice χ gets m_χ ⊕ (χ·Δ). Parties get additive XOR shares of +/// χ·Δ by taking sender share = m0 and receiver share = got ⊕ m0 path. +/// @details Sender transmits `d = m0⊕m1⊕payload`. Receiver returns +/// `choice ? mask⊕d : mask`. Sender's share is `m0`; receiver's is +/// the returned value. Then `sender⊕receiver = choice·payload` when +/// the OT is correct (`mask = m_choice`). +inline void correct_ot(net::channel & ch, int me, bool i_am_sender, + const std::vector & m0, + const std::vector & m1, + const std::vector & payloads, + const std::vector & masks, + const std::vector & choices, + std::vector & share) +{ + const std::size_t n = i_am_sender ? m0.size() : masks.size(); + share.resize(n); + if (n == 0) + return; + if (i_am_sender) + { + std::vector d(n); + for (std::size_t i = 0; i < n; ++i) + d[i] = xor_block(xor_block(m0[i], m1[i]), payloads[i]); + // Fixed order: party 0 always sends first when it is the sender; + // when party 1 is the sender it sends (party 0 receives). + if (me == 0) + ch.send_vec(d, net::msg::bytes); + else + ch.send_vec(d, net::msg::bytes); + for (std::size_t i = 0; i < n; ++i) + share[i] = m0[i]; + return; + } + auto d = ch.recv_vec(net::msg::bytes); + if (d.size() != n) + throw std::runtime_error("iknp correction length"); + for (std::size_t i = 0; i < n; ++i) + share[i] = (choices[i] & 1u) ? xor_block(masks[i], d[i]) : masks[i]; +} + +} // namespace detail + +/// @brief Sample this party's dealer pads. `me` is 0 or 1. Both parties pass +/// the same lengths and call this before any other traffic on `link`. +HEDLEY_WARN_UNUSED_RESULT +inline material sample(net::channel & link, int me, std::size_t nblock, + std::size_t nbit, std::size_t nb2a, std::size_t ncw) +{ + if (me != 0 && me != 1) + throw std::invalid_argument("iknp party"); + + auto rand_bit = [] { + return static_cast(dpf::uniform_sample() & 1u); + }; + + std::vector block_a(nblock), bit_a(nbit), bit_b(nbit), cw_bit(ncw), b2a_r(nb2a); + std::vector block_b(nblock), cw_rand(ncw); + for (std::size_t i = 0; i < nblock; ++i) + { + block_a[i] = rand_bit(); + block_b[i] = dpf::uniform_sample(); + } + for (std::size_t i = 0; i < nbit; ++i) + { + bit_a[i] = rand_bit(); + bit_b[i] = rand_bit(); + } + for (std::size_t i = 0; i < ncw; ++i) + { + cw_bit[i] = rand_bit(); + cw_rand[i] = dpf::uniform_sample(); + } + for (std::size_t i = 0; i < nb2a; ++i) + b2a_r[i] = rand_bit(); + + // Cross terms via two IKNP directions. Sender holds payload Δ, receiver + // chooses χ; shares sum to χ·Δ. + // D01 (P0 sends): χ=a1 / bit_a1 / cw_bit1, Δ=B0 / bit_b0 / cw_rand0. + // D10 (P1 sends): χ=a0 / bit_a0 / cw_bit0, Δ=B1 / bit_b1 / cw_rand1. + const std::size_t nxor = nblock + nbit + ncw; + + std::vector choices(nxor); + std::vector payloads(nxor); + for (std::size_t i = 0; i < nblock; ++i) + { + choices[i] = block_a[i]; + payloads[i] = block_b[i]; + } + for (std::size_t j = 0; j < nbit; ++j) + { + choices[nblock + j] = bit_a[j]; + payloads[nblock + j] = detail::bit_block(bit_b[j]); + } + for (std::size_t k = 0; k < ncw; ++k) + { + choices[nblock + nbit + k] = cw_bit[k]; + payloads[nblock + nbit + k] = cw_rand[k]; + } + + detail::role_state send_state; // used when we are IKNP sender (produce m0/m1) + detail::role_state recv_state; // used when we are IKNP receiver + std::vector send_m0, send_m1, recv_masks; + + // D01: party 0 sends, party 1 receives. + if (me == 0) + detail::extend_send(link, send_state, nxor, send_m0, send_m1); + else + detail::extend_recv(link, recv_state, choices.data(), nxor, recv_masks); + + std::vector d01_share; + detail::correct_ot(link, me, me == 0, + me == 0 ? send_m0 : std::vector{}, + me == 0 ? send_m1 : std::vector{}, + me == 0 ? payloads : std::vector{}, + me == 0 ? std::vector{} : recv_masks, + me == 0 ? std::vector{} : choices, + d01_share); + // d01_share_0 ⊕ d01_share_1 = χ1 · Δ0 = a1·B0 (etc.) + + // D10: party 1 sends, party 0 receives. + if (me == 0) + detail::extend_recv(link, recv_state, choices.data(), nxor, recv_masks); + else + detail::extend_send(link, send_state, nxor, send_m0, send_m1); + + std::vector d10_share; + detail::correct_ot(link, me, me == 1, + me == 1 ? send_m0 : std::vector{}, + me == 1 ? send_m1 : std::vector{}, + me == 1 ? payloads : std::vector{}, + me == 1 ? std::vector{} : recv_masks, + me == 1 ? std::vector{} : choices, + d10_share); + // d10_share_0 ⊕ d10_share_1 = χ0 · Δ1 = a0·B1 (etc.) + + // Free large OT pads. + send_m0.clear(); + send_m0.shrink_to_fit(); + send_m1.clear(); + send_m1.shrink_to_fit(); + recv_masks.clear(); + recv_masks.shrink_to_fit(); + + // CW gamma shares: gamma0 ⊕ gamma1 = (bit1·rand0) ⊕ (bit0·rand1) + // = (D01 cw) ⊕ (D10 cw). Party 0 samples gamma0 and masks with both of + // its OT shares; party 1 unmasks with both of its shares. + std::vector gamma(ncw); + if (ncw != 0) + { + const std::size_t cw_off = nblock + nbit; + if (me == 0) + { + std::vector msg(ncw); + for (std::size_t k = 0; k < ncw; ++k) + { + gamma[k] = dpf::uniform_sample(); + msg[k] = detail::xor_block(gamma[k], + detail::xor_block(d01_share[cw_off + k], d10_share[cw_off + k])); + } + link.send_vec(msg, net::msg::bytes); + } + else + { + auto msg = link.recv_vec(net::msg::bytes); + if (msg.size() != ncw) + throw std::runtime_error("iknp cw pad length"); + for (std::size_t k = 0; k < ncw; ++k) + gamma[k] = detail::xor_block(msg[k], + detail::xor_block(d01_share[cw_off + k], d10_share[cw_off + k])); + } + } + + // B2A: arithmetic shares of the XOR of the two random bits. + std::vector rho0(nb2a), arith_w(nb2a); + if (nb2a != 0) + { + std::vector bm0, bm1, bmasks; + if (me == 0) + { + detail::extend_send(link, send_state, nb2a, bm0, bm1); + std::vector corr(nb2a); + for (std::size_t i = 0; i < nb2a; ++i) + { + rho0[i] = detail::low64(bm0[i]); + const auto rho1 = detail::low64(bm1[i]); + corr[i] = rho0[i] - rho1 + b2a_r[i]; + } + link.send_vec(corr, net::msg::bytes); + } + else + { + detail::extend_recv(link, recv_state, b2a_r.data(), nb2a, bmasks); + auto corr = link.recv_vec(net::msg::bytes); + if (corr.size() != nb2a) + throw std::runtime_error("iknp b2a length"); + for (std::size_t i = 0; i < nb2a; ++i) + { + const auto rho = detail::low64(bmasks[i]); + arith_w[i] = rho + static_cast(b2a_r[i]) * corr[i]; + } + } + } + + material out; + out.blocks.resize(nblock); + out.bits.resize(nbit); + out.b2a.resize(nb2a); + out.cws.resize(ncw); + for (std::size_t i = 0; i < nblock; ++i) + { + // c0 ⊕ c1 = a0·B0 ⊕ a1·B1 ⊕ a1·B0 ⊕ a0·B1 = (a0⊕a1)·(B0⊕B1) + const auto local = detail::gate(block_a[i], block_b[i]); + // Party 0's share of a1·B0 is d01; of a0·B1 is d10. Same XOR for both + // parties (their XOR shares already sum to the cross terms). + const auto c = detail::xor_block(local, + detail::xor_block(d01_share[i], d10_share[i])); + out.blocks[i] = block_share{block_a[i], block_b[i], c}; + } + for (std::size_t j = 0; j < nbit; ++j) + { + const auto off = nblock + j; + const auto local = static_cast(bit_a[j] & bit_b[j]); + const auto c = static_cast(local + ^ detail::lsb(d01_share[off]) ^ detail::lsb(d10_share[off])); + out.bits[j] = bit_share{bit_a[j], bit_b[j], c}; + } + for (std::size_t k = 0; k < ncw; ++k) + out.cws[k] = cw_share{cw_rand[k], gamma[k], cw_bit[k]}; + for (std::size_t i = 0; i < nb2a; ++i) + { + std::uint64_t add; + if (me == 0) + add = static_cast(b2a_r[i]) + (rho0[i] << 1); + else + add = static_cast(b2a_r[i]) - (arith_w[i] << 1); + out.b2a[i] = b2a_share{b2a_r[i], add}; + } + return out; +} + +/// @brief 1-out-of-2 OT of 128-bit strings. The sender holds `(m0, m1)`. The +/// receiver holds a choice bit per row and receives `m_choice`. +/// @details Chou–Orlandi base OT runs on the first call for this `st`. Later +/// calls only extend. `st` is one direction: the sender's state is +/// not the receiver's state. `n == 0` sends nothing. Both parties +/// pass the same `n`. +/// @param ch peer channel +/// @param me 0 or 1 +/// @param i_am_sender this party holds `m0` and `m1` +/// @param st extension state for this direction +/// @param m0 sender's first message, length `n` (ignored by the receiver) +/// @param m1 sender's second message, length `n` (ignored by the receiver) +/// @param choices receiver's choice bits, length `n` (ignored by the sender) +/// @param got receiver's output `m_choice` (cleared for the sender) +inline void transfer_labels(net::channel & ch, int me, bool i_am_sender, + detail::role_state & st, const std::vector & m0, + const std::vector & m1, + const std::vector & choices, std::vector & got) +{ + if (me != 0 && me != 1) + throw std::invalid_argument("iknp party"); + const std::size_t n = i_am_sender ? m0.size() : choices.size(); + if (i_am_sender) + { + if (m1.size() != n) + throw std::invalid_argument("iknp transfer length"); + } + else if (choices.size() != n) + throw std::invalid_argument("iknp transfer length"); + got.clear(); + if (n == 0) + return; + if (i_am_sender) + { + std::vector r0, r1; + detail::extend_send(ch, st, n, r0, r1); + std::vector corr(2u * n); + for (std::size_t i = 0; i < n; ++i) + { + corr[2u * i] = detail::xor_block(m0[i], r0[i]); + corr[2u * i + 1u] = detail::xor_block(m1[i], r1[i]); + } + ch.send_vec(corr, net::msg::bytes); + return; + } + std::vector masks; + detail::extend_recv(ch, st, choices.data(), n, masks); + const auto corr = ch.recv_vec(net::msg::bytes); + if (corr.size() != 2u * n) + throw std::runtime_error("iknp transfer correction length"); + got.resize(n); + for (std::size_t i = 0; i < n; ++i) + { + const std::size_t slot = 2u * i + static_cast(choices[i] & 1u); + got[i] = detail::xor_block(masks[i], corr[slot]); + } +} + +/// @brief Channel rounds inside `sample` (base OT, extension chunks, corrections). +/// @details Two directions when `nblock+nbit+ncw > 0`: each is a 2-message +/// Chou–Orlandi base, one U-matrix per `chunk_rows`, and one +/// correction. CW gamma is one more round. B2A reuses the base OT +/// and adds an extension plus a correction. Add this to +/// `plan::rounds()` via `rounds_including`. +HEDLEY_WARN_UNUSED_RESULT +HEDLEY_PURE +inline std::size_t setup_rounds(std::size_t nblock, std::size_t nbit, + std::size_t nb2a, std::size_t ncw) noexcept +{ + const auto chunks = [](std::size_t n) { + return n == 0 ? std::size_t{0} + : (n + detail::chunk_rows - 1) / detail::chunk_rows; + }; + const std::size_t nxor = nblock + nbit + ncw; + std::size_t rounds = 0; + if (nxor != 0) + { + rounds += 2 + chunks(nxor) + 1; + rounds += 2 + chunks(nxor) + 1; + } + if (ncw != 0) + ++rounds; + if (nb2a != 0) + rounds += chunks(nb2a) + 1; + return rounds; +} + +} // namespace iknp +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_IKNP_HPP__ diff --git a/include/dpf/iknp_graphs.hpp b/include/dpf/iknp_graphs.hpp new file mode 100644 index 0000000..d4afae0 --- /dev/null +++ b/include/dpf/iknp_graphs.hpp @@ -0,0 +1,32 @@ +/// @file dpf/iknp_graphs.hpp +/// @brief IKNP setup as `schedule_round` lists (pulls Asio; keep out of app_plans). +#ifndef LIBDPF_INCLUDE_DPF_IKNP_GRAPHS_HPP__ +#define LIBDPF_INCLUDE_DPF_IKNP_GRAPHS_HPP__ + +#include +#include +#include +#include + +#include "dpf/iknp.hpp" +#include "dpf/pad_graphs.hpp" +#include "dpf/protocol.hpp" + +namespace dpf +{ +namespace protocol +{ + +/// @brief IKNP `sample` wire frames as schedule rounds (count from setup_rounds). +inline std::vector iknp_setup_graph(std::size_t nblock, + std::size_t nbit, std::size_t nb2a, std::size_t ncw, + const std::shared_ptr> & tape) +{ + return make_pad_rounds(iknp::setup_rounds(nblock, nbit, nb2a, ncw), 16, tape, + edge_channel::peer); +} + +} // namespace protocol +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_IKNP_GRAPHS_HPP__ diff --git a/include/dpf/incremental.hpp b/include/dpf/incremental.hpp index 30c5d65..19a39fc 100644 --- a/include/dpf/incremental.hpp +++ b/include/dpf/incremental.hpp @@ -38,6 +38,7 @@ #include "dpf/subsequence_iterable.hpp" #include "dpf/dcf.hpp" #include "dpf/blocked_dcf.hpp" +#include "dpf/random.hpp" namespace dpf { @@ -57,6 +58,108 @@ template inline constexpr bool args_have_extractable_v = (is_extractable_tag_v> || ...); +template +inline constexpr bool args_have_updatable_v = + (is_updatable_tag_v> || ...); + +/// @brief Out-parameter tag for `make_dpf`: record ring shares of a bit leaf's +/// sign. `w0 - w1` is `+1` or `-1`, the sign the papers read off `Gen`'s +/// final control bit. A 1-bit leaf lifts to a ring unit by multiplying +/// its lifted bit share by this sign; Duoram's flag and Pika's +/// early-stop leaf need it without a second (word-payload) tree. +/// @details Absent the tag, keygen is unchanged. The tag holds references to +/// two caller-owned ints, filled after the key is built. +struct unit_sign +{ + int & w0; + int & w1; +}; + +template +struct is_unit_sign : std::false_type {}; +template <> +struct is_unit_sign : std::true_type {}; + +template +inline constexpr bool args_have_unit_sign_v = + (is_unit_sign>::value || ...); + +namespace detail +{ +namespace incr +{ + +/// @brief Address of the (single) `unit_sign` out-parameter among `args`. +template +HEDLEY_NO_THROW +unit_sign * find_unit_sign(Args & ...args) noexcept +{ + unit_sign * p = nullptr; + ((void)([&] { + if constexpr (is_unit_sign>::value) + p = &args; + }()), ...); + return p; +} + +/// @brief Drop `unit_sign` args; keep the rest as a forwarding tuple. +template +HEDLEY_ALWAYS_INLINE +decltype(auto) drop_unit_sign(T && t) +{ + if constexpr (is_unit_sign>::value) + return std::tuple<>{}; + else + return std::forward_as_tuple(std::forward(t)); +} + +/// @brief Fill `us` with each party's lifted bit share at `x`. `w0 - w1` is the +/// `±1` unit sign. Uses ADL `eval_point` (resolved at instantiation). +template +void fill_unit_sign(const K0 & k0, const K1 & k1, const InputT & x, unit_sign us) +{ + us.w0 = static_cast(static_cast((*eval_point(k0, x)).raw())); + us.w1 = static_cast(static_cast((*eval_point(k1, x)).raw())); +} + +} // namespace incr +} // namespace detail + +template +inline constexpr bool args_have_output_mac_v = + (is_output_mac_tag_v> || ...); + +template +struct arg_has_bit_payload : std::bool_constant< + std::is_same_v>, dpf::bit>> +{ }; + +template +struct arg_has_bit_payload> || is_eq_spec_v>>> + : std::bool_constant::beta_type>, dpf::bit>> +{ }; + +template +struct arg_has_bit_payload, void> + : std::bool_constant<(std::is_same_v, dpf::bit> || ... + || std::is_same_v, dpf::bit>)> +{ }; + +template +struct arg_has_bit_payload> + || is_extractable_tag_v> + || is_updatable_tag_v> + || is_output_mac_tag_v>>> + : std::false_type +{ }; + +template +inline constexpr bool args_have_bit_payload_v = + (arg_has_bit_payload>::value || ...); + template inline constexpr bool args_have_eq_v = (is_eq_spec_v> || ...); @@ -167,6 +270,11 @@ struct dcf_runtime_spec detail::group_elem false_g{}; cmp_kind kind = cmp_kind::lt; bool is_wildcard = false; // payload assigned after keygen (δ unknown now) + /// @brief Payload group is `from_seed` / `+` / unary `-`, not the limb ring. + bool use_payload_group = false; + detail::payload_ops payload{}; + alignas(16) unsigned char payload_beta[detail::payload_ops::cap]{}; + alignas(16) unsigned char payload_false[detail::payload_ops::cap]{}; std::size_t length_bits = 0; bool incremental = false; std::function paint; @@ -199,7 +307,8 @@ auto flatten_one(Arg && arg) { return std::tuple<>{}; } - else if constexpr (is_verifiable_tag_v || is_extractable_tag_v) + else if constexpr (is_verifiable_tag_v || is_extractable_tag_v + || is_updatable_tag_v || is_output_mac_tag_v) { return std::tuple<>{}; } @@ -213,7 +322,8 @@ auto flatten_one(Arg && arg) static_assert(pref <= BitLen, "eq_at exceeds input bitlength"); using Beta = typename A::beta_type; Beta delta = detail::dcf_impl::sub_beta(arg.if_true, arg.if_false); - return std::make_tuple(placed{std::move(delta), arg.if_false}); + return std::make_tuple( + placed{std::move(delta), arg.if_false}); } else if constexpr (is_at_v) { @@ -251,6 +361,21 @@ void collect_cmp_one(dcf_runtime_spec & spec, bool & found, Arg && arg) spec.paint = arg.fn; using Beta = typename A::beta_type; using Concrete = dpf::concrete_type_t; + if constexpr (detail::has_from_seed::value) + { + spec.use_payload_group = true; + spec.payload = detail::make_payload_ops(); + if constexpr (dpf::is_wildcard_v) + { + spec.is_wildcard = true; + } + else + { + const Concrete delta = arg.if_true - arg.if_false; + std::memcpy(spec.payload_beta, &delta, sizeof(delta)); + std::memcpy(spec.payload_false, &arg.if_false, sizeof(arg.if_false)); + } + } constexpr auto bits = [] { if constexpr (std::is_same_v) return std::size_t{1}; @@ -258,6 +383,8 @@ void collect_cmp_one(dcf_runtime_spec & spec, bool & found, Arg && arg) return utils::bitlength_of_v; }(); spec.mask = detail::dcf_impl::default_mask_for_bits(bits); + if constexpr (!detail::has_from_seed::value) + { if constexpr (detail::cmp_group_info::custom) { spec.custom = true; @@ -294,6 +421,7 @@ void collect_cmp_one(dcf_runtime_spec & spec, bool & found, Arg && arg) spec.false_value = detail::dcf_impl::beta_to_u64_simple( arg.if_false, spec.mask); } + } } } @@ -321,9 +449,16 @@ constexpr bool classic_pack_impl(std::index_sequence) { using first = std::tuple_element_t<0, PlacedTuple>; constexpr auto w0 = out_bits_v; - return ((std::tuple_element_t::prefix == BitLen) && ...) - && ((out_bits_v::output_type> == w0) && ...); + // Wildcards need the incremental leaf/beaver path; classic DS rejects them. + constexpr bool any_wild = (dpf::is_wildcard_v< + typename std::tuple_element_t::output_type> || ...); + if constexpr (any_wild) + return false; + else + return ((std::tuple_element_t::prefix == BitLen) && ...) + && ((out_bits_v::output_type> == + w0) && ...); } template @@ -400,10 +535,11 @@ using group_outputs_t = std::tuple< template + std::size_t LocalI, std::size_t GlobalI, std::size_t... AllGlobals, + typename InputT> void overwrite_arith_slot_one(CwProtocol & proto, const SeedT & s0, const SeedT & s1, uint8_t t0, uint8_t t1, std::size_t pos_base, - std::size_t lane, PlacedTuple & placed, Leaves0T & leaves0, + InputT x0, InputT x1, PlacedTuple & placed, Leaves0T & leaves0, Leaves1T & leaves1, std::index_sequence) { using P = std::tuple_element_t; @@ -412,7 +548,7 @@ void overwrite_arith_slot_one(CwProtocol & proto, const SeedT & s0, using outs = group_outputs_t; auto & slot = std::get(placed); auto cw = proto.template open_arith_leaf( - s0, s1, t0, t1, slot.value.y0, slot.value.y1, pos_base, lane); + s0, s1, t0, t1, slot.value.y0, slot.value.y1, pos_base, x0, x1); std::get(leaves0) = cw; std::get(leaves1) = cw; } @@ -420,16 +556,16 @@ void overwrite_arith_slot_one(CwProtocol & proto, const SeedT & s0, template + std::size_t... GlobalIs, std::size_t... LocalIs, typename InputT> void overwrite_arith_slots(CwProtocol & proto, const SeedT & s0, const SeedT & s1, uint8_t t0, uint8_t t1, std::size_t pos_base, - std::size_t lane, PlacedTuple & placed, Leaves0T & leaves0, + InputT x0, InputT x1, PlacedTuple & placed, Leaves0T & leaves0, Leaves1T & leaves1, std::index_sequence, std::index_sequence) { (overwrite_arith_slot_one(proto, s0, s1, t0, t1, - pos_base, lane, placed, leaves0, leaves1, + pos_base, x0, x1, placed, leaves0, leaves1, std::index_sequence{}), ...); } @@ -477,7 +613,8 @@ template ; constexpr std::size_t bitlen = utils::bitlength_of_v; @@ -509,17 +646,31 @@ void gen_group(InputT x, const typename InteriorPRG::block_type & s0, { if (proto != nullptr) { - constexpr auto to_int = utils::to_integral_type{}; - const std::size_t lane = static_cast(to_int(lane_x)); - overwrite_arith_slots( - *proto, s0, s1, t0, t1, pos_base, lane, placed, leaves0, - leaves1, idxs{}, std::make_index_sequence{}); + if (x0_share != nullptr && x1_share != nullptr) + { + const InputT l0 = lane_input(*x0_share, prefix, bitlen); + const InputT l1 = lane_input(*x1_share, prefix, bitlen); + overwrite_arith_slots( + *proto, s0, s1, t0, t1, pos_base, l0, l1, placed, leaves0, + leaves1, idxs{}, std::make_index_sequence{}); + } + else + { + // Clear lane as a trivial XOR sharing (lane ⊕ 0). + const InputT zero{}; + overwrite_arith_slots( + *proto, s0, s1, t0, t1, pos_base, lane_x, zero, placed, + leaves0, leaves1, idxs{}, + std::make_index_sequence{}); + } } } else { (void)t1; (void)proto; + (void)x0_share; + (void)x1_share; static_assert(!placed_has_arith_beta_impl(idxs{}), "arith_beta payloads require Doerner–Shelat gen (CwProtocol)"); } @@ -579,6 +730,12 @@ namespace detail namespace incr { +template +constexpr bool extractable_pack_ok(std::index_sequence) noexcept +{ + return (extractable_codomain_ok_v< + typename Key::template concrete_output_type> && ...); +} /// @brief Map kind → flags. Tree keep-path stays on α; leq/gt plant δ on that path /// via `include_eq`. Domain-edge α yields trivial always-true/false. @@ -618,6 +775,8 @@ inline void adjust_cmp_threshold(detail::cmp_meta & ch, if (nbits < 128 && thresh == domain) ch.trivial = cmp_trivial::always_false; break; + default: + break; } if (ch.incremental) ch.trivial = cmp_trivial::none; @@ -689,11 +848,9 @@ auto make_incremental_impl(InputT x, PlacedTuple placed, if constexpr (IsExtractable) { static_assert(n > 0, "extractable requires at least one output"); - [](std::index_sequence) { - static_assert((extractable_codomain_ok_v< - typename key_type::template concrete_output_type> && ...), - "extractable: each output must be fp61 or >= 128 bits"); - }(std::make_index_sequence{}); + static_assert(extractable_pack_ok( + std::make_index_sequence{}), + "extractable: each output must embed injectively into fp61"); } utils::flip_msb_if_signed_integral(x); @@ -773,9 +930,13 @@ HEDLEY_PRAGMA(GCC diagnostic pop) if (cmp_spec->custom && (CmpBlock > 0 || is_paint_kind(cmp.kind))) throw std::invalid_argument( "this comparison payload uses the per-level channel"); + if (cmp_spec->use_payload_group && (CmpBlock > 0 || is_paint_kind(cmp.kind))) + throw std::invalid_argument( + "this comparison payload uses the per-level channel"); } const bool custom_cmp = cmp_spec != nullptr && cmp_spec->custom; + const bool payload_cmp = cmp_spec != nullptr && cmp_spec->use_payload_group; detail::group_elem g_delta = custom_cmp ? cmp_spec->beta_g : detail::group_elem{}; detail::group_elem g_false = custom_cmp @@ -792,6 +953,11 @@ HEDLEY_PRAGMA(GCC diagnostic pop) } typename key_type::value_cw_word g_last{}; typename key_type::value_cw_word g_last_coeff{}; + unsigned char pva[detail::payload_ops::cap]{}; + std::int64_t pva_c = 0; + typename key_type::value_cw_word p_last{}; + typename key_type::value_cw_word p_last_coeff{}; + const detail::payload_ops * pops = payload_cmp ? &cmp_spec->payload : nullptr; const paint_callback paint_cb = (cmp_spec != nullptr && cmp_spec->paint) @@ -816,22 +982,48 @@ HEDLEY_PRAGMA(GCC diagnostic pop) { if (!cmp.incremental || cmp.trivial != cmp_trivial::none) return; - const uint64_t word = detail::dcf_impl::make_final_cw(parent[0], - parent[1], static_cast(dpf::get_lo_bit(parent[1])), - Va, cmp.mask, on_path); - prefix_cw[at] = static_cast(word); - if constexpr (CmpWild) + if (payload_cmp) { - const uint64_t w1 = detail::dcf_impl::make_final_cw(parent[0], + unsigned char outb[detail::payload_ops::cap]{}; + std::int64_t coeff = 0; + const bool wild = cmp_spec->is_wildcard; + const bool plant = cmp.include_eq && !is_paint_kind(cmp.kind); + detail::payload_final_cw(*pops, &parent[0], &parent[1], + sizeof(parent[0]), + static_cast(dpf::get_lo_bit(parent[1])), + pva, pva_c, + (!wild && plant) ? cmp_spec->payload_beta : nullptr, + plant && wild ? 1 : 0, + outb, wild ? &coeff : nullptr); + prefix_cw[at] = detail::payload_to_word< + typename key_type::value_cw_word>(outb, pops->size); + if constexpr (CmpWild) + { + if (wild) + prefix_coeff[at] = detail::payload_coeff_word< + typename key_type::value_cw_word>(coeff); + } + return; + } + if constexpr (std::is_integral_v) + { + const uint64_t word = detail::dcf_impl::make_final_cw(parent[0], parent[1], static_cast(dpf::get_lo_bit(parent[1])), - Va1, cmp.mask, on_path_unit); - prefix_coeff[at] = static_cast( - (w1 + detail::dcf_impl::neg_m(word, cmp.mask)) & cmp.mask); + Va, cmp.mask, on_path); + prefix_cw[at] = static_cast(word); + if constexpr (CmpWild) + { + const uint64_t w1 = detail::dcf_impl::make_final_cw(parent[0], + parent[1], static_cast(dpf::get_lo_bit(parent[1])), + Va1, cmp.mask, on_path_unit); + prefix_coeff[at] = static_cast( + (w1 + detail::dcf_impl::neg_m(word, cmp.mask)) & cmp.mask); + } } } }; auto snap_prefix_group = [&](std::size_t at) { - if constexpr (CmpIdcf) + if constexpr (CmpIdcf && std::is_integral_v) { if (!cmp.incremental || cmp.trivial != cmp_trivial::none) return; @@ -888,14 +1080,46 @@ HEDLEY_PRAGMA(GCC diagnostic pop) const auto prefix = static_cast( utils::to_integral_type{}(x) >> (utils::bitlength_of_v - (level + 1))); - correction_seeds[level] = detail::vdpf::make_cs(level, prefix, - parent[0], parent[1]); + if constexpr (CmpBlock > 0) + { + correction_seeds[level] = detail::vdpf::make_cs( + detail::blocked::fold_spine_tag | level, prefix, + parent[0], parent[1]); + } + else + { + correction_seeds[level] = detail::vdpf::make_cs(level, prefix, + parent[0], parent[1]); + } } if constexpr (CmpBlock == 0) { if (cmp.active && cmp.trivial == cmp_trivial::none - && level < cmp_nbits && !custom_cmp) + && level < cmp_nbits && payload_cmp) + { + const int ai = static_cast( + (thresh >> (cmp_nbits - 1 - level)) & 1); + unsigned char vcw[detail::payload_ops::cap]{}; + std::int64_t coeff = 0; + const bool wild = cmp_spec->is_wildcard; + detail::payload_value_cw(*pops, &val0[0], &val0[1], &val1[0], &val1[1], + sizeof(val0[0]), static_cast(advice1), ai, + pva, pva_c, wild ? nullptr : cmp_spec->payload_beta, + vcw, wild ? &coeff : nullptr); + value_cws[level] = detail::payload_to_word( + vcw, pops->size); + if constexpr (CmpWild) + { + if (wild) + value_cw_coeff[level] = + detail::payload_coeff_word(coeff); + } + snap_prefix(level + 1); + } + else if constexpr (std::is_integral_v) + if (cmp.active && cmp.trivial == cmp_trivial::none + && level < cmp_nbits && !custom_cmp && !payload_cmp) { const int ai = static_cast( (thresh >> (cmp_nbits - 1 - level)) & 1); @@ -1023,7 +1247,29 @@ HEDLEY_PRAGMA(GCC diagnostic pop) if constexpr (CmpBlock == 0) { if (cmp.active && cmp.trivial == cmp_trivial::none - && level + 1 == cmp_nbits && !custom_cmp) + && level + 1 == cmp_nbits && payload_cmp) + { + unsigned char outb[detail::payload_ops::cap]{}; + std::int64_t coeff = 0; + const bool wild = cmp_spec->is_wildcard; + const bool plant = cmp.include_eq && !is_paint_kind(cmp.kind); + detail::payload_final_cw(*pops, &parent[0], &parent[1], sizeof(parent[0]), + static_cast(dpf::get_lo_bit(parent[1])), pva, pva_c, + (!wild && plant) ? cmp_spec->payload_beta : nullptr, + (!wild && plant) ? 0 : (plant ? 1 : 0), + outb, wild ? &coeff : nullptr); + p_last = detail::payload_to_word( + outb, pops->size); + if constexpr (CmpWild) + { + if (wild) + p_last_coeff = + detail::payload_coeff_word(coeff); + } + } + else if constexpr (std::is_integral_v) + if (cmp.active && cmp.trivial == cmp_trivial::none + && level + 1 == cmp_nbits && !custom_cmp && !payload_cmp) { cw_last = make_final_cw(parent[0], parent[1], static_cast(dpf::get_lo_bit(parent[1])), Va, cmp.mask, @@ -1109,7 +1355,26 @@ HEDLEY_PRAGMA(GCC diagnostic pop) uint64_t cmp_add0 = 0, cmp_add1 = 0; typename key_type::value_cw_word g_add0{}; typename key_type::value_cw_word g_add1{}; - if (cmp.active && !custom_cmp) + if (cmp.active && payload_cmp) + { + unsigned char target[detail::payload_ops::cap]{}; + detail::payload_copy(target, cmp_spec->payload_false, pops->size); + if (cmp.trivial == cmp_trivial::always_true || cmp.eval_as_ge) + pops->add(target, target, cmp_spec->payload_beta); + unsigned char blind[detail::payload_ops::cap]{}; + const auto seed = root_sampler(); + pops->from_node(blind, &seed, sizeof(seed)); + unsigned char neg_blind[detail::payload_ops::cap]{}; + unsigned char other[detail::payload_ops::cap]{}; + pops->neg(neg_blind, blind); + pops->add(other, target, neg_blind); + g_add0 = detail::payload_to_word( + blind, pops->size); + g_add1 = detail::payload_to_word( + other, pops->size); + } + else if constexpr (std::is_integral_v) + if (cmp.active && !custom_cmp && !payload_cmp) { uint64_t target = false_value; if (cmp.trivial == cmp_trivial::always_true) @@ -1151,6 +1416,11 @@ HEDLEY_PRAGMA(GCC diagnostic pop) key0.set_cmp_scalars(g_last, g_add0, g_last_coeff); key1.set_cmp_scalars(g_last, g_add1, g_last_coeff); } + if (payload_cmp) + { + key0.set_cmp_scalars(p_last, g_add0, p_last_coeff); + key1.set_cmp_scalars(p_last, g_add1, p_last_coeff); + } return dpf::make_party_key_pair(std::move(key0), std::move(key1)); } @@ -1235,11 +1505,8 @@ HEDLEY_PRAGMA(GCC diagnostic pop) uint64_t false_value = 0; if (cmp_spec != nullptr) { - // The comparison channel is a dealer-equivalent computation: in this - // local joint simulation the threshold lane comes from the two shares. - // (The *leaf* phase does not reconstruct `x` at this call site — it is - // handed to `proto.open_leaf_group` below.) - const input_type cmp_x = utils::xor_input_shares(x0, x1); + // Threshold lane is opened only inside the CW protocol (paint / + // domain-edge / blocked suffix). Value-word ai uses share bits. const std::size_t cmp_nbits = cmp_spec->prefix ? cmp_spec->prefix : utils::bitlength_of_v; cmp.nbits = static_cast(cmp_nbits); @@ -1253,10 +1520,8 @@ HEDLEY_PRAGMA(GCC diagnostic pop) cmp.trivial = cmp_trivial::none; cmp.block_width = static_cast(CmpBlock); cmp.tail_bits = static_cast(key_type::cmp_q); - auto lane = lane_input(cmp_x, cmp_nbits, - utils::bitlength_of_v); - unsigned __int128 thresh = static_cast( - utils::to_integral_type{}(lane)); + unsigned __int128 thresh = + proto.open_cmp_threshold(x0, x1, cmp_nbits); adjust_cmp_threshold(cmp, thresh, cmp_nbits); if (CmpBlock > 0 && is_paint_kind(cmp.kind)) throw std::invalid_argument( @@ -1264,6 +1529,9 @@ HEDLEY_PRAGMA(GCC diagnostic pop) if (cmp_spec->custom && (CmpBlock > 0 || is_paint_kind(cmp.kind))) throw std::invalid_argument( "this comparison payload uses the per-level channel"); + if (cmp_spec->use_payload_group && (CmpBlock > 0 || is_paint_kind(cmp.kind))) + throw std::invalid_argument( + "this comparison payload uses the per-level channel"); cmp_st.active = cmp.active; cmp_st.nbits = cmp_nbits; cmp_st.mask = cmp.mask; @@ -1287,6 +1555,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) } const bool custom_cmp = cmp_spec != nullptr && cmp_spec->custom; + const bool payload_cmp = cmp_spec != nullptr && cmp_spec->use_payload_group; detail::group_elem g_delta = custom_cmp ? cmp_spec->beta_g : detail::group_elem{}; detail::group_elem g_false = custom_cmp @@ -1303,6 +1572,11 @@ HEDLEY_PRAGMA(GCC diagnostic pop) } typename key_type::value_cw_word g_last{}; typename key_type::value_cw_word g_last_coeff{}; + unsigned char pva[detail::payload_ops::cap]{}; + std::int64_t pva_c = 0; + typename key_type::value_cw_word p_last{}; + typename key_type::value_cw_word p_last_coeff{}; + const detail::payload_ops * pops = payload_cmp ? &cmp_spec->payload : nullptr; typename key_type::prefix_cw_array prefix_cw{}; typename key_type::prefix_cw_array prefix_coeff{}; @@ -1327,20 +1601,46 @@ HEDLEY_PRAGMA(GCC diagnostic pop) { if (!cmp.incremental || cmp.trivial != cmp_trivial::none) return; - HEDLEY_PRAGMA(GCC diagnostic push) - HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") - const uint64_t word = proto.open_final_cw(st.seed0(), st.seed1(), - static_cast(dpf::get_lo_bit(st.seed1())), cmp_st.Va, - cmp.mask, on_path); - HEDLEY_PRAGMA(GCC diagnostic pop) - prefix_cw[at] = static_cast(word); - if constexpr (CmpWild) + if (payload_cmp) { - const uint64_t w1 = proto.open_final_cw(st.seed0(), st.seed1(), - static_cast(dpf::get_lo_bit(st.seed1())), - cmp_st.Va1, cmp.mask, on_path_unit); - prefix_coeff[at] = static_cast( - (w1 + neg_m(word, cmp.mask)) & cmp.mask); + unsigned char outb[detail::payload_ops::cap]{}; + std::int64_t coeff = 0; + const bool wild = cmp_spec->is_wildcard; + const bool plant = cmp.include_eq && !is_paint_kind(cmp.kind); + auto s0 = st.seed0(); + auto s1 = st.seed1(); + detail::payload_final_cw(*pops, &s0, &s1, sizeof(s0), + static_cast(dpf::get_lo_bit(s1)), pva, pva_c, + (!wild && plant) ? cmp_spec->payload_beta : nullptr, + plant && wild ? 1 : 0, + outb, wild ? &coeff : nullptr); + prefix_cw[at] = detail::payload_to_word< + typename key_type::value_cw_word>(outb, pops->size); + if constexpr (CmpWild) + { + if (wild) + prefix_coeff[at] = detail::payload_coeff_word< + typename key_type::value_cw_word>(coeff); + } + return; + } + if constexpr (std::is_integral_v) + { + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + const uint64_t word = proto.open_final_cw(st.seed0(), st.seed1(), + static_cast(dpf::get_lo_bit(st.seed1())), cmp_st.Va, + cmp.mask, on_path); + HEDLEY_PRAGMA(GCC diagnostic pop) + prefix_cw[at] = static_cast(word); + if constexpr (CmpWild) + { + const uint64_t w1 = proto.open_final_cw(st.seed0(), st.seed1(), + static_cast(dpf::get_lo_bit(st.seed1())), + cmp_st.Va1, cmp.mask, on_path_unit); + prefix_coeff[at] = static_cast( + (w1 + neg_m(word, cmp.mask)) & cmp.mask); + } } } }; @@ -1375,11 +1675,21 @@ HEDLEY_PRAGMA(GCC diagnostic pop) } auto mask = key_type::msb_mask; + constexpr auto to_int_x = utils::to_integral_type{}; + using mask_type = std::decay_t; + constexpr auto to_mask = utils::to_integral_type{}; for (std::size_t level = 0; level < depth; ++level, mask >>= 1) { uint64_t vcw = 0; + const auto mi = to_mask(mask); + const uint8_t path_bit0 = + static_cast(!!(mi & to_int_x(x0))); + const uint8_t path_bit1 = + static_cast(!!(mi & to_int_x(x1))); + const int path_ai = static_cast((path_bit0 ^ path_bit1) & 1u); if constexpr (CmpBlock == 0) { + if constexpr (std::is_integral_v) if (custom_cmp && cmp_st.active && cmp_st.trivial == cmp_trivial::none && level < cmp_st.nbits) { @@ -1390,8 +1700,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) const auto a1 = static_cast(dpf::get_lo_bit(s1)); auto v0 = tree::expand_value(s0); auto v1 = tree::expand_value(s1); - const int ai = static_cast( - (cmp_st.thresh >> (cmp_st.nbits - 1 - level)) & 1); + const int ai = path_ai; const auto base = detail::group_value_cw(v0[0], v0[1], v1[0], v1[1], a0, a1, ai, g_va, g_delta); value_cws[level] = @@ -1405,21 +1714,44 @@ HEDLEY_PRAGMA(GCC diagnostic pop) detail::group_sub(v1w, base)); } } + if (payload_cmp && cmp_st.active && cmp_st.trivial == cmp_trivial::none + && level < cmp_st.nbits) + { + using tree = dpf::tree_traits; + auto s0 = st.seed0(); + auto s1 = st.seed1(); + const auto a1 = static_cast(dpf::get_lo_bit(s1)); + auto v0 = tree::expand_value(s0); + auto v1 = tree::expand_value(s1); + const int ai = path_ai; + unsigned char vcw_b[detail::payload_ops::cap]{}; + std::int64_t coeff = 0; + const bool wild = cmp_spec->is_wildcard; + detail::payload_value_cw(*pops, &v0[0], &v0[1], &v1[0], &v1[1], + sizeof(v0[0]), a1, ai, pva, pva_c, + wild ? nullptr : cmp_spec->payload_beta, vcw_b, + wild ? &coeff : nullptr); + value_cws[level] = detail::payload_to_word< + typename key_type::value_cw_word>(vcw_b, pops->size); + if constexpr (CmpWild) + { + if (wild) + value_cw_coeff[level] = detail::payload_coeff_word< + typename key_type::value_cw_word>(coeff); + } + } ds_advance_level(st, x0, x1, mask, level, depth, proto, correction_words[level], correction_advice[level], - (!custom_cmp && cmp_st.active) ? &vcw : nullptr, - (!custom_cmp && cmp_st.active) ? &cmp_st : nullptr); + (!custom_cmp && !payload_cmp && cmp_st.active) ? &vcw : nullptr, + (!custom_cmp && !payload_cmp && cmp_st.active) ? &cmp_st : nullptr); if constexpr (IsVerifiable) { - const auto prefix = static_cast( - utils::to_integral_type{}( - utils::xor_input_shares(x0, x1)) - >> (utils::bitlength_of_v - (level + 1))); - correction_seeds[level] = detail::vdpf::make_cs(level, prefix, - st.seed0(), st.seed1()); + correction_seeds[level] = proto.open_correction_seed(level, x0, + x1, level + 1, st.seed0(), st.seed1()); } - if (!custom_cmp && cmp_st.active && cmp_st.trivial == cmp_trivial::none - && level < cmp_st.nbits) + if constexpr (std::is_integral_v) + if (!custom_cmp && !payload_cmp && cmp_st.active + && cmp_st.trivial == cmp_trivial::none && level < cmp_st.nbits) { value_cws[level] = static_cast(vcw); @@ -1443,12 +1775,10 @@ HEDLEY_PRAGMA(GCC diagnostic pop) correction_words[level], correction_advice[level]); if constexpr (IsVerifiable) { - const auto prefix = static_cast( - utils::to_integral_type{}( - utils::xor_input_shares(x0, x1)) - >> (utils::bitlength_of_v - (level + 1))); - correction_seeds[level] = detail::vdpf::make_cs(level, prefix, - st.seed0(), st.seed1()); + // Domain-separate blocked CS from native per-level folds. + correction_seeds[level] = proto.open_correction_seed( + detail::blocked::fold_spine_tag | level, x0, x1, + level + 1, st.seed0(), st.seed1()); } if (cmp_st.active && cmp_st.trivial == cmp_trivial::none) { @@ -1504,7 +1834,31 @@ HEDLEY_PRAGMA(GCC diagnostic pop) if constexpr (CmpBlock == 0) { if (cmp_st.active && cmp_st.trivial == cmp_trivial::none - && level + 1 == cmp_st.nbits && !custom_cmp) + && level + 1 == cmp_st.nbits && payload_cmp) + { + unsigned char outb[detail::payload_ops::cap]{}; + std::int64_t coeff = 0; + const bool wild = cmp_spec->is_wildcard; + const bool plant = cmp.include_eq && !is_paint_kind(cmp.kind); + auto s0 = st.seed0(); + auto s1 = st.seed1(); + detail::payload_final_cw(*pops, &s0, &s1, sizeof(s0), + static_cast(dpf::get_lo_bit(s1)), pva, pva_c, + (!wild && plant) ? cmp_spec->payload_beta : nullptr, + plant && wild ? 1 : 0, + outb, wild ? &coeff : nullptr); + p_last = detail::payload_to_word( + outb, pops->size); + if constexpr (CmpWild) + { + if (wild) + p_last_coeff = detail::payload_coeff_word< + typename key_type::value_cw_word>(coeff); + } + } + else if constexpr (std::is_integral_v) + if (cmp_st.active && cmp_st.trivial == cmp_trivial::none + && level + 1 == cmp_st.nbits && !custom_cmp && !payload_cmp) { cw_last = proto.open_final_cw(st.seed0(), st.seed1(), static_cast(dpf::get_lo_bit(st.seed1())), cmp_st.Va, @@ -1555,12 +1909,12 @@ HEDLEY_PRAGMA(GCC diagnostic pop) constexpr auto order = build_group_order(key_type::meta, n); - // Leaf phase: hand both point shares to the protocol. In the local joint - // simulation `open_leaf_group` reconstructs `x` internally and runs - // `make_leaves` per group via this closure; the gen body never forms `x`. + // Leaf phase: hand both point shares to the protocol. Reconstruct only + // inside this hook to emit public leaf CWs; the gen body never forms `x`. using leaf_prg = std::conditional_t, ExteriorPRG>; - proto.open_leaf_group(x0, x1, [&](input_type x) { + proto.open_leaf_group(x0, x1, [&](input_type sx0, input_type sx1) { + const input_type x = utils::xor_input_shares(sx0, sx1); for_each_index(std::make_index_sequence{}, [&](auto oi) { constexpr std::size_t G = order[decltype(oi)::value]; constexpr std::size_t lvl = [] { @@ -1578,7 +1932,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) dpf::unset_lo_2bits(snap1[lvl]), static_cast(snap_sign[lvl]), static_cast(dpf::get_lo_bit(snap1[lvl])), placed, - leaves0, beavers0, leaves1, beavers1, &proto); + leaves0, beavers0, leaves1, beavers1, &proto, &sx0, &sx1); HEDLEY_PRAGMA(GCC diagnostic pop) }); }); @@ -1591,7 +1945,26 @@ HEDLEY_PRAGMA(GCC diagnostic pop) uint64_t cmp_add0 = 0, cmp_add1 = 0; typename key_type::value_cw_word g_add0{}; typename key_type::value_cw_word g_add1{}; - if (cmp.active && !custom_cmp) + if (cmp.active && payload_cmp) + { + unsigned char target[detail::payload_ops::cap]{}; + detail::payload_copy(target, cmp_spec->payload_false, pops->size); + if (cmp.trivial == cmp_trivial::always_true || cmp.eval_as_ge) + pops->add(target, target, cmp_spec->payload_beta); + unsigned char blind[detail::payload_ops::cap]{}; + const auto seed = static_cast(root_sampler()); + pops->from_node(blind, &seed, sizeof(seed)); + unsigned char neg_blind[detail::payload_ops::cap]{}; + unsigned char other[detail::payload_ops::cap]{}; + pops->neg(neg_blind, blind); + pops->add(other, target, neg_blind); + g_add0 = detail::payload_to_word( + blind, pops->size); + g_add1 = detail::payload_to_word( + other, pops->size); + } + else if constexpr (std::is_integral_v) + if (cmp.active && !custom_cmp && !payload_cmp) { uint64_t target = false_value; if (cmp.trivial == cmp_trivial::always_true) @@ -1639,18 +2012,171 @@ HEDLEY_PRAGMA(GCC diagnostic pop) key0.set_cmp_scalars(g_last, g_add0, g_last_coeff); key1.set_cmp_scalars(g_last, g_add1, g_last_coeff); } + if (payload_cmp) + { + key0.set_cmp_scalars(p_last, g_add0, p_last_coeff); + key1.set_cmp_scalars(p_last, g_add1, p_last_coeff); + } return dpf::make_party_key_pair(std::move(key0), std::move(key1)); } +template +struct saved_leaf +{ + static constexpr std::size_t slot = Slot; + T value; +}; + +template +constexpr std::size_t rewrite_slot_count() noexcept +{ + if constexpr (is_updatable_tag_v || is_cmp_spec_v + || is_verifiable_tag_v || is_extractable_tag_v + || is_output_mac_tag_v || is_eq_spec_v) + return 0; + else if constexpr (is_at_v) + return std::tuple_size_v; + else if constexpr (is_idpf_v) + return A::n; + else + return 1; +} + +template +auto rewrite_leaf(T && value) +{ + using A = std::decay_t; + if constexpr (is_wildcard_v) + return std::make_pair(std::forward(value), std::tuple<>{}); + else if constexpr (is_arith_beta_v) + { + static_assert(!is_arith_beta_v, + "updatable does not apply to arith_beta"); + return std::make_pair(std::tuple<>{}, std::tuple<>{}); + } + else + { + using C = concrete_type_t; + C kept = static_cast(std::forward(value)); + return std::make_pair(wildcard_value{}, + std::make_tuple(saved_leaf{std::move(kept)})); + } +} + +template +auto rewrite_placed_values(Tuple && values, std::index_sequence, + std::integral_constant) +{ + auto parts = std::make_tuple( + rewrite_leaf(std::get(std::forward(values)))...); + auto planted = at(std::move(std::get<0>(std::get(parts)))...); + auto saved = std::tuple_cat(std::move(std::get<1>(std::get(parts)))...); + return std::make_pair(std::make_tuple(std::move(planted)), std::move(saved)); +} + +template +auto rewrite_idpf_values(Tuple && values, std::index_sequence, + std::index_sequence) +{ + auto parts = std::make_tuple( + rewrite_leaf(std::get(std::forward(values)))...); + auto planted = idpf_at( + std::move(std::get<0>(std::get(parts)))...); + auto saved = std::tuple_cat(std::move(std::get<1>(std::get(parts)))...); + return std::make_pair(std::make_tuple(std::move(planted)), std::move(saved)); +} + +template +auto rewrite_one(idpf_pack, Betas...> pack) +{ + return rewrite_idpf_values(std::move(pack.values), + std::index_sequence_for{}, + std::index_sequence{}); +} + +template +auto rewrite_one(Arg && arg) +{ + using A = std::decay_t; + if constexpr (is_updatable_tag_v) + return std::make_pair(std::tuple<>{}, std::tuple<>{}); + else if constexpr (is_eq_spec_v) + { + static_assert(!is_eq_spec_v, + "updatable does not apply to eq"); + return std::make_pair(std::tuple<>{}, std::tuple<>{}); + } + else if constexpr (is_cmp_spec_v || is_verifiable_tag_v + || is_extractable_tag_v || is_output_mac_tag_v) + return std::make_pair(std::make_tuple(std::forward(arg)), + std::tuple<>{}); + else if constexpr (is_at_v) + return rewrite_placed_values(std::move(arg.values), + std::make_index_sequence>{}, + std::integral_constant{}); + else + { + auto part = rewrite_leaf(std::forward(arg)); + return std::make_pair(std::make_tuple(std::move(part.first)), + std::move(part.second)); + } +} + +template +auto rewrite_all() +{ + return std::make_pair(std::tuple<>{}, std::tuple<>{}); +} + +template +auto rewrite_all(Arg && arg, Rest && ...rest) +{ + auto head = rewrite_one(std::forward(arg)); + auto tail = rewrite_all>()>( + std::forward(rest)...); + return std::make_pair( + std::tuple_cat(std::move(head.first), std::move(tail.first)), + std::tuple_cat(std::move(head.second), std::move(tail.second))); +} + +template +void assign_saved_one(K0 & k0, K1 & k1, Item & item) +{ + auto shares = dpf::additively_share(item.value); + auto & w0 = std::get(k0.leaf_nodes); + auto & w1 = std::get(k1.leaf_nodes); + const auto b0 = w0.compute_and_get_blinded_output_share(shares.first.raw()); + const auto b1 = w1.compute_and_get_blinded_output_share(shares.second.raw()); + const auto l0 = w0.compute_and_get_leaf_share(b1); + const auto l1 = w1.compute_and_get_leaf_share(b0); + w0.reconstruct_correction_word(l1); + w1.reconstruct_correction_word(l0); +} + +template +void assign_saved(K0 & k0, K1 & k1, Saved & saved) +{ + std::apply([&](auto & ...items) { + (assign_saved_one(k0, k1, items), ...); + }, saved); +} + } // namespace incr } // namespace detail -// --------------------------------------------------------------------------- -// Convenience make_dpf(x, y...): classic or incremental (+ optional cmp) -// --------------------------------------------------------------------------- - +/// @brief Build two party keys for one point. +/// @param x plaintext domain point +/// @param ys payloads, comparison specs, and key tags +/// @return the two party keys +/// @note Signed domains flip the MSB before the walk. A comparison spec walks the same n levels and writes a value correction word per level. +/// @note Following Boyle, Gilboa, and Ishai, CCS 2016 (full version ePrint 2018/707): one correction word per level, the n(λ+2)-bit key, not their EUROCRYPT 2015 key of 4n(λ+1) bits. +/// @note Remark 3.4 of that full version is this packing. `depth` is `n - lg(outputs_per_leaf)`, and `outputs_per_leaf` is how many copies of `G` fit in one `λ`-bit block, so `ν = log2(λ / log2|G|)`. Those low input bits select the lane inside the leaf. The tree does not write a correction word for them. A comparison still writes a value word on each remaining level. +/// @note Boyle, Gilboa, Ishai, and Kolobov (ePrint 2023/028) give a statistically private 3-server DPF and a perfectly private 4-server DPF. This function is a 2-party PRG key. +/// @see dpf::eval_point +/// @see dpf::lt +/// \complexity O(n) time and O(n) key size. n is the domain bitlength (`depth`). The loop does two interior PRG expansions and writes one correction word per level, then builds one exterior leaf per output. template ) + { + // Strip the `unit_sign` out-parameter, build the key from the rest, + // then fill the caller's sign shares from the bit leaf at `x`. + auto * us = detail::incr::find_unit_sign(ys...); + auto rest = std::tuple_cat( + detail::incr::drop_unit_sign(std::forward(ys))...); + auto keys = std::apply([&](auto && ...zs) { + return make_dpf( + x, std::forward(zs)...); + }, std::move(rest)); + detail::incr::fill_unit_sign(keys.first, keys.second, x, *us); + return keys; + } + else if constexpr (args_have_updatable_v) + { + auto bundle = detail::incr::rewrite_all<0>(std::forward(ys)...); + auto keys = std::apply([&](auto && ...zs) { + return make_dpf( + std::forward(x), std::forward(zs)...); + }, std::move(bundle.first)); + detail::incr::assign_saved(keys.first, keys.second, bundle.second); + return keys; + } + else + { using input_type = std::decay_t; static_assert(!is_secret_share_v, "make_dpf: domain point must be plaintext (use raw() or reconstruct)"); static_assert((!is_secret_share_v> && ...), "make_dpf: payloads must be plaintext (use raw() or reconstruct)"); + static_assert(!args_have_output_mac_v + || !args_have_bit_payload_v, + "output_mac: a MAC on a bare parity bit is not offered"); using node = typename ExteriorPRG::block_type; constexpr auto bitlen = utils::bitlength_of_v; constexpr std::size_t CD = forced_cmp_depth_v; @@ -1708,8 +2263,40 @@ auto make_dpf(InputT && x, OutputTs && ...ys) input_type, placed_tuple, CD, CB, CW, BK, ID, V, E>(x, std::move(placed), dpf::uniform_sample, cs); } + } } +/// @brief `make_dpf` with phantom tags from `auth_profile` (empty when semi-honest). +/// @tparam Profile an `auth_profile` specialization. `output_mac` is ignored here +/// as a key tag; when set, bit payloads are rejected at construction. +/// @tparam InteriorPRG PRG that expands interior nodes +/// @tparam ExteriorPRG PRG that expands the root +/// @tparam InputT input domain type +/// @tparam OutputTs payload and comparison arguments +/// @param x the target point +/// @param ys payloads, comparison specs, and any extra tags from the profile +/// @return the two party keys +/// @throws std::invalid_argument if there is no output +/// @see key_tags_tuple +template +HEDLEY_WARN_UNUSED_RESULT +auto make_dpf_profile(InputT && x, OutputTs && ...ys) +{ + static_assert(!Profile::output_mac || !args_have_bit_payload_v, + "output_mac: a MAC on a bare parity bit is not offered"); + return std::apply( + [&](auto ...tags) { + return make_dpf( + std::forward(x), std::forward(ys)..., tags...); + }, + key_tags_tuple()); +} + +/// \complexity O(n) time and O(n) key size. n is the domain bitlength (`depth`). The loop does two interior PRG expansions and writes one correction word per level, then builds one exterior leaf per output. template ) + { + auto bundle = detail::incr::rewrite_all<0>(std::forward(ys)...); + auto keys = std::apply([&](auto && ...zs) { + return make_dpf( + std::forward(x), std::forward(zs)...); + }, std::move(bundle.first)); + detail::incr::assign_saved(keys.first, keys.second, bundle.second); + return keys; + } + else + { using input_type = std::decay_t; static_assert(!is_secret_share_v, "make_dpf: domain point must be plaintext (use raw() or reconstruct)"); static_assert((!is_secret_share_v> && ...), "make_dpf: payloads must be plaintext (use raw() or reconstruct)"); + static_assert(!args_have_output_mac_v + || !args_have_bit_payload_v, + "output_mac: a MAC on a bare parity bit is not offered"); using node = typename ExteriorPRG::block_type; constexpr auto bitlen = utils::bitlength_of_v; constexpr std::size_t CD = forced_cmp_depth_v; @@ -1768,8 +2370,10 @@ auto make_dpf(InputT && x, OutputTs && ...ys) return detail::incr::make_incremental_impl(x, std::move(placed), seed, cs); } + } } +/// \complexity O(n) time and O(n) key size. n is the domain bitlength (`depth`). The loop does two interior PRG expansions and writes one correction word per level, then builds one exterior leaf per output. template root_sampler, OutputTs && ...ys) { + if constexpr (args_have_updatable_v) + { + auto bundle = detail::incr::rewrite_all<0>(std::forward(ys)...); + auto keys = std::apply([&](auto && ...zs) { + return make_dpf( + std::forward(x), std::move(root_sampler), + std::forward(zs)...); + }, std::move(bundle.first)); + detail::incr::assign_saved(keys.first, keys.second, bundle.second); + return keys; + } + else + { using input_type = std::decay_t; static_assert(!is_secret_share_v, "make_dpf: domain point must be plaintext (use raw() or reconstruct)"); @@ -1829,6 +2446,7 @@ auto make_dpf(InputT && x, root_sampler_t root_sampler, input_type, placed_tuple, CD, CB, CW, BK, ID, V, E>(x, std::move(placed), root_sampler, cs); } + } } // --------------------------------------------------------------------------- @@ -1850,6 +2468,11 @@ auto make_dpf(InputT && x, root_sampler_t root_sampler, /// @param rng the Doerner–Shelat randomness tapes /// @param ys the `ys` /// @return Doerner–Shelat keygen with caller-supplied roots and pad stream +/// @note Following Jack Doerner and abhi shelat, CCS 2017 (ePrint 2017/827): one correction word per level. The other `make_dpf_doerner_shelat` overloads are the same opening. +/// \complexity O(n) time. One `ds_advance_level` per level: two PRG expansions and one `prepare_level`. n is `depth`. +/// \rounds No sockets. This is the in-process transcript. A networked walk is `dpf::party::dist::point_party`. +/// \communication none here. `local_cw_protocol` opens the correction word locally. +/// \preprocessing Per level, `prepare_level` draws one `ds_cw_pads` (two parties × a 128-bit rand, a 128-bit gamma, and a bit) and two `ds_and_pads`. Arithmetic inputs also run a carry chain of n-1 bit-AND triples in `encode_walk_shares`. template (y), std::forward(ys)...); } +/// \complexity O(n) time. One `ds_advance_level` per level: two PRG expansions and one `prepare_level`. n is `depth`. +/// \rounds No sockets. This is the in-process transcript. A networked walk is `dpf::party::dist::point_party`. +/// \communication none here. `local_cw_protocol` opens the correction word locally. +/// \preprocessing Per level, `prepare_level` draws one `ds_cw_pads` (two parties × a 128-bit rand, a 128-bit gamma, and a bit) and two `ds_and_pads`. Arithmetic inputs also run a carry chain of n-1 bit-AND triples in `encode_walk_shares`. template (y), std::forward(ys)...); } +/// \complexity O(n) time. One `ds_advance_level` per level: two PRG expansions and one `prepare_level`. n is `depth`. +/// \rounds No sockets. This is the in-process transcript. A networked walk is `dpf::party::dist::point_party`. +/// \communication none here. `local_cw_protocol` opens the correction word locally. +/// \preprocessing Per level, `prepare_level` draws one `ds_cw_pads` (two parties × a 128-bit rand, a 128-bit gamma, and a bit) and two `ds_and_pads`. Arithmetic inputs also run a carry chain of n-1 bit-AND triples in `encode_walk_shares`. template (y), std::forward(ys)...); } +/// \complexity O(n) time. One `ds_advance_level` per level: two PRG expansions and one `prepare_level`. n is `depth`. +/// \rounds No sockets. This is the in-process transcript. A networked walk is `dpf::party::dist::point_party`. +/// \communication none here. `local_cw_protocol` opens the correction word locally. +/// \preprocessing Per level, `prepare_level` draws one `ds_cw_pads` (two parties × a 128-bit rand, a 128-bit gamma, and a bit) and two `ds_and_pads`. Arithmetic inputs also run a carry chain of n-1 bit-AND triples in `encode_walk_shares`. template (ys)...); } +/// \complexity O(n) time. One `ds_advance_level` per level: two PRG expansions and one `prepare_level`. n is `depth`. +/// \rounds No sockets. This is the in-process transcript. A networked walk is `dpf::party::dist::point_party`. +/// \communication none here. `local_cw_protocol` opens the correction word locally. +/// \preprocessing Per level, `prepare_level` draws one `ds_cw_pads` (two parties × a 128-bit rand, a 128-bit gamma, and a bit) and two `ds_and_pads`. Arithmetic inputs also run a carry chain of n-1 bit-AND triples in `encode_walk_shares`. template ; - if constexpr (detail::cmp_group_info::custom) + if constexpr (detail::has_from_seed::value) + { + const Concrete delta = if_true - if_false; + Concrete target = if_false; + if (ch.trivial == cmp_trivial::always_true || ch.eval_as_ge) + target = delta + if_false; + using prg = typename KeyT::interior_prg; + const auto seed = dpf::uniform_sample(); + const Concrete blind = Concrete::from_seed(&seed, sizeof(seed)); + const Concrete share0 = blind; + const Concrete share1 = target + (-blind); + const auto ops = detail::make_payload_ops(); + auto mix = [&](auto base_w, auto coeff_w) { + unsigned char base[detail::payload_ops::cap]{}; + unsigned char del[detail::payload_ops::cap]{}; + unsigned char scaled[detail::payload_ops::cap]{}; + unsigned char outb[detail::payload_ops::cap]{}; + const Concrete base_e = detail::payload_from_word(base_w); + std::memcpy(base, &base_e, sizeof(base_e)); + std::memcpy(del, &delta, sizeof(delta)); + ops.scale(scaled, del, detail::payload_coeff_of(coeff_w)); + ops.add(outb, base, scaled); + return detail::payload_to_word( + outb, sizeof(Concrete)); + }; + key0.assign_cmp_payload(mix, detail::payload_to_word( + reinterpret_cast(&share0), sizeof(share0))); + key1.assign_cmp_payload(mix, detail::payload_to_word( + reinterpret_cast(&share1), sizeof(share1))); + return; + } + else if constexpr (detail::cmp_group_info::custom) { const auto layout = detail::group_layout(); const auto delta = detail::group_sub( @@ -2510,9 +3220,19 @@ void assign_cmp_local(KeyT & key, uint64_t delta, static_assert(party_of_v == Party, "assign_cmp_local: share party must match party_key"); } - const auto additive = addend_share.as_additive(); - assign_cmp_local(key, delta, - static_cast(additive.raw())); + // Comparison absorb is a (2,2) additive share. A (3,3) component and a + // replicated share are not addends of a two-party comparison key. + if constexpr (is_two_party_sharing_v) + { + const auto additive = addend_share.as_additive(); + assign_cmp_local(key, delta, + static_cast(additive.raw())); + } + else + { + static_assert(is_two_party_sharing_v, + "assign_cmp_local: comparison addend is a (2,2) share"); + } } // --------------------------------------------------------------------------- @@ -2544,7 +3264,62 @@ namespace incr /// @tparam QueryT query type /// @tparam PathMemoizer path memoizer type /// @param dpf the DPF key -/// @param x the `x` +/// @brief Party 0 absorbs a nonzero public `eq`/`eq_at` if_false addend. +/// @details Leaf shares open as y0 − y1 (XOR groups: y0 ⊕ y1). Wildcard slots +/// carry no comparable public addend and are skipped (their exterior walk +/// already throws if unassigned). +template +constexpr bool party0_absorbs_public_addend(const KeyT & dpf) noexcept +{ + using output_type = typename KeyT::template concrete_output_type; + if constexpr (dpf::is_wildcard_v>) + return false; + else + { + const auto & add = std::get(dpf.public_addends); + return add != output_type{} && !dpf::get_lo_bit(dpf.root()); + } +} + +/// @brief Fold `public_addends[I]` into one lane of an exterior leaf (point eval). +template +void absorb_public_addend_lane(const KeyT & dpf, LeafT & leaf, LaneT lane_x) +{ + using output_type = typename KeyT::template concrete_output_type; + if (!party0_absorbs_public_addend(dpf)) + return; + using exterior_node = typename KeyT::exterior_node; + const auto & add = std::get(dpf.public_addends); + auto addon = dpf::make_naked_leaf(lane_x, add); + leaf = dpf::add_leaf(leaf, addon); +} + +/// @brief Fold `public_addends[I]` into every packing lane of an exterior leaf. +/// @details Interval / full / IP exterior walks materialise whole leaves; the +/// constant if_false must land on every lane so each reconstructed output +/// picks up the absorb (on-point: δ + if_false = if_true). +template +void absorb_public_addend_all_lanes(const KeyT & dpf, LeafT & leaf) +{ + using output_type = typename KeyT::template concrete_output_type; + if (!party0_absorbs_public_addend(dpf)) + return; + using exterior_node = typename KeyT::exterior_node; + using input_type = typename KeyT::input_type; + constexpr auto opl = KeyT::template outputs_per_leaf_of; + const auto & add = std::get(dpf.public_addends); + LeafT addon{}; + for (std::size_t i = 0; i < opl; ++i) + { + addon = dpf::add_leaf(addon, + dpf::make_naked_leaf(static_cast(i), + add)); + } + leaf = dpf::add_leaf(leaf, addon); +} + +/// @param dpf the DPF key +/// @param x the query /// @param path the root-to-leaf path /// @return the evaluation result template (path[level]); auto lane_x = detail::incr::lane_input(tx, N, key_type::input_bits); - // Public eq if_false: absorb so subtractive reconstruction picks it up. - // Leaf shares open as y0 − y1 (XOR groups: y0 ⊕ y1); party 0 absorbs. - // Wildcard slots carry no public addend and cannot be materialized until - // assigned; `traverse_exterior` above already throws for an unassigned - // wildcard leaf, so the addend fold is simply skipped for wildcard slots - // (its `public_addends` element is wildcard-typed and not comparable). - if constexpr (!dpf::is_wildcard_v>) - { - const auto & add = std::get(dpf.public_addends); - if (add != output_type{}) - { - const bool absorb = !dpf::get_lo_bit(dpf.root()); // party 0 - if (absorb) - { - using exterior_node = typename key_type::exterior_node; - auto addon = dpf::make_naked_leaf(lane_x, add); - node = dpf::add_leaf(node, addon); - } - } - } + absorb_public_addend_lane(dpf, node, lane_x); return make_eval_dpf_output(node, lane_x); } @@ -2607,6 +3363,7 @@ auto eval_out_point_impl( /// @param x the `x` /// @param path the root-to-leaf path /// @return the evaluation result +/// \complexity O(n) time. n is `depth`. One interior traversal per level from the memoizer resume index through the leaf. Extra space is the path memoizer (O(n) nodes, or one node if it does not memoize). A proof token adds one fold per level walked. template , std::enable_if_t, bool> = true> @@ -2663,6 +3420,7 @@ namespace incr template auto make_output_buffer_for_out_interval_impl(const KeyT & key, LaneT from, LaneT to) { + (void)key; static_assert(KeyT::meta[I].prefix == N, "interval buffer: prefix mismatch"); using output_type = typename KeyT::template concrete_output_type; using buffer_elem = leaf_buffer_elem_t; @@ -2789,13 +3547,14 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") for (std::size_t j = 0, k = start; j < nodes_in_interval; ++j, ++k) { auto leaf = dpf.template traverse_exterior(nodes[j]); + absorb_public_addend_all_lanes(dpf, leaf); if constexpr (utils::is_packed_subbyte_v) { store_leaf_bytes(outbuf, k, leaf); } else { - std::memcpy(&outbuf[k * opl], &leaf, sizeof(output_type) * opl); + utils::raw_memcpy(&outbuf[k * opl], &leaf, sizeof(output_type) * opl); } } HEDLEY_PRAGMA(GCC diagnostic pop) @@ -2945,6 +3704,7 @@ auto eval_out_full_impl( /// @tparam KeyT key type /// @param dpf the DPF key /// @return Deepest-group full-domain eval (first cut of incremental `eval_full`) +/// \complexity Same expansion as `eval_interval` on the whole domain. L = 2^{n - lg(outputs_per_leaf)} leaf nodes, n = `depth`. Time Θ(L) interior traversals. The output buffer stores one slot per domain point (2^n). template , bool> = true> auto eval_full( @@ -3002,7 +3762,7 @@ auto eval_out_sequence_impl( } else { - std::memcpy(&outbuf[i * opl], &out.node, sizeof(output_type) * opl); + utils::raw_memcpy(&outbuf[i * opl], &out.node, sizeof(output_type) * opl); } } return subsequence_iterable, bool> = true> auto eval_sequence( @@ -3045,7 +3806,8 @@ namespace incr template uint64_t eval_cmp_path_sum(const KeyT & dpf, typename KeyT::input_type tx, - PathMemoizer & path, bool as_prefix = false, std::size_t prefix_len = 0) + PathMemoizer & path, bool as_prefix = false, std::size_t prefix_len = 0, + proof_token * pi = nullptr) { using namespace detail::dcf_impl; const auto & ch = dpf.cmp(); @@ -3062,7 +3824,7 @@ uint64_t eval_cmp_path_sum(const KeyT & dpf, typename KeyT::input_type tx, if (as_prefix) throw std::invalid_argument( "cmp_prefix is not defined for a blocked comparison"); - return detail::blocked::eval_share(dpf, tx, path); + return detail::blocked::eval_share(dpf, tx, path, pi); } const std::size_t full_bits = static_cast(ch.nbits); @@ -3072,7 +3834,7 @@ uint64_t eval_cmp_path_sum(const KeyT & dpf, typename KeyT::input_type tx, && (!as_prefix || prefix_len == full_bits)) return add; - dpf::detail::ensure_level(dpf, tx, path, nbits); + dpf::detail::ensure_level(dpf, tx, path, nbits, pi); const int party = dpf::get_lo_bit(dpf.root()) ? 1 : 0; uint64_t V = 0; @@ -3105,7 +3867,9 @@ uint64_t eval_cmp_path_sum(const KeyT & dpf, typename KeyT::input_type tx, /// unlike `basic_interval_memoizer_at` which ping-pongs two buffers). /// @tparam DpfKey DPF key type /// @tparam StopLevel stop level -/// @tparam interior_node interior node +/// @tparam Allocator node allocator (defaults to aligned SIMD blocks) +HEDLEY_PRAGMA(GCC diagnostic push) +HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") template ::interior_node>> @@ -3180,6 +3944,15 @@ struct cmp_full_interval_memo return Allocator::assume_aligned(&buf[level_endpoints[level]]); } + /// @brief Drop a cached interval so the next `assign_interval` rebuilds + /// from the root (needed when folding a proof over the tree). + void clear_assignment() + { + from_ = std::nullopt; + to_ = std::nullopt; + level_index = 0; + } + private: std::size_t output_length; std::size_t level_index; @@ -3204,6 +3977,47 @@ struct cmp_full_interval_memo return eps; } }; +HEDLEY_PRAGMA(GCC diagnostic pop) + +/// @brief Fold every node at `level_index` of a truncated cmp interval into `pi`. +/// @details Prefix addressing uses comparison `nbits`, not `KeyT::depth`. +/// Blocked keys use a domain-separated level tag so tokens diverge +/// from native per-level folds. +template +HEDLEY_ALWAYS_INLINE +void fold_cmp_interval_level(proof_token & pi, const KeyT & dpf, + std::size_t level_index, IntegralT from_node, std::size_t nbits, + std::size_t nodes_at_level, const NodeT * curr) +{ + if constexpr (!KeyT::is_verifiable) + return; + if (level_index == 0 || nodes_at_level == 0) + return; + const auto start = static_cast( + utils::shift_right(from_node, nbits - level_index)); + const auto & cs = dpf.correction_seeds()[level_index - 1]; + for (std::size_t i = 0; i < nodes_at_level; ++i) + { + if constexpr (unwrap_party_key_t::cmp_block > 0) + { + detail::blocked::fold_spine_node(pi, level_index - 1, + start + i, curr[i], cs); + } + else + { + detail::vdpf::fold_node(pi, level_index - 1, start + i, curr[i], + cs); + } + } +} + +template +struct has_clear_assignment : std::false_type {}; + +template +struct has_clear_assignment().clear_assignment())>> + : std::true_type {}; /// @brief Expand interval interior nodes for the comparison prefix (stop = nbits). /// @tparam KeyT key type @@ -3215,10 +4029,12 @@ struct cmp_full_interval_memo /// @param nbits the width in bits /// @param memoizer the memoizer built for this key /// @param tree_levels the `tree_levels` +/// @param pi optional VDPF proof accumulator (once per BFS node) template void eval_cmp_interval_impl_interior(const KeyT & dpf, IntegralT from_node, IntegralT to_node, std::size_t nbits, IntervalMemoizer & memoizer, - std::size_t tree_levels = static_cast(-1)) + std::size_t tree_levels = static_cast(-1), + proof_token * pi = nullptr) { if (tree_levels == static_cast(-1)) tree_levels = nbits; @@ -3227,6 +4043,14 @@ void eval_cmp_interval_impl_interior(const KeyT & dpf, IntegralT from_node, const input_type lane_msb = static_cast(input_type{1} << (nbits - 1)); + // Proving needs every truncated-tree node: a warm memoizer that resumes + // past level 1 would skip upper folds. + if (pi != nullptr) + { + if constexpr (has_clear_assignment::value) + memoizer.clear_assignment(); + } + std::size_t level_index = memoizer.assign_interval(dpf, from_node, to_node); std::size_t nodes_at_level = memoizer.get_nodes_at_level(); IntegralT mask = static_cast( @@ -3261,6 +4085,12 @@ void eval_cmp_interval_impl_interior(const KeyT & dpf, IntegralT from_node, } if (to_offset == true) curr[i] = KeyT::traverse_interior(prev[j], cw[0], 0, is_last); + + if (pi != nullptr) + { + fold_cmp_interval_level(*pi, dpf, level_index, from_node, nbits, + nodes_at_level, curr); + } } } @@ -3324,7 +4154,8 @@ namespace incr template auto eval_group_path_sum(const KeyT & dpf, typename KeyT::input_type tx, - PathMemoizer & path, bool as_prefix = false, std::size_t prefix_len = 0) + PathMemoizer & path, bool as_prefix = false, std::size_t prefix_len = 0, + proof_token * pi = nullptr) { using prg = typename unwrap_party_key_t::interior_prg; using concrete = dpf::concrete_type_t; @@ -3338,7 +4169,7 @@ auto eval_group_path_sum(const KeyT & dpf, typename KeyT::input_type tx, && (!as_prefix || prefix_len == full_bits)) return detail::group_to_beta(add); - dpf::detail::ensure_level(dpf, tx, path, nbits); + dpf::detail::ensure_level(dpf, tx, path, nbits, pi); const int party = dpf::get_lo_bit(dpf.root()) ? 1 : 0; auto V = detail::group_zero(layout); const auto zero = detail::group_zero(layout); @@ -3366,10 +4197,52 @@ auto eval_group_path_sum(const KeyT & dpf, typename KeyT::input_type tx, return detail::group_to_beta(detail::group_add(V, add)); } +template +auto eval_payload_path_sum(const KeyT & dpf, typename KeyT::input_type tx, + PathMemoizer & path, bool as_prefix = false, std::size_t prefix_len = 0, + proof_token * pi = nullptr) +{ + using concrete = dpf::concrete_type_t; + const auto & ch = dpf.cmp(); + concrete add = detail::payload_from_word(dpf.cmp_addend_word()); + const std::size_t full_bits = static_cast(ch.nbits); + const std::size_t nbits = as_prefix ? prefix_len : full_bits; + if ((ch.trivial == cmp_trivial::always_true + || ch.trivial == cmp_trivial::always_false) + && (!as_prefix || prefix_len == full_bits)) + return add; + + dpf::detail::ensure_level(dpf, tx, path, nbits, pi); + const int party = dpf::get_lo_bit(dpf.root()) ? 1 : 0; + concrete V{}; + auto bit_mask = KeyT::msb_mask; + for (std::size_t i = 0; i < nbits; ++i, bit_mask >>= 1) + { + const bool xi = !!(bit_mask & tx); + const auto & parent = path[i]; + const uint8_t t = static_cast(dpf::get_lo_bit(parent)); + auto kids = KeyT::tree::expand_value(parent); + const concrete v = concrete::from_seed(&kids[xi ? 1 : 0], sizeof(kids[0])); + const concrete cw = detail::payload_from_word(dpf.value_cw()[i]); + const concrete contrib = v + (t ? cw : concrete{}); + V = party ? (V + (-contrib)) : (V + contrib); + } + const auto & leaf = path[nbits]; + const uint8_t t = static_cast(dpf::get_lo_bit(leaf)); + const concrete c = concrete::from_seed(&leaf, sizeof(leaf)); + const concrete last = detail::payload_from_word( + as_prefix ? dpf.prefix_cws()[nbits] : dpf.cw_last_word()); + const concrete contrib = c + (t ? last : concrete{}); + V = party ? (V + (-contrib)) : (V + contrib); + if (ch.eval_as_ge) + V = -V; + return V + add; +} + template > auto eval_cmp_point_impl(const KeyT & dpf, QueryT && x, - PathMemoizer && path = PathMemoizer{}) + PathMemoizer && path = PathMemoizer{}, proof_token * pi = nullptr) { if (!dpf.has_cmp()) throw std::invalid_argument("cmp eval: key has no comparison channel"); @@ -3378,15 +4251,20 @@ auto eval_cmp_point_impl(const KeyT & dpf, QueryT && x, "cmp eval: wildcard comparison payload not assigned (call assign_cmp)"); auto tx = dpf.offset_x(std::forward(x)); utils::flip_msb_if_signed_integral(tx); - if constexpr (detail::cmp_group_info>::custom) + if constexpr (detail::has_from_seed>::value) { return make_eval_cmp_result( - detail::incr::eval_group_path_sum(dpf, tx, path)); + detail::incr::eval_payload_path_sum(dpf, tx, path, false, 0, pi)); + } + else if constexpr (detail::cmp_group_info>::custom) + { + return make_eval_cmp_result( + detail::incr::eval_group_path_sum(dpf, tx, path, false, 0, pi)); } else { const uint64_t raw = - detail::incr::eval_cmp_path_sum(dpf, tx, path); + detail::incr::eval_cmp_path_sum(dpf, tx, path, false, 0, pi); return make_eval_cmp_result( detail::dcf_impl::u64_to_beta(raw)); } @@ -3395,7 +4273,7 @@ auto eval_cmp_point_impl(const KeyT & dpf, QueryT && x, template > auto eval_cmp_prefix_point_impl(const KeyT & dpf, QueryT && x, - PathMemoizer && path = PathMemoizer{}) + PathMemoizer && path = PathMemoizer{}, proof_token * pi = nullptr) { static_assert(unwrap_party_key_t::cmp_idcf, "cmp_prefix requires an idcf key"); @@ -3410,15 +4288,20 @@ auto eval_cmp_prefix_point_impl(const KeyT & dpf, QueryT && x, throw std::invalid_argument("cmp_prefix: prefix is longer than the comparison"); auto tx = dpf.offset_x(std::forward(x)); utils::flip_msb_if_signed_integral(tx); - if constexpr (detail::cmp_group_info>::custom) + if constexpr (detail::has_from_seed>::value) { return make_eval_cmp_result( - detail::incr::eval_group_path_sum(dpf, tx, path, true, L)); + detail::incr::eval_payload_path_sum(dpf, tx, path, true, L, pi)); + } + else if constexpr (detail::cmp_group_info>::custom) + { + return make_eval_cmp_result( + detail::incr::eval_group_path_sum(dpf, tx, path, true, L, pi)); } else { const uint64_t raw = - detail::incr::eval_cmp_path_sum(dpf, tx, path, true, L); + detail::incr::eval_cmp_path_sum(dpf, tx, path, true, L, pi); return make_eval_cmp_result( detail::dcf_impl::u64_to_beta(raw)); } @@ -3483,19 +4366,19 @@ template > void eval_cmp_sequence_impl(const KeyT & dpf, ForwardIterator begin, ForwardIterator end, OutputBuffer && outbuf, - PathMemoizer && path = PathMemoizer{}) + PathMemoizer && path = PathMemoizer{}, proof_token * pi = nullptr) { if (!dpf.has_cmp()) throw std::invalid_argument("cmp sequence eval: no comparison channel"); std::size_t i = 0; for (auto it = begin; it != end; ++it, ++i) - outbuf[i] = eval_cmp_point_impl(dpf, *it, path); + outbuf[i] = eval_cmp_point_impl(dpf, *it, path, pi); } template void eval_cmp_interval_impl(const KeyT & dpf, LaneT from, LaneT to, - OutputBuffer && outbuf) + OutputBuffer && outbuf, proof_token * pi = nullptr) { if (!dpf.has_cmp()) throw std::invalid_argument("cmp interval eval: no comparison channel"); @@ -3508,7 +4391,7 @@ void eval_cmp_interval_impl(const KeyT & dpf, LaneT from, LaneT to, dpf::basic_path_memoizer path; for (LaneT q = from; ; ++q, ++i) { - outbuf[i] = eval_cmp_point_impl(dpf, q, path); + outbuf[i] = eval_cmp_point_impl(dpf, q, path, pi); if (q == to) break; } @@ -3538,7 +4421,7 @@ void eval_cmp_interval_impl(const KeyT & dpf, LaneT from, LaneT to, const std::size_t levels = unwrap_party_key_t::cmp_block > 0 ? unwrap_party_key_t::cmp_h : nbits; detail::incr::eval_cmp_interval_impl_interior(dpf, a, cmp_exclusive_end(b), - nbits, memo, levels); + nbits, memo, levels, pi); for (std::size_t i = 0; i < count; ++i) { @@ -3566,7 +4449,7 @@ void eval_cmp_interval_impl(const KeyT & dpf, LaneT from, LaneT to, template void eval_cmp_interval_impl(const KeyT & dpf, LaneT from, LaneT to, - OutputBuffer && outbuf, IntervalMemoizer && memo) + OutputBuffer && outbuf, IntervalMemoizer && memo, proof_token * pi = nullptr) { if (!dpf.has_cmp()) throw std::invalid_argument("cmp interval eval: no comparison channel"); @@ -3580,7 +4463,7 @@ void eval_cmp_interval_impl(const KeyT & dpf, LaneT from, LaneT to, dpf::basic_path_memoizer path; for (LaneT q = from; ; ++q, ++i) { - outbuf[i] = eval_cmp_point_impl(dpf, q, path); + outbuf[i] = eval_cmp_point_impl(dpf, q, path, pi); if (q == to) break; } @@ -3601,7 +4484,7 @@ void eval_cmp_interval_impl(const KeyT & dpf, LaneT from, LaneT to, const std::size_t levels = unwrap_party_key_t::cmp_block > 0 ? unwrap_party_key_t::cmp_h : nbits; detail::incr::eval_cmp_interval_impl_interior(dpf, a, cmp_exclusive_end(b), - nbits, memo, levels); + nbits, memo, levels, pi); for (std::size_t i = 0; i < count; ++i) { @@ -3627,13 +4510,49 @@ void eval_cmp_interval_impl(const KeyT & dpf, LaneT from, LaneT to, } template -auto eval_cmp_interval_impl(const KeyT & dpf, LaneT from, LaneT to) +auto eval_cmp_interval_impl(const KeyT & dpf, LaneT from, LaneT to, + proof_token * pi = nullptr) { auto buf = make_output_buffer_for_cmp_interval_impl(dpf, from, to); - eval_cmp_interval_impl(dpf, from, to, buf); + eval_cmp_interval_impl(dpf, from, to, buf, pi); return buf; } +/// @brief Fold every truncated cmp-tree node of `[from, to]` into `pi`. +/// @details Caller must `init_proof` first, or use `prove_cmp_interval`. +template +void prove_fold_cmp_interval(const KeyT & dpf, LaneT from, LaneT to, + proof_token & pi) +{ + static_assert(KeyT::is_verifiable, + "prove_fold_cmp_interval: key must carry dpf::verifiable"); + if (!dpf.has_cmp()) + throw std::invalid_argument("prove_cmp_interval: no comparison channel"); + if (!dpf.cmp_assigned()) + throw std::invalid_argument( + "prove_cmp_interval: wildcard payload not assigned (call assign_cmp)"); + constexpr auto to_int = utils::to_integral_type{}; + auto from_x = from; + auto to_x = to; + utils::flip_msb_if_signed_integral(from_x); + utils::flip_msb_if_signed_integral(to_x); + const auto nbits = static_cast(dpf.cmp().nbits); + using integral = typename KeyT::integral_type; + const auto a = static_cast(to_int(from_x)); + const auto b = static_cast(to_int(to_x)); + const auto count = cmp_inclusive_count(a, b); + constexpr std::size_t stop = + KeyT::cmp_depth == 0 ? KeyT::depth : KeyT::cmp_depth; + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + cmp_full_interval_memo memo{count}; + HEDLEY_PRAGMA(GCC diagnostic pop) + const std::size_t levels = unwrap_party_key_t::cmp_block > 0 + ? unwrap_party_key_t::cmp_h : nbits; + eval_cmp_interval_impl_interior(dpf, a, cmp_exclusive_end(b), nbits, memo, + levels, &pi); +} + } // namespace incr } // namespace detail diff --git a/include/dpf/interleave_leaves.hpp b/include/dpf/interleave_leaves.hpp new file mode 100644 index 0000000..153f043 --- /dev/null +++ b/include/dpf/interleave_leaves.hpp @@ -0,0 +1,568 @@ +/// @file dpf/interleave_leaves.hpp +/// @brief Interleave (and deinterleave) per-key leaf vectors into cohort order. +/// @details Given `nkeys` vectors of length `nleaves`, write one buffer whose +/// logical lane index is `cohort_index(i, k, nkeys) = i * nkeys + k` +/// (leaf `i` of key `k`). That matches sequence-cohort layout and the +/// key-major axis of interval-cohort leaves (lanes inside a leaf stay +/// contiguous in each one-key buffer; this routine interleaves whole +/// leaf *values*, not interior walk nodes). +/// +/// Storage and packing: +/// - `uint64_t` / `uint32_t` / `uint16_t` / `uint8_t`: one array element +/// per leaf; `out[i * nkeys + k] = keys[k][i]`. +/// - `dpf::bit`, `dpf::twobit`, `dpf::nyble`, and the matching +/// `dpf::gf2` / `gf22` / `gf24` lanes: same logical order, packed +/// tightly into `uint64_t` words like `dynamic_bit_array` / +/// `dynamic_packed_array` — lane `j` occupies bits +/// `[j * W, (j + 1) * W)` of the flat stream (`W` = 1, 2, or 4), +/// low lane in the low bits of each word. So a naive *element* +/// index `i * nkeys + k` is wrong for sub-byte widths; use the +/// logical index above, then pack with width `W`. +/// +/// Kernels are word-wise (and 8×8 bit transpose batches for 1-bit), +/// not a scalar loop per bit. Deinterleave is the inverse transpose. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_INTERLEAVE_LEAVES_HPP__ +#define LIBDPF_INCLUDE_DPF_INTERLEAVE_LEAVES_HPP__ + +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/bit.hpp" +#include "dpf/modint.hpp" +#include "dpf/nyble.hpp" +#include "dpf/twobit.hpp" +#include "dpf/utils.hpp" + +namespace dpf +{ + +/// @brief Underlying word/element type used to store a sequence of `LaneT` leaves. +template +struct leaf_storage +{ + using type = LaneT; +}; + +template +struct leaf_storage>> +{ + using type = std::uint64_t; +}; + +template <> +struct leaf_storage +{ + using type = std::uint64_t; +}; + +template <> +struct leaf_storage +{ + using type = std::uint64_t; +}; + +template <> +struct leaf_storage +{ + using type = std::uint64_t; +}; + +template +using leaf_storage_t = typename leaf_storage::type; + +/// @brief Number of `leaf_storage_t` words needed for `n` logical leaves. +template +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr std::size_t leaf_storage_words(std::size_t n) noexcept +{ + if constexpr (utils::is_packed_subbyte_v) + { + constexpr std::size_t w = utils::packed_lane_bits_v; + return (n * w + 63u) / 64u; + } + else + { + return n; + } +} + +namespace interleave_detail +{ + +/// @brief 8×8 bit matrix transpose in a 64-bit word (Hacker's Delight). +/// @details Byte `r` holds row `r`; bit `c` of that byte is column `c` +/// (LSB = column 0). Transpose swaps rows and columns. +HEDLEY_CONST +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +constexpr std::uint64_t bit_transpose_8x8(std::uint64_t x) noexcept +{ + std::uint64_t t = (x ^ (x >> 7)) & 0x00AA00AA00AA00AAull; + x = x ^ t ^ (t << 7); + t = (x ^ (x >> 14)) & 0x0000CCCC0000CCCCull; + x = x ^ t ^ (t << 14); + t = (x ^ (x >> 28)) & 0x00000000F0F0F0F0ull; + x = x ^ t ^ (t << 28); + return x; +} + +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +void write_bits(std::uint64_t * out, std::size_t bit_pos, std::uint64_t bits, + unsigned nbits) noexcept +{ + if (nbits == 0) + return; + const std::size_t word = bit_pos / 64u; + const unsigned shift = static_cast(bit_pos % 64u); + const std::uint64_t mask = nbits == 64 + ? ~std::uint64_t{0} + : ((std::uint64_t{1} << nbits) - 1u); + const std::uint64_t val = bits & mask; + out[word] |= val << shift; + if (shift + nbits > 64u) + out[word + 1u] |= val >> (64u - shift); +} + +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +std::uint64_t read_bits(const std::uint64_t * in, std::size_t bit_pos, + unsigned nbits) noexcept +{ + if (nbits == 0) + return 0; + const std::size_t word = bit_pos / 64u; + const unsigned shift = static_cast(bit_pos % 64u); + const std::uint64_t mask = nbits == 64 + ? ~std::uint64_t{0} + : ((std::uint64_t{1} << nbits) - 1u); + std::uint64_t val = in[word] >> shift; + if (shift + nbits > 64u) + val |= in[word + 1u] << (64u - shift); + return val & mask; +} + +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +std::uint8_t load_key_byte_bits(const std::uint64_t * key, std::size_t nleaves, + std::size_t i0) noexcept +{ + if (i0 >= nleaves) + return 0; + const unsigned take = static_cast( + nleaves - i0 < 8u ? nleaves - i0 : 8u); + return static_cast(read_bits(key, i0, take)); +} + +/// @brief Interleave 1-bit lanes with 8×8 transpose batches plus a bit writer. +HEDLEY_NO_THROW +inline void interleave_bits(std::uint64_t * HEDLEY_RESTRICT out, + const std::uint64_t * const * HEDLEY_RESTRICT keys, std::size_t nkeys, + std::size_t nleaves) noexcept +{ + const std::size_t out_words = leaf_storage_words(nkeys * nleaves); + if (out_words != 0) + std::memset(out, 0, out_words * sizeof(std::uint64_t)); + if (nkeys == 0 || nleaves == 0) + return; + + for (std::size_t i0 = 0; i0 < nleaves; i0 += 8u) + { + const unsigned nrows = static_cast( + nleaves - i0 < 8u ? nleaves - i0 : 8u); + for (std::size_t k0 = 0; k0 < nkeys; k0 += 8u) + { + const unsigned ncols = static_cast( + nkeys - k0 < 8u ? nkeys - k0 : 8u); + std::uint64_t packed = 0; + DPF_UNROLL_LOOP + for (unsigned c = 0; c < 8u; ++c) + { + std::uint8_t b = 0; + if (c < ncols) + b = load_key_byte_bits(keys[k0 + c], nleaves, i0); + packed |= static_cast(b) << (8u * c); + } + const std::uint64_t t = bit_transpose_8x8(packed); + DPF_UNROLL_LOOP + for (unsigned r = 0; r < nrows; ++r) + { + const std::uint64_t row + = (t >> (8u * r)) & ((std::uint64_t{1} << ncols) - 1u); + write_bits(out, (i0 + r) * nkeys + k0, row, ncols); + } + } + } +} + +HEDLEY_NO_THROW +inline void deinterleave_bits(std::uint64_t * const * HEDLEY_RESTRICT keys, + const std::uint64_t * HEDLEY_RESTRICT in, std::size_t nkeys, + std::size_t nleaves) noexcept +{ + if (nkeys == 0 || nleaves == 0) + return; + for (std::size_t k = 0; k < nkeys; ++k) + { + const std::size_t words = leaf_storage_words(nleaves); + if (words != 0) + std::memset(keys[k], 0, words * sizeof(std::uint64_t)); + } + + for (std::size_t i0 = 0; i0 < nleaves; i0 += 8u) + { + const unsigned nrows = static_cast( + nleaves - i0 < 8u ? nleaves - i0 : 8u); + for (std::size_t k0 = 0; k0 < nkeys; k0 += 8u) + { + const unsigned ncols = static_cast( + nkeys - k0 < 8u ? nkeys - k0 : 8u); + std::uint64_t packed = 0; + DPF_UNROLL_LOOP + for (unsigned r = 0; r < nrows; ++r) + { + const std::uint64_t row + = read_bits(in, (i0 + r) * nkeys + k0, ncols); + packed |= row << (8u * r); + } + // Inverse of the interleave transpose: same 8×8 transpose. + const std::uint64_t t = bit_transpose_8x8(packed); + DPF_UNROLL_LOOP + for (unsigned c = 0; c < ncols; ++c) + { + const std::uint64_t col + = (t >> (8u * c)) & ((std::uint64_t{1} << nrows) - 1u); + write_bits(keys[k0 + c], i0, col, nrows); + } + } + } +} + +/// @brief Interleave `W`-bit lanes (`W` = 2 or 4) by filling output words. +template +HEDLEY_NO_THROW +void interleave_packed_w(std::uint64_t * HEDLEY_RESTRICT out, + const std::uint64_t * const * HEDLEY_RESTRICT keys, std::size_t nkeys, + std::size_t nleaves) noexcept +{ + static_assert(W == 2 || W == 4, "packed width must be 2 or 4"); + constexpr std::uint64_t lane_mask = (std::uint64_t{1} << W) - 1u; + constexpr unsigned lanes_per_word = 64u / W; + const std::size_t total = nkeys * nleaves; + const std::size_t out_words = (total * W + 63u) / 64u; + if (out_words != 0) + std::memset(out, 0, out_words * sizeof(std::uint64_t)); + if (nkeys == 0 || nleaves == 0) + return; + + for (std::size_t ow = 0; ow < out_words; ++ow) + { + std::uint64_t word = 0; + const std::size_t base = ow * lanes_per_word; + const unsigned nlanes = static_cast( + total - base < lanes_per_word ? total - base : lanes_per_word); + DPF_UNROLL_LOOP + for (unsigned t = 0; t < nlanes; ++t) + { + const std::size_t g = base + t; + const std::size_t i = g / nkeys; + const std::size_t k = g - i * nkeys; + const std::size_t src_bit = i * W; + const std::uint64_t lane + = (keys[k][src_bit / 64u] >> (src_bit % 64u)) & lane_mask; + word |= lane << (t * W); + } + out[ow] = word; + } +} + +template +HEDLEY_NO_THROW +void deinterleave_packed_w(std::uint64_t * const * HEDLEY_RESTRICT keys, + const std::uint64_t * HEDLEY_RESTRICT in, std::size_t nkeys, + std::size_t nleaves) noexcept +{ + static_assert(W == 2 || W == 4, "packed width must be 2 or 4"); + constexpr std::uint64_t lane_mask = (std::uint64_t{1} << W) - 1u; + if (nkeys == 0 || nleaves == 0) + return; + for (std::size_t k = 0; k < nkeys; ++k) + { + const std::size_t words = (nleaves * W + 63u) / 64u; + if (words != 0) + std::memset(keys[k], 0, words * sizeof(std::uint64_t)); + } + + const std::size_t total = nkeys * nleaves; + for (std::size_t g = 0; g < total; ++g) + { + const std::size_t i = g / nkeys; + const std::size_t k = g - i * nkeys; + const std::size_t src_bit = g * W; + const std::uint64_t lane + = (in[src_bit / 64u] >> (src_bit % 64u)) & lane_mask; + const std::size_t dst_bit = i * W; + keys[k][dst_bit / 64u] |= lane << (dst_bit % 64u); + } +} + +template +HEDLEY_NO_THROW +void interleave_wide(T * HEDLEY_RESTRICT out, const T * const * HEDLEY_RESTRICT keys, + std::size_t nkeys, std::size_t nleaves) noexcept +{ + if (nkeys == 0 || nleaves == 0) + return; + if (nkeys == 1) + { + std::memcpy(out, keys[0], nleaves * sizeof(T)); + return; + } + for (std::size_t i = 0; i < nleaves; ++i) + { + T * dst = out + i * nkeys; + DPF_UNROLL_LOOP + for (std::size_t k = 0; k < nkeys; ++k) + dst[k] = keys[k][i]; + } +} + +template +HEDLEY_NO_THROW +void deinterleave_wide(T * const * HEDLEY_RESTRICT keys, + const T * HEDLEY_RESTRICT in, std::size_t nkeys, std::size_t nleaves) noexcept +{ + if (nkeys == 0 || nleaves == 0) + return; + if (nkeys == 1) + { + std::memcpy(keys[0], in, nleaves * sizeof(T)); + return; + } + for (std::size_t i = 0; i < nleaves; ++i) + { + const T * src = in + i * nkeys; + DPF_UNROLL_LOOP + for (std::size_t k = 0; k < nkeys; ++k) + keys[k][i] = src[k]; + } +} + +} // namespace interleave_detail + +/// @brief Interleave `nkeys` leaf vectors of length `nleaves` into `out`. +/// @tparam LaneT an integer, a packed lane (`bit`, `twobit`, `nyble`, +/// `gf2`, `gf22`, `gf24`), or a trivially copyable element of at +/// most 8 bytes (`gf28`, `gf216`, `gf232`, `gf264`) +/// @param out destination storage (`leaf_storage_t`; see file comment) +/// @param keys array of `nkeys` pointers to per-key leaf storage +/// @param nkeys number of keys (`m`) +/// @param nleaves number of leaves per key (`L`) +/// \complexity Θ(`nkeys * nleaves`) lane moves. Wide types stream by leaf; +/// 1-bit uses 8×8 transpose tiles; 2/4-bit fill output words. +template +HEDLEY_NO_THROW +void interleave_leaves(leaf_storage_t * out, + const leaf_storage_t * const * keys, std::size_t nkeys, + std::size_t nleaves) noexcept +{ + if constexpr (utils::is_packed_subbyte_v) + { + constexpr unsigned w = utils::packed_lane_bits_v; + if constexpr (w == 1) + interleave_detail::interleave_bits(out, keys, nkeys, nleaves); + else if constexpr (w == 2) + interleave_detail::interleave_packed_w<2>(out, keys, nkeys, nleaves); + else + { + static_assert(w == 4, "packed lane width must be 1, 2, or 4"); + interleave_detail::interleave_packed_w<4>(out, keys, nkeys, nleaves); + } + } + else if constexpr ((std::is_integral_v && !std::is_same_v) + || (std::is_trivially_copyable_v && std::is_standard_layout_v + && sizeof(LaneT) > 0 && sizeof(LaneT) <= 8)) + { + interleave_detail::interleave_wide(out, keys, nkeys, nleaves); + } + else + { + static_assert(std::is_integral_v, + "interleave_leaves LaneT must be an integer, a packed lane, or a field element of at most 8 bytes"); + } +} + +/// @brief Inverse of `interleave_leaves`: split one interleaved buffer into +/// `nkeys` per-key leaf vectors of length `nleaves`. +/// @tparam LaneT same set as `interleave_leaves` +/// @param keys destination per-key storage pointers +/// @param in interleaved source +/// @param nkeys number of keys +/// @param nleaves number of leaves per key +/// \complexity Same order as `interleave_leaves`. +template +HEDLEY_NO_THROW +void deinterleave_leaves(leaf_storage_t * const * keys, + const leaf_storage_t * in, std::size_t nkeys, + std::size_t nleaves) noexcept +{ + if constexpr (utils::is_packed_subbyte_v) + { + constexpr unsigned w = utils::packed_lane_bits_v; + if constexpr (w == 1) + interleave_detail::deinterleave_bits(keys, in, nkeys, nleaves); + else if constexpr (w == 2) + interleave_detail::deinterleave_packed_w<2>(keys, in, nkeys, nleaves); + else + { + static_assert(w == 4, "packed lane width must be 1, 2, or 4"); + interleave_detail::deinterleave_packed_w<4>(keys, in, nkeys, nleaves); + } + } + else if constexpr ((std::is_integral_v && !std::is_same_v) + || (std::is_trivially_copyable_v && std::is_standard_layout_v + && sizeof(LaneT) > 0 && sizeof(LaneT) <= 8)) + { + interleave_detail::deinterleave_wide(keys, in, nkeys, nleaves); + } + else + { + static_assert(std::is_integral_v, + "deinterleave_leaves LaneT must be an integer, a packed lane, or a field element of at most 8 bytes"); + } +} + +/// @brief Dot an interleaved 1-bit cohort with `weights`, as `modint`. +/// @details `bits` is the buffer from `interleave_leaves`: leaf `i` +/// is the integer whose bit `k` is key `k`'s leaf `i`. That integer, +/// reduced modulo `2^Nbits` (the low `Nbits` bits), is one `modint`. +/// The result is `sum_i modint(leaf i) * weights[i]`. `weights[i]` +/// may be a `modint` or an integer. +/// When `nkeys == Nbits` and that width is 8, 16, 32, 64, or 128, +/// the leaves are contiguous native words and the product is a +/// straight multiply-accumulate. +/// @tparam Nbits modulus width, `1` through `256` +/// @param bits interleaved 1-bit stream +/// @param nleaves number of leaves (domain points) +/// @param nkeys number of keys that were interleaved +/// @param weights one weight per leaf +/// @return the inner product in `modint` +/// \complexity Θ(`nleaves`) multiplications in the `modint` word. Aligned +/// widths do one native multiply per leaf; other widths extract +/// the `Nbits` bits of each leaf first. +template +HEDLEY_NO_THROW +HEDLEY_WARN_UNUSED_RESULT +modint interleaved_bits_inner_product(const std::uint64_t * bits, + std::size_t nleaves, std::size_t nkeys, Weights && weights) +{ + using mod = modint; + using limb = typename mod::integral_type; + mod acc{}; + if (nleaves == 0 || nkeys == 0 || bits == nullptr) + return acc; + + auto limb_of = [](auto v) -> limb { + using T = std::decay_t; + if constexpr (std::is_same_v) + return static_cast(v); + else + return static_cast(mod(static_cast(v))); + }; + + auto mac = [&](limb v, std::size_t i) { + acc += mod(v) * mod(limb_of(weights[i])); + }; + + if constexpr (Nbits == 128) + { + if (nkeys == 128) + { + limb sum{}; + for (std::size_t i = 0; i < nleaves; ++i) + { + const std::uint64_t * p = bits + i * 2u; + const limb v = static_cast(p[0]) + | (static_cast(p[1]) << 64); + sum += v * limb_of(weights[i]); + } + return mod(sum); + } + } + if constexpr (Nbits == 8 || Nbits == 16 || Nbits == 32 || Nbits == 64) + { + if (nkeys == Nbits) + { + limb sum{}; + for (std::size_t i = 0; i < nleaves; ++i) + { + limb v{}; + if constexpr (Nbits == 64) + v = static_cast(bits[i]); + else if constexpr (Nbits == 32) + { + const std::uint64_t word = bits[i / 2u]; + v = static_cast((i & 1u) ? (word >> 32) : (word & 0xffffffffu)); + } + else if constexpr (Nbits == 16) + { + const std::uint64_t word = bits[i / 4u]; + v = static_cast((word >> ((i % 4u) * 16u)) & 0xffffu); + } + else + { + const std::uint64_t word = bits[i / 8u]; + v = static_cast((word >> ((i % 8u) * 8u)) & 0xffu); + } + sum += v * limb_of(weights[i]); + } + return mod(sum); + } + } + + for (std::size_t i = 0; i < nleaves; ++i) + { + const std::size_t bit_pos = i * nkeys; + limb v{}; + if constexpr (Nbits <= 64) + { + const unsigned take = static_cast( + nkeys < Nbits ? nkeys : Nbits); + v = static_cast(interleave_detail::read_bits(bits, bit_pos, take)); + } + else + { + unsigned left = static_cast(Nbits); + std::size_t pos = bit_pos; + unsigned shift = 0; + while (left != 0 && shift < nkeys) + { + const unsigned room = static_cast(nkeys - shift); + const unsigned n = left < 64u ? left : 64u; + const unsigned take = n < room ? n : room; + const auto chunk = interleave_detail::read_bits(bits, pos, take); + v |= static_cast(chunk) << shift; + shift += take; + pos += take; + left -= take; + if (take == 0) + break; + } + } + mac(v, i); + } + return acc; +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_INTERLEAVE_LEAVES_HPP__ diff --git a/include/dpf/interval.hpp b/include/dpf/interval.hpp index 740183e..fea2130 100644 --- a/include/dpf/interval.hpp +++ b/include/dpf/interval.hpp @@ -5,7 +5,9 @@ /// `p ≤ (x − r) mod 2^n ≤ q`, and the false payload otherwise. /// /// The key is one `lt` comparison at `γ = r − 1`, the Boyle–Chandran– -/// Gilboa–Gupta–Ishai–Kumar–Rathee reduction (EUROCRYPT 2021, Fig. 3). +/// Gilboa–Gupta–Ishai–Kumar–Rathee reduction (EUROCRYPT 2021, Fig. 3; +/// ePrint 2020/1392). Their Section 4.1 is one DCF for a public interval, +/// where the earlier gate used about two. /// Evaluation walks that key at the two public shifts of `x` and adds /// a secret-shared correction. Seed corrections, advice bits, leaves, /// and the path memoizer stay single-path. @@ -26,6 +28,8 @@ #include "dpf/dcf.hpp" #include "dpf/eval_unified.hpp" #include "dpf/geneval.hpp" +#include "dpf/grow.hpp" +#include "dpf/grow_ds.hpp" #include "dpf/incremental.hpp" #include "dpf/output_buffer.hpp" #include "dpf/secret_share.hpp" @@ -86,7 +90,9 @@ struct ic_key detail::cmp_group_info>::custom, detail::group_elem, uint64_t>; - key_type key; + /// @brief Inner comparison key. Eval that accepts a `dpf_key` also accepts + /// this object and reads `dpf_key`. + key_type dpf_key; uint64_t lo = 0; uint64_t hi = 0; uint64_t input_mask = 0; @@ -103,7 +109,7 @@ struct ic_key ic_key(key_type k, uint64_t lo_in, uint64_t hi_in, uint64_t nmask, uint64_t gmask, share_type dshare, share_type cshare, share_type dcoeff, share_type ccoeff) noexcept(std::is_nothrow_move_constructible_v) - : key(std::move(k)) + : dpf_key(std::move(k)) , lo(lo_in) , hi(hi_in) , input_mask(nmask) @@ -417,7 +423,8 @@ Input gamma_of(Input r) } template -auto eval_one(const IcKey & k, Query && x, Memo & memo) +auto eval_one(const IcKey & k, Query && x, Memo & memo, + proof_token * pi = nullptr) { if (!k.assigned) throw std::invalid_argument( @@ -435,10 +442,10 @@ auto eval_one(const IcKey & k, Query && x, Memo & memo) else return detail::group_from_beta(v); }; - const auto a = opened(eval_point(dpf::cmp, k.key, - input_from_bits(xp), memo)); - const auto b = opened(eval_point(dpf::cmp, k.key, - input_from_bits(xq), memo)); + const auto a = opened(detail::incr::eval_cmp_point_impl(k.dpf_key, + input_from_bits(xp), memo, pi)); + const auto b = opened(detail::incr::eval_cmp_point_impl(k.dpf_key, + input_from_bits(xq), memo, pi)); const int cx = public_cx(xu, k.lo, k.hi, k.input_mask); auto scaled = detail::group_zero(a); if (cx == 1) @@ -453,10 +460,12 @@ auto eval_one(const IcKey & k, Query && x, Memo & memo) else { const uint64_t a = opened_u64( - eval_point(dpf::cmp, k.key, input_from_bits(xp), memo), + detail::incr::eval_cmp_point_impl(k.dpf_key, + input_from_bits(xp), memo, pi), k.group_mask); const uint64_t b = opened_u64( - eval_point(dpf::cmp, k.key, input_from_bits(xq), memo), + detail::incr::eval_cmp_point_impl(k.dpf_key, + input_from_bits(xq), memo, pi), k.group_mask); const int cx = public_cx(xu, k.lo, k.hi, k.input_mask); uint64_t scaled = 0; @@ -482,6 +491,8 @@ auto eval_one(const IcKey & k, Query && x, Memo & memo) /// @param r the secret input mask /// @param spec the public bounds and payloads /// @return Dealer key for public bounds `spec` and secret mask `r` +/// @note Following Boyle, Chandran, Gilboa, Gupta, Ishai, Kumar, and Rathee, EUROCRYPT 2021, Fig. 3 (ePrint 2020/1392): one comparison key, evaluated at two public shifts. +/// \complexity O(n) time and O(n) key size. n is the domain bitlength (`depth`). The loop does two interior PRG expansions and writes one correction word per level, then builds one exterior leaf per output. template & spec) /// @param r1 party 1's share of the mask /// @param rng the Doerner–Shelat randomness tapes /// @param spec the public bounds and payloads +/// @param tags optional `verifiable` or `extractable` markers /// @return the two party keys +/// \complexity O(n) time. One `ds_advance_level` per level: two PRG expansions and one `prepare_level`. n is `depth`. +/// \rounds No sockets. This is the in-process transcript. A networked walk is `dpf::party::dist::point_party`. +/// \communication none here. `local_cw_protocol` opens the correction word locally. +/// \preprocessing Per level, `prepare_level` draws one `ds_cw_pads` (two parties × a 128-bit rand, a 128-bit gamma, and a bit) and two `ds_and_pads`. Arithmetic inputs also run a carry chain of n-1 bit-AND triples in `encode_walk_shares`. template + typename Beta, + typename ...Tags> HEDLEY_WARN_UNUSED_RESULT auto make_dpf_doerner_shelat(InputT r0, InputT r1, - ds_randomness rng, const ic_pack & spec) + ds_randomness rng, const ic_pack & spec, + Tags && ...tags) { using input_type = std::decay_t; detail::ic_impl::check_input(); @@ -536,7 +554,8 @@ auto make_dpf_doerner_shelat(InputT r0, InputT r1, const input_type g0 = r0; const input_type g1 = utils::xor_input_shares(g0, gamma); auto inner = make_dpf_doerner_shelat(g0, g1, - std::move(rng), detail::ic_impl::inner_lt(spec)); + std::move(rng), detail::ic_impl::inner_lt(spec), + std::forward(tags)...); return detail::ic_impl::finish(r_bits, spec, std::move(inner)); } @@ -547,16 +566,23 @@ auto make_dpf_doerner_shelat(InputT r0, InputT r1, /// @param r1 party 1's share of the mask /// @param rng the Doerner–Shelat randomness tapes /// @param spec the public bounds and payloads +/// @param tags optional `verifiable` or `extractable` markers /// @return the two party keys +/// \complexity O(n) time. One `ds_advance_level` per level: two PRG expansions and one `prepare_level`. n is `depth`. +/// \rounds No sockets. This is the in-process transcript. A networked walk is `dpf::party::dist::point_party`. +/// \communication none here. `local_cw_protocol` opens the correction word locally. +/// \preprocessing Per level, `prepare_level` draws one `ds_cw_pads` (two parties × a 128-bit rand, a 128-bit gamma, and a bit) and two `ds_and_pads`. Arithmetic inputs also run a carry chain of n-1 bit-AND triples in `encode_walk_shares`. template + typename Beta, + typename ...Tags> HEDLEY_WARN_UNUSED_RESULT auto make_dpf_doerner_shelat(arith_input_t, InputT r0, InputT r1, - ds_randomness rng, const ic_pack & spec) + ds_randomness rng, const ic_pack & spec, + Tags && ...tags) { using input_type = std::decay_t; detail::ic_impl::check_input(); @@ -570,42 +596,56 @@ auto make_dpf_doerner_shelat(arith_input_t, InputT r0, InputT r1, (detail::ic_impl::bits_of(r0) - 1ULL) & nmask); const input_type g1 = r1; auto inner = make_dpf_doerner_shelat( - arith_input, g0, g1, std::move(rng), detail::ic_impl::inner_lt(spec)); + arith_input, g0, g1, std::move(rng), detail::ic_impl::inner_lt(spec), + std::forward(tags)...); return detail::ic_impl::finish( detail::ic_impl::bits_of(r), spec, std::move(inner)); } /// @brief XOR shares, sampled from the library entropy source. /// @return the two party keys +/// \complexity O(n) time. One `ds_advance_level` per level: two PRG expansions and one `prepare_level`. n is `depth`. +/// \rounds No sockets. This is the in-process transcript. A networked walk is `dpf::party::dist::point_party`. +/// \communication none here. `local_cw_protocol` opens the correction word locally. +/// \preprocessing Per level, `prepare_level` draws one `ds_cw_pads` (two parties × a 128-bit rand, a 128-bit gamma, and a bit) and two `ds_and_pads`. Arithmetic inputs also run a carry chain of n-1 bit-AND triples in `encode_walk_shares`. template + typename Beta, + typename ...Tags> HEDLEY_WARN_UNUSED_RESULT -auto make_dpf_doerner_shelat(InputT r0, InputT r1, const ic_pack & spec) +auto make_dpf_doerner_shelat(InputT r0, InputT r1, const ic_pack & spec, + Tags && ...tags) { using block = typename InteriorPRG::block_type; ds_randomness rng{ dpf::uniform_sample, {}}; return make_dpf_doerner_shelat( - std::move(r0), std::move(r1), rng, spec); + std::move(r0), std::move(r1), rng, spec, + std::forward(tags)...); } /// @brief Additive shares, sampled from the library entropy source. /// @return the two party keys +/// \complexity O(n) time. One `ds_advance_level` per level: two PRG expansions and one `prepare_level`. n is `depth`. +/// \rounds No sockets. This is the in-process transcript. A networked walk is `dpf::party::dist::point_party`. +/// \communication none here. `local_cw_protocol` opens the correction word locally. +/// \preprocessing Per level, `prepare_level` draws one `ds_cw_pads` (two parties × a 128-bit rand, a 128-bit gamma, and a bit) and two `ds_and_pads`. Arithmetic inputs also run a carry chain of n-1 bit-AND triples in `encode_walk_shares`. template + typename Beta, + typename ...Tags> HEDLEY_WARN_UNUSED_RESULT auto make_dpf_doerner_shelat(arith_input_t, InputT r0, InputT r1, - const ic_pack & spec) + const ic_pack & spec, Tags && ...tags) { using block = typename InteriorPRG::block_type; ds_randomness rng{ dpf::uniform_sample, {}}; return make_dpf_doerner_shelat( - arith_input, std::move(r0), std::move(r1), rng, spec); + arith_input, std::move(r0), std::move(r1), rng, spec, + std::forward(tags)...); } /// @} @@ -633,7 +673,7 @@ void assign_cmp(ic_key<0, Key, Input, Beta> & k0, const auto delta = detail::group_sub( detail::group_from_beta(if_true), detail::group_from_beta(if_false)); const auto fval = detail::group_from_beta(if_false); - assign_cmp(k0.key, k1.key, + assign_cmp(k0.dpf_key, k1.dpf_key, detail::group_to_beta(delta), detail::group_to_beta(detail::group_zero(layout))); k0.delta_share = detail::group_mul(k0.delta_coeff, delta); @@ -656,7 +696,7 @@ void assign_cmp(ic_key<0, Key, Input, Beta> & k0, detail::dcf_impl::beta_delta_u64(if_true, if_false, mask); const uint64_t fval = detail::dcf_impl::beta_to_u64_simple(if_false, mask); - assign_cmp(k0.key, k1.key, + assign_cmp(k0.dpf_key, k1.dpf_key, detail::dcf_impl::u64_to_beta(delta), detail::dcf_impl::u64_to_beta(0)); k0.delta_share = detail::ic_impl::mul_mask(k0.delta_coeff, delta, mask); @@ -680,6 +720,7 @@ void assign_cmp(ic_key<0, Key, Input, Beta> & k0, /// @param x the `x` /// @param memo the memoizer reused across queries /// @return Point evaluation +/// \complexity Two comparison point-walks (`eval_cmp_point_impl`), each O(n) interior steps, plus O(1) group arithmetic. n is the key depth. A path memoizer reuses a shared prefix. template , typename = std::enable_if_t>> @@ -707,6 +748,7 @@ auto eval_point(ic_fn, const IcKey & key, Query && x, Memo && memo = Memo{}) /// @param to the inclusive end of the range /// @param buf the output buffer /// @param memo the memoizer reused across queries +/// \complexity One `eval_one` per input from `from` through `to`. Each `eval_one` is two comparison point-walks, so this is not the truncated-tree interval walk. A path memoizer reuses prefixes across those walks. Counted the `for (x = a; x != b; ++x)` loop. template >> void eval_interval(ic_fn, const IcKey & key, Lane from, Lane to, @@ -731,6 +773,7 @@ void eval_interval(ic_fn, const IcKey & key, Lane from, Lane to, } /// @brief Inclusive interval `[from, to]`, with a fresh path memoizer. +/// \complexity One `eval_one` per input from `from` through `to`. Each `eval_one` is two comparison point-walks, so this is not the truncated-tree interval walk. A path memoizer reuses prefixes across those walks. Counted the `for (x = a; x != b; ++x)` loop. template >> void eval_interval(ic_fn, const IcKey & key, Lane from, Lane to, Buffer && buf) @@ -758,6 +801,7 @@ void eval_interval(ic_fn, const IcKey & key, Lane from, Lane to, Buffer && buf) /// @param end the iterator past the last query /// @param buf the output buffer /// @param memo the memoizer reused across queries +/// \complexity One `eval_one` per input from `from` through `to`. Each `eval_one` is two comparison point-walks, so this is not the truncated-tree interval walk. A path memoizer reuses prefixes across those walks. Counted the `for (x = a; x != b; ++x)` loop. template >> void eval_sequence(ic_fn, const IcKey & key, Iter begin, Iter end, @@ -769,6 +813,7 @@ void eval_sequence(ic_fn, const IcKey & key, Iter begin, Iter end, } /// @brief Evaluate `[begin, end)`, with a fresh path memoizer. +/// \complexity One `eval_one` per input from `from` through `to`. Each `eval_one` is two comparison point-walks, so this is not the truncated-tree interval walk. A path memoizer reuses prefixes across those walks. Counted the `for (x = a; x != b; ++x)` loop. template >> void eval_sequence(ic_fn, const IcKey & key, Iter begin, Iter end, Buffer && buf) @@ -829,8 +874,70 @@ auto make_output_buffer(ic_fn, const IcKey & key, Lane from, Lane to) /// @return the opened party shares /// @{ +namespace detail +{ +namespace ic_impl +{ + +/// @brief Fill `out` from a verifiable IC key pair, reusing one path memoizer. +template +void geneval_ic_eval(geneval_cmp_result & out, const IcKey0 & k0, + const IcKey1 & k1, Iter begin, Iter end) +{ + using key_type = unwrap_party_key_t; + constexpr std::size_t depth = key_type::depth; + out.live_levels = depth; + out.mask = k0.dpf_key.cmp().mask; + out.cw_last = k0.dpf_key.cw_last(); + out.addend0 = k0.dpf_key.cmp_addend().raw(); + out.addend1 = k1.dpf_key.cmp_addend().raw(); + out.correction_words.resize(depth); + out.correction_advice.resize(depth); + if constexpr (key_type::cmp_block > 0) + { + out.value_cw.resize(key_type::cmp_checkpoints); + for (std::size_t i = 0; i < key_type::cmp_checkpoints; ++i) + out.value_cw[i] = k0.dpf_key.value_cw(i); + out.tail_cw.resize(key_type::cmp_tail); + for (std::size_t z = 0; z < key_type::cmp_tail; ++z) + out.tail_cw[z] = k0.dpf_key.tail_cw(z); + } + else + out.value_cw.resize(depth); + for (std::size_t level = 0; level < depth; ++level) + { + out.correction_words[level] = k0.dpf_key.correction_word(level); + out.correction_advice[level] = + static_cast(k0.dpf_key.correction_advice(level)); + if constexpr (key_type::cmp_block == 0) + out.value_cw[level] = k0.dpf_key.value_cw(level); + } + // Empty query lists keep default-constructed (zero) tokens. `verify` + // rejects the all-zero token, so an empty geneval does not verify as + // two matching zeros. + detail::vdpf::init_proof(out.proof0, k0.dpf_key); + detail::vdpf::init_proof(out.proof1, k1.dpf_key); + auto path0 = make_basic_path_memoizer(k0.dpf_key); + auto path1 = make_basic_path_memoizer(k1.dpf_key); + for (auto it = begin; it != end; ++it) + { + out.party0.push_back(opened_u64( + eval_one(k0, *it, path0, &out.proof0), out.mask)); + out.party1.push_back(opened_u64( + eval_one(k1, *it, path1, &out.proof1), out.mask)); + } + detail::vdpf::fold_output_binding(out.proof0, k0.dpf_key); + detail::vdpf::fold_output_binding(out.proof1, k1.dpf_key); +} + +} // namespace ic_impl +} // namespace detail + /// @brief XOR mask. `r0 XOR r1` is the secret mask. Each query is /// returned already combined into the interval share. +/// @details Builds a verifiable inner comparison key and folds correction +/// seeds into `proof0` / `proof1` while reusing one path memoizer per party. +/// An empty query range leaves both tokens zero; those do not verify. template HEDLEY_WARN_UNUSED_RESULT @@ -844,33 +951,8 @@ geneval_cmp_result geneval_ic(InputT r0, InputT r1, Iter begin, Iter end, return out; auto keys = make_dpf_doerner_shelat(std::move(r0), std::move(r1), - std::move(rng), spec); - const auto & k0 = keys.first; - const auto & k1 = keys.second; - using key_type = unwrap_party_key_t::key_type>; - constexpr std::size_t depth = key_type::depth; - out.live_levels = depth; - out.mask = k0.key.cmp().mask; - out.cw_last = k0.key.cw_last(); - out.addend0 = k0.key.cmp_addend().raw(); - out.addend1 = k1.key.cmp_addend().raw(); - out.correction_words.resize(depth); - out.correction_advice.resize(depth); - out.value_cw.resize(depth); - for (std::size_t level = 0; level < depth; ++level) - { - out.correction_words[level] = k0.key.correction_word(level); - out.correction_advice[level] = - static_cast(k0.key.correction_advice(level)); - out.value_cw[level] = k0.key.value_cw(level); - } - for (auto it = begin; it != end; ++it) - { - out.party0.push_back(detail::ic_impl::opened_u64( - eval_point(ic, k0, *it), out.mask)); - out.party1.push_back(detail::ic_impl::opened_u64( - eval_point(ic, k1, *it), out.mask)); - } + std::move(rng), spec, dpf::verifiable{}); + detail::ic_impl::geneval_ic_eval(out, keys.first, keys.second, begin, end); return out; } @@ -888,38 +970,339 @@ geneval_cmp_result geneval_ic(arith_input_t, InputT r0, InputT r1, Iter begin, return out; auto keys = make_dpf_doerner_shelat(arith_input, std::move(r0), std::move(r1), - std::move(rng), spec); - const auto & k0 = keys.first; - const auto & k1 = keys.second; - using key_type = unwrap_party_key_t::key_type>; - constexpr std::size_t depth = key_type::depth; - out.live_levels = depth; - out.mask = k0.key.cmp().mask; - out.cw_last = k0.key.cw_last(); - out.addend0 = k0.key.cmp_addend().raw(); - out.addend1 = k1.key.cmp_addend().raw(); - out.correction_words.resize(depth); - out.correction_advice.resize(depth); - out.value_cw.resize(depth); - for (std::size_t level = 0; level < depth; ++level) - { - out.correction_words[level] = k0.key.correction_word(level); - out.correction_advice[level] = - static_cast(k0.key.correction_advice(level)); - out.value_cw[level] = k0.key.value_cw(level); - } - for (auto it = begin; it != end; ++it) - { - out.party0.push_back(detail::ic_impl::opened_u64( - eval_point(ic, k0, *it), out.mask)); - out.party1.push_back(detail::ic_impl::opened_u64( - eval_point(ic, k1, *it), out.mask)); - } + std::move(rng), spec, dpf::verifiable{}); + detail::ic_impl::geneval_ic_eval(out, keys.first, keys.second, begin, end); return out; } /// @} +// --------------------------------------------------------------------------- +// Grow adaptations: run on the inner `dpf_key`, then refresh `cr_share` from +// the secret mask `r` when depth changes (`add_output` copies the fields). +// --------------------------------------------------------------------------- + +template +HEDLEY_WARN_UNUSED_RESULT +auto extend(const ic_key & k0, + const ic_key & k1, uint64_t r, bool bit, InputT x, + Specs &&... specs) +{ + auto inner = dpf::extend(k0.dpf_key, k1.dpf_key, bit, x, + std::forward(specs)...); + using new_raw = typename std::decay_t::key_type; + const uint64_t nmask = detail::ic_impl::input_mask_of(); + const uint64_t gmask = k0.group_mask; + using share_t = typename ic_key::share_type; + share_t c0{}; + share_t c1{}; + if constexpr (is_wildcard_v) + { + // Wildcard: keep cr_coeff; concrete cr_share is filled by assign_cmp. + c0 = k0.cr_share; + c1 = k1.cr_share; + } + else if constexpr (detail::cmp_group_info::custom) + { + using prg = typename new_raw::interior_prg; + const auto layout = detail::group_layout>(); + const auto cr_g = detail::group_scalar( + detail::ic_impl::correction_s(r, k0.lo, k0.hi, nmask), layout); + const auto target = detail::group_add( + detail::group_mul(k0.delta_share, cr_g), // wrong: need open δ + detail::group_zero(layout)); + (void)target; + // Reconstruct δ = d0+d1, if_false from old cr, then new cr = δ·c_r + f. + const auto delta = detail::group_add(k0.delta_share, k1.delta_share); + const auto old_cr_open = detail::group_add(k0.cr_share, k1.cr_share); + const auto old_cr_term = detail::group_mul(delta, + detail::group_scalar( + detail::ic_impl::correction_s(r, k0.lo, k0.hi, k0.input_mask), + layout)); + const auto if_false = detail::group_sub(old_cr_open, old_cr_term); + const auto new_target = + detail::group_add(detail::group_mul(delta, cr_g), if_false); + const auto blind = detail::group_from_node( + dpf::uniform_sample(), layout); + c0 = blind; + c1 = detail::group_sub(new_target, blind); + } + else + { + const uint64_t delta = + (static_cast(k0.delta_share) + + static_cast(k1.delta_share)) + & gmask; + const uint64_t old_cr_open = + (static_cast(k0.cr_share) + + static_cast(k1.cr_share)) + & gmask; + const uint64_t old_cr_term = detail::ic_impl::mul_mask(delta, + detail::ic_impl::correction(r, k0.lo, k0.hi, k0.input_mask, gmask), + gmask); + const uint64_t if_false = + (old_cr_open + detail::dcf_impl::neg_m(old_cr_term, gmask)) & gmask; + const uint64_t cr = + detail::ic_impl::correction(r, k0.lo, k0.hi, nmask, gmask); + const uint64_t target = + (detail::ic_impl::mul_mask(delta, cr, gmask) + if_false) & gmask; + const uint64_t blind = detail::dcf_impl::sample_addend_blind(gmask, + [] { + return dpf::uniform_sample(); + }); + uint64_t a0 = 0, a1 = 0; + detail::incr::split_cmp_addend(target, gmask, blind, a0, a1); + c0 = static_cast(a0); + c1 = static_cast(a1); + } + auto out0 = detail::ic_impl::make_side( + std::move(inner.first), k0.lo, k0.hi, nmask, gmask, k0.delta_share, c0, + k0.delta_coeff, k0.cr_coeff); + auto out1 = detail::ic_impl::make_side( + std::move(inner.second), k1.lo, k1.hi, nmask, gmask, k1.delta_share, c1, + k1.delta_coeff, k1.cr_coeff); + out0.assigned = k0.assigned; + out1.assigned = k1.assigned; + return std::make_pair(std::move(out0), std::move(out1)); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto extend(const ic_key & k0, + const ic_key & k1, uint64_t r, InputT x, + Specs &&... specs) +{ + const bool bit = detail::grow_impl::bit_at( + static_cast(x), Key::depth); + return extend(k0, k1, r, bit, x, std::forward(specs)...); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto add_output(const ic_key & k0, + const ic_key & k1, InputT x, Specs &&... specs) +{ + auto inner = dpf::add_output(k0.dpf_key, k1.dpf_key, x, + std::forward(specs)...); + using new_raw = typename std::decay_t::key_type; + auto out0 = detail::ic_impl::make_side( + std::move(inner.first), k0.lo, k0.hi, k0.input_mask, k0.group_mask, + k0.delta_share, k0.cr_share, k0.delta_coeff, k0.cr_coeff); + auto out1 = detail::ic_impl::make_side( + std::move(inner.second), k1.lo, k1.hi, k1.input_mask, k1.group_mask, + k1.delta_share, k1.cr_share, k1.delta_coeff, k1.cr_coeff); + out0.assigned = k0.assigned; + out1.assigned = k1.assigned; + return std::make_pair(std::move(out0), std::move(out1)); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto extend(const ic_key & k0, + const ic_key & k1, uint64_t r, Memo0 & m0, Memo1 & m1, + bool bit, InputT x, Specs &&... specs) +{ + auto inner = dpf::extend(k0.dpf_key, k1.dpf_key, m0, m1, bit, x, + std::forward(specs)...); + using new_raw = typename std::decay_t::key_type; + const uint64_t nmask = detail::ic_impl::input_mask_of(); + const uint64_t gmask = k0.group_mask; + using share_t = typename ic_key::share_type; + share_t c0{}; + share_t c1{}; + if constexpr (is_wildcard_v) + { + c0 = k0.cr_share; + c1 = k1.cr_share; + } + else if constexpr (detail::cmp_group_info::custom) + { + using prg = typename new_raw::interior_prg; + const auto layout = detail::group_layout>(); + const auto cr_g = detail::group_scalar( + detail::ic_impl::correction_s(r, k0.lo, k0.hi, nmask), layout); + const auto delta = detail::group_add(k0.delta_share, k1.delta_share); + const auto old_cr_open = detail::group_add(k0.cr_share, k1.cr_share); + const auto old_cr_term = detail::group_mul(delta, + detail::group_scalar( + detail::ic_impl::correction_s(r, k0.lo, k0.hi, k0.input_mask), + layout)); + const auto if_false = detail::group_sub(old_cr_open, old_cr_term); + const auto new_target = + detail::group_add(detail::group_mul(delta, cr_g), if_false); + const auto blind = detail::group_from_node( + dpf::uniform_sample(), layout); + c0 = blind; + c1 = detail::group_sub(new_target, blind); + } + else + { + const uint64_t delta = + (static_cast(k0.delta_share) + + static_cast(k1.delta_share)) + & gmask; + const uint64_t old_cr_open = + (static_cast(k0.cr_share) + + static_cast(k1.cr_share)) + & gmask; + const uint64_t old_cr_term = detail::ic_impl::mul_mask(delta, + detail::ic_impl::correction(r, k0.lo, k0.hi, k0.input_mask, gmask), + gmask); + const uint64_t if_false = + (old_cr_open + detail::dcf_impl::neg_m(old_cr_term, gmask)) & gmask; + const uint64_t cr = + detail::ic_impl::correction(r, k0.lo, k0.hi, nmask, gmask); + const uint64_t target = + (detail::ic_impl::mul_mask(delta, cr, gmask) + if_false) & gmask; + const uint64_t blind = detail::dcf_impl::sample_addend_blind(gmask, + [] { + return dpf::uniform_sample(); + }); + uint64_t a0 = 0, a1 = 0; + detail::incr::split_cmp_addend(target, gmask, blind, a0, a1); + c0 = static_cast(a0); + c1 = static_cast(a1); + } + auto out0 = detail::ic_impl::make_side( + std::move(inner.first), k0.lo, k0.hi, nmask, gmask, k0.delta_share, c0, + k0.delta_coeff, k0.cr_coeff); + auto out1 = detail::ic_impl::make_side( + std::move(inner.second), k1.lo, k1.hi, nmask, gmask, k1.delta_share, c1, + k1.delta_coeff, k1.cr_coeff); + out0.assigned = k0.assigned; + out1.assigned = k1.assigned; + return std::make_pair(std::move(out0), std::move(out1)); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto add_output(const ic_key & k0, + const ic_key & k1, Memo0 & m0, Memo1 & m1, InputT x, + Specs &&... specs) +{ + auto inner = dpf::add_output(k0.dpf_key, k1.dpf_key, m0, m1, x, + std::forward(specs)...); + using new_raw = typename std::decay_t::key_type; + auto out0 = detail::ic_impl::make_side( + std::move(inner.first), k0.lo, k0.hi, k0.input_mask, k0.group_mask, + k0.delta_share, k0.cr_share, k0.delta_coeff, k0.cr_coeff); + auto out1 = detail::ic_impl::make_side( + std::move(inner.second), k1.lo, k1.hi, k1.input_mask, k1.group_mask, + k1.delta_share, k1.cr_share, k1.delta_coeff, k1.cr_coeff); + out0.assigned = k0.assigned; + out1.assigned = k1.assigned; + return std::make_pair(std::move(out0), std::move(out1)); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto extend_ds(const ic_key & k0, + const ic_key & k1, uint64_t r, Memo0 & m0, Memo1 & m1, + InputT x0, InputT x1, CwProtocol & proto, Specs &&... specs) +{ + auto inner = dpf::extend_ds(k0.dpf_key, k1.dpf_key, m0, m1, x0, x1, proto, + std::forward(specs)...); + using new_raw = typename std::decay_t::key_type; + const uint64_t nmask = detail::ic_impl::input_mask_of(); + const uint64_t gmask = k0.group_mask; + using share_t = typename ic_key::share_type; + share_t c0{}; + share_t c1{}; + if constexpr (is_wildcard_v) + { + c0 = k0.cr_share; + c1 = k1.cr_share; + } + else if constexpr (detail::cmp_group_info::custom) + { + using prg = typename new_raw::interior_prg; + const auto layout = detail::group_layout>(); + const auto cr_g = detail::group_scalar( + detail::ic_impl::correction_s(r, k0.lo, k0.hi, nmask), layout); + const auto delta = detail::group_add(k0.delta_share, k1.delta_share); + const auto old_cr_open = detail::group_add(k0.cr_share, k1.cr_share); + const auto old_cr_term = detail::group_mul(delta, + detail::group_scalar( + detail::ic_impl::correction_s(r, k0.lo, k0.hi, k0.input_mask), + layout)); + const auto if_false = detail::group_sub(old_cr_open, old_cr_term); + const auto new_target = + detail::group_add(detail::group_mul(delta, cr_g), if_false); + const auto blind = detail::group_from_node( + dpf::uniform_sample(), layout); + c0 = blind; + c1 = detail::group_sub(new_target, blind); + } + else + { + const uint64_t delta = + (static_cast(k0.delta_share) + + static_cast(k1.delta_share)) + & gmask; + const uint64_t old_cr_open = + (static_cast(k0.cr_share) + + static_cast(k1.cr_share)) + & gmask; + const uint64_t old_cr_term = detail::ic_impl::mul_mask(delta, + detail::ic_impl::correction(r, k0.lo, k0.hi, k0.input_mask, gmask), + gmask); + const uint64_t if_false = + (old_cr_open + detail::dcf_impl::neg_m(old_cr_term, gmask)) & gmask; + const uint64_t cr = + detail::ic_impl::correction(r, k0.lo, k0.hi, nmask, gmask); + const uint64_t target = + (detail::ic_impl::mul_mask(delta, cr, gmask) + if_false) & gmask; + const uint64_t blind = detail::dcf_impl::sample_addend_blind(gmask, + [] { + return dpf::uniform_sample(); + }); + uint64_t a0 = 0, a1 = 0; + detail::incr::split_cmp_addend(target, gmask, blind, a0, a1); + c0 = static_cast(a0); + c1 = static_cast(a1); + } + auto out0 = detail::ic_impl::make_side( + std::move(inner.first), k0.lo, k0.hi, nmask, gmask, k0.delta_share, c0, + k0.delta_coeff, k0.cr_coeff); + auto out1 = detail::ic_impl::make_side( + std::move(inner.second), k1.lo, k1.hi, nmask, gmask, k1.delta_share, c1, + k1.delta_coeff, k1.cr_coeff); + out0.assigned = k0.assigned; + out1.assigned = k1.assigned; + return std::make_pair(std::move(out0), std::move(out1)); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto add_output_ds(const ic_key & k0, + const ic_key & k1, Memo0 & m0, Memo1 & m1, InputT x0, + InputT x1, CwProtocol & proto, Specs &&... specs) +{ + auto inner = dpf::add_output_ds(k0.dpf_key, k1.dpf_key, m0, m1, x0, x1, proto, + std::forward(specs)...); + using new_raw = typename std::decay_t::key_type; + auto out0 = detail::ic_impl::make_side( + std::move(inner.first), k0.lo, k0.hi, k0.input_mask, k0.group_mask, + k0.delta_share, k0.cr_share, k0.delta_coeff, k0.cr_coeff); + auto out1 = detail::ic_impl::make_side( + std::move(inner.second), k1.lo, k1.hi, k1.input_mask, k1.group_mask, + k1.delta_share, k1.cr_share, k1.delta_coeff, k1.cr_coeff); + out0.assigned = k0.assigned; + out1.assigned = k1.assigned; + return std::make_pair(std::move(out0), std::move(out1)); +} + } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_INTERVAL_HPP__ diff --git a/include/dpf/interval_memoizer.hpp b/include/dpf/interval_memoizer.hpp index be8589a..a333bc5 100644 --- a/include/dpf/interval_memoizer.hpp +++ b/include/dpf/interval_memoizer.hpp @@ -73,6 +73,16 @@ struct interval_memoizer_base HEDLEY_NO_THROW virtual return_type end() const noexcept = 0; + /// @brief Drop a cached interval so the next `assign_interval` rebuilds + /// from the root (needed when folding a proof over the tree). + void clear_assignment() + { + dpf_ = std::nullopt; + from_ = std::nullopt; + to_ = std::nullopt; + level_index = 0; + } + virtual std::size_t assign_interval(const dpf_type & dpf, integral_type new_from, integral_type new_to) { static constexpr auto complement_of = std::bit_not{}; @@ -148,11 +158,11 @@ struct interval_memoizer_base std::size_t level_index; // indicates current level being built explicit interval_memoizer_base(std::size_t output_len) - : dpf_{std::nullopt}, + : output_length{output_len}, + level_index{0}, + dpf_{std::nullopt}, from_{std::nullopt}, - to_{std::nullopt}, - output_length{output_len}, - level_index{0} + to_{std::nullopt} { } private: @@ -167,6 +177,7 @@ struct interval_memoizer_base /// `eval_interval(key, from, to)` allocates when you omit the memoizer. /// @tparam DpfKey DPF key type /// @tparam interior_node interior node +/// \complexity O(L) nodes. The buffer length is about `interval_memoizer_slots(output_len)` (the last level plus the previous level's pivot). L is that output length. template ::interior_node>> @@ -248,6 +259,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) /// @brief Every level of the interval. `retains_all_levels` is true. /// @tparam DpfKey DPF key type /// @tparam interior_node interior node +/// \complexity Allocates `level_endpoints[depth] + output_len` nodes: the prefix sum of `get_nodes_at_level` over every level, plus the output length. template ::interior_node>> @@ -326,7 +338,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) std::array level_endpoints{0}; for (std::size_t level=depth; level > 0; --level) { - len = std::min(len+2 >> 1, integral_type(1) << level-1); + len = std::min((len + 2) >> 1, integral_type(1) << (level - 1)); level_endpoints[level] = len; } @@ -468,10 +480,22 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") HEDLEY_PRAGMA(GCC diagnostic pop) } +/// @brief Size for the tree walk of `[from, to]` after `offset_x`. +/// @details Leaf packing depends on alignment (and wrap). Sizing on the +/// logical endpoints alone can undersize once a wildcard `δ` is set. +/// When the offset is not ready yet, falls back to logical endpoints +/// (identity tree coordinates). template -inline auto make_basic_interval_memoizer(const DpfKey &, InputT from, InputT to) +inline auto make_basic_interval_memoizer(const DpfKey & dpf, InputT from, InputT to) { + using input_type = typename DpfKey::input_type; + if (dpf.offset_x.is_ready()) + { + return make_basic_interval_memoizer( + dpf.offset_x(static_cast(from)), + dpf.offset_x(static_cast(to))); + } return make_basic_interval_memoizer(from, to); } @@ -513,8 +537,15 @@ HEDLEY_PRAGMA(GCC diagnostic pop) template -inline auto make_full_tree_interval_memoizer(const DpfKey &, InputT from, InputT to) +inline auto make_full_tree_interval_memoizer(const DpfKey & dpf, InputT from, InputT to) { + using input_type = typename DpfKey::input_type; + if (dpf.offset_x.is_ready()) + { + return make_full_tree_interval_memoizer( + dpf.offset_x(static_cast(from)), + dpf.offset_x(static_cast(to))); + } return make_full_tree_interval_memoizer(from, to); } @@ -583,8 +614,15 @@ inline auto make_basic_interval_memoizer(InputT from, InputT to) template = true> -inline auto make_basic_interval_memoizer(const DpfKey &, InputT from, InputT to) +inline auto make_basic_interval_memoizer(const DpfKey & dpf, InputT from, InputT to) { + using input_type = typename DpfKey::input_type; + if (dpf.offset_x.is_ready()) + { + return make_basic_interval_memoizer( + dpf.offset_x(static_cast(from)), + dpf.offset_x(static_cast(to))); + } return make_basic_interval_memoizer(from, to); } diff --git a/include/dpf/it_dpf3.hpp b/include/dpf/it_dpf3.hpp new file mode 100644 index 0000000..e0aed1d --- /dev/null +++ b/include/dpf/it_dpf3.hpp @@ -0,0 +1,94 @@ +/// @file dpf/it_dpf3.hpp +/// @brief Information-theoretic 3-server distributed point function. +/// @details Statistically private among three servers: any one key is +/// independent of `(α, β)`, and the **sum** of all three evaluations +/// is the point function (Boyle–Gilboa–Ishai–Kolobov, ePrint 2023/028). +/// Distinct from the computational `(2,3)` Shamir key `make_dpf3` +/// (ePrint 2024/1658), where any two shares reconstruct. Domain +/// `uint8_t`, payload `uint64_t`. For this domain size the share is a +/// full additive truth table (no GGM correction words); the paper's +/// matching-vector packing targets asymptotically large `N`. +/// @see dpf/dpf3.hpp, examples/applications/it_pir3.cpp, examples/applications/pir3.cpp +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_IT_DPF3_HPP__ +#define LIBDPF_INCLUDE_DPF_IT_DPF3_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/random.hpp" +#include "dpf/secret_share.hpp" + +namespace dpf +{ + +/// @brief One evaluator's key for the information-theoretic 3-server DPF. +struct it_dpf3_key +{ + static constexpr std::size_t domain_size = 256; + using input_type = std::uint8_t; + using output_type = std::uint64_t; + + std::uint8_t party = 0; + std::array share{}; +}; + +/// @brief Three additive keys for `f_{α,β}` on `{0..255} → uint64_t`. +/// @details `eval_it_dpf3(k0,x) + eval_it_dpf3(k1,x) + eval_it_dpf3(k2,x)` equals +/// `β` at `x = α` and `0` elsewhere (wrapping `uint64_t` arithmetic). +/// \complexity O(N) samples for domain size `N = 256`. Key size is `N` words +/// per party (truth-table share), not subpolynomial. +HEDLEY_WARN_UNUSED_RESULT +inline auto make_it_dpf3(std::uint8_t alpha, std::uint64_t beta) +{ + it_dpf3_key k0; + it_dpf3_key k1; + it_dpf3_key k2; + k0.party = 0; + k1.party = 1; + k2.party = 2; + for (std::size_t x = 0; x < it_dpf3_key::domain_size; ++x) + { + const std::uint64_t secret = + (static_cast(x) == alpha) ? beta : 0; + auto [a, b, c] = additively_share3(secret); + k0.share[x] = a.raw(); + k1.share[x] = b.raw(); + k2.share[x] = c.raw(); + } + return std::make_tuple(std::move(k0), std::move(k1), std::move(k2)); +} + +/// @brief One additive share of `f_{α,β}(x)`. +/// \complexity O(1). +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +HEDLEY_WARN_UNUSED_RESULT +constexpr std::uint64_t eval_it_dpf3(const it_dpf3_key & key, + std::uint8_t x) noexcept +{ + return key.share[x]; +} + +/// @brief `sum_x eval_it_dpf3(key, x) * weights[x]` over the whole domain. +/// \complexity O(N) multiply-adds, `N = 256`. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_it_dpf3_inner_product(const it_dpf3_key & key, Weights && weights) +{ + std::uint64_t acc = 0; + for (std::size_t x = 0; x < it_dpf3_key::domain_size; ++x) + acc += key.share[x] * static_cast(weights[x]); + return acc; +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_IT_DPF3_HPP__ diff --git a/include/dpf/json.hpp b/include/dpf/json.hpp index 11547d2..f31fa27 100644 --- a/include/dpf/json.hpp +++ b/include/dpf/json.hpp @@ -396,6 +396,8 @@ struct adl_serializer, void> beaver.output_blind = dpf::json::codec::load(j.at("output_blind")); beaver.vector_blind = dpf::json::codec::load(j.at("vector_blind")); beaver.blinded_vector = dpf::json::codec::load(j.at("blinded_vector")); + if (j.contains("assign_pad")) + beaver.assign_pad = dpf::json::codec::load(j.at("assign_pad")); } static void to_json(nlohmann::json & j, const dpf::beaver & beaver) // NOLINT(runtime/references) @@ -403,7 +405,8 @@ struct adl_serializer, void> j = nlohmann::json{ {"output_blind", dpf::json::codec::dump(beaver.output_blind)}, {"vector_blind", dpf::json::codec::dump(beaver.vector_blind)}, - {"blinded_vector", dpf::json::codec::dump(beaver.blinded_vector)} + {"blinded_vector", dpf::json::codec::dump(beaver.blinded_vector)}, + {"assign_pad", dpf::json::codec::dump(beaver.assign_pad)} }; } }; @@ -506,7 +509,8 @@ struct adl_serializer( stored.at("blinded_vector")); + if (stored.contains("assign_pad")) + beaver.assign_pad = dpf::json::codec::load( + stored.at("assign_pad")); return beaver; } else @@ -604,6 +611,9 @@ struct adl_serializer( stored.at("blinded_vector")); + if (stored.contains("assign_pad")) + beaver.assign_pad = dpf::json::codec::load( + stored.at("assign_pad")); wrapper out{std::move(leaf), std::move(beaver)}; restore_leaf(out, entry); return out; diff --git a/include/dpf/keyword.hpp b/include/dpf/keyword.hpp index 7da834b..c5a0340 100644 --- a/include/dpf/keyword.hpp +++ b/include/dpf/keyword.hpp @@ -389,6 +389,10 @@ class basic_fixed_length_string : public dpf::modint(st /// uses `char` (i.e., bytes) as its **character type**, with its /// default `char_traits` and `allocator` types (see /// `dpf::basic_fixed_length_string` for more info on the template). +/// @note A fixed-alphabet domain. The successor is `dpf::keyword2`, which +/// stores a rank in a pattern language and is also not a leaf. +/// @see dpf::keyword2 +/// @see dpf::alphabets template using keyword = basic_fixed_length_string; diff --git a/include/dpf/keyword2.hpp b/include/dpf/keyword2.hpp index 6b32fea..998d44c 100644 --- a/include/dpf/keyword2.hpp +++ b/include/dpf/keyword2.hpp @@ -1686,7 +1686,10 @@ constexpr u256 unpack_rank(Integral v) } // namespace detail /// @brief Ranked keyword whose language is the pattern `Pattern`. +/// @note A domain. It stores a `modint` rank. It is not a leaf type. /// @tparam Pattern null-terminated pattern with static storage. +/// @see dpf::keyword +/// @see dpf::modint /// `pad('0')[0-9]{0,4}` is a decimal of at most 4 digits. /// `[0-9a-f]{8}` is exactly 8 significant hex digits. template diff --git a/include/dpf/launch.hpp b/include/dpf/launch.hpp new file mode 100644 index 0000000..1377dd0 --- /dev/null +++ b/include/dpf/launch.hpp @@ -0,0 +1,62 @@ +/// @file dpf/launch.hpp +/// @brief Start here: run a composed protocol as 2 or 3 parties. +/// @details +/// * In one process: `dpf::run_two_party` / `dpf::run_three_party`, with +/// every choice in `app::run_config` (transport: async memory, unix +/// sockets, TCP mux, parallel TCP, SCTP; lanes; framing; instances; +/// window; timeouts). Party 2 is the dealer / RSS third party. +/// * In separate processes: `app::parse_node_args(argc, argv)` then +/// `app::run_node(args, plan, values)`, started as +/// `--party=i --peers=host:port,host:port[,host:port]` on each machine. +/// See `examples/protocol/party_node.cpp`. +/// Both ends exchange a plan-shape hello, so a lane, framing, instance, or +/// plan mismatch fails with a message that names the field. +#ifndef LIBDPF_INCLUDE_DPF_LAUNCH_HPP__ +#define LIBDPF_INCLUDE_DPF_LAUNCH_HPP__ + +#include +#include +#include + +#include "dpf/party_runner.hpp" +#include "dpf/run_config.hpp" + +namespace dpf +{ + +/// @brief Parties 0 and 1 on threads over `cfg.kind`. +inline app::parties_result run_two_party(const protocol::plan & p0, + const protocol::plan & p1, app::party_values & v0, app::party_values & v1, + const std::map & kernels = {}, + const app::run_config & cfg = {}) +{ + std::vector values(2); + values[0] = std::move(v0); + values[1] = std::move(v1); + auto r = app::run_parties({p0, p1}, values, kernels, cfg); + v0 = std::move(values[0]); + v1 = std::move(values[1]); + return r; +} + +/// @brief Parties 0, 1, and 2 (dealer / RSS third party) on threads. +inline app::parties_result run_three_party(const protocol::plan & p0, + const protocol::plan & p1, const protocol::plan & p2, app::party_values & v0, + app::party_values & v1, app::party_values & v2, + const std::map & kernels = {}, + const app::run_config & cfg = {}) +{ + std::vector values(3); + values[0] = std::move(v0); + values[1] = std::move(v1); + values[2] = std::move(v2); + auto r = app::run_parties({p0, p1, p2}, values, kernels, cfg); + v0 = std::move(values[0]); + v1 = std::move(values[1]); + v2 = std::move(values[2]); + return r; +} + +} // namespace dpf + +#endif diff --git a/include/dpf/leaf_arithmetic.hpp b/include/dpf/leaf_arithmetic.hpp index 361a5d1..7390929 100644 --- a/include/dpf/leaf_arithmetic.hpp +++ b/include/dpf/leaf_arithmetic.hpp @@ -23,6 +23,7 @@ #include "dpf/bit.hpp" #include "dpf/bitstring.hpp" +#include "dpf/blob.hpp" #include "dpf/packed_lane_arithmetic.hpp" #include "dpf/wildcard.hpp" #include "dpf/xor_wrapper.hpp" @@ -90,6 +91,83 @@ static constexpr auto subtract_leaf = leaf_arithmetic::subtract_t static constexpr auto multiply_leaf = leaf_arithmetic::multiply_t{}; +/// @brief Scalar add in the leaf output group. +/// @details `float`/`double` use XOR of the IEEE bit pattern (same as +/// `add_t` on packed leaves), not IEEE floating-point addition. +/// \complexity O(1) for a scalar. A packed node walks its bytes once (`add_t` / the lane loops): O(sizeof node) and the carry stays inside a `twobit` or `nyble` lane. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +HEDLEY_PURE +T leaf_group_add(const T & a, const T & b) noexcept +{ + if constexpr (std::is_same_v || std::is_same_v) + { + using bits_t = std::conditional_t; + bits_t aa{}, bb{}; + utils::raw_memcpy(&aa, &a, sizeof(T)); + utils::raw_memcpy(&bb, &b, sizeof(T)); + bits_t cc = static_cast(aa ^ bb); + T out{}; + utils::raw_memcpy(&out, &cc, sizeof(T)); + return out; + } + else + { + return static_cast(a + b); + } +} + +/// @brief Scalar multiply in the leaf output group (`float`/`double`: AND of bits). +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +HEDLEY_PURE +T leaf_group_mul(const T & a, const T & b) noexcept +{ + if constexpr (std::is_same_v || std::is_same_v) + { + using bits_t = std::conditional_t; + bits_t aa{}, bb{}; + utils::raw_memcpy(&aa, &a, sizeof(T)); + utils::raw_memcpy(&bb, &b, sizeof(T)); + bits_t cc = static_cast(aa & bb); + T out{}; + utils::raw_memcpy(&out, &cc, sizeof(T)); + return out; + } + else + { + return static_cast(a * b); + } +} + +/// @brief Multiplicative identity for leaf scaling (all-ones for XOR/AND groups). +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +HEDLEY_PURE +T leaf_group_one() noexcept +{ + if constexpr (std::is_same_v || std::is_same_v) + { + using bits_t = std::conditional_t; + bits_t ones = static_cast(~bits_t{0}); + T out{}; + utils::raw_memcpy(&out, &ones, sizeof(T)); + return out; + } + else if constexpr (utils::is_xor_wrapper_v) + { + using u = typename T::value_type; + return T{static_cast(~u{0})}; + } + else + { + return T{1}; + } +} + namespace leaf_arithmetic { @@ -260,10 +338,10 @@ struct add_array_t c; output_type a_, b_; - std::memcpy(&a_, std::data(a), sizeof(a_)); - std::memcpy(&b_, std::data(b), sizeof(b_)); + utils::raw_memcpy(&a_, std::data(a), sizeof(a_)); + utils::raw_memcpy(&b_, std::data(b), sizeof(b_)); output_type c_ = a_ + b_; - std::memcpy(std::data(c), &c_, sizeof(c_)); + utils::raw_memcpy(std::data(c), &c_, sizeof(c_)); return c; } }; @@ -294,10 +372,10 @@ template <> struct add_t final { simde__m128i ret; simde_int128 lhs_, rhs_; - std::memcpy(&lhs_, &lhs, sizeof(simde_int128)); - std::memcpy(&rhs_, &rhs, sizeof(simde_int128)); + utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_int128)); + utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_int128)); simde_int128 sum = lhs_ + rhs_; - std::memcpy(&ret, &sum, sizeof(simde__m128i)); + utils::raw_memcpy(&ret, &sum, sizeof(simde__m128i)); return ret; } }; @@ -307,10 +385,10 @@ template <> struct add_t final { simde__m128i ret; simde_uint128 lhs_, rhs_; - std::memcpy(&lhs_, &lhs, sizeof(simde_uint128)); - std::memcpy(&rhs_, &rhs, sizeof(simde_uint128)); + utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_uint128)); + utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_uint128)); simde_uint128 sum = lhs_ + rhs_; - std::memcpy(&ret, &sum, sizeof(simde__m128i)); + utils::raw_memcpy(&ret, &sum, sizeof(simde__m128i)); return ret; } }; @@ -335,10 +413,10 @@ template <> struct add_t final { simde__m256i ret; simde_int128 lhs_[2], rhs_[2]; - std::memcpy(&lhs_, &lhs, sizeof(simde_int128) * 2); - std::memcpy(&rhs_, &rhs, sizeof(simde_int128) * 2); + utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_int128) * 2); + utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_int128) * 2); simde_int128 sum[2] = { lhs_[0] + rhs_[0], lhs_[1] + rhs_[1] }; - std::memcpy(&ret, &sum, sizeof(simde__m256i)); + utils::raw_memcpy(&ret, &sum, sizeof(simde__m256i)); return ret; } }; @@ -348,21 +426,28 @@ template <> struct add_t final { simde__m256i ret; simde_uint128 lhs_[2], rhs_[2]; - std::memcpy(&lhs_, &lhs, sizeof(simde_uint128) * 2); - std::memcpy(&rhs_, &rhs, sizeof(simde_uint128) * 2); + utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_uint128) * 2); + utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_uint128) * 2); simde_uint128 sum[2] = { lhs_[0] + rhs_[0], lhs_[1] + rhs_[1] }; - std::memcpy(&ret, &sum, sizeof(simde__m256i)); + utils::raw_memcpy(&ret, &sum, sizeof(simde__m256i)); return ret; } }; template struct add_t> final : public detail::add_array_t {}; template struct add_t, void> final : public detail::bitstring_xor_t {}; +template struct add_t, void> final : public detail::bitstring_xor_t {}; +template +struct add_t, NodeT> final : public detail::bitstring_xor_t {}; /// @brief Bitwise XOR, not IEEE addition. Float addition does not form an /// exact secret-sharing group; XOR of the representation does. -/// @tparam NodeT GGM node type -template struct add_t final : public std::bit_xor<> {}; -template struct add_t final : public std::bit_xor<> {}; +/// @tparam NodeT GGM node type (not `void`; that selects the scalar wrapper) +template +struct add_t>> + final : public std::bit_xor<> {}; +template +struct add_t>> + final : public std::bit_xor<> {}; template <> struct add_t final : public std::bit_xor<> {}; template struct add_t final : public std::bit_xor<> {}; template struct add_t, void> final : public std::bit_xor<> {}; @@ -546,10 +631,10 @@ struct sub_array_t c; output_type a_, b_; - std::memcpy(&a_, std::data(a), sizeof(a_)); - std::memcpy(&b_, std::data(b), sizeof(b_)); + utils::raw_memcpy(&a_, std::data(a), sizeof(a_)); + utils::raw_memcpy(&b_, std::data(b), sizeof(b_)); output_type c_ = a_ - b_; - std::memcpy(std::data(c), &c_, sizeof(c_)); + utils::raw_memcpy(std::data(c), &c_, sizeof(c_)); return c; } }; @@ -580,10 +665,10 @@ template <> struct subtract_t final { simde__m128i ret; simde_int128 lhs_, rhs_; - std::memcpy(&lhs_, &lhs, sizeof(simde_int128)); - std::memcpy(&rhs_, &rhs, sizeof(simde_int128)); + utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_int128)); + utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_int128)); simde_int128 sum = lhs_ - rhs_; - std::memcpy(&ret, &sum, sizeof(simde__m128i)); + utils::raw_memcpy(&ret, &sum, sizeof(simde__m128i)); return ret; } }; @@ -593,10 +678,10 @@ template <> struct subtract_t final { simde__m128i ret; simde_uint128 lhs_, rhs_; - std::memcpy(&lhs_, &lhs, sizeof(simde_uint128)); - std::memcpy(&rhs_, &rhs, sizeof(simde_uint128)); + utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_uint128)); + utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_uint128)); simde_uint128 sum = lhs_ - rhs_; - std::memcpy(&ret, &sum, sizeof(simde__m128i)); + utils::raw_memcpy(&ret, &sum, sizeof(simde__m128i)); return ret; } }; @@ -622,10 +707,10 @@ template <> struct subtract_t final { simde__m256i ret; simde_int128 lhs_[2], rhs_[2]; - std::memcpy(&lhs_, &lhs, sizeof(simde_int128) * 2); - std::memcpy(&rhs_, &rhs, sizeof(simde_int128) * 2); + utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_int128) * 2); + utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_int128) * 2); simde_int128 sum[2] = { lhs_[0] - rhs_[0], lhs_[1] - rhs_[1] }; - std::memcpy(&ret, &sum, sizeof(simde__m256i)); + utils::raw_memcpy(&ret, &sum, sizeof(simde__m256i)); return ret; } }; @@ -635,20 +720,27 @@ template <> struct subtract_t final { simde__m256i ret; simde_uint128 lhs_[2], rhs_[2]; - std::memcpy(&lhs_, &lhs, sizeof(simde_uint128) * 2); - std::memcpy(&rhs_, &rhs, sizeof(simde_uint128) * 2); + utils::raw_memcpy(&lhs_, &lhs, sizeof(simde_uint128) * 2); + utils::raw_memcpy(&rhs_, &rhs, sizeof(simde_uint128) * 2); simde_uint128 sum[2] = { lhs_[0] - rhs_[0], lhs_[1] - rhs_[1] }; - std::memcpy(&ret, &sum, sizeof(simde__m256i)); + utils::raw_memcpy(&ret, &sum, sizeof(simde__m256i)); return ret; } }; template struct subtract_t> final : public detail::sub_array_t {}; template struct subtract_t, void> final : public detail::bitstring_xor_t {}; +template struct subtract_t, void> final : public detail::bitstring_xor_t {}; +template +struct subtract_t, NodeT> final : public detail::bitstring_xor_t {}; /// @brief Bitwise XOR, not IEEE subtraction. /// @tparam NodeT GGM node type -template struct subtract_t final : public std::bit_xor<> {}; -template struct subtract_t final : public std::bit_xor<> {}; +template +struct subtract_t>> + final : public std::bit_xor<> {}; +template +struct subtract_t>> + final : public std::bit_xor<> {}; template struct subtract_t final : public std::bit_xor<> {}; template <> struct subtract_t final : public std::bit_xor<> {}; template struct subtract_t, void> final : public std::bit_xor<> {}; @@ -847,9 +939,9 @@ template <> struct multiply_t final { simde_int128 a_; simde__m128i c; - std::memcpy(&a_, &a, sizeof(simde_int128)); + utils::raw_memcpy(&a_, &a, sizeof(simde_int128)); simde_int128 c_ = a_ * b; - std::memcpy(&c, &c_, sizeof(simde__m128i)); + utils::raw_memcpy(&c, &c_, sizeof(simde__m128i)); return c; } }; @@ -860,9 +952,9 @@ template <> struct multiply_t final { simde_uint128 a_; simde__m128i c; - std::memcpy(&a_, &a, sizeof(simde_uint128)); + utils::raw_memcpy(&a_, &a, sizeof(simde_uint128)); simde_uint128 c_ = a_ * b; - std::memcpy(&c, &c_, sizeof(simde__m128i)); + utils::raw_memcpy(&c, &c_, sizeof(simde__m128i)); return c; } }; @@ -908,8 +1000,8 @@ struct multiply_t, simde__m128i> final } else { alignas(simde__m128i) unsigned char buf[sizeof(simde__m128i)]{}; for (std::size_t off = 0; off + sizeof(val_t) <= sizeof(buf); off += sizeof(val_t)) - std::memcpy(buf + off, &v, sizeof(val_t)); - std::memcpy(&bb, buf, sizeof(bb)); + utils::raw_memcpy(buf + off, &v, sizeof(val_t)); + utils::raw_memcpy(&bb, buf, sizeof(bb)); } return simde_mm_and_si128(a, bb); } @@ -933,8 +1025,8 @@ struct multiply_t, simde__m256i> final } else { alignas(simde__m256i) unsigned char buf[sizeof(simde__m256i)]{}; for (std::size_t off = 0; off + sizeof(val_t) <= sizeof(buf); off += sizeof(val_t)) - std::memcpy(buf + off, &v, sizeof(val_t)); - std::memcpy(&bb, buf, sizeof(bb)); + utils::raw_memcpy(buf + off, &v, sizeof(val_t)); + utils::raw_memcpy(&bb, buf, sizeof(bb)); } return simde_mm256_and_si256(a, bb); } @@ -986,7 +1078,7 @@ struct multiply_t final { static_assert(sizeof(float) == 4, "float must be 32 bits"); psnip_uint32_t bits = 0; - std::memcpy(&bits, &b, sizeof(bits)); + utils::raw_memcpy(&bits, &b, sizeof(bits)); return simde_mm_and_si128(a, simde_mm_set1_epi32(static_cast(bits))); } }; @@ -998,7 +1090,7 @@ struct multiply_t final { static_assert(sizeof(float) == 4, "float must be 32 bits"); psnip_uint32_t bits = 0; - std::memcpy(&bits, &b, sizeof(bits)); + utils::raw_memcpy(&bits, &b, sizeof(bits)); return simde_mm256_and_si256(a, simde_mm256_set1_epi32(static_cast(bits))); } }; @@ -1010,7 +1102,7 @@ struct multiply_t final { static_assert(sizeof(double) == 8, "double must be 64 bits"); psnip_uint64_t bits = 0; - std::memcpy(&bits, &b, sizeof(bits)); + utils::raw_memcpy(&bits, &b, sizeof(bits)); return simde_mm_and_si128(a, simde_mm_set1_epi64x(static_cast(bits))); } }; @@ -1022,7 +1114,7 @@ struct multiply_t final { static_assert(sizeof(double) == 8, "double must be 64 bits"); psnip_uint64_t bits = 0; - std::memcpy(&bits, &b, sizeof(bits)); + utils::raw_memcpy(&bits, &b, sizeof(bits)); return simde_mm256_and_si256(a, simde_mm256_set1_epi64x(static_cast(bits))); } }; diff --git a/include/dpf/leaf_later.hpp b/include/dpf/leaf_later.hpp new file mode 100644 index 0000000..e413850 --- /dev/null +++ b/include/dpf/leaf_later.hpp @@ -0,0 +1,232 @@ +/// @file dpf/leaf_later.hpp +/// @brief Defer the leaf correction until a public group element is known. +/// @details `eval_full` / `eval_full_add_into` with `leaf_later` skip the leaf +/// correction word, write the uncorrected group share, and fill a +/// parallel control-bit buffer the caller owns. After a rotate of +/// value and control together, `apply_leaf_correction` does +/// `buf[i] += F * control[i]` so Duoram's `v[i−s] + F·t[i−s]` never +/// reapplies a walk. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_LEAF_LATER_HPP__ +#define LIBDPF_INCLUDE_DPF_LEAF_LATER_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/dpf_key.hpp" +#include "dpf/eval_common.hpp" +#include "dpf/eval_interval.hpp" +#include "dpf/interval_memoizer.hpp" +#include "dpf/leaf_arithmetic.hpp" +#include "dpf/leaf_node.hpp" +#include "dpf/twiddle.hpp" +#include "dpf/utils.hpp" + +namespace dpf +{ + +/// @brief Tag: expand without applying the leaf correction word. +struct leaf_later +{ + static constexpr bool is_leaf_later_tag = true; +}; + +template +struct is_leaf_later : std::false_type {}; +template <> +struct is_leaf_later : std::true_type {}; +template +inline constexpr bool is_leaf_later_v = is_leaf_later>::value; + +// Forward declaration: defined in eval_walk.hpp (same offset convention). +struct rotate; + +namespace detail_leaf_later +{ + +template +HEDLEY_NO_THROW +constexpr std::size_t domain_size() noexcept +{ + constexpr std::size_t bits = + utils::bitlength_of_v; + static_assert(bits < 8 * sizeof(std::size_t), + "leaf_later: input domain does not fit a std::size_t index"); + return std::size_t{1} << bits; +} + +/// @brief Uncorrected exterior leaf: `0 − mask` (same group as traverse_exterior). +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +auto traverse_exterior_uncorrected(const typename DpfKey::interior_node & node) +{ + using output_type = typename DpfKey::concrete_output_type; + using exterior_prg = typename DpfKey::exterior_prg; + using outputs_tuple = typename DpfKey::concrete_outputs_tuple; + using leaf_type = dpf::leaf_node_t; + leaf_type zero{}; + return dpf::subtract_leaf( + zero, + make_leaf_mask_inner( + unset_lo_2bits(node))); +} + +template +struct has_opl_of : std::false_type {}; +template +struct has_opl_of)>> + : std::true_type {}; + +template +HEDLEY_NO_THROW +constexpr std::size_t opl_of() noexcept +{ + if constexpr (has_opl_of::value) + return DpfKey::template outputs_per_leaf_of<0>; + else + return DpfKey::outputs_per_leaf; +} + +} // namespace detail_leaf_later + +/// @brief Full-domain expansion without the leaf correction; also fills `control`. +/// @details `buf[i]` receives the uncorrected share at domain point `i`, and +/// `control[i]` is the leaf node's control bit. Both must be sized to +/// `2^n`. +/// \complexity One full-domain expansion, `Θ(2^n)`. +template + && !is_multilevel_key_v, bool> = true> +void eval_full(Buffer & buf, Control & control, const DpfKey & dpf, + leaf_later) // NOLINT(runtime/references) +{ + using input_type = typename DpfKey::input_type; + using output_type = typename DpfKey::concrete_output_type; + using exterior_node = typename DpfKey::exterior_node; + constexpr std::size_t opl = DpfKey::outputs_per_leaf; + const std::size_t n = detail_leaf_later::domain_size(); + if (buf.size() < n || control.size() < n) + throw std::invalid_argument("eval_full(leaf_later): buffer too small"); + + auto memo = make_basic_full_memoizer(dpf); + const input_type from = std::numeric_limits::min(); + const input_type to = std::numeric_limits::max(); + const auto from_node = utils::get_from_node(from); + const auto to_node = utils::get_to_node(to); + internal::eval_interval_interior(dpf, from_node, to_node, memo); + + const std::size_t nodes_in_interval = + static_cast(to_node - from_node); + auto * nodes = memo[DpfKey::depth]; + + for (std::size_t j = 0; j < nodes_in_interval; ++j) + { + const auto & node = nodes[j]; + const bool tbit = static_cast(get_lo_bit(node)); + auto leaf = detail_leaf_later::traverse_exterior_uncorrected( + node); + for (std::size_t o = 0; o < opl; ++o) + { + const std::size_t idx = j * opl + o; + if (idx >= n) + break; + output_type y = extract_leaf(leaf, o); + buf[idx] = y; + control[idx] = tbit; + } + } +} + +/// @brief Add an uncorrected full-domain expansion into `buf` and fill `control`. +template + && !is_multilevel_key_v, bool> = true> +void eval_full_add_into(Buffer & buf, Control & control, const DpfKey & dpf, + leaf_later) // NOLINT(runtime/references) +{ + using output_type = typename DpfKey::concrete_output_type; + const std::size_t n = detail_leaf_later::domain_size(); + std::vector tmp(n); + std::vector ctl(n); + eval_full(tmp, ctl, dpf, leaf_later{}); + for (std::size_t i = 0; i < n; ++i) + { + buf[i] = buf[i] + tmp[i]; + control[i] = static_cast(ctl[i]); + } +} + +/// @brief Uncorrected expansion written at `(i + rot.shift) mod 2^n`, with +/// control bits rotated the same way. +template + && !is_multilevel_key_v, bool> = true> +void eval_full_add_into(Buffer & buf, Control & control, const DpfKey & dpf, + leaf_later, rotate rot) // NOLINT(runtime/references) +{ + using output_type = typename DpfKey::concrete_output_type; + const std::size_t n = detail_leaf_later::domain_size(); + const std::size_t s = rot.shift % n; + std::vector tmp(n); + std::vector ctl(n); + eval_full(tmp, ctl, dpf, leaf_later{}); + for (std::size_t i = 0; i < n; ++i) + { + const std::size_t j = (i + s) % n; + buf[j] = buf[j] + tmp[i]; + control[j] = static_cast(ctl[i]); + } +} + +/// @brief Rotate value and control by the same offset (`new[i] = old[(i-s) mod n]`). +/// @details Domain point `k` lands at `(k + s) mod n`, matching `dpf::rotate{s}`. +template +void cyclic_shift_pair(Buffer & buf, Control & control, std::size_t s) // NOLINT(runtime/references) +{ + const std::size_t n = buf.size(); + if (n == 0 || control.size() != n) + throw std::invalid_argument("cyclic_shift_pair: size mismatch"); + const std::size_t sh = s % n; + if (sh == 0) + return; + Buffer out_buf(buf); + Control out_ctl(control); + for (std::size_t i = 0; i < n; ++i) + { + out_buf[i] = buf[(i + n - sh) % n]; + out_ctl[i] = control[(i + n - sh) % n]; + } + buf = std::move(out_buf); + control = std::move(out_ctl); +} + +/// @brief `buf[i] += F * control[i]` in the leaf's group. +/// @details XOR leaves treat `+` as XOR. `F` is a public group element. +template +void apply_leaf_correction(Buffer & buf, const Control & control, const F & f) // NOLINT(runtime/references) +{ + const std::size_t n = buf.size(); + if (control.size() < n) + throw std::invalid_argument("apply_leaf_correction: control too small"); + for (std::size_t i = 0; i < n; ++i) + { + if (static_cast(control[i])) + buf[i] = buf[i] + f; + } +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_LEAF_LATER_HPP__ diff --git a/include/dpf/leaf_node.hpp b/include/dpf/leaf_node.hpp index 15960c3..417302e 100644 --- a/include/dpf/leaf_node.hpp +++ b/include/dpf/leaf_node.hpp @@ -77,6 +77,27 @@ template ::value; +// --------------------------------------------------------------------------- +// dpf::blob stretched byte leaves. +// A `dpf::blob` is an XOR share of `N` bytes and is *never* packed several +// per node: Boyle packing keeps `lg(outputs_per_leaf) = 0` so the tree depth +// follows the input bitlength (Express `genDPF`). Instead it stretches the +// final seed over `ceil(8N / lambda)` exterior blocks in counter mode. These +// specializations override the generic `is_packable` heuristic, which would +// otherwise pack small blobs (e.g. `blob<1>`, whose 8 bits divide `lambda`). +// See dpf/blob.hpp. +template +struct outputs_per_leaf, NodeT> + : public std::integral_constant { }; + +template +struct block_length_of_leaf, NodeT> + : public std::integral_constant)> { }; + template @@ -205,6 +226,10 @@ struct beaver final OutputT output_blind; LeafT vector_blind; LeafT blinded_vector; + /// @brief Keygen pad `vector_blind_i · output_blind_{1-i}` so a later + /// `begin_update` can open a fresh naked delta without replaying + /// the zero-payload correction word. + LeafT assign_pad{}; }; template +struct is_curve_leaf_encode : std::false_type {}; + +template +struct is_curve_leaf_encode, + decltype(Concrete::from_seed(static_cast(nullptr), + std::size_t{0})), + std::integral_constant, + decltype(std::declval().bytes())>> + : std::bool_constant {}; + +template +HEDLEY_ALWAYS_INLINE +void encode_curve_leaf_mask(Leaf & leaf) noexcept +{ + if constexpr (is_curve_leaf_encode::value) + { + const Concrete pt = Concrete::from_seed( + std::addressof(leaf), sizeof(leaf)); + leaf = Leaf{}; + std::memcpy(std::addressof(leaf), pt.bytes(), + Concrete::encoded_size); + } +} + template ; + using concrete = concrete_type_t; HEDLEY_PRAGMA(GCC diagnostic push) HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") using leaf_type = dpf::leaf_node_t; @@ -305,6 +358,7 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") auto seed_ = utils::to_exterior_node(seed); ExteriorPRG::eval(seed_, leaf_blocks(output), count, static_cast(pos)); + encode_curve_leaf_mask(output); return output; HEDLEY_PRAGMA(GCC diagnostic pop) @@ -370,6 +424,23 @@ auto make_leaves_impl(InputT x, const ExteriorBlock & seed0, const ExteriorBlock make_leaf(x, seed0, seed1, sign, pos_base, ys...)...); } +namespace beavers +{ + +/// @brief Fill wildcard leaf scale blinds from `sample_scale`. +/// @tparam Concrete lane type +/// @tparam LeafT packed leaf type +/// @tparam Sample ring sampler +template +void fill_wildcard_scale_blinds(Concrete & out0, Concrete & out1, LeafT & vec0, + LeafT & vec1, std::size_t nlanes, Sample && rng); + +template +void fill_wildcard_scale_blinds(Concrete & out0, Concrete & out1, LeafT & vec0, + LeafT & vec1, std::size_t nlanes); + +} // namespace beavers + template (leaf, leaf0); - // also initialize the beavers - if constexpr(!dpf::utils::has_characteristic_two_v - || dpf::outputs_per_leaf_v > 1) + // Always plant a scale Beaver, including full-width XOR + // (char-2, one lane). Skipping it left blinds at zero so + // online assign exchanged beta in the clear. + dpf::leaf_node_t vector; + // XOR/AND leaf groups use the all-ones word as unit, not ±1. + // Check the OUTPUT type: input may be modint while the + // leaf is xor_wrapper (wildcard XOR payload). IEEE + // float/double leaves are the same bitwise group. + if constexpr(utils::is_xor_wrapper_v> == true + || utils::is_xor_wrapper_v == true + || std::is_same_v + || std::is_same_v) { - dpf::leaf_node_t vector; - // XOR-group multiply is AND, whose unit is ~0, not ±1. - // Check the OUTPUT type: input may be modint while the - // leaf is xor_wrapper (wildcard XOR payload). - if constexpr(utils::is_xor_wrapper_v> == true - || utils::is_xor_wrapper_v == true) - { - vector = make_naked_leaf(x, concrete_type(~0)); - } - else - { - vector = make_naked_leaf(x, concrete_type(2*sign-1)); - } - - uniform_fill(beaver0.output_blind); - uniform_fill(beaver0.vector_blind); - - uniform_fill(beaver1.output_blind); - uniform_fill(beaver1.vector_blind); - - beaver0.blinded_vector = dpf::add_leaf(vector, beaver1.vector_blind); - beaver1.blinded_vector = dpf::add_leaf(vector, beaver0.vector_blind); - - leaf0 = dpf::add_leaf(leaf0, - dpf::multiply_leaf(beaver0.vector_blind, beaver1.output_blind)); - leaf1 = dpf::add_leaf(leaf1, - dpf::multiply_leaf(beaver1.vector_blind, beaver0.output_blind)); + vector = make_naked_leaf(x, + dpf::leaf_group_one()); } + else + { + vector = make_naked_leaf(x, concrete_type(2*sign-1)); + } + + constexpr std::size_t nlanes = + dpf::outputs_per_leaf_v; + dpf::beavers::fill_wildcard_scale_blinds( + beaver0.output_blind, beaver1.output_blind, + beaver0.vector_blind, beaver1.vector_blind, + nlanes > 0 ? nlanes : std::size_t{1}); + + beaver0.blinded_vector = dpf::add_leaf(vector, beaver1.vector_blind); + beaver1.blinded_vector = dpf::add_leaf(vector, beaver0.vector_blind); + + beaver0.assign_pad = dpf::multiply_leaf( + beaver0.vector_blind, beaver1.output_blind); + beaver1.assign_pad = dpf::multiply_leaf( + beaver1.vector_blind, beaver0.output_blind); + leaf0 = dpf::add_leaf(leaf0, beaver0.assign_pad); + leaf1 = dpf::add_leaf(leaf1, beaver1.assign_pad); } else { diff --git a/include/dpf/leaf_wrapper.hpp b/include/dpf/leaf_wrapper.hpp index 2798926..13f59a2 100644 --- a/include/dpf/leaf_wrapper.hpp +++ b/include/dpf/leaf_wrapper.hpp @@ -8,13 +8,20 @@ #ifndef LIBDPF_INCLUDE_DPF_LEAF_WRAPPER_HPP__ #define LIBDPF_INCLUDE_DPF_LEAF_WRAPPER_HPP__ +#include + #include "hedley/hedley.h" +#include "dpf/leaf_arithmetic.hpp" #include "dpf/secret_share.hpp" namespace dpf { +/// @brief Concrete leaf. `get()` is ready immediately. +/// @tparam OutputT output type +/// @tparam NodeT exterior node type +/// @see dpf::wildcard_value template struct leaf_wrapper @@ -31,10 +38,18 @@ struct leaf_wrapper HEDLEY_NO_THROW constexpr const leaf_type & get() const noexcept { return leaf_; } + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + constexpr leaf_type & get() noexcept { return leaf_; } + HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW constexpr const leaf_type & raw_leaf() const noexcept { return leaf_; } + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + constexpr leaf_type & raw_leaf() noexcept { return leaf_; } + HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW const dpf::beaver & beaver() const noexcept @@ -141,10 +156,11 @@ struct leaf_wrapper, NodeT> leaf_wrapper() = delete; leaf_wrapper(leaf_type leaf_share, beaver_type beaver) - : leaf_{std::forward(leaf_share)}, + : leaf_{leaf_share}, beaver_{beaver}, output_share_{}, - leaf_state_{leaf_status::notset} + leaf_state_{leaf_status::notset}, + updating_{false} { } HEDLEY_ALWAYS_INLINE @@ -157,11 +173,12 @@ struct leaf_wrapper, NodeT> return leaf_; } - const output_type compute_and_get_blinded_output_share(output_type output_share) + output_type compute_and_get_blinded_output_share(output_type output_share) { begin_transition(leaf_status::notset); output_share_ = output_share; - auto blinded_output_share = output_share_ + beaver_.output_blind; + // Use the leaf group (XOR of IEEE bits for float/double), not `operator+`. + auto blinded_output_share = leaf_group_add(output_share_, beaver_.output_blind); leaf_state_ = leaf_status::blinded; return blinded_output_share; } @@ -170,16 +187,28 @@ struct leaf_wrapper, NodeT> /// @tparam Party party index, `0` or `1` /// @tparam Scheme scheme /// @param output_share the `output_share` - /// @return the returned `const output_type` + /// @return the blinded output share template - const output_type compute_and_get_blinded_output_share( + output_type compute_and_get_blinded_output_share( const secret_share & output_share) { - return compute_and_get_blinded_output_share( - output_share.as_additive().raw()); + // Beaver leaf math is a (2,2) additive absorb. (3,3) and replicated + // shares are a different party count; fold them with `add_replicated`. + if constexpr (is_two_party_sharing_v) + { + return compute_and_get_blinded_output_share( + output_share.as_additive().raw()); + } + else + { + static_assert(is_two_party_sharing_v, + "wildcard Beaver absorb expects a (2,2) additive or " + "subtractive share"); + return output_type{}; + } } - const leaf_type compute_and_get_leaf_share(output_type other_output_share) + leaf_type compute_and_get_leaf_share(output_type other_output_share) { begin_transition(leaf_status::blinded); leaf_ = add_leaf(leaf_, subtract_leaf( @@ -189,10 +218,16 @@ struct leaf_wrapper, NodeT> return leaf_; } - const leaf_type reconstruct_correction_word(leaf_type other_share) + leaf_type reconstruct_correction_word(leaf_type other_share) { begin_transition(leaf_status::waiting); leaf_ = add_leaf(leaf_, other_share); + if (updating_) + { + // Opened naked delta; add it onto the previously committed payload. + leaf_ = add_leaf(committed_, leaf_); + updating_ = false; + } leaf_state_ = leaf_status::ready; return leaf_; } @@ -211,6 +246,10 @@ struct leaf_wrapper, NodeT> HEDLEY_NO_THROW const leaf_type & raw_leaf() const noexcept { return leaf_; } + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + leaf_type & raw_leaf() noexcept { return leaf_; } + HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW const beaver_type & beaver() const noexcept { return beaver_; } @@ -241,6 +280,23 @@ struct leaf_wrapper, NodeT> leaf_state_ = static_cast(state); } + /// @brief Re-open a ready leaf so a later assign installs `β' − β`. + /// @details Saves the committed correction word and restores the keygen + /// Beaver pad (not the zero-payload CW) so the next opening adds + /// only a naked delta. Reusing one scale Beaver for two openings + /// is not maliciously secure; honest parties that install `β'−β` + /// still get a correct leaf. + HEDLEY_ALWAYS_INLINE + void begin_update() + { + if (leaf_state_ != leaf_status::ready) + throw std::runtime_error("begin_update: leaf is not ready"); + committed_ = leaf_; + leaf_ = beaver_.assign_pad; + updating_ = true; + leaf_state_ = leaf_status::notset; + } + private: enum class leaf_status : psnip_uint8_t { ready = 0, waiting = 1, computing = 2, blinded = 3, notset = 4 }; @@ -254,9 +310,11 @@ struct leaf_wrapper, NodeT> } leaf_type leaf_; + leaf_type committed_{}; beaver_type beaver_; output_type output_share_; leaf_status leaf_state_; + bool updating_; }; } // namespace dpf diff --git a/include/dpf/literals.hpp b/include/dpf/literals.hpp index 7eee820..6d1f9df 100644 --- a/include/dpf/literals.hpp +++ b/include/dpf/literals.hpp @@ -15,10 +15,15 @@ namespace dpf namespace literals { +/// @brief Re-export of `N_uN` modint literals. namespace modints{} using namespace dpf::literals::modints; +/// @brief Re-export of `N_xN` xint literals. namespace xints{} using namespace dpf::literals::xints; +/// @brief Re-export of bitstring literals. namespace bitstrings{} using namespace dpf::literals::bitstrings; +/// @brief Re-export of `_twobit`. namespace twobit{} using namespace dpf::literals::twobit; +/// @brief Re-export of `_nyble`. namespace nyble{} using namespace dpf::literals::nyble; } // namespace literals diff --git a/include/dpf/log.hpp b/include/dpf/log.hpp new file mode 100644 index 0000000..e7638b9 --- /dev/null +++ b/include/dpf/log.hpp @@ -0,0 +1,701 @@ +/// @file dpf/log.hpp +/// @brief Leveled run log: one `key=value` line per record, written to +/// stderr, syslog, or a file. +/// @details Nothing is written until `log::configure` runs (normally through +/// `app::start_logging`), so library code logs freely and a test or +/// embedder that never configures the log stays quiet. +/// +/// A record is built in a local string and written with one +/// `write(2)` per sink, so party threads, and party processes that +/// append to one file, never interleave inside a line. Every line +/// starts with `ts= lvl= inv= +/// pid= tid=`, then `role=` when the +/// thread has one (`role_scope`), then `ev=` and the event's +/// fields. A value with a space, quote, `=`, backslash, or control +/// character is double-quoted with backslash escapes. +/// +/// Seed bytes go through `record::seed`, which prints them as hex, as +/// a SHA-256 fingerprint, or not at all, per `settings::seeds`. +/// +/// Levels, from quiet to loud: `silent`, `error`, `warning`, `info`, +/// `debug`, `trace` (or `0`-`5`; `warn` and `absurd` are accepted as +/// aliases). `DPF_LOG(level, "event").kv("key", value)` builds the +/// record only when that level is enabled. +#ifndef LIBDPF_INCLUDE_DPF_LOG_HPP__ +#define LIBDPF_INCLUDE_DPF_LOG_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if defined(__linux__) +#include +#endif + +#if defined(__has_include) +#if __has_include() +#include +#define DPF_LOG_HAS_SYSLOG 1 +#endif +#endif +#ifndef DPF_LOG_HAS_SYSLOG +#define DPF_LOG_HAS_SYSLOG 0 +#endif + +namespace dpf +{ +namespace log +{ + +enum class level : unsigned char +{ + silent = 0, + error = 1, + warning = 2, + info = 3, + debug = 4, + trace = 5 +}; + +inline const char * level_name(level l) noexcept +{ + switch (l) + { + case level::silent: + return "silent"; + case level::error: + return "error"; + case level::warning: + return "warning"; + case level::info: + return "info"; + case level::debug: + return "debug"; + case level::trace: + return "trace"; + } + return "info"; +} + +/// @brief Parse a level name or digit. Unknown names throw. +inline level parse_level(const std::string & s) +{ + if (s == "silent" || s == "none" || s == "off" || s == "0") + return level::silent; + if (s == "error" || s == "1") + return level::error; + if (s == "warning" || s == "warn" || s == "2") + return level::warning; + if (s == "info" || s == "3") + return level::info; + if (s == "debug" || s == "4") + return level::debug; + if (s == "trace" || s == "absurd" || s == "5") + return level::trace; + throw std::invalid_argument("unknown log level: " + s + + " (silent|error|warning|info|debug|trace or 0-5)"); +} + +/// @brief How seed bytes appear in records. +enum class seed_policy : unsigned char +{ + full, ///< the bytes as hex: the run can be replayed from the log + hash, ///< a SHA-256 fingerprint: runs can be compared, not replayed + off ///< neither; the field reads `withheld` +}; + +inline const char * seed_policy_name(seed_policy p) noexcept +{ + switch (p) + { + case seed_policy::full: + return "full"; + case seed_policy::hash: + return "hash"; + case seed_policy::off: + return "off"; + } + return "full"; +} + +inline seed_policy parse_seed_policy(const std::string & s) +{ + if (s == "full" || s == "hex" || s == "1") + return seed_policy::full; + if (s == "hash" || s == "fingerprint" || s == "sha256") + return seed_policy::hash; + if (s == "off" || s == "none" || s == "0") + return seed_policy::off; + throw std::invalid_argument("unknown log_seeds: " + s + " (full|hash|off)"); +} + +struct settings +{ + level threshold = level::info; + /// Comma-separated sinks: `stderr`, `syslog`, `file:PATH`, or `none`. + /// One file at most; it is opened for append, so parties may share it. + std::string sinks = "stderr"; + seed_policy seeds = seed_policy::full; + /// syslog identity (facility `LOG_USER`). + std::string ident = "libdpf"; +}; + +namespace detail +{ + +inline std::atomic threshold{0}; +inline std::atomic seeds{0}; + +struct sinks_state +{ + std::mutex mu; + bool to_stderr = false; + bool to_syslog = false; + int fd = -1; + std::string path; + std::string ident; + std::set said; + + sinks_state() = default; + sinks_state(const sinks_state &) = delete; + sinks_state & operator=(const sinks_state &) = delete; + + ~sinks_state() + { + threshold.store(0, std::memory_order_relaxed); + if (fd >= 0) + ::close(fd); +#if DPF_LOG_HAS_SYSLOG + if (to_syslog) + ::closelog(); +#endif + } +}; + +inline sinks_state & sinks() +{ + static sinks_state s; + return s; +} + +inline thread_local std::string role_tls; + +inline long kernel_tid() noexcept +{ +#if defined(__linux__) && defined(SYS_gettid) + static thread_local const long tid = static_cast(::syscall(SYS_gettid)); + return tid; +#else + return static_cast( + std::hash{}(std::this_thread::get_id()) & 0x7fffffffu); +#endif +} + +/// @brief `YYYY-MM-DDTHH:MM:SS.uuuuuuZ` for `tp`. +inline std::string utc_text(std::chrono::system_clock::time_point tp) +{ + const auto us = std::chrono::duration_cast( + tp.time_since_epoch()).count(); + const std::time_t secs = static_cast(us / 1000000); + const auto frac = static_cast((us % 1000000 + 1000000) % 1000000); + std::tm tm{}; + ::gmtime_r(&secs, &tm); + char buf[96]; + std::snprintf(buf, sizeof(buf), "%04d-%02d-%02dT%02d:%02d:%02d.%06uZ", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, + tm.tm_sec, frac); + return buf; +} + +inline void append_value(std::string & out, const char * p, std::size_t n) +{ + bool plain = n != 0; + for (std::size_t i = 0; i < n && plain; ++i) + { + const auto c = static_cast(p[i]); + plain = c > 0x20 && c < 0x7f && c != '"' && c != '=' && c != '\\'; + } + if (plain) + { + out.append(p, n); + return; + } + out += '"'; + for (std::size_t i = 0; i < n; ++i) + { + const auto c = static_cast(p[i]); + switch (c) + { + case '"': + out += "\\\""; + break; + case '\\': + out += "\\\\"; + break; + case '\n': + out += "\\n"; + break; + case '\r': + out += "\\r"; + break; + case '\t': + out += "\\t"; + break; + default: + if (c < 0x20 || c == 0x7f) + { + char esc[5]; + std::snprintf(esc, sizeof(esc), "\\x%02x", c); + out += esc; + } + else + out += static_cast(c); + } + } + out += '"'; +} + +inline void append_hex(std::string & out, const std::uint8_t * p, std::size_t n) +{ + static const char digits[] = "0123456789abcdef"; + for (std::size_t i = 0; i < n; ++i) + { + out += digits[p[i] >> 4]; + out += digits[p[i] & 0x0f]; + } +} + +/// @brief SHA-256 of `label || data` (FIPS 180-4), for seed fingerprints. +inline std::array sha256(const char * label, + const std::uint8_t * data, std::size_t n) +{ + static constexpr std::uint32_t k[64] = { + 0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu, + 0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u, 0xd807aa98u, 0x12835b01u, + 0x243185beu, 0x550c7dc3u, 0x72be5d74u, 0x80deb1feu, 0x9bdc06a7u, + 0xc19bf174u, 0xe49b69c1u, 0xefbe4786u, 0x0fc19dc6u, 0x240ca1ccu, + 0x2de92c6fu, 0x4a7484aau, 0x5cb0a9dcu, 0x76f988dau, 0x983e5152u, + 0xa831c66du, 0xb00327c8u, 0xbf597fc7u, 0xc6e00bf3u, 0xd5a79147u, + 0x06ca6351u, 0x14292967u, 0x27b70a85u, 0x2e1b2138u, 0x4d2c6dfcu, + 0x53380d13u, 0x650a7354u, 0x766a0abbu, 0x81c2c92eu, 0x92722c85u, + 0xa2bfe8a1u, 0xa81a664bu, 0xc24b8b70u, 0xc76c51a3u, 0xd192e819u, + 0xd6990624u, 0xf40e3585u, 0x106aa070u, 0x19a4c116u, 0x1e376c08u, + 0x2748774cu, 0x34b0bcb5u, 0x391c0cb3u, 0x4ed8aa4au, 0x5b9cca4fu, + 0x682e6ff3u, 0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u, + 0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u}; + std::uint32_t h[8] = {0x6a09e667u, 0xbb67ae85u, 0x3c6ef372u, 0xa54ff53au, + 0x510e527fu, 0x9b05688cu, 0x1f83d9abu, 0x5be0cd19u}; + std::string m(label == nullptr ? "" : label); + m.append(reinterpret_cast(data), n); + const std::uint64_t bits = static_cast(m.size()) * 8u; + m += static_cast(0x80); + while (m.size() % 64 != 56) + m += '\0'; + for (int i = 7; i >= 0; --i) + m += static_cast((bits >> (8 * i)) & 0xffu); + auto rotr = [](std::uint32_t x, int r) { return (x >> r) | (x << (32 - r)); }; + for (std::size_t off = 0; off < m.size(); off += 64) + { + std::uint32_t w[64]; + for (int i = 0; i < 16; ++i) + { + const auto * b = reinterpret_cast(m.data() + off + 4 * i); + w[i] = (static_cast(b[0]) << 24) + | (static_cast(b[1]) << 16) + | (static_cast(b[2]) << 8) | static_cast(b[3]); + } + for (int i = 16; i < 64; ++i) + { + const std::uint32_t s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >> 3); + const std::uint32_t s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >> 10); + w[i] = w[i - 16] + s0 + w[i - 7] + s1; + } + std::uint32_t a = h[0], b = h[1], c = h[2], d = h[3]; + std::uint32_t e = h[4], f = h[5], g = h[6], hh = h[7]; + for (int i = 0; i < 64; ++i) + { + const std::uint32_t s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25); + const std::uint32_t ch = (e & f) ^ (~e & g); + const std::uint32_t t1 = hh + s1 + ch + k[i] + w[i]; + const std::uint32_t s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22); + const std::uint32_t mj = (a & b) ^ (a & c) ^ (b & c); + const std::uint32_t t2 = s0 + mj; + hh = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + h[0] += a; + h[1] += b; + h[2] += c; + h[3] += d; + h[4] += e; + h[5] += f; + h[6] += g; + h[7] += hh; + } + std::array out{}; + for (int i = 0; i < 8; ++i) + for (int j = 0; j < 4; ++j) + out[static_cast(4 * i + j)] = + static_cast((h[i] >> (24 - 8 * j)) & 0xffu); + return out; +} + +#if DPF_LOG_HAS_SYSLOG +inline int syslog_priority(level l) noexcept +{ + switch (l) + { + case level::error: + return LOG_ERR; + case level::warning: + return LOG_WARNING; + case level::info: + return LOG_INFO; + default: + return LOG_DEBUG; + } +} +#endif + +inline void write_all(int fd, const char * p, std::size_t n) noexcept +{ + while (n > 0) + { + const ssize_t r = ::write(fd, p, n); + if (r > 0) + { + p += r; + n -= static_cast(r); + continue; + } + if (r < 0 && errno == EINTR) + continue; + return; + } +} + +inline void emit(level l, std::string & line) noexcept +{ + try + { + line += '\n'; + auto & s = sinks(); + std::lock_guard lock(s.mu); + if (s.to_stderr) + write_all(STDERR_FILENO, line.data(), line.size()); + if (s.fd >= 0) + write_all(s.fd, line.data(), line.size()); +#if DPF_LOG_HAS_SYSLOG + if (s.to_syslog) + ::syslog(syslog_priority(l), "%.*s", static_cast(line.size() - 1), + line.data()); +#else + (void)l; +#endif + } + catch (...) + { + } +} + +} // namespace detail + +/// @brief True when records at `l` are written somewhere. +inline bool enabled(level l) noexcept +{ + return l != level::silent + && static_cast(l) <= detail::threshold.load(std::memory_order_relaxed); +} + +inline seed_policy seeds() noexcept +{ + return static_cast(detail::seeds.load(std::memory_order_relaxed)); +} + +/// @brief Random per-process id stamped on every record (and on CSV rows that +/// want to point back at the log). Drawn once from `std::random_device`, +/// never from `dpf::uniform_fill`, so it does not perturb seed streams +/// or random-byte counts. +inline const std::string & invocation_id() +{ + static const std::string id = [] { + std::uint64_t v = 0; + try + { + std::random_device rd; + v = (static_cast(rd()) << 32) ^ rd(); + } + catch (...) + { + v = static_cast( + std::chrono::system_clock::now().time_since_epoch().count()) + ^ (static_cast(::getpid()) << 40); + } + std::string out; + std::uint8_t b[8]; + for (int i = 0; i < 8; ++i) + b[i] = static_cast((v >> (56 - 8 * i)) & 0xffu); + detail::append_hex(out, b, 8); + return out; + }(); + return id; +} + +/// @brief Apply `cfg`. A bad sink name or unopenable file throws and leaves the +/// previous configuration in place. `none` (or no sinks) silences. +inline void configure(const settings & cfg) +{ + bool want_stderr = false; + bool want_syslog = false; + std::string path; + std::size_t start = 0; + while (start <= cfg.sinks.size()) + { + const auto comma = cfg.sinks.find(',', start); + std::string tok = cfg.sinks.substr(start, + comma == std::string::npos ? std::string::npos : comma - start); + while (!tok.empty() && tok.front() == ' ') + tok.erase(tok.begin()); + while (!tok.empty() && tok.back() == ' ') + tok.pop_back(); + if (tok == "stderr") + want_stderr = true; + else if (tok == "syslog") + want_syslog = true; + else if (tok.rfind("file:", 0) == 0 && tok.size() > 5) + path = tok.substr(5); + else if (!tok.empty() && tok != "none") + throw std::invalid_argument("unknown log sink '" + tok + + "' (stderr|syslog|file:PATH|none)"); + if (comma == std::string::npos) + break; + start = comma + 1; + } +#if !DPF_LOG_HAS_SYSLOG + if (want_syslog) + throw std::invalid_argument("log sink 'syslog' is not available here"); +#endif + (void)invocation_id(); + auto & s = detail::sinks(); + std::lock_guard lock(s.mu); + int fd = -1; + if (!path.empty()) + { + if (path == s.path && s.fd >= 0) + fd = s.fd; + else + { + fd = ::open(path.c_str(), O_WRONLY | O_CREAT | O_APPEND | O_CLOEXEC, 0640); + if (fd < 0) + throw std::runtime_error("log: cannot open '" + path + "': " + + std::strerror(errno)); + } + } + if (s.fd >= 0 && s.fd != fd) + ::close(s.fd); + s.fd = fd; + s.path = path; +#if DPF_LOG_HAS_SYSLOG + if (s.to_syslog && (!want_syslog || s.ident != cfg.ident)) + { + ::closelog(); + s.to_syslog = false; + } + if (want_syslog && !s.to_syslog) + { + s.ident = cfg.ident; + ::openlog(s.ident.c_str(), LOG_PID | LOG_NDELAY, LOG_USER); + } +#endif + s.to_syslog = want_syslog; + s.to_stderr = want_stderr; + detail::seeds.store(static_cast(cfg.seeds), std::memory_order_relaxed); + const bool any = want_stderr || want_syslog || fd >= 0; + detail::threshold.store(any ? static_cast(cfg.threshold) : 0u, + std::memory_order_relaxed); +} + +/// @brief True the first time `key` is seen in this process (for one-shot +/// warnings from code that runs per trial or per cell). +inline bool first_time(const std::string & key) +{ + auto & s = detail::sinks(); + std::lock_guard lock(s.mu); + return s.said.insert(key).second; +} + +/// @brief The party role stamped on this thread's records (`p0`, `p1`, `p2`). +inline const std::string & role() noexcept { return detail::role_tls; } + +/// @brief Set this thread's role for the scope's lifetime. +class role_scope +{ +public: + explicit role_scope(std::string role) : prev_(std::move(detail::role_tls)) + { + detail::role_tls = std::move(role); + } + ~role_scope() { detail::role_tls = std::move(prev_); } + role_scope(const role_scope &) = delete; + role_scope & operator=(const role_scope &) = delete; + +private: + std::string prev_; +}; + +/// @brief One log line. Written when it goes out of scope. +class record +{ +public: + record(level l, const char * event) : level_(l) + { + line_.reserve(256); + line_ += "ts="; + line_ += detail::utc_text(std::chrono::system_clock::now()); + line_ += " lvl="; + line_ += level_name(l); + line_ += " inv="; + line_ += invocation_id(); + line_ += " pid="; + line_ += std::to_string(::getpid()); + line_ += " tid="; + line_ += std::to_string(detail::kernel_tid()); + if (!detail::role_tls.empty()) + { + line_ += " role="; + detail::append_value(line_, detail::role_tls.data(), detail::role_tls.size()); + } + line_ += " ev="; + const char * ev = event == nullptr ? "event" : event; + detail::append_value(line_, ev, std::strlen(ev)); + } + + record(const record &) = delete; + record & operator=(const record &) = delete; + + ~record() { detail::emit(level_, line_); } + + record & kv(const char * key, const std::string & v) + { + key_(key); + detail::append_value(line_, v.data(), v.size()); + return *this; + } + + record & kv(const char * key, const char * v) + { + key_(key); + const char * p = v == nullptr ? "" : v; + detail::append_value(line_, p, std::strlen(p)); + return *this; + } + + record & kv(const char * key, bool v) + { + key_(key); + line_ += v ? '1' : '0'; + return *this; + } + + template && !std::is_same_v, int> = 0> + record & kv(const char * key, T v) + { + key_(key); + line_ += std::to_string(v); + return *this; + } + + template , int> = 0> + record & kv(const char * key, T v) + { + key_(key); + char buf[32]; + std::snprintf(buf, sizeof(buf), "%.6g", static_cast(v)); + line_ += buf; + return *this; + } + + record & hex(const char * key, const void * bytes, std::size_t n) + { + key_(key); + if (n == 0 || bytes == nullptr) + line_ += "\"\""; + else + detail::append_hex(line_, static_cast(bytes), n); + return *this; + } + + /// @brief Seed bytes under the configured `seed_policy`. + record & seed(const char * key, const void * bytes, std::size_t n) + { + switch (seeds()) + { + case seed_policy::full: + return hex(key, bytes, n); + case seed_policy::hash: + { + const auto d = detail::sha256("libdpf seed fingerprint", + static_cast(bytes), bytes == nullptr ? 0 : n); + key_(key); + line_ += "sha256:"; + detail::append_hex(line_, d.data(), 8); + return *this; + } + case seed_policy::off: + break; + } + key_(key); + line_ += "withheld"; + return *this; + } + +private: + void key_(const char * key) + { + line_ += ' '; + line_ += key == nullptr ? "field" : key; + line_ += '='; + } + + level level_; + std::string line_; +}; + +} // namespace log +} // namespace dpf + +/// @brief `DPF_LOG(info, "event").kv("key", value)`: the record and its +/// arguments are only evaluated when `info` is enabled. The single-pass +/// `for` has no `else` to pair with an enclosing unbraced `if`. +#define DPF_LOG(LEVEL, EVENT) \ + for (bool dpf_log_on_ = ::dpf::log::enabled(::dpf::log::level::LEVEL); \ + dpf_log_on_; dpf_log_on_ = false) \ + ::dpf::log::record(::dpf::log::level::LEVEL, EVENT) + +#endif // LIBDPF_INCLUDE_DPF_LOG_HPP__ diff --git a/include/dpf/matmul.hpp b/include/dpf/matmul.hpp new file mode 100644 index 0000000..b4f6ed1 --- /dev/null +++ b/include/dpf/matmul.hpp @@ -0,0 +1,173 @@ +/// @file dpf/matmul.hpp +/// @brief Matrix Beaver triples and online matmul / im2col convolution. +#ifndef LIBDPF_INCLUDE_DPF_MATMUL_HPP__ +#define LIBDPF_INCLUDE_DPF_MATMUL_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/random.hpp" +#include "dpf/share_vec.hpp" + +namespace dpf +{ +namespace matmul +{ + +template +struct dims +{ + std::size_t m = 0; + std::size_t k = 0; + std::size_t n = 0; +}; + +template +struct matrix_triple +{ + dims d{}; + std::vector a0, a1; ///< m×k + std::vector b0, b1; ///< k×n + std::vector c0, c1; ///< m×n = AB +}; + +template +HEDLEY_WARN_UNUSED_RESULT +std::vector clear_mul(const std::vector & a, + const std::vector & b, dims d) +{ + if (a.size() != d.m * d.k || b.size() != d.k * d.n) + throw std::invalid_argument("matmul clear size"); + std::vector c(d.m * d.n, Ring{}); + for (std::size_t i = 0; i < d.m; ++i) + for (std::size_t j = 0; j < d.n; ++j) + { + Ring acc{}; + for (std::size_t t = 0; t < d.k; ++t) + acc = static_cast( + acc + a[i * d.k + t] * b[t * d.n + j]); + c[i * d.n + j] = acc; + } + return c; +} + +template +HEDLEY_WARN_UNUSED_RESULT +matrix_triple sample_triple(dims d) +{ + matrix_triple t; + t.d = d; + t.a0.resize(d.m * d.k); + t.a1.resize(d.m * d.k); + t.b0.resize(d.k * d.n); + t.b1.resize(d.k * d.n); + std::vector a(d.m * d.k), b(d.k * d.n); + for (std::size_t i = 0; i < a.size(); ++i) + { + a[i] = dpf::uniform_sample(); + t.a0[i] = dpf::uniform_sample(); + t.a1[i] = static_cast(a[i] - t.a0[i]); + } + for (std::size_t i = 0; i < b.size(); ++i) + { + b[i] = dpf::uniform_sample(); + t.b0[i] = dpf::uniform_sample(); + t.b1[i] = static_cast(b[i] - t.b0[i]); + } + auto c = clear_mul(a, b, d); + t.c0.resize(c.size()); + t.c1.resize(c.size()); + for (std::size_t i = 0; i < c.size(); ++i) + { + t.c0[i] = dpf::uniform_sample(); + t.c1[i] = static_cast(c[i] - t.c0[i]); + } + return t; +} + +/// @brief Online: open `D = X-A`, `E = Y-B`; `Z = C + D B + A E + D E` (p0 adds DE). +template +HEDLEY_WARN_UNUSED_RESULT +std::vector online(const std::vector & x_share, + const std::vector & y_share, const std::vector & a_share, + const std::vector & b_share, const std::vector & c_share, + const std::vector & d_open, const std::vector & e_open, + dims d, unsigned party) +{ + if (x_share.size() != d.m * d.k || y_share.size() != d.k * d.n) + throw std::invalid_argument("matmul online size"); + auto db = clear_mul(d_open, b_share, d); + // A·E : a is m×k, e is k×n + auto ae = clear_mul(a_share, e_open, d); + std::vector z(d.m * d.n); + for (std::size_t i = 0; i < z.size(); ++i) + z[i] = static_cast(c_share[i] + db[i] + ae[i]); + if (party == 0) + { + auto de = clear_mul(d_open, e_open, d); + for (std::size_t i = 0; i < z.size(); ++i) + z[i] = static_cast(z[i] + de[i]); + } + (void)x_share; + (void)y_share; + return z; +} + +/// @brief Full clear+share test: return shares of X Y. +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, std::vector> mul_shared( + const std::vector & x, const std::vector & y, dims d) +{ + auto t = sample_triple(d); + std::vector x0(x.size()), x1(x.size()), y0(y.size()), y1(y.size()); + for (std::size_t i = 0; i < x.size(); ++i) + { + x0[i] = dpf::uniform_sample(); + x1[i] = static_cast(x[i] - x0[i]); + } + for (std::size_t i = 0; i < y.size(); ++i) + { + y0[i] = dpf::uniform_sample(); + y1[i] = static_cast(y[i] - y0[i]); + } + std::vector d_open(d.m * d.k), e_open(d.k * d.n); + for (std::size_t i = 0; i < d_open.size(); ++i) + d_open[i] = static_cast((x0[i] + x1[i]) - (t.a0[i] + t.a1[i])); + for (std::size_t i = 0; i < e_open.size(); ++i) + e_open[i] = static_cast((y0[i] + y1[i]) - (t.b0[i] + t.b1[i])); + auto z0 = online(x0, y0, t.a0, t.b0, t.c0, d_open, e_open, d, 0); + auto z1 = online(x1, y1, t.a1, t.b1, t.c1, d_open, e_open, d, 1); + return {std::move(z0), std::move(z1)}; +} + +/// @brief im2col: flatten `h×w` patches of size `kh×kw` with stride 1 into rows. +template +HEDLEY_WARN_UNUSED_RESULT +std::vector im2col(const std::vector & img, std::size_t h, + std::size_t w, std::size_t kh, std::size_t kw) +{ + if (img.size() != h * w || kh > h || kw > w) + throw std::invalid_argument("im2col"); + const std::size_t out_h = h - kh + 1; + const std::size_t out_w = w - kw + 1; + std::vector col(out_h * out_w * kh * kw); + std::size_t row = 0; + for (std::size_t i = 0; i < out_h; ++i) + for (std::size_t j = 0; j < out_w; ++j, ++row) + for (std::size_t u = 0; u < kh; ++u) + for (std::size_t v = 0; v < kw; ++v) + col[row * (kh * kw) + u * kw + v] = + img[(i + u) * w + (j + v)]; + return col; +} + +} // namespace matmul +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_MATMUL_HPP__ diff --git a/include/dpf/mesh_apps.hpp b/include/dpf/mesh_apps.hpp new file mode 100644 index 0000000..78f866b --- /dev/null +++ b/include/dpf/mesh_apps.hpp @@ -0,0 +1,91 @@ +/// @file dpf/mesh_apps.hpp +/// @brief Micro-plan builders for PIRsona and hushmap on the edge mesh. +#ifndef LIBDPF_INCLUDE_DPF_MESH_APPS_HPP__ +#define LIBDPF_INCLUDE_DPF_MESH_APPS_HPP__ + +#include +#include +#include +#include +#include + +#include "dpf/compose.hpp" +#include "dpf/pad_graphs.hpp" +#include "dpf/protocol.hpp" + +namespace dpf +{ +namespace protocol +{ + +/// @brief PIRsona: BitMore-shaped star fetch (L bit keys → 2^L servers). +/// @details Returns upload+answer rounds for `n_servers = 1u << L`. +inline std::vector pirsona_bitmore_fetch(std::size_t L, + std::size_t seed_bytes, std::size_t answer_bytes, + const std::shared_ptr>> & seeds, + const std::shared_ptr>> & answers) +{ + const std::size_t n = std::size_t{1} << L; + return star_upload_answer_graph(n, seed_bytes * L, answer_bytes, seeds, + answers); +} + +/// @brief PIRsona one gradient-descent update: Du-Atallah mul graph (stub body). +inline std::vector pirsona_gd_update_graph( + const std::shared_ptr> & tape) +{ + return du_atallah_mul_graph(tape, /*slot_bytes=*/32); +} + +/// @brief Hushmap KHM ADD online skeleton: Beaver open + masked open rounds. +/// @details Matches the barrier count of MPC_PROTOCOL-v3 Phase 1 (2 peer opens) +/// after a dealer tape of `n_layers` triples has been spliced. +inline std::vector hushmap_add_online_graph( + std::size_t n_layers, std::size_t open_bytes = 8) +{ + (void)n_layers; + std::vector rounds(2); + for (std::size_t r = 0; r < 2; ++r) + { + rounds[r].slot_bytes = open_bytes; + rounds[r].edge = edge_peer; + rounds[r].channel = edge_channel::peer; + rounds[r].recv = receive_rule::domain_open; + rounds[r].sink_round = static_cast(r); + rounds[r].produce = [open_bytes, r](std::size_t, const std::uint8_t *, + std::size_t, std::uint8_t * out) { + if (out != nullptr) + std::memset(out, static_cast(0x10 + r), open_bytes); + }; + } + return rounds; +} + +/// @brief Full hushmap ADD schedule: dealer tape then online opens. +inline std::vector hushmap_add_schedule(std::size_t n_layers, + const std::shared_ptr> & tape, + std::size_t triple_bytes = 24, std::size_t open_bytes = 8) +{ + auto pads = dealer_tape_graph(n_layers, triple_bytes, tape); + auto online = hushmap_add_online_graph(n_layers, open_bytes); + // Online peer sink_rounds start at 0 on a peer-only sink after dealer + // edges are separate — keep sink_round as assigned. + return splice_rounds(std::move(pads), std::move(online)); +} + +/// @brief Composer plan for a 2-server keyword-PIR-shaped client_servers flow. +/// @details Prefer `n_server_pir_plan` / `keyword_pir_compose_plan` in +/// [app_plans.hpp](@ref dpf/app_plans.hpp) for depth-derived sizes. +inline plan keyword_pir_plan(std::size_t party, std::size_t query_bytes, + std::size_t answer_bytes) +{ + composer c(party); + auto q = c.client_servers(2, query_bytes, answer_bytes); + (void)q; + return c.default_plan(); +} + +} // namespace protocol +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_MESH_APPS_HPP__ diff --git a/include/dpf/modint.hpp b/include/dpf/modint.hpp index 1b1ac6f..e34dfb8 100644 --- a/include/dpf/modint.hpp +++ b/include/dpf/modint.hpp @@ -34,6 +34,10 @@ namespace dpf /// @brief represents an unsigned integer modulo `2^Nbits` for small values of `Nbits` /// @tparam Nbits width in bits +/// @note Domain widths 1, 2, and 4 are this type or `dpf::xint`, not +/// `dpf::bit` / `dpf::twobit` / `dpf::nyble`. +/// @see dpf::xint +/// @see dpf::modints::modintN_t template class modint { @@ -831,6 +835,12 @@ struct mod_pow_2> namespace modints { +/// @name modintN_t +/// @{ + +/// @brief `modintN_t` is `dpf::modint` for N from 1 through 256. +/// @see dpf::modint +/// @see dpf::xint // 1--9 using modint1_t = dpf::modint<1>; using modint2_t = dpf::modint<2>; @@ -1114,6 +1124,8 @@ using modint254_t = dpf::modint<254>; using modint255_t = dpf::modint<255>; using modint256_t = dpf::modint<256>; +/// @} + namespace literals = dpf::literals::modints; } // namespace modints @@ -1124,6 +1136,11 @@ namespace literals namespace modints { +/// @name modint literals `N_uN` +/// @{ + +/// @brief Decimal literal for `dpf::modint`. Widths through 64 take an integer; wider widths take a digit string. +/// @see dpf::modints::modintN_t // 1--9 constexpr static auto operator "" _u1(unsigned long long int x) { return dpf::modints::modint1_t{static_cast(x)}; } constexpr static auto operator "" _u2(unsigned long long int x) { return dpf::modints::modint2_t{static_cast(x)}; } @@ -1408,6 +1425,8 @@ template constexpr static auto operator "" _u254() { utils::con template constexpr static auto operator "" _u255() { utils::constexpr_maybe_throw(!(std::isdigit(digits) && ...), "invalid char"); uint256_t x{0}; ((x = x * 10 + (digits - '0')), ...); return dpf::modints::modint255_t{x}; } template constexpr static auto operator "" _u256() { utils::constexpr_maybe_throw(!(std::isdigit(digits) && ...), "invalid char"); uint256_t x{0}; ((x = x * 10 + (digits - '0')), ...); return dpf::modints::modint256_t{x}; } +/// @} + } // namespace modints } // namespace literals diff --git a/include/dpf/multipoint.hpp b/include/dpf/multipoint.hpp index 888d41e..16a3a79 100644 --- a/include/dpf/multipoint.hpp +++ b/include/dpf/multipoint.hpp @@ -1,10 +1,11 @@ /// @file dpf/multipoint.hpp /// @brief Cuckoo-packed multi-point DPF and verifiable multi-point DPF. /// @details Packs t distinct points into m ≈ O(t) buckets (de Castro– -/// Polychroniadou, EUROCRYPT 2022, §4). Each bucket is an ordinary +/// Polychroniadou, EUROCRYPT 2022, §4, ePrint 2021/580). Each bucket is an ordinary /// point key on a smaller domain — `dpf::verifiable` selects VDPF /// buckets. Evaluation probes κ = 3 buckets and sums the shares. /// A batched proof is one 2λ token. +/// @note Following that section: κ = 3 cuckoo hashes, one point key per bucket. /// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license; /// see [LICENSE.md](@ref license) for details. @@ -32,6 +33,7 @@ #include "dpf/prg_aes.hpp" #include "dpf/random.hpp" #include "dpf/secret_share.hpp" +#include "dpf/uint256_t.hpp" #include "dpf/verifiable.hpp" namespace dpf @@ -45,6 +47,26 @@ struct multipoint_params int retries = 8; }; +/// @brief 512-bit word for the cuckoo PRP. Holds `3·2^b` for every input +/// width this library can form a point key on (up to 256 bits). +struct mpf_word +{ + uint256_t lo{}; + uint256_t hi{}; + + friend bool operator==(mpf_word a, mpf_word b) noexcept + { + return a.lo == b.lo && a.hi == b.hi; + } + + friend bool operator<(mpf_word a, mpf_word b) noexcept + { + if (a.hi != b.hi) + return a.hi < b.hi; + return a.lo < b.lo; + } +}; + template struct is_multipoint_key : std::false_type { @@ -68,8 +90,8 @@ struct multipoint_key using share_type = subtractive_share; simde__m128i sigma{}; - std::uint32_t bucket_count = 0; - std::uint64_t bucket_domain = 0; + std::uint64_t bucket_count = 0; + mpf_word bucket_domain{}; std::vector> buckets{}; }; @@ -98,15 +120,237 @@ struct prp_walk_error : std::runtime_error struct located { - std::uint32_t bucket = 0; - std::uint64_t index = 0; + std::uint64_t bucket = 0; + mpf_word index{}; }; -using wide = unsigned __int128; - -inline wide domain_size(std::size_t bits) +inline mpf_word word_add(mpf_word a, mpf_word b) { - return wide{1} << bits; + mpf_word r; + r.lo = a.lo + b.lo; + r.hi = a.hi + b.hi; + if (r.lo < a.lo) + r.hi = r.hi + uint256_t{1}; + return r; +} + +inline mpf_word word_sub(mpf_word a, mpf_word b) +{ + mpf_word r; + r.lo = a.lo - b.lo; + r.hi = a.hi - b.hi; + if (a.lo < b.lo) + r.hi = r.hi - uint256_t{1}; + return r; +} + +inline mpf_word word_shl(mpf_word a, unsigned shift) +{ + if (shift == 0) + return a; + if (shift >= 512) + return {}; + if (shift >= 256) + { + mpf_word r; + r.hi = a.lo << (shift - 256); + return r; + } + mpf_word r; + r.lo = a.lo << shift; + r.hi = (a.hi << shift) | (a.lo >> (256 - shift)); + return r; +} + +inline mpf_word word_shr(mpf_word a, unsigned shift) +{ + if (shift == 0) + return a; + if (shift >= 512) + return {}; + if (shift >= 256) + { + mpf_word r; + r.lo = a.hi >> (shift - 256); + return r; + } + mpf_word r; + r.hi = a.hi >> shift; + r.lo = (a.lo >> shift) | (a.hi << (256 - shift)); + return r; +} + +inline mpf_word word_or(mpf_word a, mpf_word b) +{ + a.lo = a.lo | b.lo; + a.hi = a.hi | b.hi; + return a; +} + +inline mpf_word word_and(mpf_word a, mpf_word b) +{ + a.lo = a.lo & b.lo; + a.hi = a.hi & b.hi; + return a; +} + +inline bool word_bit(mpf_word a, unsigned bit) +{ + if (bit >= 512) + return false; + if (bit >= 256) + return static_cast((a.hi >> (bit - 256)) & uint256_t{1}); + return static_cast((a.lo >> bit) & uint256_t{1}); +} + +inline int word_bit_length(mpf_word a) +{ + for (int i = 255; i >= 0; --i) + { + if (static_cast((a.hi >> i) & uint256_t{1})) + return i + 1 + 256; + } + for (int i = 255; i >= 0; --i) + { + if (static_cast((a.lo >> i) & uint256_t{1})) + return i + 1; + } + return 0; +} + +inline mpf_word word_mul_small(mpf_word a, std::uint64_t k) +{ + mpf_word r{}; + while (k != 0) + { + if ((k & 1u) != 0) + r = word_add(r, a); + a = word_shl(a, 1); + k >>= 1; + } + return r; +} + +inline std::pair word_divmod(mpf_word num, mpf_word den) +{ + if (den == mpf_word{}) + throw std::invalid_argument("multipoint division by zero"); + mpf_word q{}; + mpf_word r{}; + const int top = word_bit_length(num); + for (int i = top - 1; i >= 0; --i) + { + r = word_shl(r, 1); + if (word_bit(num, static_cast(i))) + r = word_add(r, mpf_word{uint256_t{1}, uint256_t{0}}); + if (!(r < den)) + { + r = word_sub(r, den); + mpf_word bit{}; + if (i >= 256) + bit.hi = uint256_t{1} << static_cast(i - 256); + else + bit.lo = uint256_t{1} << static_cast(i); + q = word_or(q, bit); + } + } + return {q, r}; +} + +inline mpf_word domain_size(std::size_t bits) +{ + mpf_word r{}; + if (bits >= 512) + throw std::invalid_argument("multipoint domain shift is out of range"); + if (bits >= 256) + r.hi = uint256_t{1} << (bits - 256); + else if (bits > 0) + r.lo = uint256_t{1} << bits; + return r; +} + +template +mpf_word to_word(T x) +{ + constexpr std::size_t bits = utils::bitlength_of_v; + mpf_word w{}; + if constexpr (bits > 128) + { + w.lo = static_cast(x); + } + else if constexpr (bits > 64) + { + uint128_t low{}; + std::memcpy(&low, &x, sizeof(T)); + w.lo = uint256_t{low}; + } + else + { + w.lo = uint256_t{static_cast(x)}; + } + return w; +} + +template +T from_word(mpf_word w) +{ + constexpr std::size_t bits = utils::bitlength_of_v; + if constexpr (bits > 128) + { + return static_cast(w.lo); + } + else if constexpr (bits > 64) + { + const uint128_t low = static_cast(w.lo); + T out{}; + std::memcpy(&out, &low, sizeof(T)); + return out; + } + else + { + return static_cast(static_cast(w.lo)); + } +} + +/// @brief Low `half` bits set, as a 512-bit mask. `half <= 0` is zero. +inline mpf_word low_mask(int half) +{ + if (half <= 0) + return {}; + if (half >= 512) + { + mpf_word all; + all.lo = ~uint256_t{0}; + all.hi = ~uint256_t{0}; + return all; + } + return word_sub(domain_size(static_cast(half)), + mpf_word{uint256_t{1}, uint256_t{0}}); +} + +inline mpf_word aes_prf(simde__m128i seed, mpf_word right, int round) +{ + alignas(16) unsigned char raw[32]{}; + std::memcpy(raw, &right.lo, sizeof(right.lo)); + alignas(16) simde__m128i block0; + alignas(16) simde__m128i block1; + std::memcpy(&block0, raw, 16); + std::memcpy(&block1, raw + 16, 16); + block0 = simde_mm_xor_si128(block0, seed); + block0 = simde_mm_xor_si128(block0, simde_mm_set_epi32(0, 0, 0, round + 1)); + const auto out0 = prg::aes128::eval(block0, + static_cast(round + 1)); + block1 = simde_mm_xor_si128(block1, seed); + block1 = simde_mm_xor_si128(block1, + simde_mm_set_epi32(0, 0, 0, round + 0x11)); + const auto out1 = prg::aes128::eval(block1, + static_cast(round + 0x21)); + alignas(16) unsigned char packed[32]; + std::memcpy(packed, &out0, 16); + std::memcpy(packed + 16, &out1, 16); + mpf_word f{}; + std::memcpy(&f.lo, packed, sizeof(f.lo)); + return f; } /// @brief 4-round Feistel on the next power-of-two square, then cycle-walk @@ -117,75 +361,68 @@ inline wide domain_size(std::size_t bits) /// @return the permuted value in `[0, domain)` /// @throws std::invalid_argument if `x` is outside the domain /// @throws prp_walk_error if the cycle walk exceeds its bound -inline wide permute(simde__m128i seed, wide x, wide domain) +inline mpf_word permute(simde__m128i seed, mpf_word x, mpf_word domain) { - if (domain <= 1) - return 0; - if (x >= domain) + const mpf_word one{uint256_t{1}, uint256_t{0}}; + if (!(one < domain)) + return {}; + if (!(x < domain)) throw std::invalid_argument("multipoint PRP input is outside the domain"); - int bits = 0; - for (wide v = domain - 1; v > 0; v >>= 1) - ++bits; + const int bits = word_bit_length(word_sub(domain, one)); const int half = (bits + 1) / 2; - const wide mask = (half >= 128) - ? ~wide{0} - : (wide{1} << half) - 1; + const mpf_word mask = low_mask(half); - wide val = x; + mpf_word val = x; for (int guard = 0; guard < 128; ++guard) { - unsigned __int128 left = (val >> half) & mask; - unsigned __int128 right = val & mask; + mpf_word left = word_and(word_shr(val, static_cast(half)), mask); + mpf_word right = word_and(val, mask); for (int round = 0; round < 4; ++round) { - alignas(16) std::uint64_t lanes[2] = { - static_cast(right), - static_cast(right >> 64)}; - auto msg = simde_mm_load_si128( - reinterpret_cast(lanes)); - msg = simde_mm_xor_si128(msg, seed); - msg = simde_mm_xor_si128(msg, - simde_mm_set_epi32(0, 0, 0, round + 1)); - const auto out = prg::aes128::eval(msg, - static_cast(round + 1)); - simde_mm_store_si128(reinterpret_cast(lanes), out); - wide f = lanes[0] | (wide{lanes[1]} << 64); - f &= mask; - left ^= f; - const wide tmp = left; + const mpf_word f = word_and(aes_prf(seed, right, round), mask); + left.lo = left.lo ^ f.lo; + left.hi = left.hi ^ f.hi; + const mpf_word tmp = left; left = right; right = tmp; } - val = (left << half) | right; + val = word_or(word_shl(left, static_cast(half)), right); if (val < domain) return val; } throw prp_walk_error{}; } -inline located locate(simde__m128i sigma, wide x, int hash, - wide n, wide bucket_domain) +inline located locate(simde__m128i sigma, mpf_word x, int hash, + mpf_word n, mpf_word bucket_domain) { constexpr int kappa = 3; - const wide y = permute(sigma, - x + n * static_cast(hash), n * kappa); + const mpf_word y = permute(sigma, + word_add(x, word_mul_small(n, static_cast(hash))), + word_mul_small(n, kappa)); + const auto [quot, rem] = word_divmod(y, bucket_domain); + if (quot.hi != uint256_t{0}) + throw std::runtime_error("multipoint bucket index does not fit"); located out; - out.bucket = static_cast(y / bucket_domain); - out.index = static_cast(y % bucket_domain); + out.bucket = static_cast(quot.lo); + out.index = rem; return out; } -inline std::uint32_t bucket_count_for(std::uint32_t t, std::uint32_t lambda) +inline std::uint64_t bucket_count_for(std::uint64_t t, std::uint32_t lambda) { const double log2t = (t <= 1) ? 0.0 : std::log2(static_cast(t)); const double e = (static_cast(lambda) + 130.0 + log2t) / 123.5; - auto m = static_cast(std::ceil(e * static_cast(t))); + auto m = static_cast(std::ceil(e * static_cast(t))); if (m < t + 1) m = t + 1; // Remark 1's simplification wants t ≥ 30. Below that, keep a 2t table. if (t < 30 && m < t * 2) m = t * 2; + // At least κ buckets so each within-bucket index fits in the input type. + if (m < 3) + m = 3; return m; } @@ -199,28 +436,28 @@ inline std::uint32_t rng_seed(simde__m128i sigma) struct slot { - int item = -1; + std::int64_t item = -1; int hash = -1; }; template bool insert_cuckoo(simde__m128i sigma, const std::vector & alphas, - std::uint32_t m, wide n, wide bucket_domain, + std::uint64_t m, mpf_word n, mpf_word bucket_domain, std::uint32_t max_evictions, std::vector & table) { table.assign(m, slot{}); std::mt19937 rng(rng_seed(sigma)); std::uniform_int_distribution pick(0, 2); - const int t = static_cast(alphas.size()); - for (int omega = 0; omega < t; ++omega) + const auto t = static_cast(alphas.size()); + for (std::int64_t omega = 0; omega < t; ++omega) { - int cur = omega; + std::int64_t cur = omega; int hash = pick(rng); std::uint32_t evictions = 0; for (;;) { const auto loc = locate(sigma, - static_cast(alphas[static_cast(cur)]), + to_word(alphas[static_cast(cur)]), hash, n, bucket_domain); if (loc.bucket >= m) return false; @@ -229,7 +466,7 @@ bool insert_cuckoo(simde__m128i sigma, const std::vector & alphas, table[loc.bucket] = slot{cur, hash}; break; } - const int evicted = table[loc.bucket].item; + const std::int64_t evicted = table[loc.bucket].item; table[loc.bucket] = slot{cur, hash}; cur = evicted; hash = pick(rng); @@ -270,31 +507,26 @@ struct bucket_bare template auto make_impl(std::vector alphas, std::vector betas, multipoint_params params) { using bare = typename bucket_bare::type; + InputT, OutputT>::type; using key0 = multipoint_key<0, InputT, OutputT, bare>; using key1 = multipoint_key<1, InputT, OutputT, bare>; - static_assert(std::is_unsigned_v && !std::is_same_v, + static_assert(!std::is_same_v + && (std::is_unsigned_v || std::is_same_v), "make_multipoint: input domain must be an unsigned integer"); - static_assert(utils::bitlength_of_v <= 32, - "make_multipoint: input domain wider than 32 bits is not supported"); - static_assert(std::is_unsigned_v - && !std::is_same_v, - "make_multipoint: BucketInput must be an unsigned integer"); + static_assert(utils::bitlength_of_v <= 256, + "make_multipoint: input type is wider than a point key in this library"); if (alphas.size() != betas.size()) throw std::invalid_argument("make_multipoint: point and payload counts differ"); if (alphas.empty()) throw std::invalid_argument("make_multipoint: no points"); - if (alphas.size() > static_cast(std::numeric_limits::max())) - throw std::invalid_argument("make_multipoint: too many points"); { auto sorted = alphas; @@ -303,19 +535,16 @@ auto make_impl(std::vector alphas, std::vector betas, throw std::invalid_argument("make_multipoint: duplicate points"); } - const auto t = static_cast(alphas.size()); + const auto t = static_cast(alphas.size()); const auto m = bucket_count_for(t, params.lambda); constexpr std::size_t input_bits = utils::bitlength_of_v; - const wide n = domain_size(input_bits); + const mpf_word n = domain_size(input_bits); constexpr int kappa = 3; - const wide b = (n * kappa + m - 1) / m; - constexpr std::size_t bucket_bits = utils::bitlength_of_v; - const wide bucket_cap = domain_size(bucket_bits); - if (b > bucket_cap) - { - throw std::invalid_argument( - "make_multipoint: bucket domain does not fit in BucketInput"); - } + const mpf_word span = word_mul_small(n, kappa); + const mpf_word den{uint256_t{m}, uint256_t{0}}; + const mpf_word numer = word_add(span, + word_sub(den, mpf_word{uint256_t{1}, uint256_t{0}})); + const mpf_word b = word_divmod(numer, den).first; const int attempts = params.retries < 1 ? 1 : params.retries; for (int attempt = 0; attempt < attempts; ++attempt) @@ -333,24 +562,26 @@ auto make_impl(std::vector alphas, std::vector betas, right.sigma = sigma; left.bucket_count = m; right.bucket_count = m; - left.bucket_domain = static_cast(b); - right.bucket_domain = static_cast(b); - left.buckets.reserve(m); - right.buckets.reserve(m); + left.bucket_domain = b; + right.bucket_domain = b; + left.buckets.reserve(static_cast(m)); + right.buckets.reserve(static_cast(m)); - for (std::uint32_t i = 0; i < m; ++i) + for (std::uint64_t i = 0; i < m; ++i) { - BucketInput gamma{}; + InputT gamma{}; OutputT beta{}; - if (table[i].item >= 0) + if (table[static_cast(i)].item >= 0) { - const auto & alpha = alphas[static_cast(table[i].item)]; - const auto loc = locate(sigma, - static_cast(alpha), table[i].hash, n, b); + const auto & alpha = alphas[static_cast( + table[static_cast(i)].item)]; + const auto loc = locate(sigma, to_word(alpha), + table[static_cast(i)].hash, n, b); if (loc.bucket != i) throw prp_walk_error{}; - gamma = static_cast(loc.index); - beta = betas[static_cast(table[i].item)]; + gamma = from_word(loc.index); + beta = betas[static_cast( + table[static_cast(i)].item)]; } auto made = make_bucket( gamma, beta); @@ -371,6 +602,7 @@ inline void absorb_proof(proof_token & acc, const proof_token & inner) { acc = detail::vdpf::xor_proof(acc, inner); acc[0] = detail::vdpf::mmo(acc[0], 1); + acc[1] = detail::vdpf::mmo(acc[1], 2); } template @@ -380,17 +612,17 @@ typename Key::share_type eval_at(const Key & key, typename Key::input_type x, using input_type = typename Key::input_type; using bucket_input = typename Key::bucket_input; constexpr std::size_t input_bits = utils::bitlength_of_v; - const wide n = domain_size(input_bits); - const wide b = key.bucket_domain; + const mpf_word n = domain_size(input_bits); + const mpf_word b = key.bucket_domain; typename Key::share_type sum = Key::share_type::from_raw(typename Key::output_type{}); for (int hash = 0; hash < static_cast(Key::kappa); ++hash) { - const auto loc = locate(key.sigma, static_cast(x), hash, n, b); + const auto loc = locate(key.sigma, to_word(x), hash, n, b); if (loc.bucket >= key.bucket_count) throw std::runtime_error("multipoint eval: bucket out of range"); - const auto gamma = static_cast(loc.index); + const auto gamma = from_word(loc.index); const auto & bucket = key.buckets[loc.bucket]; if constexpr (Key::is_verifiable) { @@ -413,7 +645,6 @@ typename Key::share_type eval_at(const Key & key, typename Key::input_type x, /// @brief Cuckoo-pack distinct points into ordinary point-key buckets. /// @tparam InteriorPRG PRG that expands interior nodes. Defaults to `dpf::prg::aes128` /// @tparam ExteriorPRG PRG that expands the root. Defaults to `InteriorPRG` -/// @tparam BucketInput unsigned type of a bucket index. Defaults to `uint32_t` /// @tparam AlphaRange range of distinct domain points /// @tparam BetaRange range of payloads, one per point /// @param alphas the secret points @@ -421,11 +652,12 @@ typename Key::share_type eval_at(const Key & key, typename Key::input_type x, /// @param params packing knobs. `lambda` is the Remark 1 failure target /// @return the two party keys /// @throws std::invalid_argument if the lists differ in length, are empty, -/// contain a duplicate, or a bucket index does not fit `BucketInput` +/// or contain a duplicate /// @throws std::runtime_error if cuckoo hashing does not succeed +/// @note Following de Castro and Polychroniadou, EUROCRYPT 2022, §4 (ePrint 2021/580): κ = 3 cuckoo buckets, one point key each. +/// \complexity For t points, `bucket_count_for` sets m = ceil((lambda + 130 + log2(t)) / 123.5 * t) (at least 2t when t < 30, and at least 3). Each attempt inserts t cuckoo items (up to `max_evictions` swaps each) and then one `make_dpf` per bucket. The within-bucket domain `b` is ceil(3 * 2^{input bits} / m). Counted `insert_cuckoo` and the bucket loop. Retries are `params.retries`. template HEDLEY_WARN_UNUSED_RESULT @@ -434,7 +666,7 @@ auto make_multipoint(const AlphaRange & alphas, const BetaRange & betas, { using input_type = std::decay_t; using output_type = std::decay_t; - return detail::mpf::make_impl( + return detail::mpf::make_impl( std::vector(std::begin(alphas), std::end(alphas)), std::vector(std::begin(betas), std::end(betas)), params); @@ -447,11 +679,12 @@ auto make_multipoint(const AlphaRange & alphas, const BetaRange & betas, /// @param params packing knobs /// @return the two verifiable party keys /// @throws std::invalid_argument if the lists differ in length, are empty, -/// contain a duplicate, or a bucket index does not fit `BucketInput` +/// or contain a duplicate /// @throws std::runtime_error if cuckoo hashing does not succeed +/// @note Following de Castro and Polychroniadou, EUROCRYPT 2022, §4 (ePrint 2021/580): κ = 3 cuckoo buckets, one point key each. +/// \complexity For t points, `bucket_count_for` sets m = ceil((lambda + 130 + log2(t)) / 123.5 * t) (at least 2t when t < 30, and at least 3). Each attempt inserts t cuckoo items (up to `max_evictions` swaps each) and then one `make_dpf` per bucket. The within-bucket domain `b` is ceil(3 * 2^{input bits} / m). Counted `insert_cuckoo` and the bucket loop. Retries are `params.retries`. template HEDLEY_WARN_UNUSED_RESULT @@ -460,7 +693,7 @@ auto make_multipoint(const AlphaRange & alphas, const BetaRange & betas, { using input_type = std::decay_t; using output_type = std::decay_t; - return detail::mpf::make_impl( + return detail::mpf::make_impl( std::vector(std::begin(alphas), std::end(alphas)), std::vector(std::begin(betas), std::end(betas)), params); @@ -472,6 +705,7 @@ auto make_multipoint(const AlphaRange & alphas, const BetaRange & betas, /// @param x the query point /// @return the party's share of the payload, or of zero off the packed points /// @throws std::runtime_error if a located bucket is outside the key +/// \complexity Three `eval_point` calls (`Key::kappa` is 3), each O(n_b) where n_b is the bucket key depth. template , int> = 0> auto eval_multipoint(const Key & key, typename Key::input_type x) @@ -486,6 +720,7 @@ auto eval_multipoint(const Key & key, typename Key::input_type x) /// @param pr proof token replaced with this query's folded proof /// @return the party's share of the payload /// @throws std::runtime_error if a located bucket is outside the key +/// \complexity Three `eval_point` calls (`Key::kappa` is 3), each O(n_b) where n_b is the bucket key depth. template , int> = 0> auto eval_multipoint(const Key & key, typename Key::input_type x, prove_ref pr) @@ -504,6 +739,7 @@ auto eval_multipoint(const Key & key, typename Key::input_type x, prove_ref pr) /// @param xs the query points /// @param out where each share is written /// @throws std::runtime_error if a located bucket is outside the key +/// \complexity Three `eval_point` calls (`Key::kappa` is 3), each O(n_b) where n_b is the bucket key depth. template , int> = 0> void eval_multipoint(const Key & key, const Range & xs, OutIt out) @@ -521,6 +757,7 @@ void eval_multipoint(const Key & key, const Range & xs, OutIt out) /// @param out where each share is written /// @param pr proof token replaced with the folded proof of `xs` /// @throws std::runtime_error if a located bucket is outside the key +/// \complexity Three `eval_point` calls (`Key::kappa` is 3), each O(n_b) where n_b is the bucket key depth. template , int> = 0> void eval_multipoint(const Key & key, const Range & xs, OutIt out, prove_ref pr) diff --git a/include/dpf/net/asio_ns.hpp b/include/dpf/net/asio_ns.hpp new file mode 100644 index 0000000..3eaee9e --- /dev/null +++ b/include/dpf/net/asio_ns.hpp @@ -0,0 +1,43 @@ +/// @file dpf/net/asio_ns.hpp +/// @brief Standalone asio as `asio::` inside the networking namespaces. +/// @details `dpf/asio.hpp` declares `dpf::asio` (DPF key shipping), which +/// would otherwise capture unqualified `asio::` lookups made inside +/// `namespace dpf` once both are included, in either order. +#ifndef LIBDPF_INCLUDE_DPF_NET_ASIO_NS_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_ASIO_NS_HPP__ + +#include + +namespace dpf +{ +namespace net +{ +namespace asio = ::asio; +} // namespace net +namespace protocol +{ +namespace asio = ::asio; +} // namespace protocol +namespace session +{ +namespace asio = ::asio; +} // namespace session +namespace run +{ +namespace asio = ::asio; +} // namespace run +namespace app +{ +namespace asio = ::asio; +} // namespace app +namespace async +{ +namespace asio = ::asio; +} // namespace async +namespace factory +{ +namespace asio = ::asio; +} // namespace factory +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_ASIO_NS_HPP__ diff --git a/include/dpf/net/async_round_sink.hpp b/include/dpf/net/async_round_sink.hpp new file mode 100644 index 0000000..5fdf905 --- /dev/null +++ b/include/dpf/net/async_round_sink.hpp @@ -0,0 +1,876 @@ +/// @file dpf/net/async_round_sink.hpp +/// @brief Event-driven `RoundSink` over an `async_stream_array`. +/// @details Both ends first exchange a hello on lane 0 carrying the plan shape +/// (rounds, slot widths, lanes, instances, framing) and an epoch. A +/// mismatch fails both ends with a message that names the field. +/// Unframed lanes carry one round each (round == lane). Framed lanes +/// carry `{round, nbytes}` headers; payloads are read straight into the +/// round's inbox, and a partial prefix of instances is ready as soon +/// as it lands. Every outbound round stays in memory, so after a +/// transport error the sink can take a replacement link from +/// `sink_options::reconnect`, exchange what each side received, and +/// resend only the missing bytes. The schedule above never rewinds. +#ifndef LIBDPF_INCLUDE_DPF_NET_ASYNC_ROUND_SINK_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_ASYNC_ROUND_SINK_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/net/async_stream_array.hpp" +#include "dpf/net/policy.hpp" +#include "dpf/net/round_lane.hpp" +#include "dpf/net/round_sink.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Construction options for `async_round_sink`. +struct sink_options +{ + framing_mode framing = framing_mode::automatic; + /// Exchange the plan-shape hello. Both ends must agree. + bool hello = true; + /// Bound on waiting for a full write window to drain. + std::chrono::milliseconds drain_timeout{30000}; + /// Bound on the hello exchange after a reconnect. + std::chrono::milliseconds handshake_timeout{30000}; + /// On a transport error, return a replacement link (the peer must replace + /// its end too) or nullptr to fail. Runs on the drive thread. + std::function reconnect; + unsigned max_reconnects = 3; +}; + +/// @brief Per-sink counters. +struct sink_stats +{ + std::uint64_t bytes_sent = 0; + std::uint64_t bytes_received = 0; + std::uint64_t flushes = 0; + std::uint64_t window_waits = 0; + std::uint64_t window_wait_ns = 0; + std::uint64_t resumes = 0; + std::uint64_t resent_bytes = 0; + bool framed = false; + std::size_t lanes = 0; +}; + +/// @brief `RoundSink` whose I/O completes through an `io_context`, never spins. +class async_round_sink : public RoundSink +{ +public: + async_round_sink(async_stream_array & streams, + std::vector slot_bytes_per_round, std::size_t count = 1, + sink_options opt = {}) + : core_(std::make_shared(streams, streams, + std::move(slot_bytes_per_round), count, std::move(opt))) + { + core_->start(); + } + + /// @brief Send on `out`, receive on `in` (a ring edge: to the previous + /// party, from the next). Both must run on the same `io_context`. + /// Reconnect resume needs a single link. + async_round_sink(async_stream_array & out, async_stream_array & in, + std::vector slot_bytes_per_round, std::size_t count = 1, + sink_options opt = {}) + : core_(std::make_shared(out, in, std::move(slot_bytes_per_round), + count, std::move(opt))) + { + core_->start(); + } + + async_round_sink(const async_round_sink &) = delete; + async_round_sink & operator=(const async_round_sink &) = delete; + + ~async_round_sink() override + { + std::lock_guard lock(core_->mu); + core_->dead = true; + } + + std::size_t count() const noexcept override { return core_->count; } + std::size_t rounds() const noexcept override { return core_->slots.size(); } + bool framed() const noexcept { return core_->map.framed; } + std::size_t lanes() const noexcept { return core_->map.n_lanes; } + + std::size_t slot_bytes(std::uint16_t round) const override + { + if (round >= core_->slots.size()) + throw std::out_of_range("async_round_sink round"); + return core_->slots[round]; + } + + asio::io_context & context() noexcept { return *core_->io; } + async_stream_array & link() noexcept { return *core_->streams; } + async_stream_array & in_link() noexcept { return *core_->in; } + + sink_stats stats() const + { + std::lock_guard lock(core_->mu); + sink_stats s = core_->st; + s.framed = core_->map.framed; + s.lanes = core_->map.n_lanes; + return s; + } + + void submit(std::uint16_t round, std::size_t index, + const std::uint8_t * bytes, std::size_t n) override + { + std::lock_guard lock(core_->mu); + core_->window(round).submit(index, bytes, n); + } + + bool peer_ready(std::uint16_t round, std::size_t index) const override + { + { + // Bytes that already arrived stay readable after a link error. + std::lock_guard lock(core_->mu); + if (core_->ready_locked(round, index)) + return true; + } + core_->raise_if_failed(); + std::lock_guard lock(core_->mu); + return core_->ready_locked(round, index); + } + + void read_peer(std::uint16_t round, std::size_t index, std::uint8_t * out, + std::size_t n) const override + { + { + std::lock_guard lock(core_->mu); + if (round < core_->slots.size() && core_->ready_locked(round, index)) + { + if (n != core_->slots[round]) + throw std::invalid_argument("async_round_sink read size"); + if (n != 0) + std::memcpy(out, core_->inbox[round].data() + index * n, n); + return; + } + } + core_->raise_if_failed(); + std::lock_guard lock(core_->mu); + if (round >= core_->slots.size()) + throw std::out_of_range("async_round_sink read_peer round"); + if (!core_->ready_locked(round, index)) + throw std::logic_error("async_round_sink: peer not ready"); + if (n != core_->slots[round]) + throw std::invalid_argument("async_round_sink read size"); + if (n != 0) + std::memcpy(out, core_->inbox[round].data() + index * n, n); + } + + void flush() override + { + for (std::uint16_t r = 0; r < core_->slots.size(); ++r) + { + bool due = false; + { + std::lock_guard lock(core_->mu); + const auto & w = core_->win[r]; + due = w.next_unwritten() > w.flushed() + || (core_->slots[r] == 0 && !core_->announced[r]); + } + if (due) + flush_round(r); + } + } + + void flush_round(std::uint16_t round) override + { + core_->raise_if_failed(); + const std::size_t lane = core_->flush_one(round); + core_->await_window(lane); + } + + void poll() override + { + core_->restart_if_stopped(); + core_->io->poll(); + } + + bool wait_io() override + { + core_->raise_if_failed(); + core_->restart_if_stopped(); + const bool ran = core_->io->run_one() > 0; + core_->raise_if_failed(); + return ran; + } + + bool wait_io_for(std::chrono::milliseconds budget) override + { + core_->raise_if_failed(); + core_->restart_if_stopped(); + const bool ran = budget.count() <= 0 ? core_->io->poll_one() > 0 + : core_->io->run_one_for(budget) > 0; + core_->raise_if_failed(); + return ran; + } + + bool can_block() const noexcept override { return true; } + + bool can_send_ahead() const noexcept override + { + for (std::size_t l = 0; l < core_->map.n_lanes; ++l) + { + const std::size_t w = core_->streams->lane_window_bytes(l); + if (w != 0 && core_->streams->lane_buffered_bytes(l) > w) + return false; + } + return true; + } + + std::uint64_t progress() const noexcept override + { + return core_->progress.load(std::memory_order_relaxed); + } + + const void * wait_domain() const noexcept override { return core_->io; } + +private: + static constexpr std::uint32_t k_magic = 0x48535044u; // 'DPSH' + static constexpr std::uint16_t k_version = 1; + static constexpr std::size_t k_hello_fixed = 36; + static constexpr std::uint32_t k_zero_seen = 1; + + struct core : std::enable_shared_from_this + { + core(async_stream_array & s, async_stream_array & rx, + std::vector slots_, std::size_t count_, sink_options opt_) + : streams(&s), + in(&rx), + io(&s.context()), + count(count_), + slots(std::move(slots_)), + map(std::min(s.size(), rx.size()), slots.size(), opt_.framing), + opt(std::move(opt_)) + { + if (count == 0) + throw std::invalid_argument("async_round_sink: count 0"); + if (s.size() == 0 || rx.size() == 0) + throw std::invalid_argument("async_round_sink: empty streams"); + if (&s.context() != &rx.context()) + throw std::invalid_argument( + "async_round_sink: out and in links need one io_context"); + if (&s != &rx && opt.reconnect) + throw std::invalid_argument( + "async_round_sink: reconnect needs a single link"); + const std::size_t nr = slots.size(); + win.reserve(nr); + inbox.resize(nr); + in_filled.assign(nr, 0); + zero_seen.assign(nr, false); + announced.assign(nr, false); + legacy_started.assign(nr, false); + legacy_wanted.assign(nr, false); + for (std::size_t k = 0; k < nr; ++k) + { + win.emplace_back(count, slots[k]); + inbox[k].assign(count * slots[k], 0); + } + fingerprint = slots_fingerprint(slots); + } + + // --- lifecycle ------------------------------------------------- + void start() + { + std::lock_guard lock(mu); + if (opt.hello) + begin_hello_locked(); + else + hello_done_locked(); + } + + void restart_if_stopped() + { + if (io->stopped()) + io->restart(); + } + + // --- hello ------------------------------------------------------ + std::shared_ptr> build_hello_locked() const + { + const std::size_t r = slots.size(); + auto buf = acquire_buffer(k_hello_fixed + 4 * r); + auto * p = buf->data(); + std::memset(p, 0, buf->size()); + detail::put_u32(p + 0, k_magic); + p[4] = static_cast(k_version & 0xffu); + p[5] = static_cast(k_version >> 8); + p[6] = map.framed ? 1 : 0; + detail::put_u32(p + 8, static_cast(r)); + detail::put_u32(p + 12, static_cast(map.n_lanes)); + detail::put_u32(p + 16, static_cast(count)); + detail::put_u32(p + 20, gen); + for (int i = 0; i < 8; ++i) + p[24 + i] = static_cast((fingerprint >> (8 * i)) & 0xffu); + for (std::size_t k = 0; k < r; ++k) + { + const std::uint32_t got = slots[k] == 0 + ? (zero_seen[k] ? k_zero_seen : 0) + : static_cast(in_filled[k]); + detail::put_u32(p + k_hello_fixed + 4 * k, got); + } + return buf; + } + + void begin_hello_locked() + { + hello_ok = false; + auto self = shared_from_this(); + const std::uint32_t g = gen; + streams->async_write_owned(0, build_hello_locked(), + [self, g](const std::error_code & ec) { self->on_write(g, ec); }); + hello_in = std::make_shared>( + k_hello_fixed + 4 * slots.size()); + auto buf = hello_in; + in->async_read(0, buf->data(), buf->size(), + [self, g, buf](const std::error_code & ec) { + self->on_hello(g, buf, ec); + }); + } + + void on_hello(std::uint32_t g, + const std::shared_ptr> & buf, + const std::error_code & ec) + { + std::lock_guard lock(mu); + if (dead || g != gen) + return; + if (ec) + { + fail_locked(ec, "hello read", false); + return; + } + const auto * p = buf->data(); + if (detail::get_u32(p) != k_magic) + { + fail_locked(std::make_error_code(std::errc::protocol_error), + "peer did not send a sink hello (is it an async_round_sink " + "or stream_array_sink with hello enabled?)", true); + return; + } + const std::uint16_t ver = static_cast(p[4] | (p[5] << 8)); + const bool peer_framed = (p[6] & 1) != 0; + const std::uint32_t pr = detail::get_u32(p + 8); + const std::uint32_t pl = detail::get_u32(p + 12); + const std::uint32_t pc = detail::get_u32(p + 16); + const std::uint32_t pg = detail::get_u32(p + 20); + std::uint64_t pf = 0; + for (int i = 0; i < 8; ++i) + pf |= static_cast(p[24 + i]) << (8 * i); + std::string why; + if (ver != k_version) + why += " version " + std::to_string(ver) + " vs " + + std::to_string(k_version) + ";"; + if (pr != slots.size()) + why += " rounds " + std::to_string(pr) + " vs " + + std::to_string(slots.size()) + ";"; + else if (pf != fingerprint) + why += " slot widths differ;"; + if (pl != map.n_lanes) + why += " lanes " + std::to_string(pl) + " vs " + + std::to_string(map.n_lanes) + ";"; + if (pc != count) + why += " instances " + std::to_string(pc) + " vs " + + std::to_string(count) + ";"; + if (peer_framed != map.framed) + why += std::string(" framing ") + (peer_framed ? "on" : "off") + + " vs " + (map.framed ? "on" : "off") + ";"; + if (pg != gen) + why += " epoch " + std::to_string(pg) + " vs " + + std::to_string(gen) + ";"; + if (!why.empty()) + { + fail_locked(std::make_error_code(std::errc::protocol_error), + "peer sink disagrees (peer vs this side):" + why, true); + return; + } + std::vector peer_got(slots.size()); + for (std::size_t k = 0; k < slots.size(); ++k) + peer_got[k] = detail::get_u32(p + k_hello_fixed + 4 * k); + if (gen != 0 && !resend_locked(peer_got)) + return; + hello_done_locked(); + } + + void hello_done_locked() + { + hello_ok = true; + if (map.framed) + { + hdr_bufs.clear(); + for (std::size_t lane = 0; lane < map.n_lanes; ++lane) + { + hdr_bufs.push_back( + std::make_shared>()); + read_lane_hdr_locked(lane); + } + } + else + { + for (std::size_t r = 0; r < slots.size(); ++r) + if (legacy_wanted[r]) + issue_legacy_locked(static_cast(r)); + } + } + + /// @brief After a reconnect: send what the peer reported missing. + bool resend_locked(const std::vector & peer_got) + { + auto self = shared_from_this(); + const std::uint32_t g = gen; + for (std::size_t k = 0; k < slots.size(); ++k) + { + const std::size_t sb = slots[k]; + const auto round = static_cast(k); + const std::size_t lane = map.lane(round); + if (sb == 0) + { + if (map.framed && announced[k] && peer_got[k] != k_zero_seen) + { + auto frame = acquire_buffer(round_lane_hdr::size); + round_lane_hdr{round, 0}.pack(frame->data()); + streams->async_write_owned(lane, std::move(frame), + [self, g](const std::error_code & ec) { + self->on_write(g, ec); + }); + } + continue; + } + const std::size_t sent = win[k].flushed() * sb; + const std::size_t got = peer_got[k]; + if (got > sent || got % sb != 0) + { + fail_locked(std::make_error_code(std::errc::protocol_error), + "resume: peer reports " + std::to_string(got) + + " bytes of round " + std::to_string(k) + + ", this side sent " + std::to_string(sent), + true); + return false; + } + if (got == sent) + continue; + const std::size_t nbytes = sent - got; + const std::uint8_t * src = win[k].out_at(got / sb); + st.resent_bytes += nbytes; + if (map.framed) + { + auto frame = acquire_buffer(round_lane_hdr::size + nbytes); + round_lane_hdr{round, static_cast(nbytes)}.pack( + frame->data()); + std::memcpy(frame->data() + round_lane_hdr::size, src, nbytes); + streams->async_write_owned(lane, std::move(frame), + [self, g](const std::error_code & ec) { + self->on_write(g, ec); + }); + } + else + { + streams->async_write(lane, src, nbytes, + [self, g](const std::error_code & ec) { + self->on_write(g, ec); + }); + } + } + return true; + } + + // --- errors and resume ------------------------------------------ + void fail_locked(const std::error_code & ec, const std::string & what, + bool is_fatal) + { + if (fail) + return; + fail = ec; + fail_what = "async_round_sink: " + what; + fatal = is_fatal; + } + + void on_write(std::uint32_t g, const std::error_code & ec) + { + if (!ec) + return; + std::lock_guard lock(mu); + if (dead || g != gen) + return; + fail_locked(ec, "write", false); + } + + void raise_if_failed() + { + std::error_code ec; + std::string what; + { + std::lock_guard lock(mu); + if (!fail) + return; + if (fatal || !opt.reconnect || reconnects >= opt.max_reconnects) + throw std::system_error(fail, fail_what); + ec = fail; + what = fail_what; + } + async_stream_array * next = nullptr; + try + { + next = opt.reconnect(ec); + } + catch (const std::exception & e) + { + throw std::system_error(ec, what + "; reconnect failed: " + e.what()); + } + if (next == nullptr) + throw std::system_error(ec, what + "; no replacement link"); + resume(*next); + } + + void resume(async_stream_array & next) + { + { + std::lock_guard lock(mu); + if (next.size() < map.n_lanes) + throw std::invalid_argument( + "async_round_sink resume: replacement link has fewer lanes"); + ++gen; + ++reconnects; + ++st.resumes; + fail.clear(); + fail_what.clear(); + fatal = false; + streams = &next; + in = &next; + io = &next.context(); + for (std::size_t r = 0; r < slots.size(); ++r) + { + if (legacy_started[r] && in_filled[r] < count * slots[r]) + { + legacy_started[r] = false; + legacy_wanted[r] = true; + } + } + begin_hello_locked(); + } + const auto deadline = std::chrono::steady_clock::now() + + opt.handshake_timeout; + for (;;) + { + { + std::lock_guard lock(mu); + if (hello_ok) + return; + if (fail) + throw std::system_error(fail, fail_what + " (during resume)"); + } + const auto now = std::chrono::steady_clock::now(); + if (now >= deadline) + throw std::system_error(std::make_error_code(std::errc::timed_out), + "async_round_sink: resume hello timed out"); + restart_if_stopped(); + io->run_one_for(std::min( + std::chrono::duration_cast( + deadline - now), + std::chrono::milliseconds(10))); + } + } + + // --- reads ------------------------------------------------------ + /// @brief Every round's peer bytes (and zero-width announcements) are in. + bool complete_locked() const + { + for (std::size_t r = 0; r < slots.size(); ++r) + { + const std::size_t sb = slots[r]; + if (sb == 0 ? (map.framed && !zero_seen[r]) + : in_filled[r] < count * sb) + return false; + } + return true; + } + + bool ready_locked(std::uint16_t round, std::size_t index) + { + if (round >= slots.size()) + return false; + const std::size_t sb = slots[round]; + if (map.framed) + { + if (sb == 0) + return zero_seen[round]; + return in_filled[round] >= (index + 1) * sb; + } + if (sb == 0) + return true; + if (!legacy_started[round]) + { + if (hello_ok) + issue_legacy_locked(round); + else + legacy_wanted[round] = true; + } + return in_filled[round] == count * sb; + } + + void issue_legacy_locked(std::uint16_t round) + { + if (legacy_started[round]) + return; + legacy_started[round] = true; + legacy_wanted[round] = false; + const std::size_t bytes = count * slots[round]; + if (bytes == 0) + { + in_filled[round] = 0; + return; + } + auto self = shared_from_this(); + const std::uint32_t g = gen; + this->in->async_read(round, inbox[round].data(), bytes, + [self, g, round, bytes](const std::error_code & ec) { + std::lock_guard lock(self->mu); + if (self->dead || g != self->gen) + return; + if (ec) + { + self->fail_locked(ec, "read round " + + std::to_string(round), false); + return; + } + self->in_filled[round] = bytes; + self->st.bytes_received += bytes; + self->progress.fetch_add(bytes, std::memory_order_relaxed); + }); + } + + void read_lane_hdr_locked(std::size_t lane) + { + auto self = shared_from_this(); + const std::uint32_t g = gen; + auto buf = hdr_bufs[lane]; + in->async_read(lane, buf->data(), buf->size(), + [self, g, lane, buf](const std::error_code & ec) { + self->on_lane_hdr(g, lane, buf, ec); + }); + } + + void on_lane_hdr(std::uint32_t g, std::size_t lane, + const std::shared_ptr> & buf, + const std::error_code & ec) + { + std::lock_guard lock(mu); + if (dead || g != gen) + return; + if (ec) + { + // A peer that closes after its last frame finished cleanly. + if (!complete_locked()) + fail_locked(ec, "read lane " + std::to_string(lane), false); + return; + } + const auto hdr = round_lane_hdr::unpack(buf->data()); + if (hdr.round >= slots.size() || map.lane(hdr.round) != lane) + { + fail_locked(std::make_error_code(std::errc::protocol_error), + "frame for round " + std::to_string(hdr.round) + " on lane " + + std::to_string(lane), + true); + return; + } + const std::size_t sb = slots[hdr.round]; + const std::size_t cap = count * sb; + if (hdr.nbytes == 0) + { + if (sb == 0 && !zero_seen[hdr.round]) + { + zero_seen[hdr.round] = true; + progress.fetch_add(1, std::memory_order_relaxed); + } + read_lane_hdr_locked(lane); + return; + } + if (sb == 0 || hdr.nbytes % sb != 0 + || in_filled[hdr.round] + hdr.nbytes > cap) + { + fail_locked(std::make_error_code(std::errc::message_size), + "round " + std::to_string(hdr.round) + " frame of " + + std::to_string(hdr.nbytes) + " bytes does not fit", + true); + return; + } + const std::uint16_t round = hdr.round; + const std::size_t nbytes = hdr.nbytes; + auto self = shared_from_this(); + in->async_read(lane, inbox[round].data() + in_filled[round], nbytes, + [self, g, lane, round, nbytes](const std::error_code & xec) { + std::lock_guard lk(self->mu); + if (self->dead || g != self->gen) + return; + if (xec) + { + self->fail_locked(xec, "read round " + + std::to_string(round), false); + return; + } + self->in_filled[round] += nbytes; + self->st.bytes_received += nbytes; + self->progress.fetch_add(nbytes, std::memory_order_relaxed); + self->read_lane_hdr_locked(lane); + }); + } + + // --- writes ----------------------------------------------------- + round_window & window(std::uint16_t round) + { + if (round >= win.size()) + throw std::out_of_range("async_round_sink round"); + return win[round]; + } + + std::size_t flush_one(std::uint16_t round) + { + std::lock_guard lock(mu); + auto & w = window(round); + std::size_t begin = 0; + std::size_t nslots = 0; + const std::uint8_t * pend = w.pending_out(begin, nslots); + const std::size_t sb = slots[round]; + const std::size_t nbytes = nslots * sb; + const std::size_t lane = map.lane(round); + auto self = shared_from_this(); + const std::uint32_t g = gen; + auto done = [self, g](const std::error_code & ec) { + self->on_write(g, ec); + }; + if (map.framed) + { + if (nslots != 0 || (sb == 0 && !announced[round])) + { + auto frame = acquire_buffer(round_lane_hdr::size + nbytes); + round_lane_hdr{round, static_cast(nbytes)}.pack( + frame->data()); + if (nbytes != 0) + std::memcpy(frame->data() + round_lane_hdr::size, pend, + nbytes); + streams->async_write_owned(lane, std::move(frame), done); + if (sb == 0) + announced[round] = true; + ++st.flushes; + st.bytes_sent += nbytes; + } + if (nslots != 0) + w.mark_flushed(nslots); + } + else + { + if (nslots != 0 && sb != 0) + { + streams->async_write(lane, pend, nbytes, done); + ++st.flushes; + st.bytes_sent += nbytes; + } + if (nslots != 0) + w.mark_flushed(nslots); + if (!legacy_started[round]) + { + if (hello_ok) + issue_legacy_locked(round); + else + legacy_wanted[round] = true; + } + } + return lane; + } + + /// @brief Stall the producer while lane `lane`'s window is full. + void await_window(std::size_t lane) + { + const std::size_t w = streams->lane_window_bytes(lane); + if (w == 0 || streams->lane_buffered_bytes(lane) <= w) + return; + const auto t0 = std::chrono::steady_clock::now(); + auto since = t0; + std::size_t last = streams->lane_buffered_bytes(lane); + for (;;) + { + raise_if_failed(); + const std::size_t now_buf = streams->lane_buffered_bytes(lane); + if (now_buf <= streams->lane_window_bytes(lane)) + break; + const auto now = std::chrono::steady_clock::now(); + if (now_buf < last) + { + last = now_buf; + since = now; + } + else if (now - since > opt.drain_timeout) + { + throw std::runtime_error("async_round_sink: lane " + + std::to_string(lane) + " did not drain for " + + std::to_string(opt.drain_timeout.count()) + " ms (" + + std::to_string(now_buf) + " bytes buffered, window " + + std::to_string(w) + ")"); + } + restart_if_stopped(); + io->run_one_for(std::chrono::milliseconds(10)); + } + const auto dt = std::chrono::steady_clock::now() - t0; + std::lock_guard lock(mu); + ++st.window_waits; + st.window_wait_ns += static_cast( + std::chrono::duration_cast(dt).count()); + } + + async_stream_array * streams = nullptr; + async_stream_array * in = nullptr; + asio::io_context * io = nullptr; + std::size_t count = 1; + std::vector slots; + round_lane_map map; + sink_options opt; + std::uint64_t fingerprint = 0; + + std::mutex mu; + std::vector win; + std::vector> inbox; + std::vector in_filled; + std::vector zero_seen; + std::vector announced; + std::vector legacy_started; + std::vector legacy_wanted; + std::vector>> + hdr_bufs; + std::shared_ptr> hello_in; + std::uint32_t gen = 0; + bool hello_ok = false; + std::error_code fail; + std::string fail_what; + bool fatal = false; + unsigned reconnects = 0; + bool dead = false; + std::atomic progress{0}; + sink_stats st; + }; + + std::shared_ptr core_; +}; + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_ASYNC_ROUND_SINK_HPP__ diff --git a/include/dpf/net/async_sctp_stream_array.hpp b/include/dpf/net/async_sctp_stream_array.hpp new file mode 100644 index 0000000..dcb3080 --- /dev/null +++ b/include/dpf/net/async_sctp_stream_array.hpp @@ -0,0 +1,773 @@ +/// @file dpf/net/async_sctp_stream_array.hpp +/// @brief Truly asynchronous SCTP-backed indexed byte streams (Linux/libsctp). +/// @details One SCTP association carries every lane: index `i` maps to SCTP +/// stream `i`. Receive is head-of-line free across streams. Writes are +/// split into `wire_policy::chunk_bytes` messages and sent round-robin +/// across streams, so a large write on one stream does not hold small +/// writes on another behind it. The window covers the association. +/// +/// Platform contract: +/// * Linux with `` (libsctp) → real backend, needs `-lsctp`. +/// * Everything else → the class exists, every constructor throws. +#ifndef LIBDPF_INCLUDE_DPF_NET_ASYNC_SCTP_STREAM_ARRAY_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_ASYNC_SCTP_STREAM_ARRAY_HPP__ + +#if !defined(DPF_HAS_LIBSCTP) +# if defined(__linux__) && defined(__has_include) +# if __has_include() +# define DPF_HAS_LIBSCTP 1 +# else +# define DPF_HAS_LIBSCTP 0 +# endif +# else +# define DPF_HAS_LIBSCTP 0 +# endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" + +#include "hedley/hedley.h" + +#include "dpf/net/async_stream_array.hpp" +#include "dpf/net/connect.hpp" +#include "dpf/net/policy.hpp" + +#if DPF_HAS_LIBSCTP +# include +# include +# include +# include +# include +# include +# include +#endif + +namespace dpf +{ +namespace net +{ + +/// @brief True when this build has a real SCTP backend. +inline constexpr bool sctp_available() noexcept +{ + return DPF_HAS_LIBSCTP != 0; +} + +#if DPF_HAS_LIBSCTP + +namespace detail +{ + +/// @brief Stream counts, per-message `sinfo`, and socket options. +inline void sctp_configure(int fd, std::size_t nstreams, + const socket_options & o = {}) +{ + struct sctp_initmsg im; + std::memset(&im, 0, sizeof(im)); + im.sinit_num_ostreams = static_cast(nstreams); + im.sinit_max_instreams = static_cast(nstreams); + (void)::setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &im, sizeof(im)); + + struct sctp_event_subscribe ev; + std::memset(&ev, 0, sizeof(ev)); + ev.sctp_data_io_event = 1; + (void)::setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &ev, sizeof(ev)); + + const int nodelay = o.no_delay ? 1 : 0; + (void)::setsockopt(fd, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, sizeof(nodelay)); + if (o.send_buffer > 0) + (void)::setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &o.send_buffer, + sizeof(o.send_buffer)); + if (o.recv_buffer > 0) + (void)::setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &o.recv_buffer, + sizeof(o.recv_buffer)); +} + +} // namespace detail + +/// @brief N lanes over one SCTP association, fully overlapped. +class async_sctp_stream_array final : public async_stream_array +{ +public: + /// @brief Adopt a connected one-to-one SCTP fd. + async_sctp_stream_array(asio::io_context & io, int fd, std::size_t nstreams, + const wire_policy & pol = {}) + { + if (nstreams == 0) + throw std::invalid_argument("async_sctp_stream_array empty"); + if (nstreams > 0xffffu) + throw std::invalid_argument("async_sctp_stream_array: stream ids are u16"); + pol.validate(); + detail::sctp_configure(fd, nstreams, pol.socket); + impl_ = std::make_shared(io, fd, nstreams, pol); + impl_->start(); + } + + async_sctp_stream_array(const async_sctp_stream_array &) = delete; + async_sctp_stream_array & operator=(const async_sctp_stream_array &) = delete; + + ~async_sctp_stream_array() override + { + if (impl_) + impl_->close_graceful(); + } + + std::size_t size() const noexcept override { return impl_->n; } + asio::io_context & context() noexcept override { return impl_->io; } + + void async_write(std::size_t i, const void * src, std::size_t n, + async_handler h) override + { + impl_->write(i, n == 0 ? nullptr : copy_buffer(src, n), std::move(h)); + } + + void async_write_owned(std::size_t i, + std::shared_ptr> buf, async_handler h) override + { + impl_->write(i, std::move(buf), std::move(h)); + } + + void async_read(std::size_t i, void * dst, std::size_t n, + async_handler h) override + { + impl_->read(i, dst, n, std::move(h)); + } + + std::size_t buffered_bytes() const noexcept override + { + return impl_->buffered.load(std::memory_order_relaxed); + } + + std::size_t window_bytes() const noexcept override + { + return impl_->window.load(std::memory_order_relaxed); + } + + void set_window_bytes(std::size_t bytes) override + { + impl_->window.store(bytes, std::memory_order_relaxed); + } + + stream_stats stats() const override { return impl_->stats(); } + + void close() noexcept override + { + impl_->close(asio::error::operation_aborted); + } + +private: + struct chunk + { + std::shared_ptr> payload; + std::size_t off = 0; + std::size_t len = 0; + std::shared_ptr op; + }; + + struct impl : std::enable_shared_from_this + { + impl(asio::io_context & io_, int fd, std::size_t nstreams, + const wire_policy & pol_) + : io(io_), + sd(io_), + strand(asio::make_strand(io_)), + n(nstreams), + pol(pol_), + inbox(nstreams), + partial(nstreams), + wait(nstreams), + outq(nstreams), + rbuf(std::max(pol_.chunk_bytes, std::size_t{1} << 16)), + window(pol_.window_bytes) + { + const int fl = ::fcntl(fd, F_GETFL, 0); + if (fl >= 0) + (void)::fcntl(fd, F_SETFL, fl | O_NONBLOCK); + sd.assign(fd); + } + + void check(std::size_t i) const + { + if (i >= n) + throw std::out_of_range("async_sctp_stream_array index " + + std::to_string(i)); + } + + void start() + { + auto self = shared_from_this(); + asio::post(strand, [self] { self->arm_read(); }); + } + + // --- reads --------------------------------------------------------- + void read(std::size_t i, void * dst, std::size_t nbytes, async_handler h) + { + check(i); + std::lock_guard lock(mu); + if (fail) + { + detail::post_handler(io, std::move(h), fail); + return; + } + auto & w = wait[i]; + if (w.active) + throw std::logic_error( + "async_sctp_stream_array: overlapping read on stream " + + std::to_string(i)); + const std::size_t k = inbox[i].take(dst, nbytes, pol.compact_bytes); + if (k == nbytes) + { + detail::post_handler(io, std::move(h), {}); + return; + } + w.active = true; + w.dst = dst; + w.n = nbytes; + w.filled = k; + w.h = std::move(h); + } + + void satisfy_locked(std::size_t i) + { + auto & w = wait[i]; + if (!w.active) + return; + w.filled += inbox[i].take(static_cast(w.dst) + w.filled, + w.n - w.filled, pol.compact_bytes); + if (w.filled == w.n) + { + w.active = false; + detail::post_handler(io, std::move(w.h), {}); + } + } + + void arm_read() + { + auto self = shared_from_this(); + sd.async_wait(asio::posix::stream_descriptor::wait_read, + asio::bind_executor(strand, [self](const std::error_code & ec) { + self->on_readable(ec); + })); + } + + void on_readable(const std::error_code & ec) + { + if (ec) + { + deliver_error(ec); + return; + } + for (;;) + { + struct sctp_sndrcvinfo sinfo; + std::memset(&sinfo, 0, sizeof(sinfo)); + int flags = 0; + const ssize_t r = ::sctp_recvmsg(sd.native_handle(), rbuf.data(), + rbuf.size(), nullptr, nullptr, &sinfo, &flags); + if (r < 0) + { + if (errno == EAGAIN || errno == EWOULDBLOCK) + break; + deliver_error(std::error_code(errno, std::generic_category())); + return; + } + if (r == 0) + { + deliver_error(asio::error::eof); + return; + } + if (flags & MSG_NOTIFICATION) + continue; + const std::size_t stream = sinfo.sinfo_stream; + if (stream >= n) + { + deliver_error(std::make_error_code(std::errc::protocol_error)); + return; + } + bool too_big = false; + { + std::lock_guard lock(mu); + if (closed) + return; + auto & part = partial[stream]; + part.insert(part.end(), rbuf.begin(), rbuf.begin() + r); + if (part.size() > pol.max_frame) + too_big = true; + else if ((flags & MSG_EOR) != 0) + { + counters.read(part.size(), part.size(), 1); + auto & box = inbox[stream].bytes; + box.insert(box.end(), part.begin(), part.end()); + part.clear(); + satisfy_locked(stream); + } + } + if (too_big) + { + deliver_error(std::make_error_code(std::errc::message_size)); + return; + } + } + arm_read(); + } + + void fail_waiters_locked(const std::error_code & ec) + { + for (auto & w : wait) + { + if (!w.active) + continue; + w.active = false; + detail::post_handler(io, std::move(w.h), ec); + } + } + + void deliver_error(const std::error_code & ec) + { + { + std::lock_guard lock(mu); + if (!fail) + fail = ec; + fail_waiters_locked(fail); + } + auto self = shared_from_this(); + asio::post(strand, [self, ec] { self->fail_queued(ec); }); + } + + void close(const std::error_code & ec) + { + { + std::lock_guard lock(mu); + if (!fail) + fail = ec; + if (closed && aborted) + return; + closed = true; + aborted = true; + fail_waiters_locked(ec); + } + auto self = shared_from_this(); + asio::post(strand, [self, ec] { + std::error_code e; + self->sd.close(e); + self->fail_queued(ec); + }); + } + + void close_graceful() + { + { + std::lock_guard lock(mu); + if (closed) + return; + closed = true; + fail_waiters_locked(asio::error::operation_aborted); + } + auto self = shared_from_this(); + asio::post(strand, [self] { + self->draining = true; + if (!self->writing) + { + std::error_code e; + self->sd.close(e); + } + }); + } + + stream_stats stats() const + { + stream_stats s; + counters.fill(s); + s.buffered = buffered.load(std::memory_order_relaxed); + std::lock_guard lock(mu); + for (const auto & b : inbox) + s.unread += b.avail(); + s.error = fail; + s.closed = closed; + return s; + } + + // --- writes (strand) ---------------------------------------------- + void write(std::size_t i, std::shared_ptr> payload, + async_handler h) + { + check(i); + const std::size_t len = payload ? payload->size() : 0; + { + std::lock_guard lock(mu); + if (fail || closed) + { + detail::post_handler(io, std::move(h), + fail ? fail : asio::error::operation_aborted); + return; + } + } + if (len == 0) + { + detail::post_handler(io, std::move(h), {}); + return; + } + const auto pieces = detail::split_chunks(len, pol.chunk_bytes); + auto op = std::make_shared(); + op->h = std::move(h); + op->left = pieces.size(); + std::vector cs; + cs.reserve(pieces.size()); + for (const auto & pc : pieces) + cs.push_back(chunk{payload, pc.first, pc.second, op}); + buffered.fetch_add(len, std::memory_order_relaxed); + auto self = shared_from_this(); + asio::post(strand, [self, i, cs = std::move(cs)]() mutable { + std::error_code ec; + { + std::lock_guard lock(self->mu); + ec = self->fail; + } + if (ec) + { + for (auto & c : cs) + self->finish_chunk(c, ec); + return; + } + for (auto & c : cs) + self->outq[i].push_back(std::move(c)); + if (!self->writing) + self->write_next(); + }); + } + + void finish_chunk(chunk & c, const std::error_code & ec) + { + buffered.fetch_sub(std::min(buffered.load(std::memory_order_relaxed), + c.len), + std::memory_order_relaxed); + auto & op = *c.op; + if (ec && !op.ec) + op.ec = ec; + if (--op.left == 0) + detail::post_handler(io, std::move(op.h), op.ec); + } + + bool pick(std::size_t & lane) + { + for (std::size_t k = 0; k < n; ++k) + { + const std::size_t l = (rr + k) % n; + if (!outq[l].empty()) + { + lane = l; + return true; + } + } + return false; + } + + void write_next() + { + std::size_t lane = 0; + if (!pick(lane)) + { + writing = false; + if (draining) + { + std::error_code e; + sd.close(e); + } + return; + } + writing = true; + auto & front = outq[lane].front(); + const ssize_t r = ::sctp_sendmsg(sd.native_handle(), + front.payload->data() + front.off, front.len, nullptr, 0, 0, 0, + static_cast(lane), 0, 0); + if (r < 0) + { + if (errno == EAGAIN || errno == EWOULDBLOCK) + { + auto self = shared_from_this(); + sd.async_wait(asio::posix::stream_descriptor::wait_write, + asio::bind_executor(strand, + [self](const std::error_code & ec) { + if (ec) + { + self->writing = false; + self->deliver_error(ec); + return; + } + self->write_next(); + })); + return; + } + writing = false; + deliver_error(std::error_code(errno, std::generic_category())); + return; + } + const std::size_t sent = static_cast(r); + counters.wrote(sent, sent, 1); + if (sent < front.len) + { + buffered.fetch_sub(std::min(buffered.load(), sent), + std::memory_order_relaxed); + front.off += sent; + front.len -= sent; + write_next(); + return; + } + chunk done = std::move(front); + outq[lane].pop_front(); + rr = (lane + 1) % n; + finish_chunk(done, {}); + auto self = shared_from_this(); + asio::post(strand, [self] { self->write_next(); }); + } + + void fail_queued(const std::error_code & ec) + { + writing = false; + for (auto & q : outq) + { + for (auto & c : q) + finish_chunk(c, ec); + q.clear(); + } + } + + asio::io_context & io; + asio::posix::stream_descriptor sd; + asio::strand strand; + std::size_t n = 0; + wire_policy pol; + mutable std::mutex mu; + std::vector inbox; + std::vector> partial; + std::vector wait; + std::error_code fail; + bool closed = false; + bool aborted = false; + std::vector> outq; + std::size_t rr = 0; + bool writing = false; + bool draining = false; + std::vector rbuf; + std::atomic buffered{0}; + std::atomic window; + detail::io_counters counters; + }; + + std::shared_ptr impl_; +}; + +// --------------------------------------------------------------------------- +// Association setup (deadline-bounded) +// --------------------------------------------------------------------------- + +/// @brief Listening one-to-one SCTP socket. +class sctp_listener +{ +public: + sctp_listener(unsigned short port, std::size_t nstreams, + const socket_options & o = {}) + : nstreams_(nstreams), opts_(o) + { + if (nstreams == 0) + throw std::invalid_argument("sctp_listener: no streams"); + fd_ = ::socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + if (fd_ < 0) + throw std::system_error(errno, std::generic_category(), + "sctp_listener: socket"); + int one = 1; + (void)::setsockopt(fd_, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + detail::sctp_configure(fd_, nstreams, o); + struct sockaddr_in addr; + std::memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(port); + if (::bind(fd_, reinterpret_cast(&addr), sizeof(addr)) < 0 + || ::listen(fd_, 16) < 0) + { + const int e = errno; + ::close(fd_); + fd_ = -1; + throw std::system_error(e, std::generic_category(), + "sctp_listener: bind/listen on port " + std::to_string(port)); + } + socklen_t alen = sizeof(addr); + if (::getsockname(fd_, reinterpret_cast(&addr), &alen) == 0) + port_ = ntohs(addr.sin_port); + } + + sctp_listener(const sctp_listener &) = delete; + sctp_listener & operator=(const sctp_listener &) = delete; + + ~sctp_listener() + { + if (fd_ >= 0) + ::close(fd_); + } + + unsigned short port() const noexcept { return port_; } + int native_handle() const noexcept { return fd_; } + + /// @brief Accept one association within `budget`; returns the fd. + int accept(std::chrono::milliseconds budget) + { + const auto deadline = setup_clock::now() + budget; + detail::wait_fd(fd_, POLLIN, deadline, + "sctp accept on port " + std::to_string(port_)); + const int cfd = ::accept(fd_, nullptr, nullptr); + if (cfd < 0) + throw std::system_error(errno, std::generic_category(), "sctp accept"); + detail::sctp_configure(cfd, nstreams_, opts_); + return cfd; + } + +private: + int fd_ = -1; + unsigned short port_ = 0; + std::size_t nstreams_ = 0; + socket_options opts_{}; +}; + +/// @brief Connect one SCTP association, retrying refusals until `budget`. +HEDLEY_WARN_UNUSED_RESULT +inline int connect_sctp(const std::string & host, unsigned short port, + std::size_t nstreams, std::chrono::milliseconds budget, + const socket_options & o = {}) +{ + const auto deadline = setup_clock::now() + budget; + struct sockaddr_in addr; + std::memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + const std::string h = host == "localhost" ? "127.0.0.1" : host; + if (::inet_pton(AF_INET, h.c_str(), &addr.sin_addr) != 1) + throw std::invalid_argument("connect_sctp: bad host " + host); + int last = ETIMEDOUT; + for (;;) + { + const int fd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + if (fd < 0) + throw std::system_error(errno, std::generic_category(), + "connect_sctp: socket"); + detail::sctp_configure(fd, nstreams, o); + if (::connect(fd, reinterpret_cast(&addr), + sizeof(addr)) == 0) + return fd; + last = errno; + ::close(fd); + if (setup_clock::now() >= deadline) + throw std::system_error(last, std::generic_category(), + "connect_sctp " + host + ":" + std::to_string(port)); + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + } +} + +/// @brief Accept one association on an ephemeral (or given) port. +HEDLEY_WARN_UNUSED_RESULT +inline int accept_sctp_association(asio::io_context &, + std::atomic & port, std::size_t nstreams, + std::chrono::milliseconds budget = deadlines{}.accept) +{ + sctp_listener lst(port.load(), nstreams); + port.store(lst.port()); + return lst.accept(budget); +} + +/// @brief Connect one association to `host:port`. +HEDLEY_WARN_UNUSED_RESULT +inline int connect_sctp_association(asio::io_context &, const std::string & host, + std::atomic & port, std::size_t nstreams, + std::chrono::milliseconds budget = deadlines{}.connect) +{ + return connect_sctp(host, port.load(), nstreams, budget); +} + +#else // !DPF_HAS_LIBSCTP + +class async_sctp_stream_array final : public async_stream_array +{ +public: + async_sctp_stream_array(asio::io_context &, int, std::size_t, + const wire_policy & = {}) + { + throw std::logic_error( + "async_sctp_stream_array: real SCTP requires Linux + libsctp " + "(, link -lsctp)"); + } + + std::size_t size() const noexcept override { return 0; } + asio::io_context & context() noexcept override + { + std::terminate(); + } + void async_write(std::size_t, const void *, std::size_t, + async_handler) override + { + throw std::logic_error("async_sctp_stream_array: not available"); + } + void async_read(std::size_t, void *, std::size_t, async_handler) override + { + throw std::logic_error("async_sctp_stream_array: not available"); + } +}; + +class sctp_listener +{ +public: + sctp_listener(unsigned short, std::size_t, const socket_options & = {}) + { + throw std::logic_error("sctp_listener: SCTP requires Linux + libsctp"); + } + unsigned short port() const noexcept { return 0; } + int native_handle() const noexcept { return -1; } + int accept(std::chrono::milliseconds) { return -1; } +}; + +HEDLEY_WARN_UNUSED_RESULT +inline int connect_sctp(const std::string &, unsigned short, std::size_t, + std::chrono::milliseconds, const socket_options & = {}) +{ + throw std::logic_error("connect_sctp: SCTP requires Linux + libsctp"); +} + +HEDLEY_WARN_UNUSED_RESULT +inline int accept_sctp_association(asio::io_context &, + std::atomic &, std::size_t, + std::chrono::milliseconds = deadlines{}.accept) +{ + throw std::logic_error( + "accept_sctp_association: SCTP requires Linux + libsctp"); +} + +HEDLEY_WARN_UNUSED_RESULT +inline int connect_sctp_association(asio::io_context &, const std::string &, + std::atomic &, std::size_t, + std::chrono::milliseconds = deadlines{}.connect) +{ + throw std::logic_error( + "connect_sctp_association: SCTP requires Linux + libsctp"); +} + +#endif // DPF_HAS_LIBSCTP + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_ASYNC_SCTP_STREAM_ARRAY_HPP__ diff --git a/include/dpf/net/async_stream_array.hpp b/include/dpf/net/async_stream_array.hpp new file mode 100644 index 0000000..6b9d956 --- /dev/null +++ b/include/dpf/net/async_stream_array.hpp @@ -0,0 +1,2069 @@ +/// @file dpf/net/async_stream_array.hpp +/// @brief Truly asynchronous, overlapped indexed byte streams. +/// @details Every backend completes through an `asio::io_context` and never +/// spins on a `peer_ready` flag or blocks the calling thread. The +/// calling thread of `async_read` only registers a waiter and returns; +/// the completion handler fires later on an `io_context` thread. +/// * `async_dual_memory_stream_array` — paired in-process ends. +/// * `async_mux_stream_array` — N lanes on ONE TCP socket. +/// * `async_parallel_stream_array` — one socket PER lane. +/// Writes are split into `wire_policy::chunk_bytes` frames. The mux +/// sends chunks round-robin across lanes, so a large write on one lane +/// does not queue small writes on another lane behind it. When a reader +/// is already waiting, socket payloads land directly in its buffer. +#ifndef LIBDPF_INCLUDE_DPF_NET_ASYNC_STREAM_ARRAY_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_ASYNC_STREAM_ARRAY_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" + +#include "hedley/hedley.h" + +#include "dpf/net/buffer_pool.hpp" +#include "dpf/net/connect.hpp" +#include "dpf/net/policy.hpp" +#include "dpf/net/socket_tune.hpp" +#include "dpf/net/stream_array.hpp" // stream_frame_hdr + +namespace dpf +{ +namespace net +{ + +/// @brief Completion handler for a single async I/O operation. +using async_handler = std::function; + +/// @brief Counters for one stream array end. +/// @details `bytes_*` include framing; `payload_*` are caller bytes. Times are +/// `steady_clock` nanoseconds since epoch (0 = never). +struct stream_stats +{ + std::uint64_t bytes_out = 0; + std::uint64_t bytes_in = 0; + std::uint64_t payload_out = 0; + std::uint64_t payload_in = 0; + std::uint64_t frames_out = 0; + std::uint64_t frames_in = 0; + std::uint64_t write_calls = 0; + std::size_t buffered = 0; + std::size_t unread = 0; + std::int64_t last_write_ns = 0; + std::int64_t last_read_ns = 0; + /// TCP payload bytes the kernel reports sent (acknowledged) and received + /// on this link's sockets, so TLS records and handshakes included; 0 for + /// in-process, unix, and SCTP links, and once the link is closed. + std::uint64_t socket_bytes_out = 0; + std::uint64_t socket_bytes_in = 0; + std::error_code error; + bool closed = false; +}; + +namespace detail +{ + +inline std::int64_t steady_ns() noexcept +{ + return static_cast( + std::chrono::duration_cast( + std::chrono::steady_clock::now().time_since_epoch()) + .count()); +} + +/// @brief Completion shared by the chunks of one write. +struct write_op +{ + async_handler h; + std::size_t left = 0; + std::error_code ec; +}; + +struct io_counters +{ + std::atomic bytes_out{0}; + std::atomic bytes_in{0}; + std::atomic payload_out{0}; + std::atomic payload_in{0}; + std::atomic frames_out{0}; + std::atomic frames_in{0}; + std::atomic write_calls{0}; + std::atomic last_write_ns{0}; + std::atomic last_read_ns{0}; + + void wrote(std::uint64_t wire, std::uint64_t payload, std::uint64_t frames) + { + bytes_out.fetch_add(wire, std::memory_order_relaxed); + payload_out.fetch_add(payload, std::memory_order_relaxed); + frames_out.fetch_add(frames, std::memory_order_relaxed); + write_calls.fetch_add(1, std::memory_order_relaxed); + last_write_ns.store(steady_ns(), std::memory_order_relaxed); + } + + void read(std::uint64_t wire, std::uint64_t payload, std::uint64_t frames) + { + bytes_in.fetch_add(wire, std::memory_order_relaxed); + payload_in.fetch_add(payload, std::memory_order_relaxed); + frames_in.fetch_add(frames, std::memory_order_relaxed); + last_read_ns.store(steady_ns(), std::memory_order_relaxed); + } + + void fill(stream_stats & s) const + { + s.bytes_out = bytes_out.load(std::memory_order_relaxed); + s.bytes_in = bytes_in.load(std::memory_order_relaxed); + s.payload_out = payload_out.load(std::memory_order_relaxed); + s.payload_in = payload_in.load(std::memory_order_relaxed); + s.frames_out = frames_out.load(std::memory_order_relaxed); + s.frames_in = frames_in.load(std::memory_order_relaxed); + s.write_calls = write_calls.load(std::memory_order_relaxed); + s.last_write_ns = last_write_ns.load(std::memory_order_relaxed); + s.last_read_ns = last_read_ns.load(std::memory_order_relaxed); + } +}; + +/// @brief `(offset, length)` pieces of a `len`-byte write. +inline std::vector> split_chunks( + std::size_t len, std::size_t chunk) +{ + std::vector> out; + if (len == 0) + return out; + const std::size_t step = chunk == 0 ? len : chunk; + for (std::size_t off = 0; off < len; off += step) + out.emplace_back(off, std::min(step, len - off)); + return out; +} + +/// @brief One reader waiting for `n` bytes on a stream. +struct stream_waiter +{ + bool active = false; + bool reading = false; ///< a socket read is filling `dst` directly + void * dst = nullptr; + std::size_t n = 0; + std::size_t filled = 0; + async_handler h; + std::error_code abort; +}; + +/// @brief Byte inbox with a consumed-prefix cursor. +struct stream_inbox +{ + std::vector bytes; + std::size_t pos = 0; + + std::size_t avail() const noexcept { return bytes.size() - pos; } + + std::size_t take(void * dst, std::size_t n, std::size_t compact_at) + { + const std::size_t k = std::min(n, avail()); + if (k != 0) + std::memcpy(dst, bytes.data() + pos, k); + pos += k; + if (pos == bytes.size()) + { + bytes.clear(); + pos = 0; + } + else if (compact_at != 0 && pos > compact_at) + { + bytes.erase(bytes.begin(), + bytes.begin() + static_cast(pos)); + pos = 0; + } + return k; + } +}; + +inline void post_handler(asio::io_context & io, async_handler h, + std::error_code ec) +{ + if (h) + asio::post(io, [h = std::move(h), ec]() { h(ec); }); +} + +/// @brief One contiguous copy of a gather list of `bytes` total. +inline std::shared_ptr> flatten( + const std::vector & bufs, std::size_t bytes) +{ + auto flat = acquire_buffer(bytes); + std::size_t at = 0; + for (const auto & b : bufs) + { + if (b.size() != 0) + std::memcpy(flat->data() + at, b.data(), b.size()); + at += b.size(); + } + return flat; +} + +/// @brief Add the kernel's TCP byte counters for `fd` (no-op off Linux or +/// for non-TCP sockets). +inline void add_socket_bytes(int fd, stream_stats & s) +{ +#if defined(__linux__) && defined(TCP_INFO) + tcp_info ti{}; + socklen_t len = sizeof(ti); + if (fd >= 0 && ::getsockopt(fd, IPPROTO_TCP, TCP_INFO, &ti, &len) == 0 + && len >= offsetof(tcp_info, tcpi_bytes_received) + sizeof(ti.tcpi_bytes_received)) + { + s.socket_bytes_out += ti.tcpi_bytes_acked; + s.socket_bytes_in += ti.tcpi_bytes_received; + } +#else + (void)fd; + (void)s; +#endif +} + +/// @brief A TLS peer that closes without `close_notify` reads as a truncated +/// stream. Frames already say what is owed, so that is an ordinary end +/// of stream. +inline std::error_code end_of_stream(const std::error_code & ec) +{ + if (ec.value() == 1 && std::strcmp(ec.category().name(), "asio.ssl.stream") == 0) + return asio::error::eof; + return ec; +} + +} // namespace detail + +/// @brief Virtual base for N duplex streams with event-driven completion. +/// @details `async_write` / `async_read` are non-blocking initiators. The +/// handler is invoked exactly once, on a thread running `context()` +/// (never inline on the caller's thread). A short read or write is +/// reported through the handler's `error_code`. After `close()`, no +/// backend copies into a caller buffer from its inbox again; pending +/// reads complete with `operation_aborted`. +class async_stream_array +{ +public: + virtual ~async_stream_array() = default; + + virtual std::size_t size() const noexcept = 0; + + virtual asio::io_context & context() noexcept = 0; + + /// @brief Write `n` bytes on stream `i`. Backends copy `src` before return. + virtual void async_write(std::size_t i, const void * src, std::size_t n, + async_handler h) = 0; + + /// @brief Read exactly `n` bytes on stream `i` into `dst`. `dst` must stay + /// valid until `h` fires. One outstanding read per stream. + virtual void async_read(std::size_t i, void * dst, std::size_t n, + async_handler h) = 0; + + /// @brief Write an owned buffer without copying the payload again. + virtual void async_write_owned(std::size_t i, + std::shared_ptr> buf, async_handler h) + { + const std::size_t n = buf ? buf->size() : 0; + const void * p = (buf && n) ? buf->data() : nullptr; + async_write(i, p, n, [buf = std::move(buf), h = std::move(h)]( + const std::error_code & ec) { + if (h) + h(ec); + }); + } + + /// @brief Bytes accepted by `async_write*` and not yet on the wire (or not + /// yet read, for in-process backends). + virtual std::size_t buffered_bytes() const noexcept { return 0; } + + /// @brief High-water mark for `buffered_bytes` (0 = unlimited). + virtual std::size_t window_bytes() const noexcept { return 0; } + + virtual void set_window_bytes(std::size_t) {} + + /// @brief Backpressure that applies to lane `i` (whole connection on mux + /// and SCTP, that lane's socket on parallel). + virtual std::size_t lane_buffered_bytes(std::size_t) const noexcept + { + return buffered_bytes(); + } + + virtual std::size_t lane_window_bytes(std::size_t) const noexcept + { + return window_bytes(); + } + + virtual stream_stats stats() const { return {}; } + + /// @brief Abort all I/O: pending reads and queued writes fail with + /// `operation_aborted`; the peer sees EOF. Destroying a backend is + /// graceful instead: accepted writes still reach the peer. + virtual void close() noexcept {} +}; + +// --------------------------------------------------------------------------- +// Lane-range view +// --------------------------------------------------------------------------- + +/// @brief Lanes `[first, first + count)` of another array, re-indexed from 0. +/// @details Lets one connection carry several logical edges (peer, ring, +/// dealer) on disjoint lanes. Does not own or close the base. +class async_stream_view final : public async_stream_array +{ +public: + async_stream_view(async_stream_array & base, std::size_t first, + std::size_t count) + : base_(&base), first_(first), count_(count) + { + if (count == 0 || first + count > base.size()) + throw std::invalid_argument("async_stream_view: lane range"); + } + + std::size_t size() const noexcept override { return count_; } + asio::io_context & context() noexcept override { return base_->context(); } + + void async_write(std::size_t i, const void * src, std::size_t n, + async_handler h) override + { + base_->async_write(map(i), src, n, std::move(h)); + } + + void async_read(std::size_t i, void * dst, std::size_t n, + async_handler h) override + { + base_->async_read(map(i), dst, n, std::move(h)); + } + + void async_write_owned(std::size_t i, + std::shared_ptr> buf, async_handler h) override + { + base_->async_write_owned(map(i), std::move(buf), std::move(h)); + } + + std::size_t buffered_bytes() const noexcept override + { + return base_->buffered_bytes(); + } + std::size_t window_bytes() const noexcept override + { + return base_->window_bytes(); + } + void set_window_bytes(std::size_t b) override { base_->set_window_bytes(b); } + std::size_t lane_buffered_bytes(std::size_t i) const noexcept override + { + return base_->lane_buffered_bytes(first_ + i); + } + std::size_t lane_window_bytes(std::size_t i) const noexcept override + { + return base_->lane_window_bytes(first_ + i); + } + stream_stats stats() const override { return base_->stats(); } + +private: + std::size_t map(std::size_t i) const + { + if (i >= count_) + throw std::out_of_range("async_stream_view index"); + return first_ + i; + } + + async_stream_array * base_ = nullptr; + std::size_t first_ = 0; + std::size_t count_ = 0; +}; + +// --------------------------------------------------------------------------- +// In-process backend (paired ends; each end may own its own io_context) +// --------------------------------------------------------------------------- + +/// @brief Shared state for a pair of in-process async ends. +/// @details Direction `d` carries bytes written by side `d` to side `1 - d`. +/// A write that would push a direction's unread bytes past that +/// side's window waits (FIFO) until the reader consumes. Completions +/// post to the owning side's `io_context`. Closing one side fails its +/// pending I/O and gives the other side EOF once its data runs out. +class async_dual_memory_hub +{ +public: + async_dual_memory_hub(asio::io_context & io_a, asio::io_context & io_b, + std::size_t streams, std::size_t window = default_wire_window()) + : n_(streams) + { + if (streams == 0) + throw std::invalid_argument("async memory hub: empty"); + io_[0] = &io_a; + io_[1] = &io_b; + for (int d = 0; d < 2; ++d) + { + in_[d].resize(streams); + wait_[d].resize(streams); + window_[d] = window; + } + } + + async_dual_memory_hub(asio::io_context & io, std::size_t streams) + : async_dual_memory_hub(io, io, streams) + { + } + + std::size_t size() const noexcept { return n_; } + asio::io_context & context(int side) noexcept { return *io_[side]; } + + std::size_t window(int writer_side) const + { + std::lock_guard lock(mu_); + return window_[writer_side]; + } + + void set_window(int writer_side, std::size_t bytes) + { + std::lock_guard lock(mu_); + window_[writer_side] = bytes; + release_locked(writer_side); + } + + /// @brief Bytes `writer_side` wrote that its peer has not read yet. + std::size_t unread_side(int writer_side) const + { + std::lock_guard lock(mu_); + return unread_[writer_side] + pending_bytes_[writer_side]; + } + + stream_stats stats(int side) const + { + stream_stats s; + std::lock_guard lock(mu_); + s.bytes_out = s.payload_out = out_bytes_[side]; + s.bytes_in = s.payload_in = in_bytes_[side]; + s.frames_out = s.write_calls = out_frames_[side]; + s.frames_in = in_frames_[side]; + s.buffered = unread_[side] + pending_bytes_[side]; + s.unread = unread_[1 - side]; + s.last_write_ns = last_write_[side]; + s.last_read_ns = last_read_[side]; + s.closed = closed_[side]; + return s; + } + + void do_write(int ws, std::size_t i, const void * src, std::size_t n, + async_handler h) + { + check(i); + std::lock_guard lock(mu_); + if (closed_[ws]) + { + detail::post_handler(*io_[ws], std::move(h), + asio::error::operation_aborted); + return; + } + if (closed_[1 - ws]) + { + detail::post_handler(*io_[ws], std::move(h), asio::error::broken_pipe); + return; + } + if (n == 0) + { + detail::post_handler(*io_[ws], std::move(h), {}); + return; + } + const auto * p = static_cast(src); + if (!pending_[ws].empty() || !fits_locked(ws, n)) + { + pending_[ws].push_back( + pending_write{i, std::vector(p, p + n), std::move(h)}); + pending_bytes_[ws] += n; + return; + } + deliver_locked(ws, i, p, n); + detail::post_handler(*io_[ws], std::move(h), {}); + release_locked(ws); + } + + void do_read(int rs, std::size_t i, void * dst, std::size_t n, + async_handler h) + { + check(i); + const int d = 1 - rs; + std::lock_guard lock(mu_); + if (closed_[rs]) + { + detail::post_handler(*io_[rs], std::move(h), + asio::error::operation_aborted); + return; + } + detail::stream_waiter & w = wait_[d][i]; + if (w.active) + throw std::logic_error("async memory stream: overlapping read on " + "stream " + std::to_string(i)); + const std::size_t k = in_[d][i].take(dst, n, compact_); + consumed_locked(d, rs, k); + if (k == n) + { + detail::post_handler(*io_[rs], std::move(h), {}); + release_locked(d); + return; + } + if (closed_[d] && pending_[d].empty()) + { + detail::post_handler(*io_[rs], std::move(h), asio::error::eof); + return; + } + w.active = true; + w.dst = dst; + w.n = n; + w.filled = k; + w.h = std::move(h); + release_locked(d); + } + + void close_side(int s) + { + std::lock_guard lock(mu_); + if (closed_[s]) + return; + closed_[s] = true; + // Reads by `s` fail. + for (auto & w : wait_[1 - s]) + { + if (!w.active) + continue; + w.active = false; + detail::post_handler(*io_[s], std::move(w.h), + asio::error::operation_aborted); + } + // Accepted writes by `s` still reach the peer (window no longer applies). + while (!pending_[s].empty()) + { + pending_write pw = std::move(pending_[s].front()); + pending_[s].pop_front(); + pending_bytes_[s] -= pw.bytes.size(); + deliver_locked(s, pw.i, pw.bytes.data(), pw.bytes.size()); + detail::post_handler(*io_[s], std::move(pw.h), {}); + } + // Peer reads that the delivered bytes cannot satisfy end with EOF. + for (auto & w : wait_[s]) + { + if (!w.active) + continue; + w.active = false; + detail::post_handler(*io_[1 - s], std::move(w.h), asio::error::eof); + } + } + +private: + struct pending_write + { + std::size_t i = 0; + std::vector bytes; + async_handler h; + }; + + void check(std::size_t i) const + { + if (i >= n_) + throw std::out_of_range("async memory stream index " + + std::to_string(i)); + } + + bool fits_locked(int ws, std::size_t n) const + { + const std::size_t w = window_[ws]; + return w == 0 || unread_[ws] == 0 || unread_[ws] + n <= w; + } + + void deliver_locked(int d, std::size_t i, const std::uint8_t * p, + std::size_t n) + { + auto & box = in_[d][i]; + box.bytes.insert(box.bytes.end(), p, p + n); + unread_[d] += n; + out_bytes_[d] += n; + ++out_frames_[d]; + last_write_[d] = detail::steady_ns(); + satisfy_locked(d, i); + } + + void consumed_locked(int d, int rs, std::size_t k) + { + if (k == 0) + return; + unread_[d] -= std::min(unread_[d], k); + in_bytes_[rs] += k; + ++in_frames_[rs]; + last_read_[rs] = detail::steady_ns(); + } + + void satisfy_locked(int d, std::size_t i) + { + detail::stream_waiter & w = wait_[d][i]; + if (!w.active) + return; + const int rs = 1 - d; + const std::size_t k = in_[d][i].take( + static_cast(w.dst) + w.filled, w.n - w.filled, + compact_); + consumed_locked(d, rs, k); + w.filled += k; + if (w.filled == w.n) + { + w.active = false; + detail::post_handler(*io_[rs], std::move(w.h), {}); + } + } + + void release_locked(int d) + { + while (!pending_[d].empty() && !closed_[1 - d] + && fits_locked(d, pending_[d].front().bytes.size())) + { + pending_write pw = std::move(pending_[d].front()); + pending_[d].pop_front(); + pending_bytes_[d] -= pw.bytes.size(); + deliver_locked(d, pw.i, pw.bytes.data(), pw.bytes.size()); + detail::post_handler(*io_[d], std::move(pw.h), {}); + } + } + + asio::io_context * io_[2] = {nullptr, nullptr}; + std::size_t n_ = 0; + std::size_t compact_ = wire_policy{}.compact_bytes; + mutable std::mutex mu_; + std::vector in_[2]; + std::vector wait_[2]; + std::deque pending_[2]; + std::size_t pending_bytes_[2] = {0, 0}; + std::size_t unread_[2] = {0, 0}; + std::size_t window_[2] = {0, 0}; + bool closed_[2] = {false, false}; + std::uint64_t out_bytes_[2] = {0, 0}; + std::uint64_t in_bytes_[2] = {0, 0}; + std::uint64_t out_frames_[2] = {0, 0}; + std::uint64_t in_frames_[2] = {0, 0}; + std::int64_t last_write_[2] = {0, 0}; + std::int64_t last_read_[2] = {0, 0}; +}; + +/// @brief One end of an in-process async pair. Destroying it closes its side. +class async_dual_memory_stream_array final : public async_stream_array +{ +public: + async_dual_memory_stream_array(std::shared_ptr hub, + bool side_a) + : hub_(std::move(hub)), side_(side_a ? 0 : 1) + { + if (!hub_) + throw std::invalid_argument("async memory stream needs a hub"); + } + + async_dual_memory_stream_array(async_dual_memory_stream_array && o) noexcept + : hub_(std::move(o.hub_)), side_(o.side_) + { + } + + async_dual_memory_stream_array & operator=( + async_dual_memory_stream_array && o) noexcept + { + if (this != &o) + { + if (hub_) + hub_->close_side(side_); + hub_ = std::move(o.hub_); + side_ = o.side_; + } + return *this; + } + + async_dual_memory_stream_array(const async_dual_memory_stream_array &) = delete; + async_dual_memory_stream_array & operator=( + const async_dual_memory_stream_array &) = delete; + + ~async_dual_memory_stream_array() override + { + if (hub_) + hub_->close_side(side_); + } + + std::size_t size() const noexcept override { return hub_->size(); } + asio::io_context & context() noexcept override + { + return hub_->context(side_); + } + + void async_write(std::size_t i, const void * src, std::size_t n, + async_handler h) override + { + hub_->do_write(side_, i, src, n, std::move(h)); + } + + void async_read(std::size_t i, void * dst, std::size_t n, + async_handler h) override + { + hub_->do_read(side_, i, dst, n, std::move(h)); + } + + std::size_t buffered_bytes() const noexcept override + { + return hub_->unread_side(side_); + } + + std::size_t window_bytes() const noexcept override + { + return hub_->window(side_); + } + + void set_window_bytes(std::size_t bytes) override + { + hub_->set_window(side_, bytes); + } + + stream_stats stats() const override { return hub_->stats(side_); } + + void close() noexcept override + { + if (hub_) + hub_->close_side(side_); + } + +private: + std::shared_ptr hub_; + int side_ = 0; +}; + +using async_memory_hub = async_dual_memory_hub; +using async_memory_stream_array = async_dual_memory_stream_array; + +/// @brief Two ends sharing one `io_context`. +HEDLEY_WARN_UNUSED_RESULT +inline std::pair +make_async_memory_stream_pair(asio::io_context & io, std::size_t streams) +{ + auto hub = std::make_shared(io, streams); + return {async_memory_stream_array(hub, true), + async_memory_stream_array(hub, false)}; +} + +/// @brief Two ends, each completing on its own `io_context`. +HEDLEY_WARN_UNUSED_RESULT +inline std::pair +make_async_dual_memory_stream_pair(asio::io_context & io_a, + asio::io_context & io_b, std::size_t streams, + std::size_t window = default_wire_window()) +{ + auto hub = std::make_shared(io_a, io_b, streams, + window); + return {async_dual_memory_stream_array(hub, true), + async_dual_memory_stream_array(hub, false)}; +} + +// --------------------------------------------------------------------------- +// Mux backend (N lanes on ONE TCP socket) +// --------------------------------------------------------------------------- + +/// @brief N lanes multiplexed on one TCP socket, fully overlapped. +/// @details Wire frame: `u32 total` (little-endian) `|| stream_frame_hdr` +/// (`u16 index`, `u32 length`) `|| payload`, with +/// `total = sizeof(stream_frame_hdr) + length`. The synchronous +/// `mux_stream_array` writes the same frames, so the two interoperate. +/// All socket operations run on one strand. The window covers the +/// whole connection: every lane shares one TCP byte stream. +template +class basic_async_mux_stream_array final : public async_stream_array +{ +public: + basic_async_mux_stream_array(asio::io_context & io, Stream sock, + unsigned self_id, unsigned peer_id, std::size_t nstreams, + const wire_policy & pol = {}) + { + if (nstreams == 0) + throw std::invalid_argument("async_mux_stream_array empty"); + if (nstreams > 0xffffu) + throw std::invalid_argument("async_mux_stream_array: lane ids are u16"); + if (self_id == peer_id) + throw std::invalid_argument("async_mux_stream_array roles"); + pol.validate(); + tune_stream(sock, pol.socket); + impl_ = std::make_shared(io, std::move(sock), nstreams, pol); + impl_->start(); + } + + basic_async_mux_stream_array(const basic_async_mux_stream_array &) = delete; + basic_async_mux_stream_array & operator=(const basic_async_mux_stream_array &) + = delete; + + ~basic_async_mux_stream_array() override + { + if (impl_) + impl_->close_graceful(); + } + + std::size_t size() const noexcept override { return impl_->n; } + asio::io_context & context() noexcept override { return impl_->io; } + + void async_write(std::size_t i, const void * src, std::size_t n, + async_handler h) override + { + impl_->write(i, n == 0 ? nullptr : copy_buffer(src, n), std::move(h)); + } + + void async_write_owned(std::size_t i, + std::shared_ptr> buf, async_handler h) override + { + impl_->write(i, std::move(buf), std::move(h)); + } + + void async_read(std::size_t i, void * dst, std::size_t n, + async_handler h) override + { + impl_->read(i, dst, n, std::move(h)); + } + + std::size_t buffered_bytes() const noexcept override + { + return impl_->buffered.load(std::memory_order_relaxed); + } + + std::size_t window_bytes() const noexcept override + { + return impl_->window.load(std::memory_order_relaxed); + } + + void set_window_bytes(std::size_t bytes) override + { + impl_->window.store(bytes, std::memory_order_relaxed); + } + + stream_stats stats() const override { return impl_->stats(); } + + void close() noexcept override + { + impl_->close(asio::error::operation_aborted); + } + +private: + struct impl : std::enable_shared_from_this + { + static constexpr std::size_t hdr_wire = 4 + sizeof(stream_frame_hdr); + + struct chunk + { + std::uint32_t total_le = 0; + stream_frame_hdr hdr{}; + std::shared_ptr> payload; + std::size_t off = 0; + std::size_t len = 0; + std::shared_ptr op; + }; + + impl(asio::io_context & io_, Stream sock_, + std::size_t nstreams, const wire_policy & pol_) + : io(io_), + sock(std::move(sock_)), + strand(asio::make_strand(io_)), + n(nstreams), + pol(pol_), + inbox(nstreams), + wait(nstreams), + outq(nstreams), + window(pol_.window_bytes) + { + fd = base_socket(sock).native_handle(); + } + + void check(std::size_t i) const + { + if (i >= n) + throw std::out_of_range("async_mux_stream_array index " + + std::to_string(i)); + } + + void start() + { + auto self = this->shared_from_this(); + asio::post(strand, [self] { self->read_hdr(); }); + } + + // --- reads --------------------------------------------------------- + void read(std::size_t i, void * dst, std::size_t nbytes, async_handler h) + { + check(i); + std::lock_guard lock(mu); + if (fail) + { + detail::post_handler(io, std::move(h), fail); + return; + } + detail::stream_waiter & w = wait[i]; + if (w.active) + throw std::logic_error( + "async_mux_stream_array: overlapping read on stream " + + std::to_string(i)); + const std::size_t k = inbox[i].take(dst, nbytes, pol.compact_bytes); + if (k == nbytes) + { + detail::post_handler(io, std::move(h), {}); + return; + } + w.active = true; + w.reading = false; + w.dst = dst; + w.n = nbytes; + w.filled = k; + w.h = std::move(h); + w.abort.clear(); + } + + void satisfy_locked(std::size_t i) + { + detail::stream_waiter & w = wait[i]; + if (!w.active || w.reading) + return; + w.filled += inbox[i].take(static_cast(w.dst) + w.filled, + w.n - w.filled, pol.compact_bytes); + if (w.filled == w.n) + { + w.active = false; + detail::post_handler(io, std::move(w.h), {}); + } + } + + void read_hdr() + { + auto self = this->shared_from_this(); + asio::async_read(sock, asio::buffer(hdr_buf, hdr_wire), + asio::bind_executor(strand, + [self](const std::error_code & ec, std::size_t) { + self->on_hdr(ec); + })); + } + + void on_hdr(const std::error_code & ec) + { + if (ec) + { + deliver_error(detail::end_of_stream(ec)); + return; + } + std::uint32_t total = 0; + std::memcpy(&total, hdr_buf, 4); + stream_frame_hdr hdr{}; + std::memcpy(&hdr, hdr_buf + 4, sizeof(hdr)); + if (hdr.index >= n || total != sizeof(stream_frame_hdr) + hdr.length) + { + deliver_error(std::make_error_code(std::errc::protocol_error)); + return; + } + if (hdr.length > pol.max_frame) + { + deliver_error(std::make_error_code(std::errc::message_size)); + return; + } + cur_index = hdr.index; + cur_len = hdr.length; + if (cur_len == 0) + { + counters.read(hdr_wire, 0, 1); + read_hdr(); + return; + } + void * dst = nullptr; + cur_direct = false; + { + std::lock_guard lock(mu); + if (closed) + return; + detail::stream_waiter & w = wait[cur_index]; + if (w.active && !w.reading && inbox[cur_index].avail() == 0 + && w.filled + cur_len <= w.n) + { + w.reading = true; + cur_direct = true; + dst = static_cast(w.dst) + w.filled; + } + } + if (!cur_direct) + { + rbuf.resize(cur_len); + dst = rbuf.data(); + } + auto self = this->shared_from_this(); + asio::async_read(sock, asio::buffer(dst, cur_len), + asio::bind_executor(strand, + [self](const std::error_code & xec, std::size_t) { + self->on_body(xec); + })); + } + + void on_body(const std::error_code & ec) + { + if (cur_direct) + { + std::lock_guard lock(mu); + detail::stream_waiter & w = wait[cur_index]; + w.reading = false; + if (w.active && (ec || w.abort)) + { + w.active = false; + detail::post_handler(io, std::move(w.h), ec ? ec : w.abort); + } + else if (w.active && !ec) + { + w.filled += cur_len; + if (w.filled == w.n) + { + w.active = false; + detail::post_handler(io, std::move(w.h), {}); + } + } + } + if (ec) + { + deliver_error(detail::end_of_stream(ec)); + return; + } + counters.read(hdr_wire + cur_len, cur_len, 1); + if (!cur_direct) + { + std::lock_guard lock(mu); + if (closed) + return; + auto & box = inbox[cur_index].bytes; + box.insert(box.end(), rbuf.begin(), rbuf.end()); + satisfy_locked(cur_index); + } + { + std::lock_guard lock(mu); + if (closed) + return; + } + if (pol.socket.quickack) + rearm_quickack(base_socket(sock)); + read_hdr(); + } + + void fail_waiters_locked(const std::error_code & ec) + { + for (auto & w : wait) + { + if (!w.active) + continue; + if (w.reading) + { + // Completes once the in-flight socket read ends: `dst` + // must stay owned by the handler until then. + w.abort = ec; + continue; + } + w.active = false; + detail::post_handler(io, std::move(w.h), ec); + } + } + + void deliver_error(const std::error_code & ec) + { + { + std::lock_guard lock(mu); + if (!fail) + fail = ec; + fail_waiters_locked(fail); + } + auto self = this->shared_from_this(); + asio::post(strand, [self, ec] { + std::error_code e; + base_socket(self->sock).shutdown(asio::socket_base::shutdown_both, e); + self->fail_queued(ec); + }); + } + + void close(const std::error_code & ec) + { + { + std::lock_guard lock(mu); + if (!fail) + fail = ec; + if (closed && aborted) + return; + closed = true; + aborted = true; + fail_waiters_locked(ec); + } + auto self = this->shared_from_this(); + asio::post(strand, [self, ec] { + std::error_code e; + base_socket(self->sock).shutdown(asio::socket_base::shutdown_both, e); + base_socket(self->sock).close(e); + self->fail_queued(ec); + }); + } + + /// @brief Stop reads now; close the socket once queued writes drain. + void close_graceful() + { + { + std::lock_guard lock(mu); + if (closed) + return; + closed = true; + fail_waiters_locked(asio::error::operation_aborted); + } + auto self = this->shared_from_this(); + asio::post(strand, [self] { + self->draining = true; + if (!self->writing) + self->finish_close(); + }); + } + + void finish_close() + { + std::error_code e; + base_socket(sock).shutdown(asio::socket_base::shutdown_both, e); + base_socket(sock).close(e); + } + + stream_stats stats() const + { + stream_stats s; + counters.fill(s); + s.buffered = buffered.load(std::memory_order_relaxed); + std::lock_guard lock(mu); + for (const auto & b : inbox) + s.unread += b.avail(); + s.error = fail; + s.closed = closed; + if (!closed) + detail::add_socket_bytes(fd, s); + return s; + } + + // --- writes (strand) ---------------------------------------------- + void write(std::size_t i, std::shared_ptr> payload, + async_handler h) + { + check(i); + const std::size_t len = payload ? payload->size() : 0; + { + std::lock_guard lock(mu); + if (fail || closed) + { + detail::post_handler(io, std::move(h), + fail ? fail : asio::error::operation_aborted); + return; + } + } + if (len == 0) + { + detail::post_handler(io, std::move(h), {}); + return; + } + if (pol.chunk_bytes == 0 && len > 0xffffffffu - sizeof(stream_frame_hdr)) + throw std::invalid_argument("async_mux_stream_array frame too large"); + const auto pieces = detail::split_chunks(len, pol.chunk_bytes); + auto op = std::make_shared(); + op->h = std::move(h); + op->left = pieces.size(); + std::vector cs; + cs.reserve(pieces.size()); + std::size_t wire = 0; + for (const auto & pc : pieces) + { + chunk c; + c.hdr.index = static_cast(i); + c.hdr.length = static_cast(pc.second); + c.total_le = static_cast( + sizeof(stream_frame_hdr) + pc.second); + c.payload = payload; + c.off = pc.first; + c.len = pc.second; + c.op = op; + wire += hdr_wire + pc.second; + cs.push_back(std::move(c)); + } + buffered.fetch_add(wire, std::memory_order_relaxed); + auto self = this->shared_from_this(); + asio::post(strand, [self, i, cs = std::move(cs)]() mutable { + self->enqueue(i, std::move(cs)); + }); + } + + void enqueue(std::size_t i, std::vector cs) + { + std::error_code ec; + { + std::lock_guard lock(mu); + ec = fail; + } + if (ec) + { + for (auto & c : cs) + finish_chunk(c, ec); + return; + } + for (auto & c : cs) + outq[i].push_back(std::move(c)); + if (!writing) + start_write(); + } + + void finish_chunk(chunk & c, const std::error_code & ec) + { + buffered.fetch_sub(std::min(buffered.load(std::memory_order_relaxed), + hdr_wire + c.len), + std::memory_order_relaxed); + auto & op = *c.op; + if (ec && !op.ec) + op.ec = ec; + if (--op.left == 0) + detail::post_handler(io, std::move(op.h), op.ec); + } + + void start_write() + { + inflight.clear(); + std::size_t bytes = 0; + bool stop = false; + while (!stop && inflight.size() < pol.coalesce_frames) + { + bool found = false; + for (std::size_t k = 0; k < n; ++k) + { + const std::size_t lane = (rr + k) % n; + if (outq[lane].empty()) + continue; + const std::size_t wire = hdr_wire + outq[lane].front().len; + if (!inflight.empty() && bytes + wire > pol.coalesce_bytes) + { + stop = true; + break; + } + inflight.push_back(std::move(outq[lane].front())); + outq[lane].pop_front(); + bytes += wire; + rr = (lane + 1) % n; + found = true; + break; + } + if (!found) + break; + } + if (inflight.empty()) + { + writing = false; + if (draining) + finish_close(); + return; + } + writing = true; + inflight_wire = bytes; + std::vector bufs; + bufs.reserve(inflight.size() * 3); + for (auto & c : inflight) + { + bufs.push_back(asio::buffer(&c.total_le, 4)); + bufs.push_back(asio::buffer(&c.hdr, sizeof(c.hdr))); + bufs.push_back(asio::buffer(c.payload->data() + c.off, c.len)); + } + auto self = this->shared_from_this(); + if constexpr (detail::is_layered_stream::value) + { + // TLS seals each buffer as its own record; send the batch as one. + auto flat = detail::flatten(bufs, bytes); + asio::async_write(sock, asio::buffer(*flat), + asio::bind_executor(strand, + [self, flat](const std::error_code & ec, std::size_t) { + self->on_written(ec); + })); + return; + } + asio::async_write(sock, bufs, + asio::bind_executor(strand, + [self](const std::error_code & ec, std::size_t) { + self->on_written(ec); + })); + } + + void on_written(const std::error_code & ec) + { + if (!ec) + { + std::size_t payload = 0; + for (const auto & c : inflight) + payload += c.len; + counters.wrote(inflight_wire, payload, inflight.size()); + } + for (auto & c : inflight) + finish_chunk(c, ec); + inflight.clear(); + if (ec) + { + writing = false; + deliver_error(detail::end_of_stream(ec)); + if (draining) + finish_close(); + return; + } + if (pol.socket.quickack) + rearm_quickack(base_socket(sock)); + start_write(); + } + + void fail_queued(const std::error_code & ec) + { + for (auto & q : outq) + { + for (auto & c : q) + finish_chunk(c, ec); + q.clear(); + } + } + + asio::io_context & io; + Stream sock; + int fd = -1; + asio::strand strand; + std::size_t n = 0; + wire_policy pol; + + mutable std::mutex mu; + std::vector inbox; + std::vector wait; + std::error_code fail; + bool closed = false; + bool aborted = false; + + // strand-only + std::vector> outq; + std::size_t rr = 0; + bool writing = false; + bool draining = false; + std::vector inflight; + std::size_t inflight_wire = 0; + std::uint8_t hdr_buf[hdr_wire]{}; + std::vector rbuf; + std::size_t cur_index = 0; + std::size_t cur_len = 0; + bool cur_direct = false; + + std::atomic buffered{0}; + std::atomic window; + detail::io_counters counters; + }; + + std::shared_ptr impl_; +}; + +/// @brief Mux over a plain TCP socket. +using async_mux_stream_array = basic_async_mux_stream_array; + +// --------------------------------------------------------------------------- +// Parallel backend (one socket PER lane) +// --------------------------------------------------------------------------- + +/// @brief One dedicated socket per lane; each lane fully independent. +/// @details Wire frame per socket: `u32 length || payload`. Each socket has its +/// own strand, write queue, window, and read loop. Queued frames on a +/// socket are written in one gathered syscall. +template +class basic_async_parallel_stream_array final : public async_stream_array +{ +public: + basic_async_parallel_stream_array(asio::io_context & io, + std::vector socks, const wire_policy & pol = {}) + { + if (socks.empty()) + throw std::invalid_argument("async_parallel_stream_array empty"); + pol.validate(); + impl_ = std::make_shared(io, std::move(socks), pol); + impl_->start(); + } + + basic_async_parallel_stream_array(const basic_async_parallel_stream_array &) + = delete; + basic_async_parallel_stream_array & operator=( + const basic_async_parallel_stream_array &) = delete; + + ~basic_async_parallel_stream_array() override + { + if (impl_) + impl_->close_graceful(); + } + + std::size_t size() const noexcept override { return impl_->conns.size(); } + asio::io_context & context() noexcept override { return impl_->io; } + + void async_write(std::size_t i, const void * src, std::size_t n, + async_handler h) override + { + impl_->write(i, n == 0 ? nullptr : copy_buffer(src, n), std::move(h)); + } + + void async_write_owned(std::size_t i, + std::shared_ptr> buf, async_handler h) override + { + impl_->write(i, std::move(buf), std::move(h)); + } + + void async_read(std::size_t i, void * dst, std::size_t n, + async_handler h) override + { + impl_->read(i, dst, n, std::move(h)); + } + + std::size_t buffered_bytes() const noexcept override + { + std::size_t total = 0; + for (const auto & c : impl_->conns) + total += c->buffered.load(std::memory_order_relaxed); + return total; + } + + /// @brief Sum of per-socket windows (matches `buffered_bytes`). + std::size_t window_bytes() const noexcept override + { + std::size_t total = 0; + for (const auto & c : impl_->conns) + { + const std::size_t w = c->window.load(std::memory_order_relaxed); + if (w == 0) + return 0; + total += w; + } + return total; + } + + /// @brief Set every socket's window to `bytes`. + void set_window_bytes(std::size_t bytes) override + { + for (auto & c : impl_->conns) + c->window.store(bytes, std::memory_order_relaxed); + } + + std::size_t lane_buffered_bytes(std::size_t i) const noexcept override + { + return i < impl_->conns.size() + ? impl_->conns[i]->buffered.load(std::memory_order_relaxed) + : 0; + } + + std::size_t lane_window_bytes(std::size_t i) const noexcept override + { + return i < impl_->conns.size() + ? impl_->conns[i]->window.load(std::memory_order_relaxed) + : 0; + } + + stream_stats stats() const override { return impl_->stats(); } + + void close() noexcept override + { + impl_->close(asio::error::operation_aborted); + } + +private: + struct chunk + { + std::uint32_t len_le = 0; + std::shared_ptr> payload; + std::size_t off = 0; + std::size_t len = 0; + std::shared_ptr op; + }; + + struct conn + { + conn(Socket s, asio::io_context & io, const wire_policy & pol) + : sock(std::move(s)), + strand(asio::make_strand(io)), + window(pol.window_bytes) + { + tune_stream(sock, pol.socket); + fd = base_socket(sock).native_handle(); + } + + Socket sock; + int fd = -1; + asio::strand strand; + detail::stream_inbox inbox; // guarded by impl::mu + detail::stream_waiter wait; // guarded by impl::mu + std::deque outq; // strand + std::vector inflight; // strand + std::size_t inflight_wire = 0; // strand + bool writing = false; // strand + bool draining = false; // strand + std::uint32_t rlen_le = 0; // strand + std::vector rbuf; // strand + std::size_t cur_len = 0; // strand + bool cur_direct = false; // strand + std::atomic buffered{0}; + std::atomic window; + }; + + struct impl : std::enable_shared_from_this + { + impl(asio::io_context & io_, std::vector socks, + const wire_policy & pol_) + : io(io_), pol(pol_) + { + conns.reserve(socks.size()); + for (auto & s : socks) + conns.push_back(std::make_unique(std::move(s), io_, pol_)); + } + + void check(std::size_t i) const + { + if (i >= conns.size()) + throw std::out_of_range("async_parallel_stream_array index " + + std::to_string(i)); + } + + void start() + { + for (std::size_t i = 0; i < conns.size(); ++i) + { + auto self = this->shared_from_this(); + asio::post(conns[i]->strand, [self, i] { self->read_len(i); }); + } + } + + // --- reads --------------------------------------------------------- + void read(std::size_t i, void * dst, std::size_t nbytes, async_handler h) + { + check(i); + conn & c = *conns[i]; + std::lock_guard lock(mu); + if (fail) + { + detail::post_handler(io, std::move(h), fail); + return; + } + if (c.wait.active) + throw std::logic_error( + "async_parallel_stream_array: overlapping read on stream " + + std::to_string(i)); + const std::size_t k = c.inbox.take(dst, nbytes, pol.compact_bytes); + if (k == nbytes) + { + detail::post_handler(io, std::move(h), {}); + return; + } + c.wait.active = true; + c.wait.reading = false; + c.wait.dst = dst; + c.wait.n = nbytes; + c.wait.filled = k; + c.wait.h = std::move(h); + c.wait.abort.clear(); + } + + void satisfy_locked(conn & c) + { + auto & w = c.wait; + if (!w.active || w.reading) + return; + w.filled += c.inbox.take(static_cast(w.dst) + w.filled, + w.n - w.filled, pol.compact_bytes); + if (w.filled == w.n) + { + w.active = false; + detail::post_handler(io, std::move(w.h), {}); + } + } + + void read_len(std::size_t i) + { + auto self = this->shared_from_this(); + conn & c = *conns[i]; + asio::async_read(c.sock, asio::buffer(&c.rlen_le, 4), + asio::bind_executor(c.strand, + [self, i](const std::error_code & ec, std::size_t) { + self->on_len(i, ec); + })); + } + + void on_len(std::size_t i, const std::error_code & ec) + { + conn & c = *conns[i]; + if (ec) + { + deliver_error(detail::end_of_stream(ec)); + return; + } + std::uint32_t len = 0; + std::memcpy(&len, &c.rlen_le, 4); + if (len > pol.max_frame) + { + deliver_error(std::make_error_code(std::errc::message_size)); + return; + } + c.cur_len = len; + if (len == 0) + { + counters.read(4, 0, 1); + read_len(i); + return; + } + void * dst = nullptr; + c.cur_direct = false; + { + std::lock_guard lock(mu); + if (closed) + return; + auto & w = c.wait; + if (w.active && !w.reading && c.inbox.avail() == 0 + && w.filled + len <= w.n) + { + w.reading = true; + c.cur_direct = true; + dst = static_cast(w.dst) + w.filled; + } + } + if (!c.cur_direct) + { + c.rbuf.resize(len); + dst = c.rbuf.data(); + } + auto self = this->shared_from_this(); + asio::async_read(c.sock, asio::buffer(dst, len), + asio::bind_executor(c.strand, + [self, i](const std::error_code & xec, std::size_t) { + self->on_body(i, xec); + })); + } + + void on_body(std::size_t i, const std::error_code & ec) + { + conn & c = *conns[i]; + if (c.cur_direct) + { + std::lock_guard lock(mu); + auto & w = c.wait; + w.reading = false; + if (w.active && (ec || w.abort)) + { + w.active = false; + detail::post_handler(io, std::move(w.h), ec ? ec : w.abort); + } + else if (w.active && !ec) + { + w.filled += c.cur_len; + if (w.filled == w.n) + { + w.active = false; + detail::post_handler(io, std::move(w.h), {}); + } + } + } + if (ec) + { + deliver_error(detail::end_of_stream(ec)); + return; + } + counters.read(4 + c.cur_len, c.cur_len, 1); + { + std::lock_guard lock(mu); + if (closed) + return; + if (!c.cur_direct) + { + c.inbox.bytes.insert(c.inbox.bytes.end(), c.rbuf.begin(), + c.rbuf.end()); + satisfy_locked(c); + } + } + rearm_stream(c.sock, pol.socket); + read_len(i); + } + + void fail_waiters_locked(const std::error_code & ec) + { + for (auto & cp : conns) + { + auto & w = cp->wait; + if (!w.active) + continue; + if (w.reading) + { + w.abort = ec; + continue; + } + w.active = false; + detail::post_handler(io, std::move(w.h), ec); + } + } + + void deliver_error(const std::error_code & ec) + { + { + std::lock_guard lock(mu); + if (!fail) + fail = ec; + fail_waiters_locked(fail); + } + shutdown_all(ec, false); + } + + void close(const std::error_code & ec) + { + { + std::lock_guard lock(mu); + if (!fail) + fail = ec; + if (closed && aborted) + return; + closed = true; + aborted = true; + fail_waiters_locked(ec); + } + shutdown_all(ec, true); + } + + void close_graceful() + { + { + std::lock_guard lock(mu); + if (closed) + return; + closed = true; + fail_waiters_locked(asio::error::operation_aborted); + } + for (std::size_t i = 0; i < conns.size(); ++i) + { + auto self = this->shared_from_this(); + asio::post(conns[i]->strand, [self, i] { + conn & c = *self->conns[i]; + c.draining = true; + if (!c.writing) + finish_close(c); + }); + } + } + + static void finish_close(conn & c) + { + std::error_code e; + base_socket(c.sock).shutdown(asio::socket_base::shutdown_both, e); + base_socket(c.sock).close(e); + } + + void shutdown_all(const std::error_code & ec, bool close_sockets) + { + for (std::size_t i = 0; i < conns.size(); ++i) + { + auto self = this->shared_from_this(); + asio::post(conns[i]->strand, [self, i, ec, close_sockets] { + conn & c = *self->conns[i]; + std::error_code e; + base_socket(c.sock).shutdown(asio::socket_base::shutdown_both, e); + if (close_sockets) + base_socket(c.sock).close(e); + for (auto & ch : c.outq) + self->finish_chunk(c, ch, ec); + c.outq.clear(); + }); + } + } + + stream_stats stats() const + { + stream_stats s; + counters.fill(s); + for (const auto & c : conns) + s.buffered += c->buffered.load(std::memory_order_relaxed); + std::lock_guard lock(mu); + for (const auto & c : conns) + { + s.unread += c->inbox.avail(); + if (!closed) + detail::add_socket_bytes(c->fd, s); + } + s.error = fail; + s.closed = closed; + return s; + } + + // --- writes -------------------------------------------------------- + void write(std::size_t i, std::shared_ptr> payload, + async_handler h) + { + check(i); + const std::size_t len = payload ? payload->size() : 0; + { + std::lock_guard lock(mu); + if (fail || closed) + { + detail::post_handler(io, std::move(h), + fail ? fail : asio::error::operation_aborted); + return; + } + } + if (len == 0) + { + detail::post_handler(io, std::move(h), {}); + return; + } + if (pol.chunk_bytes == 0 && len > 0xffffffffu) + throw std::invalid_argument( + "async_parallel_stream_array frame too large"); + const auto pieces = detail::split_chunks(len, pol.chunk_bytes); + auto op = std::make_shared(); + op->h = std::move(h); + op->left = pieces.size(); + std::vector cs; + cs.reserve(pieces.size()); + std::size_t wire = 0; + for (const auto & pc : pieces) + { + chunk c; + c.len_le = static_cast(pc.second); + c.payload = payload; + c.off = pc.first; + c.len = pc.second; + c.op = op; + wire += 4 + pc.second; + cs.push_back(std::move(c)); + } + conn & cn = *conns[i]; + cn.buffered.fetch_add(wire, std::memory_order_relaxed); + auto self = this->shared_from_this(); + asio::post(cn.strand, [self, i, cs = std::move(cs)]() mutable { + self->enqueue(i, std::move(cs)); + }); + } + + void enqueue(std::size_t i, std::vector cs) + { + conn & c = *conns[i]; + std::error_code ec; + { + std::lock_guard lock(mu); + ec = fail; + } + if (ec) + { + for (auto & ch : cs) + finish_chunk(c, ch, ec); + return; + } + for (auto & ch : cs) + c.outq.push_back(std::move(ch)); + if (!c.writing) + start_write(i); + } + + void finish_chunk(conn & c, chunk & ch, const std::error_code & ec) + { + const std::size_t wire = 4 + ch.len; + c.buffered.fetch_sub( + std::min(c.buffered.load(std::memory_order_relaxed), wire), + std::memory_order_relaxed); + auto & op = *ch.op; + if (ec && !op.ec) + op.ec = ec; + if (--op.left == 0) + detail::post_handler(io, std::move(op.h), op.ec); + } + + void start_write(std::size_t i) + { + conn & c = *conns[i]; + c.inflight.clear(); + std::size_t bytes = 0; + while (!c.outq.empty() && c.inflight.size() < pol.coalesce_frames) + { + const std::size_t wire = 4 + c.outq.front().len; + if (!c.inflight.empty() && bytes + wire > pol.coalesce_bytes) + break; + c.inflight.push_back(std::move(c.outq.front())); + c.outq.pop_front(); + bytes += wire; + } + if (c.inflight.empty()) + { + c.writing = false; + if (c.draining) + finish_close(c); + return; + } + c.writing = true; + c.inflight_wire = bytes; + std::vector bufs; + bufs.reserve(c.inflight.size() * 2); + for (auto & ch : c.inflight) + { + bufs.push_back(asio::buffer(&ch.len_le, 4)); + bufs.push_back(asio::buffer(ch.payload->data() + ch.off, ch.len)); + } + auto self = this->shared_from_this(); + if constexpr (detail::is_layered_stream::value) + { + auto flat = detail::flatten(bufs, bytes); + asio::async_write(c.sock, asio::buffer(*flat), + asio::bind_executor(c.strand, + [self, i, flat](const std::error_code & ec, std::size_t) { + self->on_written(i, ec); + })); + return; + } + asio::async_write(c.sock, bufs, + asio::bind_executor(c.strand, + [self, i](const std::error_code & ec, std::size_t) { + self->on_written(i, ec); + })); + } + + void on_written(std::size_t i, const std::error_code & ec) + { + conn & c = *conns[i]; + if (!ec) + { + std::size_t payload = 0; + for (const auto & ch : c.inflight) + payload += ch.len; + counters.wrote(c.inflight_wire, payload, c.inflight.size()); + } + for (auto & ch : c.inflight) + finish_chunk(c, ch, ec); + c.inflight.clear(); + if (ec) + { + c.writing = false; + for (auto & ch : c.outq) + finish_chunk(c, ch, ec); + c.outq.clear(); + deliver_error(detail::end_of_stream(ec)); + if (c.draining) + finish_close(c); + return; + } + rearm_stream(c.sock, pol.socket); + start_write(i); + } + + asio::io_context & io; + wire_policy pol; + mutable std::mutex mu; + std::vector> conns; + std::error_code fail; + bool closed = false; + bool aborted = false; + detail::io_counters counters; + }; + + std::shared_ptr impl_; +}; + +/// @brief Parallel array over TCP sockets (one connection per lane). +using async_parallel_stream_array = + basic_async_parallel_stream_array; + +/// @brief Parallel array over unix-domain stream sockets. +using async_local_parallel_stream_array = + basic_async_parallel_stream_array; + +#if DPF_HAS_OPENSSL +#include "dpf/net/tls.hpp" +/// @brief N lanes on one TLS connection. +using async_tls_mux_stream_array = basic_async_mux_stream_array; +/// @brief One TLS connection per lane. +using async_tls_parallel_stream_array = basic_async_parallel_stream_array; +#endif + +// --------------------------------------------------------------------------- +// Connection helpers (setup only; protocol I/O stays async) +// --------------------------------------------------------------------------- + +/// @brief Accept `nstreams` lane sockets on ONE port. +/// @details Binds `base_port` (0 = ephemeral), publishes the port, and accepts +/// one connection per lane. Each connection announces its lane index +/// as a `u32`, so accept order does not matter. +HEDLEY_WARN_UNUSED_RESULT +inline std::vector accept_parallel_tcp( + asio::io_context & io, std::atomic & base_port, + std::size_t nstreams, + std::chrono::milliseconds budget = deadlines{}.accept) +{ + if (nstreams == 0) + throw std::invalid_argument("accept_parallel_tcp empty"); + asio::ip::tcp::acceptor acc(io); + open_listener(acc, base_port.load()); + base_port.store(acc.local_endpoint().port()); + std::vector socks; + std::vector have(nstreams, false); + for (std::size_t k = 0; k < nstreams; ++k) + socks.emplace_back(io); + for (std::size_t k = 0; k < nstreams; ++k) + { + asio::ip::tcp::socket s(io); + accept_until(acc, s, budget); + const std::uint32_t lane = exchange_u32(s.native_handle(), + static_cast(nstreams), budget, "parallel lane handshake"); + if (lane >= nstreams || have[lane]) + throw std::runtime_error("accept_parallel_tcp: bad lane " + + std::to_string(lane)); + have[lane] = true; + socks[lane] = std::move(s); + } + return socks; +} + +/// @brief Connect `nstreams` lane sockets to one port (lane index handshake). +HEDLEY_WARN_UNUSED_RESULT +inline std::vector connect_parallel_tcp( + asio::io_context & io, const std::string & host, + std::atomic & base_port, std::size_t nstreams, + std::chrono::milliseconds budget = deadlines{}.connect) +{ + if (nstreams == 0) + throw std::invalid_argument("connect_parallel_tcp empty"); + std::vector socks; + socks.reserve(nstreams); + for (std::size_t k = 0; k < nstreams; ++k) + { + asio::ip::tcp::socket s(io); + connect_until(s, host, base_port.load(), budget); + const std::uint32_t n = exchange_u32(s.native_handle(), + static_cast(k), budget, "parallel lane handshake"); + if (n != nstreams) + throw std::runtime_error("connect_parallel_tcp: peer expects " + + std::to_string(n) + " lanes, this side " + + std::to_string(nstreams)); + socks.push_back(std::move(s)); + } + return socks; +} + +/// @brief In-process unix socket pairs: lane `k` connects `ends.first[k]` +/// (on `io_a`) to `ends.second[k]` (on `io_b`). +HEDLEY_WARN_UNUSED_RESULT +inline std::pair, + std::vector> +make_local_socket_pairs(asio::io_context & io_a, asio::io_context & io_b, + std::size_t nstreams) +{ + std::pair, + std::vector> + out; + out.first.reserve(nstreams); + out.second.reserve(nstreams); + for (std::size_t k = 0; k < nstreams; ++k) + { + asio::local::stream_protocol::socket a(io_a); + asio::local::stream_protocol::socket b(io_b); + asio::local::connect_pair(a, b); + out.first.push_back(std::move(a)); + out.second.push_back(std::move(b)); + } + return out; +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_ASYNC_STREAM_ARRAY_HPP__ diff --git a/include/dpf/net/buffer_pool.hpp b/include/dpf/net/buffer_pool.hpp new file mode 100644 index 0000000..506c494 --- /dev/null +++ b/include/dpf/net/buffer_pool.hpp @@ -0,0 +1,98 @@ +/// @file dpf/net/buffer_pool.hpp +/// @brief Recycled byte buffers for framed writes. +/// @details `acquire_buffer` hands out a `shared_ptr` whose deleter returns the +/// vector to a process-wide free list (capped). Callers that already +/// own a buffer pass it to `async_write_owned` so the socket path can +/// scatter-gather without a second payload copy. +#ifndef LIBDPF_INCLUDE_DPF_NET_BUFFER_POOL_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_BUFFER_POOL_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/policy.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Default outstanding-byte window (see `wire_policy::window_bytes`). +inline std::size_t default_wire_window() noexcept +{ + return wire_policy{}.window_bytes; +} + +/// @brief Default receive cap (see `wire_policy::max_frame`). +inline constexpr std::size_t k_max_frame = std::size_t{16} << 20; + +namespace detail +{ + +struct pool_state +{ + std::mutex mu; + std::vector>> free; +}; + +inline pool_state & buffers() +{ + static pool_state s; + return s; +} + +inline void recycle(std::vector * p) +{ + std::unique_ptr> owned(p); + owned->clear(); + if (owned->capacity() > (std::size_t{1} << 20)) + return; + auto & st = buffers(); + std::lock_guard lock(st.mu); + if (st.free.size() < 128) + st.free.push_back(std::move(owned)); +} + +} // namespace detail + +/// @brief Buffer of at least `n` bytes, returned to the pool on last release. +inline std::shared_ptr> acquire_buffer(std::size_t n) +{ + std::unique_ptr> raw; + { + auto & st = detail::buffers(); + std::lock_guard lock(st.mu); + if (!st.free.empty()) + { + raw = std::move(st.free.back()); + st.free.pop_back(); + } + } + if (!raw) + raw.reset(new std::vector()); + if (raw->capacity() < n) + raw->reserve(n); + raw->resize(n); + std::vector * p = raw.release(); + return std::shared_ptr>(p, &detail::recycle); +} + +/// @brief Copy `n` bytes into a pooled buffer. +inline std::shared_ptr> copy_buffer(const void * src, + std::size_t n) +{ + auto buf = acquire_buffer(n); + if (n != 0 && src != nullptr) + std::memcpy(buf->data(), src, n); + return buf; +} + +} // namespace net +} // namespace dpf + +#endif diff --git a/include/dpf/net/channel.hpp b/include/dpf/net/channel.hpp new file mode 100644 index 0000000..18a24e5 --- /dev/null +++ b/include/dpf/net/channel.hpp @@ -0,0 +1,484 @@ +/// @file dpf/net/channel.hpp +/// @brief Framed duplex stream for party message exchange. +/// @details Every message is `u32` little-endian length, `u16` type tag, then +/// payload. `exchange` orders send/recv by role so a single stream +/// cannot deadlock. Call sites name `send` / `recv` / `exchange`; +/// they do not touch ASIO buffers. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_NET_CHANNEL_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_CHANNEL_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" +#include "dpf/net/tls.hpp" + +#include "hedley/hedley.h" + +namespace dpf +{ +namespace net +{ + +/// @brief Bytes and frames observed on one channel since the last reset. +/// @details Counts include the 6-byte frame header. A failed read or write +/// does not add to the tally. `payload_*` is the body alone; +/// `exchanges` counts `exchange()` calls (one logical round each). +struct io_tally +{ + std::uint64_t bytes_sent = 0; + std::uint64_t bytes_recv = 0; + std::uint64_t frames_sent = 0; + std::uint64_t frames_recv = 0; + std::uint64_t payload_sent = 0; + std::uint64_t payload_recv = 0; + std::uint64_t exchanges = 0; + + io_tally & operator+=(const io_tally & other) noexcept + { + bytes_sent += other.bytes_sent; + bytes_recv += other.bytes_recv; + frames_sent += other.frames_sent; + frames_recv += other.frames_recv; + payload_sent += other.payload_sent; + payload_recv += other.payload_recv; + exchanges += other.exchanges; + return *this; + } +}; + +enum class msg : std::uint16_t +{ + hangup = 0, + beaver_tape = 1, + ring_vector = 2, + delta = 3, + dpf_key = 4, + proof_token = 5, + case_ok = 6, + case_fail = 7, + bytes = 8, + mac_key = 9, + mac_share = 10, + sketch_share = 11, + round_batch = 12, +}; + +inline constexpr std::uint16_t to_u16(msg t) noexcept +{ + return static_cast(t); +} + +/// @brief One framed duplex byte stream. +class channel +{ +public: + using tcp_socket = asio::ip::tcp::socket; + using local_socket = asio::local::stream_protocol::socket; + + channel() = default; + + explicit channel(tcp_socket sock) + : tcp_(std::make_unique(std::move(sock))) + { } + + explicit channel(local_socket sock) + : local_(std::make_unique(std::move(sock))) + { } + +#if DPF_HAS_OPENSSL + /// @brief Framed channel over an established TLS 1.3 TCP stream. + static channel from_tls(asio::io_context &, tls_stream s, + std::shared_ptr ctx) + { + channel c; + c.tls_ctx_ = std::move(ctx); + c.tls_ = std::make_unique(std::move(s)); + return c; + } + + /// @brief Framed channel over an established TLS 1.3 unix-domain stream. + static channel from_tls_local(asio::io_context &, tls_local_stream s, + std::shared_ptr ctx) + { + channel c; + c.tls_ctx_ = std::move(ctx); + c.tls_local_ = std::make_unique(std::move(s)); + return c; + } +#endif + + channel(channel &&) noexcept = default; + channel & operator=(channel &&) noexcept = default; + + channel(const channel &) = delete; + channel & operator=(const channel &) = delete; + + /// @brief Replay `frames` as a recv-only dealer tape. `send` throws. + static channel from_inbox(std::vector frames) + { + channel c; + c.inbox_ = std::make_unique(); + c.inbox_->bytes = std::move(frames); + return c; + } + + /// @brief True when an inbox tape has been read through its last byte. + HEDLEY_NO_THROW + bool inbox_done() const noexcept + { + return inbox_ != nullptr && inbox_->pos == inbox_->bytes.size(); + } + + HEDLEY_NO_THROW + bool open() const noexcept + { + return tcp_ != nullptr || local_ != nullptr || inbox_ != nullptr +#if DPF_HAS_OPENSSL + || tls_ != nullptr || tls_local_ != nullptr +#endif + ; + } + + /// @brief Underlying socket descriptor, or -1 for an inbox tape / TLS edge. + /// @details Prefer framed `send` / `recv` on TLS channels. Raw descriptor + /// I/O bypasses TLS and is rejected when the channel is encrypted. + HEDLEY_NO_THROW + int native_handle() noexcept + { + if (tcp_) + return tcp_->native_handle(); + if (local_) + return local_->native_handle(); +#if DPF_HAS_OPENSSL + if (tls_ || tls_local_) + return -1; +#endif + return -1; + } + + /// @brief True when application bytes ride TLS 1.3 under the frame header. + HEDLEY_NO_THROW + bool encrypted() const noexcept + { +#if DPF_HAS_OPENSSL + return tls_ != nullptr || tls_local_ != nullptr; +#else + return false; +#endif + } + + /// @brief Bytes and frames since construction or the last `reset_tally`. + HEDLEY_NO_THROW + io_tally tally() const noexcept + { + return tally_; + } + + /// @brief Zero the byte and frame counters. Does not touch the socket. + HEDLEY_NO_THROW + void reset_tally() noexcept + { + tally_ = {}; + } + + /// @name Framed messages + /// @brief Each frame is a little-endian length, a tag, then the payload. + /// `T` must be trivially copyable. A zero-length payload is a + /// header only. + /// @throws std::runtime_error if the socket closes or the tag/size disagree + /// @throws std::invalid_argument if a frame exceeds 2^32-1 bytes, or + /// `exchange` is called with `self_id == peer_id` + /// @throws std::logic_error if the channel is closed + /// @{ + + /// @brief Send one value. + /// @tparam T trivially copyable payload + /// @param tag the message tag + /// @param value the payload + template + void send(msg tag, const T & value) + { + static_assert(std::is_trivially_copyable_v, + "net::channel::send requires a trivially copyable type"); + write_frame(tag, &value, sizeof(T)); + } + + /// @brief Receive one value. + /// @tparam T trivially copyable payload + /// @param tag the expected message tag + /// @return the payload + template + HEDLEY_WARN_UNUSED_RESULT + T recv(msg tag) + { + static_assert(std::is_trivially_copyable_v, + "net::channel::recv requires a trivially copyable type"); + T value{}; + read_frame(tag, &value, sizeof(T)); + return value; + } + + /// @brief Send `n` values. + /// @param data the values + /// @param n the value count + /// @param tag the message tag + template + void send_vec(const T * data, std::size_t n, msg tag = msg::ring_vector) + { + static_assert(std::is_trivially_copyable_v, + "net::channel::send_vec requires a trivially copyable type"); + write_frame(tag, data, n * sizeof(T)); + } + + /// @brief Send a vector of values. + /// @param v the values + /// @param tag the message tag + template + void send_vec(const std::vector & v, msg tag = msg::ring_vector) + { + send_vec(v.data(), v.size(), tag); + } + + /// @brief Receive a homogeneous vector. + /// @tparam T trivially copyable element + /// @param tag the expected message tag + /// @return the elements. Empty when the payload length is 0. + template + HEDLEY_WARN_UNUSED_RESULT + std::vector recv_vec(msg tag = msg::ring_vector) + { + static_assert(std::is_trivially_copyable_v, + "net::channel::recv_vec requires a trivially copyable type"); + auto bytes = read_frame_bytes(tag); + if (bytes.size() % sizeof(T) != 0) + throw std::runtime_error("net::channel::recv_vec size mismatch"); + std::vector out(bytes.size() / sizeof(T)); + if (!out.empty()) + std::memcpy(out.data(), bytes.data(), bytes.size()); + return out; + } + + /// @brief Send `n` bytes. + /// @param tag the message tag + /// @param data the bytes + /// @param n the byte count + void send_bytes(msg tag, const void * data, std::size_t n) + { + write_frame(tag, data, n); + } + + /// @brief Send a byte vector. + /// @param tag the message tag + /// @param bytes the bytes + void send_bytes(msg tag, const std::vector & bytes) + { + send_bytes(tag, bytes.data(), bytes.size()); + } + + /// @brief Receive an untyped payload. + /// @param tag the expected message tag + /// @return the payload bytes + HEDLEY_WARN_UNUSED_RESULT + std::vector recv_bytes(msg tag) + { + return read_frame_bytes(tag); + } + + /// @brief Exchange one value. The lower id sends first. + /// @tparam T trivially copyable payload + /// @param self_id this party's role, as an integer + /// @param peer_id the peer's role, as an integer + /// @param mine this party's value + /// @param tag the message tag + /// @return the peer's value + template + HEDLEY_WARN_UNUSED_RESULT + T exchange(unsigned self_id, unsigned peer_id, const T & mine, msg tag = msg::delta) + { + static_assert(std::is_trivially_copyable_v, + "net::channel::exchange requires a trivially copyable type"); + ++tally_.exchanges; + if (self_id < peer_id) + { + send(tag, mine); + return recv(tag); + } + if (self_id > peer_id) + { + T theirs = recv(tag); + send(tag, mine); + return theirs; + } + throw std::invalid_argument("net::channel::exchange with self"); + } + + /// @brief Exchange a homogeneous vector. One barrier; lower id sends first. + /// @tparam T trivially copyable element + /// @param self_id this party's role, as an integer + /// @param peer_id the peer's role, as an integer + /// @param mine this party's values + /// @param tag the message tag + /// @return the peer's values (same length as `mine`) + /// @throws std::runtime_error if the peer's vector length disagrees + template + HEDLEY_WARN_UNUSED_RESULT + std::vector exchange_vec(unsigned self_id, unsigned peer_id, + const std::vector & mine, msg tag = msg::ring_vector) + { + static_assert(std::is_trivially_copyable_v, + "net::channel::exchange_vec requires a trivially copyable type"); + if (mine.empty()) + return {}; + ++tally_.exchanges; + std::vector theirs; + if (self_id < peer_id) + { + send_vec(mine, tag); + theirs = recv_vec(tag); + } + else if (self_id > peer_id) + { + theirs = recv_vec(tag); + send_vec(mine, tag); + } + else + throw std::invalid_argument("net::channel::exchange_vec with self"); + if (theirs.size() != mine.size()) + throw std::runtime_error("net::channel::exchange_vec size mismatch"); + return theirs; + } + + /// @} + +private: + struct inbox_buf + { + std::vector bytes; + std::size_t pos = 0; + }; + + std::unique_ptr tcp_; + std::unique_ptr local_; +#if DPF_HAS_OPENSSL + std::unique_ptr tls_; + std::unique_ptr tls_local_; + std::shared_ptr tls_ctx_; +#endif + std::unique_ptr inbox_; + io_tally tally_{}; + + void write_all(const void * data, std::size_t n) + { + if (inbox_) + throw std::logic_error("net::channel inbox is recv-only"); + asio::const_buffer buf(data, n); + asio::error_code ec; + if (tcp_) + asio::write(*tcp_, buf, ec); + else if (local_) + asio::write(*local_, buf, ec); +#if DPF_HAS_OPENSSL + else if (tls_) + asio::write(*tls_, buf, ec); + else if (tls_local_) + asio::write(*tls_local_, buf, ec); +#endif + else + throw std::logic_error("net::channel is closed"); + if (ec) + throw std::runtime_error("net::channel write: " + ec.message()); + tally_.bytes_sent += n; + } + + void read_all(void * data, std::size_t n) + { + if (inbox_) + { + if (inbox_->pos + n > inbox_->bytes.size()) + throw std::runtime_error("net::channel inbox underrun"); + if (n != 0) + std::memcpy(data, inbox_->bytes.data() + inbox_->pos, n); + inbox_->pos += n; + tally_.bytes_recv += n; + return; + } + asio::mutable_buffer buf(data, n); + asio::error_code ec; + if (tcp_) + asio::read(*tcp_, buf, ec); + else if (local_) + asio::read(*local_, buf, ec); +#if DPF_HAS_OPENSSL + else if (tls_) + asio::read(*tls_, buf, ec); + else if (tls_local_) + asio::read(*tls_local_, buf, ec); +#endif + else + throw std::logic_error("net::channel is closed"); + if (ec) + throw std::runtime_error("net::channel read: " + ec.message()); + tally_.bytes_recv += n; + } + + void write_frame(msg tag, const void * payload, std::size_t n) + { + if (n > 0xffffffffu) + throw std::invalid_argument("net::channel frame too large"); + std::uint32_t len = static_cast(n); + std::uint16_t t = to_u16(tag); + std::array hdr{}; + std::memcpy(hdr.data(), &len, 4); + std::memcpy(hdr.data() + 4, &t, 2); + write_all(hdr.data(), hdr.size()); + if (n != 0) + write_all(payload, n); + tally_.payload_sent += n; + ++tally_.frames_sent; + } + + std::vector read_frame_bytes(msg expected) + { + std::array hdr{}; + read_all(hdr.data(), hdr.size()); + std::uint32_t len = 0; + std::uint16_t t = 0; + std::memcpy(&len, hdr.data(), 4); + std::memcpy(&t, hdr.data() + 4, 2); + if (t != to_u16(expected)) + throw std::runtime_error("net::channel unexpected message tag"); + std::vector body(len); + if (len != 0) + read_all(body.data(), body.size()); + tally_.payload_recv += len; + ++tally_.frames_recv; + return body; + } + + void read_frame(msg expected, void * dest, std::size_t expect_n) + { + auto body = read_frame_bytes(expected); + if (body.size() != expect_n) + throw std::runtime_error("net::channel frame size mismatch"); + if (expect_n != 0) + std::memcpy(dest, body.data(), expect_n); + } +}; + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_CHANNEL_HPP__ diff --git a/include/dpf/net/client_link.hpp b/include/dpf/net/client_link.hpp new file mode 100644 index 0000000..478c347 --- /dev/null +++ b/include/dpf/net/client_link.hpp @@ -0,0 +1,218 @@ +/// @file dpf/net/client_link.hpp +/// @brief Client-to-server links: TLS 1.3, the server always verified. +/// @details A client that supplies inputs (for example, one share to each +/// party) connects with `connect_server`. It verifies the server +/// unless `client_security::verify` is off: a pinned server key, a CA +/// chain for the host name, or, when neither is configured, the +/// built-in development certificate, which a `client_listener` with no +/// certificate or identity presents. The development certificate's +/// private key is public, so that pairing works out of the box and is +/// logged as providing no security. A server may also check client +/// keys (`server_security::client_pins`). Both ends get an ordinary +/// `async_stream_array` of `lanes` lanes and the link's +/// `link_security`. +#ifndef LIBDPF_INCLUDE_DPF_NET_CLIENT_LINK_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_CLIENT_LINK_HPP__ + +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/log.hpp" +#include "dpf/net/async_stream_array.hpp" +#include "dpf/net/connect.hpp" +#include "dpf/net/link_log.hpp" +#include "dpf/net/policy.hpp" +#include "dpf/net/security.hpp" +#include "dpf/net/socket_tune.hpp" +#include "dpf/net/tls.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief One client link and how it was secured. +struct client_connection +{ +#if DPF_HAS_OPENSSL + std::shared_ptr context; +#endif + std::unique_ptr link; + link_security security; +}; + +namespace detail +{ + +inline constexpr std::uint32_t client_magic = 0x4c435044u; // 'DPCL' + +#if DPF_HAS_OPENSSL +/// @brief Both ends send `{magic, lanes}` inside TLS and must agree. +inline void client_hello(asio::io_context & io, tls_stream & s, std::size_t lanes, + bool server, std::chrono::milliseconds budget, const std::string & who) +{ + std::uint8_t mine[8]; + std::uint8_t theirs[8]; + put_u32(mine, client_magic); + put_u32(mine + 4, static_cast(lanes)); + if (server) + { + tls_read(io, s, theirs, sizeof(theirs), budget, who); + tls_write(io, s, mine, sizeof(mine), budget, who); + } + else + { + tls_write(io, s, mine, sizeof(mine), budget, who); + tls_read(io, s, theirs, sizeof(theirs), budget, who); + } + if (get_u32(theirs) != client_magic) + throw std::runtime_error(who + ": the peer is not a libdpf client link"); + if (get_u32(theirs + 4) != lanes) + throw std::runtime_error(who + ": lanes " + std::to_string(get_u32(theirs + 4)) + + " vs " + std::to_string(lanes) + " (peer vs this side)"); +} +#endif + +} // namespace detail + +/// @brief Connect to the server at `host:port` and verify it. +inline client_connection connect_server(asio::io_context & io, const std::string & host, + unsigned short port, const client_security & sec, std::size_t lanes = 1, + const wire_policy & pol = {}, const deadlines & lim = {}) +{ +#if DPF_HAS_OPENSSL + const std::string where = host + ":" + std::to_string(port); + client_connection out; + out.context = make_client_tls_context(sec); + asio::ip::tcp::socket sock(io); + connect_until(sock, host, port, lim.connect); + tune_tcp(sock, pol.socket); + const int fd = sock.native_handle(); + tls_stream s(std::move(sock), *out.context); + if (sec.verify && !sec.ca_file.empty()) + tls_expect_host(s, sec.server_name.empty() ? host : sec.server_name); + tls_handshake(io, s, false, lim.handshake, "client: TLS handshake with " + where); + out.security = tls_describe(s); + try + { + check_server(out.security, s, sec, where); + } + catch (...) + { + std::error_code e; + s.lowest_layer().close(e); + throw; + } + if (!sec.verify) + DPF_LOG(error, "client.verify_off").kv("server", where) + .kv("detail", "client_verify=off: any server certificate is accepted, so " + "this connection is encrypted but the server is not authenticated"); + else if (out.security.peer_auth == "development" + && log::first_time("client.development." + where)) + DPF_LOG(warning, "client.development_certificate").kv("server", where) + .kv("detail", "the server presented the built-in development certificate, " + "whose private key is public: this connection is encrypted but the " + "server is not authenticated (pin its key or configure client_ca)"); + detail::client_hello(io, s, lanes, false, lim.handshake, "client link to " + where); + out.link = std::make_unique(io, std::move(s), 1, 0, lanes, + pol); + log_link_up("connect", "server", transport::mux, lanes, 0, 0, fd, pol.socket, + &out.security); + return out; +#else + (void)io; + (void)host; + (void)port; + (void)sec; + (void)lanes; + (void)pol; + (void)lim; + throw std::logic_error("connect_server: built without OpenSSL"); +#endif +} + +/// @brief Server side: accept clients, each on its own TLS link. +class client_listener +{ +public: + client_listener(asio::io_context & io, server_security sec, std::size_t lanes = 1, + wire_policy pol = {}, deadlines lim = {}) + : io_(&io), sec_(std::move(sec)), lanes_(lanes), pol_(pol), lim_(lim) + { +#if DPF_HAS_OPENSSL + ctx_ = make_server_tls_context(sec_, development_); + if (development_ && log::first_time("server.development")) + DPF_LOG(warning, "server.development_certificate") + .kv("detail", "presenting the built-in development certificate, whose " + "private key is public: clients cannot tell this server from any " + "other (set server_cert/server_key or server_identity)"); +#else + throw std::logic_error("client_listener: built without OpenSSL"); +#endif + } + + /// @brief Bind `port` (0 = ephemeral) and return it. + unsigned short listen(unsigned short port = 0) + { + if (!acceptor_) + { + acceptor_ = std::make_unique(*io_); + open_listener(*acceptor_, port); + log_listen(acceptor_->local_endpoint().port(), false, true); + } + return acceptor_->local_endpoint().port(); + } + + bool development() const noexcept { return development_; } + + /// @brief Wait (up to the accept deadline) for one client. + client_connection accept() + { + listen(0); + client_connection out; +#if DPF_HAS_OPENSSL + out.context = ctx_; + asio::ip::tcp::socket sock(*io_); + accept_until(*acceptor_, sock, lim_.accept); + tune_tcp(sock, pol_.socket); + const int fd = sock.native_handle(); + tls_stream s(std::move(sock), *ctx_); + tls_handshake(*io_, s, true, lim_.handshake, "server: TLS handshake with a client"); + out.security = tls_describe(s); + check_client(out.security, sec_); + detail::client_hello(*io_, s, lanes_, true, lim_.handshake, "client link"); + out.link = std::make_unique(*io_, std::move(s), 0, 1, + lanes_, pol_); + log_link_up("accept", "client", transport::mux, lanes_, 0, 0, fd, pol_.socket, + &out.security); + if (!sec_.client_pins.empty() && out.security.peer_auth == "none") + DPF_LOG(warning, "server.client_unauthenticated") + .kv("client_key", out.security.peer_key ? out.security.peer_key->base64() + : std::string("none")) + .kv("detail", "the client presented no pinned key"); +#endif + return out; + } + +private: + asio::io_context * io_ = nullptr; + server_security sec_; + std::size_t lanes_ = 1; + wire_policy pol_{}; + deadlines lim_{}; + bool development_ = false; +#if DPF_HAS_OPENSSL + std::shared_ptr ctx_; +#endif + std::unique_ptr acceptor_; +}; + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_CLIENT_LINK_HPP__ diff --git a/include/dpf/net/comm_hook.hpp b/include/dpf/net/comm_hook.hpp new file mode 100644 index 0000000..74565e1 --- /dev/null +++ b/include/dpf/net/comm_hook.hpp @@ -0,0 +1,58 @@ +/// @file dpf/net/comm_hook.hpp +/// @brief Replaceable transport under trio helpers. +/// @details Protocols call `trio::exchange_with`, `send_to` / `recv_from`, +/// `deal` / `accept_deal`, and `trio::batch`. Those helpers go through +/// a `comm_hook` when one is installed. A null hook keeps the current +/// framed mesh. `channel::send` / `recv` stay the raw bypass. +#ifndef LIBDPF_INCLUDE_DPF_NET_COMM_HOOK_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_COMM_HOOK_HPP__ + +#include +#include +#include +#include + +#include "dpf/net/channel.hpp" +#include "dpf/net/round_sink.hpp" + +namespace dpf +{ +namespace net +{ + +class trio; + +/// @brief Byte-level transport for trio helpers and RoundSink factories. +/// @details Overrides replace the mesh without changing protocol call sites. +/// Peer ids are `0..2` (`role` as unsigned). Default implementations +/// in `mesh_comm_hook` match today's `channel` framing. +class comm_hook +{ +public: + virtual ~comm_hook() = default; + + /// @brief One-way send on the link to `peer_id`. + virtual void send_bytes(trio & net, unsigned peer_id, msg tag, + const void * data, std::size_t n) = 0; + + /// @brief One-way receive from `peer_id`. + virtual std::vector recv_bytes(trio & net, unsigned peer_id, + msg tag) = 0; + + /// @brief Duplex exchange. Lower role id sends first. + virtual std::vector exchange_bytes(trio & net, + unsigned peer_id, msg tag, const void * data, std::size_t n) = 0; + + /// @brief Homogeneous vector exchange (one frame each way, same length). + virtual std::vector exchange_vec_bytes(trio & net, + unsigned peer_id, msg tag, const void * data, std::size_t nbytes) = 0; + + /// @brief Round-batched peer sink for `count` instances. + virtual std::unique_ptr batch(trio & net, std::size_t count, + std::vector slot_bytes) = 0; +}; + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_COMM_HOOK_HPP__ diff --git a/include/dpf/net/connect.hpp b/include/dpf/net/connect.hpp new file mode 100644 index 0000000..333eabc --- /dev/null +++ b/include/dpf/net/connect.hpp @@ -0,0 +1,263 @@ +/// @file dpf/net/connect.hpp +/// @brief Deadline-bounded connect, accept, and handshake I/O for setup. +/// @details Setup is blocking by design (it happens before protocol traffic), +/// but every step has a wall-clock bound. `connect_until` retries +/// refused connections until the deadline, so processes may start in +/// any order. +#ifndef LIBDPF_INCLUDE_DPF_NET_CONNECT_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_CONNECT_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/log.hpp" + +namespace dpf +{ +namespace net +{ + +using setup_clock = std::chrono::steady_clock; + +namespace detail +{ + +inline int remaining_ms(setup_clock::time_point deadline) +{ + const auto left = std::chrono::duration_cast( + deadline - setup_clock::now()); + if (left.count() <= 0) + return 0; + if (left.count() > 0x7fffffff) + return 0x7fffffff; + return static_cast(left.count()); +} + +/// @brief Wait until `fd` is ready for `events` or throw at `deadline`. +inline void wait_fd(int fd, short events, setup_clock::time_point deadline, + const std::string & what) +{ + for (;;) + { + const int ms = remaining_ms(deadline); + if (ms == 0) + throw std::system_error(std::make_error_code(std::errc::timed_out), + what + ": timed out"); + pollfd pfd{}; + pfd.fd = fd; + pfd.events = events; + const int rc = ::poll(&pfd, 1, ms); + if (rc > 0) + { + if ((pfd.revents & (POLLERR | POLLNVAL)) != 0 + && (pfd.revents & events) == 0) + throw std::system_error( + std::make_error_code(std::errc::connection_reset), what); + return; + } + if (rc < 0 && errno != EINTR) + throw std::system_error(errno, std::generic_category(), what); + } +} + +inline void send_all_until(int fd, const void * data, std::size_t n, + setup_clock::time_point deadline, const std::string & what) +{ + const auto * p = static_cast(data); + std::size_t done = 0; + while (done < n) + { + const ssize_t r = ::send(fd, p + done, n - done, + MSG_DONTWAIT | MSG_NOSIGNAL); + if (r > 0) + { + done += static_cast(r); + continue; + } + if (r < 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) + { + wait_fd(fd, POLLOUT, deadline, what); + continue; + } + throw std::system_error(errno, std::generic_category(), what); + } +} + +inline void recv_all_until(int fd, void * data, std::size_t n, + setup_clock::time_point deadline, const std::string & what) +{ + auto * p = static_cast(data); + std::size_t done = 0; + while (done < n) + { + const ssize_t r = ::recv(fd, p + done, n - done, MSG_DONTWAIT); + if (r > 0) + { + done += static_cast(r); + continue; + } + if (r == 0) + throw std::system_error(std::make_error_code( + std::errc::connection_reset), what + ": peer closed"); + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) + { + wait_fd(fd, POLLIN, deadline, what); + continue; + } + throw std::system_error(errno, std::generic_category(), what); + } +} + +inline void put_u32(std::uint8_t * dst, std::uint32_t v) noexcept +{ + dst[0] = static_cast(v & 0xffu); + dst[1] = static_cast((v >> 8) & 0xffu); + dst[2] = static_cast((v >> 16) & 0xffu); + dst[3] = static_cast((v >> 24) & 0xffu); +} + +inline std::uint32_t get_u32(const std::uint8_t * src) noexcept +{ + return static_cast(src[0]) | (static_cast(src[1]) << 8) + | (static_cast(src[2]) << 16) + | (static_cast(src[3]) << 24); +} + +} // namespace detail + +/// @brief Connect `sock` to `host:port`, retrying refusals until `budget`. +inline void connect_until(asio::ip::tcp::socket & sock, const std::string & host, + unsigned short port, std::chrono::milliseconds budget) +{ + const auto started = setup_clock::now(); + const auto deadline = started + budget; + const std::string what = "connect " + host + ":" + std::to_string(port); + asio::ip::tcp::resolver res(sock.get_executor()); + std::error_code rec; + auto eps = res.resolve(host, std::to_string(port), rec); + if (rec) + throw std::system_error(rec, what + ": resolve"); + std::error_code last = std::make_error_code(std::errc::timed_out); + std::size_t attempts = 0; + for (;;) + { + for (const auto & entry : eps) + { + std::error_code ec; + if (sock.is_open()) + sock.close(ec); + sock.open(entry.endpoint().protocol(), ec); + if (ec) + { + last = ec; + continue; + } + const int fd = sock.native_handle(); + const int fl = ::fcntl(fd, F_GETFL, 0); + (void)::fcntl(fd, F_SETFL, fl | O_NONBLOCK); + ++attempts; + int rc = ::connect(fd, entry.endpoint().data(), + static_cast(entry.endpoint().size())); + int err = rc == 0 ? 0 : errno; + if (rc != 0 && err == EINPROGRESS) + { + pollfd pfd{}; + pfd.fd = fd; + pfd.events = POLLOUT; + const int prc = ::poll(&pfd, 1, detail::remaining_ms(deadline)); + if (prc <= 0) + err = ETIMEDOUT; + else + { + socklen_t len = sizeof(err); + err = 0; + ::getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len); + } + } + if (err == 0) + { + (void)::fcntl(fd, F_SETFL, fl); + DPF_LOG(debug, "connect").kv("target", host + ":" + std::to_string(port)) + .kv("resolved", entry.endpoint().address().to_string()) + .kv("attempts", attempts) + .kv("elapsed_ms", std::chrono::duration( + setup_clock::now() - started).count()); + return; + } + last = std::error_code(err, std::generic_category()); + sock.close(ec); + } + if (setup_clock::now() >= deadline) + { + DPF_LOG(error, "connect.failed").kv("target", host + ":" + std::to_string(port)) + .kv("attempts", attempts).kv("budget_ms", budget.count()) + .kv("last_error", last.message()); + throw std::system_error(last, what + " failed after " + + std::to_string(budget.count()) + " ms"); + } + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + } +} + +/// @brief Accept one connection on `acc` within `budget`. +inline void accept_until(asio::ip::tcp::acceptor & acc, + asio::ip::tcp::socket & sock, std::chrono::milliseconds budget) +{ + const auto deadline = setup_clock::now() + budget; + const std::string what = "accept on port " + + std::to_string(acc.local_endpoint().port()); + detail::wait_fd(acc.native_handle(), POLLIN, deadline, what); + acc.accept(sock); +} + +/// @brief Open, bind, and listen on `port` (0 = ephemeral), reusing the address. +inline void open_listener(asio::ip::tcp::acceptor & acc, unsigned short port) +{ + const asio::ip::tcp::endpoint ep(asio::ip::tcp::v4(), port); + acc.open(ep.protocol()); + acc.set_option(asio::socket_base::reuse_address(true)); + acc.bind(ep); + acc.listen(); +} + +/// @brief Exchange one `u32` each way within `budget` (setup handshake). +inline std::uint32_t exchange_u32(int fd, std::uint32_t mine, + std::chrono::milliseconds budget, const std::string & what) +{ + const auto deadline = setup_clock::now() + budget; + std::uint8_t out[4]; + detail::put_u32(out, mine); + detail::send_all_until(fd, out, 4, deadline, what); + std::uint8_t in[4]; + detail::recv_all_until(fd, in, 4, deadline, what); + return detail::get_u32(in); +} + +/// @brief Send then receive a fixed-size record within `budget`. +inline void exchange_record(int fd, const void * mine, void * theirs, + std::size_t n, std::chrono::milliseconds budget, const std::string & what) +{ + const auto deadline = setup_clock::now() + budget; + detail::send_all_until(fd, mine, n, deadline, what); + detail::recv_all_until(fd, theirs, n, deadline, what); +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_CONNECT_HPP__ diff --git a/include/dpf/net/dealer_cursor.hpp b/include/dpf/net/dealer_cursor.hpp new file mode 100644 index 0000000..911bf08 --- /dev/null +++ b/include/dpf/net/dealer_cursor.hpp @@ -0,0 +1,221 @@ +/// @file dpf/net/dealer_cursor.hpp +/// @brief Per-(round, index) correction words for a batch session. +#ifndef LIBDPF_INCLUDE_DPF_NET_DEALER_CURSOR_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_DEALER_CURSOR_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/stream_array.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Empty correction / blind marker. Protocols that need no dealer +/// material specialize on this type and skip the cursor. +struct empty_pad +{ +}; + +/// @brief Seekable table of dealer corrections, one lane per round. +/// @details Size is fixed at construction: `count` instances and one slot +/// width per round. Live dealers and inbox tapes both fill this +/// table before the online session runs, or fill it lazily through +/// `put`. Sessions read with `at(round, index)`. +class dealer_cursor +{ +public: + dealer_cursor() = default; + + dealer_cursor(std::size_t count, std::vector slot_bytes) + : count_(count), + slot_bytes_(std::move(slot_bytes)), + offsets_(slot_bytes_.size() + 1, 0) + { + for (std::size_t r = 0; r < slot_bytes_.size(); ++r) + offsets_[r + 1] = offsets_[r] + count_ * slot_bytes_[r]; + store_.assign(offsets_.back(), 0); + ready_.assign(slot_bytes_.size() * count_, false); + } + + std::size_t count() const noexcept { return count_; } + std::size_t rounds() const noexcept { return slot_bytes_.size(); } + + std::size_t slot_bytes(std::uint16_t round) const + { + if (round >= slot_bytes_.size()) + throw std::out_of_range("dealer_cursor round"); + return slot_bytes_[round]; + } + + void put(std::uint16_t round, std::size_t index, const std::uint8_t * bytes, + std::size_t n) + { + check(round, index, n); + std::memcpy(ptr(round, index), bytes, n); + ready_[ready_index(round, index)] = true; + } + + /// @brief Fill every index of `round` from a contiguous dealer tape. + void put_round(std::uint16_t round, const std::uint8_t * bytes, + std::size_t nbytes) + { + if (round >= slot_bytes_.size()) + throw std::out_of_range("dealer_cursor round"); + const std::size_t need = count_ * slot_bytes_[round]; + if (nbytes != need) + throw std::invalid_argument("dealer_cursor put_round size"); + if (need != 0) + std::memcpy(store_.data() + offsets_[round], bytes, need); + for (std::size_t i = 0; i < count_; ++i) + ready_[ready_index(round, i)] = true; + } + + bool ready(std::uint16_t round, std::size_t index) const + { + if (round >= slot_bytes_.size() || index >= count_) + return false; + if (slot_bytes_[round] == 0) + return true; + return ready_[ready_index(round, index)]; + } + + void at(std::uint16_t round, std::size_t index, std::uint8_t * out, + std::size_t n) const + { + check(round, index, n); + if (n == 0) + return; + if (!ready_[ready_index(round, index)]) + throw std::logic_error("dealer_cursor not ready"); + std::memcpy(out, ptr(round, index), n); + } + + template + T at(std::uint16_t round, std::size_t index) const + { + static_assert(std::is_trivially_copyable_v, + "dealer_cursor::at requires a trivially copyable type"); + if constexpr (std::is_same_v) + { + (void)round; + (void)index; + return empty_pad{}; + } + else + { + T out{}; + at(round, index, reinterpret_cast(&out), sizeof(T)); + return out; + } + } + + /// @brief Load each round from consecutive stream indexes (one tape per round). + static dealer_cursor from_streams(stream_array & src, std::size_t count, + std::vector slot_bytes, std::size_t first_stream = 0) + { + dealer_cursor out(count, std::move(slot_bytes)); + for (std::uint16_t r = 0; r < out.rounds(); ++r) + { + const std::size_t need = count * out.slot_bytes(r); + if (need == 0) + continue; + std::vector buf(need); + src.read(first_stream + r, buf.data(), need); + out.put_round(r, buf.data(), need); + } + return out; + } + +private: + void check(std::uint16_t round, std::size_t index, std::size_t n) const + { + if (round >= slot_bytes_.size() || index >= count_) + throw std::out_of_range("dealer_cursor index"); + if (n != slot_bytes_[round]) + throw std::invalid_argument("dealer_cursor size"); + } + + std::size_t ready_index(std::uint16_t round, std::size_t index) const noexcept + { + return static_cast(round) * count_ + index; + } + + std::uint8_t * ptr(std::uint16_t round, std::size_t index) noexcept + { + return store_.data() + offsets_[round] + index * slot_bytes_[round]; + } + + const std::uint8_t * ptr(std::uint16_t round, std::size_t index) const noexcept + { + return store_.data() + offsets_[round] + index * slot_bytes_[round]; + } + + std::size_t count_ = 0; + std::vector slot_bytes_; + std::vector offsets_; + std::vector store_; + std::vector ready_; +}; + +/// @brief Prefetch a full dealer table from `stream_array` tapes (see `from_streams`). +class stream_dealer_cursor +{ +public: + stream_dealer_cursor(stream_array & src, std::size_t count, + std::vector slot_bytes, std::size_t first_stream = 0) + : inner_(dealer_cursor::from_streams(src, count, std::move(slot_bytes), + first_stream)) + { + } + + std::size_t count() const noexcept { return inner_.count(); } + std::size_t rounds() const noexcept { return inner_.rounds(); } + + std::size_t slot_bytes(std::uint16_t round) const + { + return inner_.slot_bytes(round); + } + + bool ready(std::uint16_t round, std::size_t index) const + { + return inner_.ready(round, index); + } + + void at(std::uint16_t round, std::size_t index, std::uint8_t * out, + std::size_t n) const + { + inner_.at(round, index, out, n); + } + + template + T at(std::uint16_t round, std::size_t index) const + { + return inner_.at(round, index); + } + + const dealer_cursor & cursor() const noexcept { return inner_; } + dealer_cursor & cursor() noexcept { return inner_; } + +private: + dealer_cursor inner_; +}; + +/// @brief One-round table: `nbytes` must equal `count * slot_bytes[0]`. +inline dealer_cursor dealer_cursor_from_stream(stream_array & a, + std::size_t stream_index, std::size_t count, std::size_t slot_nbytes) +{ + return dealer_cursor::from_streams(a, count, {slot_nbytes}, stream_index); +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_DEALER_CURSOR_HPP__ diff --git a/include/dpf/net/edge_mesh.hpp b/include/dpf/net/edge_mesh.hpp new file mode 100644 index 0000000..f3f764a --- /dev/null +++ b/include/dpf/net/edge_mesh.hpp @@ -0,0 +1,246 @@ +/// @file dpf/net/edge_mesh.hpp +/// @brief N-edge RoundSink mesh for star / dealer / 4PC topologies. +#ifndef LIBDPF_INCLUDE_DPF_NET_EDGE_MESH_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_EDGE_MESH_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/memory_sink.hpp" +#include "dpf/net/round_sink.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Index of a duplex link in an `edge_mesh`. +using edge_id = std::uint16_t; + +/// @brief Named edges for the common 2PC / RSS / dealer trio (also mesh ids 0..2). +/// @details For the dealer (party 2), `edge_dealer` is its link to party 0 and +/// `edge_dealer_p1` its link to party 1. +inline constexpr edge_id edge_peer = 0; +inline constexpr edge_id edge_rss_next = 1; +inline constexpr edge_id edge_dealer = 2; +inline constexpr edge_id edge_dealer_p1 = 3; + +inline std::string edge_name(edge_id e) +{ + switch (e) + { + case edge_peer: + return "peer"; + case edge_rss_next: + return "rss_next"; + case edge_dealer: + return "dealer"; + case edge_dealer_p1: + return "dealer->p1"; + default: + return "edge " + std::to_string(e); + } +} + +/// @brief Collection of duplex RoundSinks keyed by `edge_id`. +struct edge_mesh +{ + std::vector sinks; + + RoundSink & at(edge_id id) const + { + if (static_cast(id) >= sinks.size() || sinks[id] == nullptr) + throw std::logic_error("edge_mesh: edge not bound"); + return *sinks[id]; + } + + bool has(edge_id id) const noexcept + { + return static_cast(id) < sinks.size() + && sinks[id] != nullptr; + } + + std::size_t size() const noexcept { return sinks.size(); } + + void flush_all() + { + for (auto * s : sinks) + { + if (s == nullptr) + continue; + s->flush(); + s->poll(); + } + } + + /// @brief Sum of `progress()` over distinct bound sinks. + std::uint64_t progress_total() const noexcept + { + std::uint64_t total = 0; + for (std::size_t i = 0; i < sinks.size(); ++i) + { + const RoundSink * s = sinks[i]; + if (s == nullptr) + continue; + bool seen = false; + for (std::size_t j = 0; j < i && !seen; ++j) + seen = sinks[j] == s; + if (!seen) + total += s->progress(); + } + return total; + } + + /// @brief Block until at least one bound sink makes I/O progress. + /// @details Returns true if any sink's `wait_io()` ran a real event (an + /// async sink slept in `epoll`); false if none did (memory sinks), + /// so the caller can fall back to its spin guard. + bool wait_io_all() + { + bool progressed = false; + for (auto * s : sinks) + { + if (s == nullptr) + continue; + if (s->wait_io()) + progressed = true; + } + return progressed; + } +}; + +/// @brief In-process star: one client edge per server, matching server ends. +struct memory_star +{ + std::size_t servers = 0; + std::vector> hubs; + std::vector client; ///< client side of edge i + std::vector server; ///< server i side of edge i + + /// @brief Client mesh: edges `[0, servers)`. + edge_mesh client_mesh() + { + edge_mesh m; + m.sinks.resize(client.size()); + for (std::size_t i = 0; i < client.size(); ++i) + m.sinks[i] = &client[i]; + return m; + } + + /// @brief Server `i` mesh with a single live edge at `edge_id{i}` (sparse). + /// Prefer `server_edge(i)` when the schedule uses `edge_id{0}` locally. + edge_mesh server_mesh_at(std::size_t i) + { + if (i >= server.size()) + throw std::out_of_range("memory_star server"); + edge_mesh m; + m.sinks.assign(server.size(), nullptr); + m.sinks[i] = &server[i]; + return m; + } + + /// @brief Server `i` as a one-edge mesh (`edge_id` 0 → that duplex). + edge_mesh server_edge(std::size_t i) + { + if (i >= server.size()) + throw std::out_of_range("memory_star server"); + return edge_mesh{{&server[i]}}; + } +}; + +/// @brief Build an in-process client↔N-server star. +/// @param slot_bytes Round widths shared by every edge (same schedule shape). +inline memory_star make_memory_star(std::size_t n_servers, std::size_t count, + std::vector slot_bytes) +{ + if (n_servers < 2) + throw std::invalid_argument("make_memory_star needs >= 2 servers"); + memory_star star; + star.servers = n_servers; + star.hubs.reserve(n_servers); + star.client.reserve(n_servers); + star.server.reserve(n_servers); + for (std::size_t i = 0; i < n_servers; ++i) + { + auto hub = std::make_shared(count, slot_bytes); + star.hubs.push_back(hub); + star.client.emplace_back(hub, true); + star.server.emplace_back(hub, false); + } + return star; +} + +/// @brief Fully connected memory clique of `n` roles (every unordered pair). +/// @details Edge id for ordered pair (a,b) with a> hubs; + /// hubs[edge], ends[edge].first = lower role, .second = higher role + std::vector> ends; + + static edge_id pair_edge(std::size_t a, std::size_t b, std::size_t n) + { + if (a == b || a >= n || b >= n) + throw std::invalid_argument("memory_clique pair"); + if (a > b) + std::swap(a, b); + // Index among pairs (i,j) with i(e + (n - 1 - i)); + e = static_cast(e + (b - a - 1)); + return e; + } + + RoundSink & end(std::size_t role, std::size_t peer) + { + const auto e = pair_edge(role, peer, roles); + if (role < peer) + return ends[e].first; + return ends[e].second; + } + + edge_mesh mesh_for(std::size_t role) + { + edge_mesh m; + m.sinks.assign(ends.size(), nullptr); + for (std::size_t p = 0; p < roles; ++p) + { + if (p == role) + continue; + m.sinks[pair_edge(role, p, roles)] = &end(role, p); + } + return m; + } +}; + +inline memory_clique make_memory_clique(std::size_t n_roles, std::size_t count, + std::vector slot_bytes) +{ + if (n_roles < 2) + throw std::invalid_argument("make_memory_clique needs >= 2 roles"); + memory_clique c; + c.roles = n_roles; + const std::size_t n_edges = n_roles * (n_roles - 1) / 2; + c.hubs.reserve(n_edges); + c.ends.reserve(n_edges); + for (std::size_t e = 0; e < n_edges; ++e) + { + auto hub = std::make_shared(count, slot_bytes); + c.hubs.push_back(hub); + c.ends.emplace_back(memory_sink(hub, true), memory_sink(hub, false)); + } + return c; +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_EDGE_MESH_HPP__ diff --git a/include/dpf/net/identity.hpp b/include/dpf/net/identity.hpp new file mode 100644 index 0000000..87b7669 --- /dev/null +++ b/include/dpf/net/identity.hpp @@ -0,0 +1,378 @@ +/// @file dpf/net/identity.hpp +/// @brief Party identity keys (Ed25519) and their text and file forms. +/// @details A party is identified by a raw 32-byte Ed25519 public key, written +/// as 44 characters of base64 (the same shape as a WireGuard key). A +/// key file holds the 32-byte private seed as one base64 line and is +/// created mode 0600. TLS needs a certificate, so `identity` also +/// carries a self-signed certificate generated in memory from the +/// key; peers check the key inside it, never the certificate fields. +/// `development()` is a fixed, publicly known identity: it keeps the +/// client path working with no configuration and provides no security. +#ifndef LIBDPF_INCLUDE_DPF_NET_IDENTITY_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_IDENTITY_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifndef DPF_HAS_OPENSSL +#if defined(__has_include) +#if __has_include() +#define DPF_HAS_OPENSSL 1 +#endif +#endif +#endif +#ifndef DPF_HAS_OPENSSL +#define DPF_HAS_OPENSSL 0 +#endif + +#if DPF_HAS_OPENSSL +#include +#include +#include +#include +#endif + +#include "dpf/log.hpp" + +namespace dpf +{ +namespace net +{ +namespace detail +{ + +inline std::string base64_encode(const std::uint8_t * p, std::size_t n) +{ + static const char tab[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + std::string out; + out.reserve((n + 2) / 3 * 4); + for (std::size_t i = 0; i < n; i += 3) + { + const std::uint32_t a = p[i]; + const std::uint32_t b = i + 1 < n ? p[i + 1] : 0; + const std::uint32_t c = i + 2 < n ? p[i + 2] : 0; + const std::uint32_t v = (a << 16) | (b << 8) | c; + out += tab[(v >> 18) & 63]; + out += tab[(v >> 12) & 63]; + out += i + 1 < n ? tab[(v >> 6) & 63] : '='; + out += i + 2 < n ? tab[v & 63] : '='; + } + return out; +} + +/// @brief Strict base64 (standard alphabet, padded). Returns false on any +/// malformed input. +inline bool base64_decode(const std::string & s, std::string & out) +{ + auto val = [](char ch) -> int { + if (ch >= 'A' && ch <= 'Z') + return ch - 'A'; + if (ch >= 'a' && ch <= 'z') + return ch - 'a' + 26; + if (ch >= '0' && ch <= '9') + return ch - '0' + 52; + if (ch == '+') + return 62; + if (ch == '/') + return 63; + return -1; + }; + out.clear(); + if (s.size() % 4 != 0) + return false; + for (std::size_t i = 0; i < s.size(); i += 4) + { + const bool last = i + 4 == s.size(); + int v[4]; + for (int k = 0; k < 4; ++k) + { + const char ch = s[i + k]; + if (ch == '=' && last && k >= 2) + v[k] = -2; + else + v[k] = val(ch); + if (v[k] == -1) + return false; + } + if (v[0] < 0 || v[1] < 0 || (v[2] == -2 && v[3] != -2)) + return false; + const std::uint32_t x = (static_cast(v[0]) << 18) + | (static_cast(v[1]) << 12) + | (static_cast(v[2] < 0 ? 0 : v[2]) << 6) + | static_cast(v[3] < 0 ? 0 : v[3]); + out += static_cast((x >> 16) & 0xff); + if (v[2] >= 0) + out += static_cast((x >> 8) & 0xff); + if (v[3] >= 0) + out += static_cast(x & 0xff); + } + return true; +} + +/// @brief First line of `path` that is neither blank nor a `#` comment. +inline std::string first_key_line(const std::string & path, const char * what) +{ + std::ifstream in(path); + if (!in) + throw std::runtime_error(std::string(what) + ": cannot read '" + path + "'"); + std::string line; + while (std::getline(in, line)) + { + while (!line.empty() + && (line.back() == '\r' || line.back() == ' ' || line.back() == '\t')) + line.pop_back(); + std::size_t b = 0; + while (b < line.size() && (line[b] == ' ' || line[b] == '\t')) + ++b; + line.erase(0, b); + if (!line.empty() && line[0] != '#') + return line; + } + throw std::runtime_error(std::string(what) + ": '" + path + "' holds no key"); +} + +#if DPF_HAS_OPENSSL +inline std::string openssl_error(const char * what) +{ + std::string out = what; + unsigned long e = 0; + bool first = true; + while ((e = ERR_get_error()) != 0) + { + char buf[256]; + ERR_error_string_n(e, buf, sizeof(buf)); + out += first ? ": " : "; "; + out += buf; + first = false; + } + return out; +} + +struct pkey_free +{ + void operator()(EVP_PKEY * k) const noexcept { EVP_PKEY_free(k); } +}; +struct x509_free +{ + void operator()(X509 * x) const noexcept { X509_free(x); } +}; +#endif + +} // namespace detail + +/// @brief A party's raw Ed25519 public key. +struct public_key +{ + static constexpr std::size_t size = 32; + std::array bytes{}; + + /// @brief 44 characters of base64. + std::string base64() const { return detail::base64_encode(bytes.data(), size); } + + /// @brief Parse base64, or read a public-key file given as `file:PATH`. + static public_key parse(const std::string & text) + { + std::string s = text; + if (s.rfind("file:", 0) == 0) + s = detail::first_key_line(s.substr(5), "public key"); + std::string raw; + if (!detail::base64_decode(s, raw) || raw.size() != size) + throw std::invalid_argument("public key must be 32 bytes of base64 " + "(44 characters), got '" + s + "'"); + public_key k; + std::memcpy(k.bytes.data(), raw.data(), size); + return k; + } + + friend bool operator==(const public_key & a, const public_key & b) noexcept + { + return a.bytes == b.bytes; + } + friend bool operator!=(const public_key & a, const public_key & b) noexcept + { + return !(a == b); + } +}; + +/// @brief A party's private key plus the self-signed certificate TLS presents. +/// @details Copies share the key. Without OpenSSL every constructor throws. +class identity +{ +public: + /// @brief A fresh random key. + static identity generate() + { +#if DPF_HAS_OPENSSL + std::uint8_t seed[32]; + if (RAND_bytes(seed, sizeof(seed)) != 1) + throw std::runtime_error(detail::openssl_error("identity: RAND_bytes")); + auto id = from_seed(seed); + OPENSSL_cleanse(seed, sizeof(seed)); + return id; +#else + throw std::logic_error("identity: built without OpenSSL"); +#endif + } + + /// @brief The key whose private seed is `seed`. + static identity from_seed(const std::uint8_t * seed, const char * cn = "libdpf party") + { +#if DPF_HAS_OPENSSL + identity id; + EVP_PKEY * k = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, nullptr, seed, 32); + if (k == nullptr) + throw std::runtime_error(detail::openssl_error("identity: bad Ed25519 seed")); + id.key_.reset(k, detail::pkey_free{}); + std::size_t n = public_key::size; + if (EVP_PKEY_get_raw_public_key(k, id.pub_.bytes.data(), &n) != 1 + || n != public_key::size) + throw std::runtime_error(detail::openssl_error("identity: public key")); + id.cert_ = self_signed(k, cn); + return id; +#else + (void)seed; + (void)cn; + throw std::logic_error("identity: built without OpenSSL"); +#endif + } + + /// @brief Read a key file (one base64 line holding the 32-byte seed). + /// @details Warns when the file is readable by group or others. + static identity load(const std::string & path) + { + std::string raw; + const auto line = detail::first_key_line(path, "identity"); + if (!detail::base64_decode(line, raw) || raw.size() != 32) + throw std::invalid_argument("identity: '" + path + + "' is not a key file (expected 32 bytes of base64)"); + struct stat st{}; + if (::stat(path.c_str(), &st) == 0 && (st.st_mode & 077) != 0) + DPF_LOG(warning, "security.key_file_mode").kv("path", path) + .kv("detail", "identity key file is readable by group or others; " + "chmod 600 it"); + auto id = from_seed(reinterpret_cast(raw.data())); + std::fill(raw.begin(), raw.end(), '\0'); + return id; + } + + /// @brief The fixed development identity. Its private key is in this + /// source file, so it authenticates nothing. + static const identity & development() + { + static const identity dev = [] { +#if DPF_HAS_OPENSSL + static const char phrase[] = + "libdpf development identity (public; provides no security)"; + std::uint8_t seed[32]; + unsigned int n = sizeof(seed); + if (EVP_Digest(phrase, sizeof(phrase) - 1, seed, &n, EVP_sha256(), nullptr) + != 1) + throw std::runtime_error(detail::openssl_error("identity: digest")); + auto id = from_seed(seed, "libdpf development certificate (no security)"); + id.development_ = true; + return id; +#else + return identity(); +#endif + }(); + if (!dev.key_) + throw std::logic_error("identity: built without OpenSSL"); + return dev; + } + + /// @brief Write the private seed to a new file with mode 0600. Refuses to + /// replace an existing file unless `overwrite`. + void save(const std::string & path, bool overwrite = false) const + { +#if DPF_HAS_OPENSSL + std::uint8_t seed[32]; + std::size_t n = sizeof(seed); + if (!key_ || EVP_PKEY_get_raw_private_key(key_.get(), seed, &n) != 1 || n != 32) + throw std::runtime_error(detail::openssl_error("identity: private key")); + const std::string text = "# libdpf identity key (private; keep mode 600)\n" + + detail::base64_encode(seed, sizeof(seed)) + "\n"; + OPENSSL_cleanse(seed, sizeof(seed)); + const int flags = O_WRONLY | O_CREAT | O_CLOEXEC | (overwrite ? O_TRUNC : O_EXCL); + const int fd = ::open(path.c_str(), flags, 0600); + if (fd < 0) + throw std::runtime_error("identity: cannot create '" + path + "': " + + std::strerror(errno)); + const bool ok = ::fchmod(fd, 0600) == 0 + && ::write(fd, text.data(), text.size()) == static_cast(text.size()); + ::close(fd); + if (!ok) + throw std::runtime_error("identity: cannot write '" + path + "'"); +#else + (void)path; + (void)overwrite; + throw std::logic_error("identity: built without OpenSSL"); +#endif + } + + const public_key & key() const noexcept { return pub_; } + bool is_development() const noexcept { return development_; } + +#if DPF_HAS_OPENSSL + EVP_PKEY * pkey() const noexcept { return key_.get(); } + X509 * cert() const noexcept { return cert_.get(); } +#endif + +private: + identity() = default; + +#if DPF_HAS_OPENSSL + static std::shared_ptr self_signed(EVP_PKEY * k, const char * cn) + { + std::shared_ptr x(X509_new(), detail::x509_free{}); + if (!x) + throw std::runtime_error(detail::openssl_error("identity: X509_new")); + std::uint8_t serial[8]; + if (RAND_bytes(serial, sizeof(serial)) != 1) + throw std::runtime_error(detail::openssl_error("identity: serial")); + std::uint64_t s = 0; + for (auto b : serial) + s = (s << 8) | b; + s &= 0x7fffffffffffffffull; + bool ok = X509_set_version(x.get(), 2) == 1 + && ASN1_INTEGER_set_uint64(X509_get_serialNumber(x.get()), s) == 1 + && X509_gmtime_adj(X509_getm_notBefore(x.get()), -86400) != nullptr + && X509_time_adj_ex(X509_getm_notAfter(x.get()), 36500, 0, nullptr) != nullptr + && X509_set_pubkey(x.get(), k) == 1; + X509_NAME * name = X509_get_subject_name(x.get()); + ok = ok && name != nullptr + && X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + reinterpret_cast(cn), -1, -1, 0) + == 1 + && X509_set_issuer_name(x.get(), name) == 1 + && X509_sign(x.get(), k, nullptr) > 0; + if (!ok) + throw std::runtime_error(detail::openssl_error("identity: certificate")); + return x; + } + + std::shared_ptr key_; + std::shared_ptr cert_; +#else + std::shared_ptr key_; +#endif + public_key pub_{}; + bool development_ = false; +}; + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_IDENTITY_HPP__ diff --git a/include/dpf/net/io_pool.hpp b/include/dpf/net/io_pool.hpp new file mode 100644 index 0000000..3d5cbd2 --- /dev/null +++ b/include/dpf/net/io_pool.hpp @@ -0,0 +1,88 @@ +/// @file dpf/net/io_pool.hpp +/// @brief Socket completion threads and a separate compute pool. +/// @details `context()` is run by `io_threads` workers (0 = hardware +/// concurrency). `post_compute` runs on `compute_threads` workers +/// (0 = same as io), so a DPF evaluation never occupies a thread that +/// should be completing reads and writes. Shutdown stops socket I/O +/// first, then joins compute. +#ifndef LIBDPF_INCLUDE_DPF_NET_IO_POOL_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_IO_POOL_HPP__ + +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" +#include + +namespace dpf +{ +namespace net +{ + +class io_pool +{ +public: + explicit io_pool(std::size_t io_threads = 0, std::size_t compute_threads = 0) + : work_(asio::make_work_guard(io_)), + compute_n_(pick(compute_threads == 0 ? io_threads : compute_threads)), + compute_(compute_n_) + { + const std::size_t n = pick(io_threads); + threads_.reserve(n); + for (std::size_t i = 0; i < n; ++i) + threads_.emplace_back([this] { io_.run(); }); + } + + io_pool(const io_pool &) = delete; + io_pool & operator=(const io_pool &) = delete; + + ~io_pool() + { + work_.reset(); + io_.stop(); + for (auto & t : threads_) + if (t.joinable()) + t.join(); + compute_.join(); + } + + asio::io_context & context() noexcept { return io_; } + std::size_t size() const noexcept { return threads_.size(); } + std::size_t compute_size() const noexcept { return compute_n_; } + + /// @brief Run `fn` on a socket worker. + template + void post(Fn && fn) + { + asio::post(io_, std::forward(fn)); + } + + /// @brief Run `fn` on the compute pool, leaving socket workers free. + template + void post_compute(Fn && fn) + { + asio::post(compute_, std::forward(fn)); + } + +private: + static std::size_t pick(std::size_t n) + { + if (n != 0) + return n; + const auto hw = std::thread::hardware_concurrency(); + return hw == 0 ? 1 : hw; + } + + asio::io_context io_; + asio::executor_work_guard work_; + std::size_t compute_n_ = 1; + asio::thread_pool compute_; + std::vector threads_; +}; + +} // namespace net +} // namespace dpf + +#endif diff --git a/include/dpf/net/link_log.hpp b/include/dpf/net/link_log.hpp new file mode 100644 index 0000000..f542e92 --- /dev/null +++ b/include/dpf/net/link_log.hpp @@ -0,0 +1,161 @@ +/// @file dpf/net/link_log.hpp +/// @brief Run-log records for listeners and established party links. +/// @details `log_link_up` is called once per socket after the handshake and +/// after the stream array has adopted and tuned it, so the socket +/// options it reads back are the ones the kernel applied (Linux +/// doubles `SO_SNDBUF`/`SO_RCVBUF` and clamps them to `wmem_max` and +/// `rmem_max`). `TCP_INFO` at that point carries the kernel's RTT +/// estimate from the connection setup and the handshake exchange. +/// Encrypted links record the TLS version and cipher, how this side +/// authenticated the peer (`auth=key` or `none`), the peer's key, and +/// whether the peer authenticated this side. With encryption off the +/// record says `auth=none encryption=none`, and the first plaintext +/// link to an address off this host also raises one warning. +#ifndef LIBDPF_INCLUDE_DPF_NET_LINK_LOG_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_LINK_LOG_HPP__ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "dpf/log.hpp" +#include "dpf/net/policy.hpp" +#include "dpf/net/security.hpp" + +namespace dpf +{ +namespace net +{ +namespace detail +{ + +inline std::string sockaddr_text(const sockaddr_storage & ss) +{ + char host[INET6_ADDRSTRLEN] = {}; + if (ss.ss_family == AF_INET) + { + const auto & a = reinterpret_cast(ss); + if (::inet_ntop(AF_INET, &a.sin_addr, host, sizeof(host)) == nullptr) + return "unknown"; + return std::string(host) + ":" + std::to_string(ntohs(a.sin_port)); + } + if (ss.ss_family == AF_INET6) + { + const auto & a = reinterpret_cast(ss); + if (::inet_ntop(AF_INET6, &a.sin6_addr, host, sizeof(host)) == nullptr) + return "unknown"; + return "[" + std::string(host) + "]:" + std::to_string(ntohs(a.sin6_port)); + } + if (ss.ss_family == AF_UNIX) + { + const auto & a = reinterpret_cast(ss); + return std::string("unix:") + (a.sun_path[0] != '\0' ? a.sun_path : "(unnamed)"); + } + return "unknown"; +} + +inline bool loopback(const sockaddr_storage & ss) +{ + if (ss.ss_family == AF_INET) + return (ntohl(reinterpret_cast(ss).sin_addr.s_addr) >> 24) + == 127u; + if (ss.ss_family == AF_INET6) + { + const auto & a = reinterpret_cast(ss).sin6_addr; + if (IN6_IS_ADDR_LOOPBACK(&a)) + return true; + return IN6_IS_ADDR_V4MAPPED(&a) && a.s6_addr[12] == 127; + } + return ss.ss_family == AF_UNIX; +} + +inline int int_opt(int fd, int level, int name) +{ + int v = -1; + socklen_t len = sizeof(v); + if (::getsockopt(fd, level, name, &v, &len) != 0) + return -1; + return v; +} + +} // namespace detail + +/// @brief Record a listener: this process accepts any address on `port`. +/// @param encrypted whether connections on it must complete TLS 1.3 first +inline void log_listen(unsigned short port, bool sctp, bool encrypted = false) +{ + DPF_LOG(info, "listen").kv("addr", "0.0.0.0").kv("port", port) + .kv("tcp", true).kv("sctp", sctp) + .kv("encryption", encrypted ? "tls1.3" : "none"); +} + +/// @brief Record one established socket of a party link. +/// @param how `accept` or `connect` +/// @param peer the other end's role (`p1`, `dealer`, ...) +/// @param lane which socket of a `parallel` link (0 otherwise) +/// @param sec how the link was secured (null or unencrypted: plaintext) +inline void log_link_up(const char * how, const std::string & peer, transport kind, + std::size_t lanes, std::uint32_t lane, std::uint32_t epoch, int fd, + const socket_options & requested, const link_security * sec = nullptr) +{ + const bool encrypted = sec != nullptr && sec->encrypted; + if (!log::enabled(log::level::info) || fd < 0) + return; + sockaddr_storage local{}; + sockaddr_storage remote{}; + socklen_t local_len = sizeof(local); + socklen_t remote_len = sizeof(remote); + const bool have_local = + ::getsockname(fd, reinterpret_cast(&local), &local_len) == 0; + const bool have_remote = + ::getpeername(fd, reinterpret_cast(&remote), &remote_len) == 0; + { + log::record rec(log::level::info, "link.up"); + rec.kv("how", how).kv("peer", peer).kv("transport", transport_name(kind)) + .kv("lanes", lanes).kv("lane", lane).kv("epoch", epoch) + .kv("local", have_local ? detail::sockaddr_text(local) : std::string("unknown")) + .kv("remote", have_remote ? detail::sockaddr_text(remote) : std::string("unknown")) + .kv("auth", encrypted ? sec->peer_auth : std::string("none")) + .kv("encryption", + encrypted ? sec->protocol + "/" + sec->cipher : std::string("none")); + if (encrypted) + rec.kv("peer_key", sec->peer_key ? sec->peer_key->base64() : std::string("none")) + .kv("peer_verified_us", sec->peer_verified_us); + if (kind != transport::sctp) + { + rec.kv("nodelay", detail::int_opt(fd, IPPROTO_TCP, TCP_NODELAY)) + .kv("quickack_req", requested.quickack) + .kv("keepalive", detail::int_opt(fd, SOL_SOCKET, SO_KEEPALIVE)) + .kv("sndbuf_req", requested.send_buffer) + .kv("sndbuf", detail::int_opt(fd, SOL_SOCKET, SO_SNDBUF)) + .kv("rcvbuf_req", requested.recv_buffer) + .kv("rcvbuf", detail::int_opt(fd, SOL_SOCKET, SO_RCVBUF)); +#if defined(TCP_INFO) + tcp_info ti{}; + socklen_t ti_len = sizeof(ti); + if (::getsockopt(fd, IPPROTO_TCP, TCP_INFO, &ti, &ti_len) == 0) + rec.kv("rtt_us", ti.tcpi_rtt).kv("rttvar_us", ti.tcpi_rttvar) + .kv("pmtu", ti.tcpi_pmtu).kv("snd_mss", ti.tcpi_snd_mss) + .kv("snd_cwnd", ti.tcpi_snd_cwnd) + .kv("retrans", ti.tcpi_total_retrans); +#endif + } + } + if (!encrypted && have_remote && !detail::loopback(remote) + && log::first_time("net.plaintext_remote")) + DPF_LOG(warning, "link.plaintext").kv("remote", detail::sockaddr_text(remote)) + .kv("detail", "encryption is off: this party link is unauthenticated " + "and unencrypted, and the handshake's party id is not verified"); +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_LINK_LOG_HPP__ diff --git a/include/dpf/net/memory_sink.hpp b/include/dpf/net/memory_sink.hpp new file mode 100644 index 0000000..ce54233 --- /dev/null +++ b/include/dpf/net/memory_sink.hpp @@ -0,0 +1,179 @@ +/// @file dpf/net/memory_sink.hpp +/// @brief In-process paired RoundSink for correctness tests. +#ifndef LIBDPF_INCLUDE_DPF_NET_MEMORY_SINK_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_MEMORY_SINK_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/round_sink.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Shared state between the two ends of a memory sink pair. +struct memory_sink_hub +{ + std::size_t count = 0; + std::vector slot_bytes; + std::vector a; + std::vector b; + mutable std::mutex mu; + + explicit memory_sink_hub(std::size_t n, std::vector slots) + : count(n), slot_bytes(std::move(slots)) + { + a.reserve(slot_bytes.size()); + b.reserve(slot_bytes.size()); + for (std::size_t sb : slot_bytes) + { + a.emplace_back(count, sb); + b.emplace_back(count, sb); + } + } +}; + +/// @brief One end of a memory-paired RoundSink. +class memory_sink : public RoundSink +{ +public: + memory_sink(std::shared_ptr hub, bool side_a) + : hub_(std::move(hub)), side_a_(side_a) + { + if (!hub_) + throw std::invalid_argument("memory_sink needs a hub"); + } + + std::size_t count() const noexcept override { return hub_->count; } + std::size_t rounds() const noexcept override + { + return hub_->slot_bytes.size(); + } + + std::size_t slot_bytes(std::uint16_t round) const override + { + if (round >= hub_->slot_bytes.size()) + throw std::out_of_range("memory_sink round"); + return hub_->slot_bytes[round]; + } + + void submit(std::uint16_t round, std::size_t index, + const std::uint8_t * bytes, std::size_t n) override + { + std::lock_guard lock(hub_->mu); + mine(round).submit(index, bytes, n); + } + + bool peer_ready(std::uint16_t round, std::size_t index) const override + { + std::lock_guard lock(hub_->mu); + return mine(round).peer_ready(index); + } + + void read_peer(std::uint16_t round, std::size_t index, std::uint8_t * out, + std::size_t n) const override + { + std::lock_guard lock(hub_->mu); + mine(round).read_peer(index, out, n); + } + + void flush() override + { + std::lock_guard lock(hub_->mu); + flush_unlocked(); + } + + void flush_round(std::uint16_t round) override + { + std::lock_guard lock(hub_->mu); + flush_round_unlocked(round); + } + + void poll() override {} + +private: + void flush_unlocked() + { + for (std::uint16_t r = 0; r < hub_->slot_bytes.size(); ++r) + { + std::size_t begin = 0; + std::size_t n = 0; + mine(r).pending_out(begin, n); + if (n != 0) + { + flush_round_unlocked(r); + continue; + } + peer(r).pending_out(begin, n); + if (n != 0) + flush_round_unlocked(r); + } + } + + void flush_round_unlocked(std::uint16_t round) + { + if (round >= hub_->slot_bytes.size()) + throw std::out_of_range("memory_sink flush_round"); + auto & local = mine(round); + auto & remote = peer(round); + std::size_t begin_l = 0; + std::size_t n_l = 0; + const std::uint8_t * pend_l = local.pending_out(begin_l, n_l); + std::size_t begin_r = 0; + std::size_t n_r = 0; + const std::uint8_t * pend_r = remote.pending_out(begin_r, n_r); + if (n_l != 0) + { + remote.accept_peer_at(begin_l, pend_l, n_l); + local.mark_flushed(n_l); + } + if (n_r != 0) + { + local.accept_peer_at(begin_r, pend_r, n_r); + remote.mark_flushed(n_r); + } + } + round_window & mine(std::uint16_t round) + { + if (round >= hub_->slot_bytes.size()) + throw std::out_of_range("memory_sink round"); + return side_a_ ? hub_->a[round] : hub_->b[round]; + } + + const round_window & mine(std::uint16_t round) const + { + if (round >= hub_->slot_bytes.size()) + throw std::out_of_range("memory_sink round"); + return side_a_ ? hub_->a[round] : hub_->b[round]; + } + + round_window & peer(std::uint16_t round) + { + if (round >= hub_->slot_bytes.size()) + throw std::out_of_range("memory_sink round"); + return side_a_ ? hub_->b[round] : hub_->a[round]; + } + + std::shared_ptr hub_; + bool side_a_ = true; +}; + +/// @brief Build a connected pair of memory sinks that share one hub. +inline std::pair make_memory_sink_pair( + std::size_t count, std::vector slot_bytes) +{ + auto hub = std::make_shared(count, std::move(slot_bytes)); + return {memory_sink(hub, true), memory_sink(hub, false)}; +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_MEMORY_SINK_HPP__ diff --git a/include/dpf/net/mesh_rendezvous.hpp b/include/dpf/net/mesh_rendezvous.hpp new file mode 100644 index 0000000..56d3d57 --- /dev/null +++ b/include/dpf/net/mesh_rendezvous.hpp @@ -0,0 +1,28 @@ +/// @file dpf/net/mesh_rendezvous.hpp +/// @brief Shared in-process port table for party clique joins. +#ifndef LIBDPF_INCLUDE_DPF_NET_MESH_RENDEZVOUS_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_MESH_RENDEZVOUS_HPP__ + +#include +#include + +namespace dpf +{ +namespace net +{ + +/// @brief Shared port table: `ports[i]` is party `i`'s listen port (0 until bound). +using mesh_ports = std::vector>; + +inline mesh_ports make_mesh_ports(unsigned n) +{ + mesh_ports ports(n); + for (auto & p : ports) + p.store(0); + return ports; +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_MESH_RENDEZVOUS_HPP__ diff --git a/include/dpf/net/mux_sink.hpp b/include/dpf/net/mux_sink.hpp new file mode 100644 index 0000000..5c67d7a --- /dev/null +++ b/include/dpf/net/mux_sink.hpp @@ -0,0 +1,269 @@ +/// @file dpf/net/mux_sink.hpp +/// @brief RoundSink multiplexed on one framed trio channel. +#ifndef LIBDPF_INCLUDE_DPF_NET_MUX_SINK_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_MUX_SINK_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/channel.hpp" +#include "dpf/net/comm_hook.hpp" +#include "dpf/net/round_sink.hpp" +#include "dpf/net/trio.hpp" + +namespace dpf +{ +namespace net +{ + +#pragma pack(push, 1) +struct round_batch_hdr +{ + std::uint16_t round = 0; + std::uint32_t begin = 0; + std::uint32_t count = 0; +}; +#pragma pack(pop) + +/// @brief Prefix-flush RoundSink over a single duplex `channel`. +/// @details Each flush sends one `msg::round_batch` frame per round that has +/// a new contiguous prefix: header `(round, begin, count)` then +/// `count * slot_bytes` payload. The peer's matching frames are +/// read in the same flush (lower role sends first). +class mux_sink : public RoundSink +{ +public: + mux_sink(channel & link, unsigned self_id, unsigned peer_id, + std::size_t count, std::vector slot_bytes) + : link_(link), + self_id_(self_id), + peer_id_(peer_id), + count_(count), + slot_bytes_(std::move(slot_bytes)) + { + windows_.reserve(slot_bytes_.size()); + for (std::size_t sb : slot_bytes_) + windows_.emplace_back(count_, sb); + } + + std::size_t count() const noexcept override { return count_; } + std::size_t rounds() const noexcept override { return slot_bytes_.size(); } + + std::size_t slot_bytes(std::uint16_t round) const override + { + if (round >= slot_bytes_.size()) + throw std::out_of_range("mux_sink round"); + return slot_bytes_[round]; + } + + void submit(std::uint16_t round, std::size_t index, + const std::uint8_t * bytes, std::size_t n) override + { + window(round).submit(index, bytes, n); + } + + bool peer_ready(std::uint16_t round, std::size_t index) const override + { + return window(round).peer_ready(index); + } + + void read_peer(std::uint16_t round, std::size_t index, std::uint8_t * out, + std::size_t n) const override + { + window(round).read_peer(index, out, n); + } + + void flush() override + { + std::vector payload; + for (std::uint16_t r = 0; r < slot_bytes_.size(); ++r) + append_pending(r, payload); + exchange_payload(payload); + } + + void flush_round(std::uint16_t round) override + { + if (round >= slot_bytes_.size()) + throw std::out_of_range("mux_sink flush_round"); + std::vector payload; + append_pending(round, payload); + exchange_payload(payload); + } + + void poll() override {} + + std::uint64_t exchanges() const noexcept { return link_exchanges_; } + +private: + round_window & window(std::uint16_t round) + { + if (round >= windows_.size()) + throw std::out_of_range("mux_sink round"); + return windows_[round]; + } + + const round_window & window(std::uint16_t round) const + { + if (round >= windows_.size()) + throw std::out_of_range("mux_sink round"); + return windows_[round]; + } + + void append_pending(std::uint16_t r, std::vector & payload) + { + std::size_t begin = 0; + std::size_t nslots = 0; + const std::uint8_t * pending = windows_[r].pending_out(begin, nslots); + if (nslots == 0) + return; + round_batch_hdr hdr{}; + hdr.round = r; + hdr.begin = static_cast(begin); + hdr.count = static_cast(nslots); + const std::size_t body = nslots * slot_bytes_[r]; + const std::size_t old = payload.size(); + payload.resize(old + sizeof(hdr) + body); + std::memcpy(payload.data() + old, &hdr, sizeof(hdr)); + if (body != 0) + std::memcpy(payload.data() + old + sizeof(hdr), pending, body); + windows_[r].mark_flushed(nslots); + } + + void exchange_payload(const std::vector & payload) + { + // Always exchange so a party with nothing new still receives. + std::vector theirs; + if (self_id_ < peer_id_) + { + link_.send_bytes(msg::round_batch, payload); + theirs = link_.recv_bytes(msg::round_batch); + } + else if (self_id_ > peer_id_) + { + theirs = link_.recv_bytes(msg::round_batch); + link_.send_bytes(msg::round_batch, payload); + } + else + throw std::invalid_argument("mux_sink flush with self"); + ++link_exchanges_; + ingest(theirs); + } + + void ingest(const std::vector & bytes) + { + std::size_t off = 0; + while (off < bytes.size()) + { + if (off + sizeof(round_batch_hdr) > bytes.size()) + throw std::runtime_error("mux_sink truncated header"); + round_batch_hdr hdr{}; + std::memcpy(&hdr, bytes.data() + off, sizeof(hdr)); + off += sizeof(hdr); + if (hdr.round >= slot_bytes_.size()) + throw std::runtime_error("mux_sink bad round"); + const std::size_t body = + static_cast(hdr.count) * slot_bytes_[hdr.round]; + if (off + body > bytes.size()) + throw std::runtime_error("mux_sink truncated body"); + windows_[hdr.round].accept_peer_at(hdr.begin, bytes.data() + off, + hdr.count); + off += body; + } + } + + channel & link_; + unsigned self_id_ = 0; + unsigned peer_id_ = 0; + std::size_t count_ = 0; + std::vector slot_bytes_; + std::vector windows_; + std::uint64_t link_exchanges_ = 0; +}; + +/// @brief Bind a mux sink to the p0–p1 link of an existing trio. +inline mux_sink make_mux_sink(trio & net, std::size_t count, + std::vector slot_bytes) +{ + const role self = net.self(); + if (self == role::p2) + throw std::logic_error("mux_sink is for computing parties"); + const role peer = self == role::p0 ? role::p1 : role::p0; + return mux_sink(net.to(peer), to_u(self), to_u(peer), count, + std::move(slot_bytes)); +} + +/// @brief Default `comm_hook`: framed mesh channels and a mux batch sink. +/// @details Subclass to reroute selected calls; leave the rest to these +/// defaults. Installing this hook is equivalent to a null hook for +/// framing, but lets overrides replace individual methods. +class mesh_comm_hook : public comm_hook +{ +public: + void send_bytes(trio & net, unsigned peer_id, msg tag, const void * data, + std::size_t n) override + { + net.to(static_cast(peer_id)).send_bytes(tag, data, n); + } + + std::vector recv_bytes(trio & net, unsigned peer_id, + msg tag) override + { + return net.to(static_cast(peer_id)).recv_bytes(tag); + } + + std::vector exchange_bytes(trio & net, unsigned peer_id, + msg tag, const void * data, std::size_t n) override + { + auto & link = net.to(static_cast(peer_id)); + const unsigned self_id = to_u(net.self()); + std::vector theirs(n); + if (self_id < peer_id) + { + link.send_bytes(tag, data, n); + theirs = link.recv_bytes(tag); + } + else if (self_id > peer_id) + { + theirs = link.recv_bytes(tag); + link.send_bytes(tag, data, n); + } + else + throw std::invalid_argument("mesh_comm_hook exchange with self"); + if (theirs.size() != n) + throw std::runtime_error("mesh_comm_hook exchange size"); + return theirs; + } + + std::vector exchange_vec_bytes(trio & net, unsigned peer_id, + msg tag, const void * data, std::size_t nbytes) override + { + return exchange_bytes(net, peer_id, tag, data, nbytes); + } + + std::unique_ptr batch(trio & net, std::size_t count, + std::vector slot_bytes) override + { + return std::make_unique(make_mux_sink(net, count, + std::move(slot_bytes))); + } +}; + +inline std::unique_ptr trio::batch(std::size_t count, + std::vector slot_bytes) +{ + if (hook_) + return hook_->batch(*this, count, std::move(slot_bytes)); + return std::make_unique(make_mux_sink(*this, count, + std::move(slot_bytes))); +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_MUX_SINK_HPP__ diff --git a/include/dpf/net/party_session.hpp b/include/dpf/net/party_session.hpp new file mode 100644 index 0000000..305b6ec --- /dev/null +++ b/include/dpf/net/party_session.hpp @@ -0,0 +1,1171 @@ +/// @file dpf/net/party_session.hpp +/// @brief One role's TCP/SCTP session: join, per-edge transport, dealer, reconnect. +/// @details Socket edges run TLS 1.3 unless `session_options::security.encrypt` +/// is off (see `dpf/net/security.hpp`): each side presents its +/// identity key and authenticates the peer only if it holds that +/// peer's key, so authentication can run in one direction, both, or +/// neither; every unauthenticated direction is logged. After the TLS +/// handshake (or directly, with encryption off) both ends exchange a +/// fixed record (party id, epoch, transport, lane count, lane index, +/// and whether the sender authenticated the receiver) under a +/// deadline, so two ends that disagree fail at connect time with a +/// message instead of corrupting frames later. Lower ids accept, +/// higher ids connect; connects retry until the peer listens, so +/// processes may start in any order. `join(table)` takes a static +/// `host:port` table (separate processes); `join(host, ports)` is the +/// in-process rendezvous. `reconnect(peer)` replaces one edge and +/// returns the new link; `reconnector(peer)` adapts it for +/// `sink_options::reconnect`. The dealer link has its own policy, +/// `io_context`, epoch, and reconnect. SCTP edges cannot be encrypted +/// and are refused while encryption is on. +#ifndef LIBDPF_INCLUDE_DPF_NET_PARTY_SESSION_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_PARTY_SESSION_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/log.hpp" +#include "dpf/net/async_sctp_stream_array.hpp" +#include "dpf/net/async_stream_array.hpp" +#include "dpf/net/connect.hpp" +#include "dpf/net/identity.hpp" +#include "dpf/net/link_log.hpp" +#include "dpf/net/policy.hpp" +#include "dpf/net/security.hpp" +#include "dpf/net/mesh_rendezvous.hpp" +#include "dpf/net/socket_tune.hpp" +#include "dpf/net/tls.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Where one party listens. +struct peer_address +{ + std::string host = "127.0.0.1"; + unsigned short port = 0; +}; + +/// @brief Session-wide defaults. Per-edge overrides live on `party_session`. +struct session_options +{ + std::size_t n_lanes = 1; + transport kind = transport::mux; + wire_policy policy{}; + deadlines limits{}; + peer_security security{}; +}; + +namespace detail +{ + +struct session_hello +{ + static constexpr std::uint32_t magic = 0x53535044u; // 'DPSS' + static constexpr std::size_t size = 28; + /// The sender authenticated the receiver's key. + static constexpr std::uint32_t verified_you = 1; + + std::uint32_t id = 0; + std::uint32_t epoch = 0; + std::uint32_t kind = 0; + std::uint32_t lanes = 0; + std::uint32_t lane = 0; + std::uint32_t flags = 0; + + void pack(std::uint8_t * p) const + { + put_u32(p, magic); + put_u32(p + 4, id); + put_u32(p + 8, epoch); + put_u32(p + 12, kind); + put_u32(p + 16, lanes); + put_u32(p + 20, lane); + put_u32(p + 24, flags); + } + + static session_hello unpack(const std::uint8_t * p) + { + if (p[0] == 0x16 && p[1] == 0x03) + throw std::runtime_error("party_session: the peer started a TLS handshake " + "but this side has encryption off (set encryption the same at both " + "ends)"); + if (get_u32(p) != magic) + throw std::runtime_error( + "party_session: peer is not a party_session (bad handshake magic)"); + session_hello h; + h.id = get_u32(p + 4); + h.epoch = get_u32(p + 8); + h.kind = get_u32(p + 12); + h.lanes = get_u32(p + 16); + h.lane = get_u32(p + 20); + h.flags = get_u32(p + 24); + return h; + } +}; + +inline std::string id_name(std::uint32_t id) +{ + return id == 0xfffffffeu ? std::string("dealer") : "party " + std::to_string(id); +} + +inline std::string role_name(std::uint32_t id) +{ + return id == 0xfffffffeu ? std::string("dealer") : "p" + std::to_string(id); +} + +/// @brief One TCP connection on its way into a link: plain, or TLS once the +/// handshake is done. +struct peer_conn +{ + explicit peer_conn(asio::ip::tcp::socket s) + : plain(std::move(s)), fd(plain.native_handle()) + { + } + + asio::ip::tcp::socket plain; +#if DPF_HAS_OPENSSL + std::unique_ptr tls; +#endif + int fd = -1; + link_security sec; + + bool encrypted() const noexcept + { +#if DPF_HAS_OPENSSL + return static_cast(tls); +#else + return false; +#endif + } +}; + +inline std::chrono::milliseconds left(setup_clock::time_point deadline) +{ + return std::chrono::milliseconds(std::max(1, remaining_ms(deadline))); +} + +#if DPF_HAS_OPENSSL +using peer_tls_context = tls_context; +#else +struct peer_tls_context +{ +}; +#endif + +/// @brief Tune `c` (TCP_NODELAY first: the handshake is several round trips), +/// then run the TLS handshake when `ctx` is set. +inline void secure(peer_conn & c, asio::io_context & io, peer_tls_context * ctx, + bool server, const socket_options & so, std::chrono::milliseconds budget, + const std::string & who) +{ + tune_tcp(c.plain, so); + if (ctx == nullptr) + return; +#if DPF_HAS_OPENSSL + c.tls = std::make_unique(std::move(c.plain), *ctx); + try + { + tls_handshake(io, *c.tls, server, budget, who); + } + catch (const std::system_error & e) + { + throw std::runtime_error(std::string(e.what()) + + " (if the peer has encryption off, set it the same at both ends)"); + } + c.sec = tls_describe(*c.tls); +#else + (void)io; + (void)server; + (void)budget; + (void)who; +#endif +} + +inline void send_hello(peer_conn & c, asio::io_context & io, const session_hello & h, + setup_clock::time_point deadline, const std::string & what) +{ + std::uint8_t out[session_hello::size]; + h.pack(out); +#if DPF_HAS_OPENSSL + if (c.tls) + { + tls_write(io, *c.tls, out, sizeof(out), left(deadline), what); + return; + } +#endif + (void)io; + send_all_until(c.plain.native_handle(), out, sizeof(out), deadline, what); +} + +inline session_hello recv_hello(peer_conn & c, asio::io_context & io, + setup_clock::time_point deadline, const std::string & what) +{ + std::uint8_t in[session_hello::size]; +#if DPF_HAS_OPENSSL + if (c.tls) + { + tls_read(io, *c.tls, in, sizeof(in), left(deadline), what); + return session_hello::unpack(in); + } +#endif + (void)io; + recv_all_until(c.plain.native_handle(), in, sizeof(in), deadline, what); + return session_hello::unpack(in); +} + +/// @brief Authenticate `party` on an encrypted connection (no-op when plain). +inline void check_party(peer_conn & c, const peer_security & policy, + std::uint32_t party, const std::string & who) +{ +#if DPF_HAS_OPENSSL + if (c.encrypted()) + { + try + { + check_peer(c.sec, policy, party, who); + } + catch (...) + { + std::error_code e; + c.tls->lowest_layer().close(e); + throw; + } + } +#else + (void)c; + (void)policy; + (void)party; + (void)who; +#endif +} + +inline std::unique_ptr mux_link(asio::io_context & io, + peer_conn & c, unsigned self, unsigned peer, std::size_t lanes, + const wire_policy & pol) +{ +#if DPF_HAS_OPENSSL + if (c.tls) + return std::make_unique(io, std::move(*c.tls), self, + peer, lanes, pol); +#endif + return std::make_unique(io, std::move(c.plain), self, peer, + lanes, pol); +} + +inline std::unique_ptr parallel_link(asio::io_context & io, + std::vector> & cs, const wire_policy & pol) +{ +#if DPF_HAS_OPENSSL + if (cs.front()->tls) + { + std::vector v; + v.reserve(cs.size()); + for (auto & c : cs) + v.push_back(std::move(*c->tls)); + return std::make_unique(io, std::move(v), pol); + } +#endif + std::vector v; + v.reserve(cs.size()); + for (auto & c : cs) + v.push_back(std::move(c->plain)); + return std::make_unique(io, std::move(v), pol); +} + +/// @brief This process's key for party links, or a fresh one (logged). +inline std::shared_ptr link_identity(const peer_security & sec, + const std::string & who) +{ + if (sec.self) + { + DPF_LOG(info, "security.identity").kv("who", who) + .kv("key", sec.self->key().base64()).kv("ephemeral", false) + .kv("trusted", sec.trusted.size()); + return sec.self; + } + auto id = std::make_shared(identity::generate()); + DPF_LOG(info, "security.identity").kv("who", who).kv("key", id->key().base64()) + .kv("ephemeral", true).kv("trusted", sec.trusted.size()); + if (log::first_time("security.no_identity." + log::role() + "." + who)) + DPF_LOG(warning, "security.no_identity").kv("who", who) + .kv("detail", "no identity key configured: links are encrypted to a fresh " + "key for this run, so peers cannot authenticate " + who); + return id; +} + +/// @brief Log a link direction this side could not authenticate. +inline void note_link(const std::string & peer_role, const link_security & sec) +{ + if (!sec.encrypted) + return; + const std::string me = log::role().empty() ? std::string("this party") : log::role(); + if (sec.peer_auth == "none" + && log::first_time("security.unauthenticated." + me + "." + peer_role)) + DPF_LOG(warning, "security.unauthenticated").kv("peer", peer_role) + .kv("peer_key", sec.peer_key ? sec.peer_key->base64() : std::string("none")) + .kv("detail", "no key configured for " + peer_role + ": the link is " + "encrypted but " + peer_role + " is not authenticated"); + if (!sec.peer_verified_us + && log::first_time("security.not_authenticated_by." + me + "." + peer_role)) + DPF_LOG(info, "security.not_authenticated_by_peer").kv("peer", peer_role) + .kv("detail", peer_role + " holds no key for " + me); +} + +} // namespace detail + +class party_session +{ +public: + static constexpr unsigned k_dealer_id = dealer_id; + + party_session(asio::io_context & io, unsigned me, unsigned parties, + session_options opt) + : io_(&io), + dealer_io_(&io), + me_(me), + parties_(parties), + opt_(std::move(opt)) + { + if (parties_ < 2 || me_ >= parties_) + throw std::invalid_argument("party_session: party/n"); + if (opt_.n_lanes == 0) + throw std::invalid_argument("party_session: n_lanes 0"); + opt_.policy.validate(); + links_.resize(parties_); + sec_.resize(parties_); + table_.resize(parties_); + epoch_.assign(parties_, 0); + kind_.assign(parties_, opt_.kind); + policy_.assign(parties_, opt_.policy); + dealer_policy_ = opt_.policy; + if (opt_.security.encrypt) + { + refuse_sctp(opt_.kind); +#if DPF_HAS_OPENSSL + self_ = detail::link_identity(opt_.security, "p" + std::to_string(me_)); + tls_ = make_peer_tls_context(*self_); +#else + throw std::logic_error("party_session: built without OpenSSL; set " + "encryption=off for plaintext links"); +#endif + } + } + + party_session(asio::io_context & io, unsigned me, unsigned parties, + std::size_t nstreams) + : party_session(io, me, parties, make_opts(nstreams)) + { + } + + unsigned me() const noexcept { return me_; } + unsigned parties() const noexcept { return parties_; } + std::size_t streams() const noexcept { return opt_.n_lanes; } + asio::io_context & context() noexcept { return *io_; } + const session_options & options() const noexcept { return opt_; } + + /// @brief This party's link key (null with encryption off). + std::shared_ptr identity_key() const noexcept { return self_; } + + // --- configuration (before join, both ends must agree) --------------- + + void set_edge_transport(unsigned peer, transport t) + { + check_peer(peer); + if (t != transport::mux && t != transport::parallel && t != transport::sctp) + throw std::invalid_argument(std::string("party_session: transport ") + + transport_name(t) + " is not a socket edge"); + if (t == transport::sctp && !sctp_available()) + throw std::logic_error("party_session: SCTP needs Linux + libsctp"); + if (opt_.security.encrypt) + refuse_sctp(t); + kind_[peer] = t; + } + + transport edge_transport(unsigned peer) const + { + check_peer(peer); + return kind_[peer]; + } + + void set_edge_policy(unsigned peer, const wire_policy & pol) + { + check_peer(peer); + pol.validate(); + policy_[peer] = pol; + if (links_[peer]) + links_[peer]->set_window_bytes(pol.window_bytes); + } + + /// @brief Window for every edge and the dealer link, now and later. + void set_window_bytes(std::size_t bytes) + { + for (auto & p : policy_) + p.window_bytes = bytes; + dealer_policy_.window_bytes = bytes; + for (auto & link : links_) + if (link) + link->set_window_bytes(bytes); + if (dealer_) + dealer_->set_window_bytes(bytes); + } + + void set_dealer_policy(const wire_policy & pol) + { + pol.validate(); + dealer_policy_ = pol; + if (dealer_) + dealer_->set_window_bytes(pol.window_bytes); + } + + /// @brief Run the dealer link on its own `io_context` (own failure domain). + void set_dealer_context(asio::io_context & io) { dealer_io_ = &io; } + + void set_deadlines(const deadlines & d) { opt_.limits = d; } + + // --- listen / join --------------------------------------------------- + + /// @brief Bind TCP (and SCTP if any edge uses it) on `port`; 0 = ephemeral. + unsigned short listen(unsigned short port = 0) + { + if (!acceptor_) + { + acceptor_ = std::make_unique(*io_); + open_listener(*acceptor_, port); + published_ = acceptor_->local_endpoint().port(); + log_listen(published_, wants_sctp(), opt_.security.encrypt); + } + if (!sctp_ && wants_sctp()) + sctp_ = std::make_unique(published_, opt_.n_lanes, + opt_.policy.socket); + return published_; + } + + unsigned short port() const noexcept { return published_; } + + /// @brief Join with a static table: `table[i]` is party `i`'s address. + void join(const std::vector & table) + { + if (table.size() != parties_) + throw std::invalid_argument("party_session::join: table has " + + std::to_string(table.size()) + " entries, expected " + + std::to_string(parties_)); + table_ = table; + listen(table_[me_].port); + accept_higher(); + for (unsigned peer = 0; peer < me_; ++peer) + connect_edge(peer); + } + + /// @brief In-process rendezvous through shared `ports` (tests, one binary). + void join(const std::string & host, mesh_ports & ports, std::size_t n_lanes = 0) + { + if (ports.size() != parties_) + throw std::invalid_argument("party_session::join port table"); + if (n_lanes != 0) + opt_.n_lanes = n_lanes; + ports[me_].store(listen(ports[me_].load())); + const auto deadline = setup_clock::now() + opt_.limits.join; + std::vector table(parties_); + for (unsigned i = 0; i < parties_; ++i) + { + while (ports[i].load() == 0) + { + if (setup_clock::now() >= deadline) + throw std::runtime_error("party_session: join timed out after " + + std::to_string(opt_.limits.join.count()) + + " ms waiting for party " + std::to_string(i)); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + table[i] = peer_address{host, ports[i].load()}; + } + join(table); + } + + // --- edges ----------------------------------------------------------- + + async_stream_array & peer(unsigned p) + { + check_peer(p); + if (!links_[p]) + throw std::logic_error("party_session: no link to party " + + std::to_string(p) + " (join first)"); + return *links_[p]; + } + + stream_stats edge_stats(unsigned p) const + { + check_peer(p); + return links_[p] ? links_[p]->stats() : stream_stats{}; + } + + /// @brief How the edge to `p` was secured (encryption, cipher, who + /// authenticated whom). + const link_security & edge_security(unsigned p) const + { + check_peer(p); + return sec_[p]; + } + + std::uint32_t epoch(unsigned p) const + { + check_peer(p); + return epoch_[p]; + } + + /// @brief Replace the edge to `peer` and return it. Both ends must call. + async_stream_array & reconnect(unsigned peer) + { + check_peer(peer); + if (table_[peer].port == 0 && me_ > peer) + throw std::logic_error("party_session::reconnect before join"); + links_[peer].reset(); + ++epoch_[peer]; + if (me_ < peer) + accept_one_edge(peer); + else + connect_edge(peer); + return *links_[peer]; + } + + /// @brief `sink_options::reconnect` for the edge to `peer`. + std::function reconnector( + unsigned peer) + { + return [this, peer](const std::error_code &) { return &reconnect(peer); }; + } + + // --- dealer ---------------------------------------------------------- + + /// @brief Party side: connect to the dealer at `host:port`. + void connect_dealer(const std::string & host, unsigned short port) + { + dealer_addr_ = peer_address{host, port}; + const std::string who = "dealer at " + host + ":" + std::to_string(port); + asio::ip::tcp::socket sock(*dealer_io_); + connect_until(sock, host, port, opt_.limits.connect); + detail::peer_conn c(std::move(sock)); + const auto deadline = setup_clock::now() + opt_.limits.handshake; + detail::secure(c, *dealer_io_, tls_ptr(), false, dealer_policy_.socket, + opt_.limits.handshake, "handshake with " + who); + detail::check_party(c, opt_.security, k_dealer_id, who); + auto mine = dealer_hello(me_); + mine.flags = c.sec.peer_auth == "key" ? detail::session_hello::verified_you : 0; + detail::send_hello(c, *dealer_io_, mine, deadline, "dealer handshake"); + const auto got = detail::recv_hello(c, *dealer_io_, deadline, "dealer handshake"); + if (got.id != k_dealer_id) + throw std::runtime_error("party_session: " + host + ":" + + std::to_string(port) + " is " + detail::id_name(got.id) + + ", not the dealer"); + check_match(got, mine, "dealer"); + c.sec.peer_verified_us = (got.flags & detail::session_hello::verified_you) != 0; + dealer_sec_ = c.sec; + dealer_ = detail::mux_link(*dealer_io_, c, me_, k_dealer_id, opt_.n_lanes, + dealer_policy_); + log_link_up("connect", "dealer", transport::mux, opt_.n_lanes, 0, + dealer_epoch_, c.fd, dealer_policy_.socket, &dealer_sec_); + detail::note_link("dealer", dealer_sec_); + } + + /// @brief Dealer side of a one-party dealer link (see `dealer_session` + /// for a dealer serving several parties). + void accept_dealer() + { + listen(published_); + asio::ip::tcp::socket sock(*dealer_io_); + accept_until(*acceptor_, sock, opt_.limits.accept); + detail::peer_conn c(std::move(sock)); + const auto deadline = setup_clock::now() + opt_.limits.handshake; + detail::secure(c, *dealer_io_, tls_ptr(), true, dealer_policy_.socket, + opt_.limits.handshake, "dealer handshake"); + const auto got = detail::recv_hello(c, *dealer_io_, deadline, "dealer handshake"); + detail::check_party(c, opt_.security, got.id, detail::id_name(got.id)); + auto mine = dealer_hello(k_dealer_id); + mine.flags = c.sec.peer_auth == "key" ? detail::session_hello::verified_you : 0; + detail::send_hello(c, *dealer_io_, mine, deadline, "dealer handshake"); + check_match(got, mine, "dealer"); + c.sec.peer_verified_us = (got.flags & detail::session_hello::verified_you) != 0; + dealer_is_server_ = true; + dealer_sec_ = c.sec; + dealer_ = detail::mux_link(*dealer_io_, c, k_dealer_id, got.id, opt_.n_lanes, + dealer_policy_); + log_link_up("accept", detail::role_name(got.id), transport::mux, opt_.n_lanes, + 0, dealer_epoch_, c.fd, dealer_policy_.socket, &dealer_sec_); + detail::note_link(detail::role_name(got.id), dealer_sec_); + } + + /// @brief Replace the dealer link (both ends must call). + async_stream_array & reconnect_dealer() + { + dealer_.reset(); + ++dealer_epoch_; + if (dealer_is_server_) + accept_dealer(); + else + connect_dealer(dealer_addr_.host, dealer_addr_.port); + return *dealer_; + } + + std::function + dealer_reconnector() + { + return [this](const std::error_code &) { return &reconnect_dealer(); }; + } + + bool has_dealer() const noexcept { return static_cast(dealer_); } + + async_stream_array & dealer() + { + if (!dealer_) + throw std::logic_error("party_session: no dealer link"); + return *dealer_; + } + + stream_stats dealer_stats() const + { + return dealer_ ? dealer_->stats() : stream_stats{}; + } + + const link_security & dealer_security() const noexcept { return dealer_sec_; } + +private: + static session_options make_opts(std::size_t nstreams) + { + session_options o; + o.n_lanes = nstreams; + return o; + } + + static void refuse_sctp(transport t) + { + if (t == transport::sctp) + throw std::invalid_argument("party_session: SCTP links cannot be " + "encrypted (OpenSSL has no TLS over SCTP streams); use mux or " + "parallel, or set encryption=off"); + } + + detail::peer_tls_context * tls_ptr() const noexcept + { +#if DPF_HAS_OPENSSL + return tls_.get(); +#else + return nullptr; +#endif + } + + detail::session_hello dealer_hello(std::uint32_t id) const + { + detail::session_hello h; + h.id = id; + h.epoch = dealer_epoch_; + h.kind = static_cast(transport::mux); + h.lanes = static_cast(opt_.n_lanes); + return h; + } + + void check_peer(unsigned p) const + { + if (p == me_ || p >= parties_) + throw std::invalid_argument("party_session: bad peer " + + std::to_string(p)); + } + + bool wants_sctp() const + { + for (unsigned p = 0; p < parties_; ++p) + if (p != me_ && kind_[p] == transport::sctp) + return true; + return false; + } + + std::size_t sockets_for(unsigned peer) const + { + return kind_[peer] == transport::parallel ? opt_.n_lanes : 1; + } + + detail::session_hello my_hello(unsigned peer, std::uint32_t lane) const + { + detail::session_hello h; + h.id = me_; + h.epoch = epoch_[peer]; + h.kind = static_cast(kind_[peer]); + h.lanes = static_cast(opt_.n_lanes); + h.lane = lane; + return h; + } + + void check_match(const detail::session_hello & got, + const detail::session_hello & mine, const std::string & who) const + { + std::string why; + if (got.kind != mine.kind) + why += std::string(" transport ") + + transport_name(static_cast(got.kind)) + " vs " + + transport_name(static_cast(mine.kind)) + ";"; + if (got.lanes != mine.lanes) + why += " lanes " + std::to_string(got.lanes) + " vs " + + std::to_string(mine.lanes) + ";"; + if (got.epoch != mine.epoch) + why += " epoch " + std::to_string(got.epoch) + " vs " + + std::to_string(mine.epoch) + ";"; + if (!why.empty()) + throw std::runtime_error("party_session: " + who + + " disagrees (peer vs this side):" + why); + } + + struct parallel_in_progress + { + std::vector> conns; + std::size_t got = 0; + }; + + /// @brief Accept every edge from higher-numbered parties, in any order, + /// on the TCP and SCTP listeners at once. + void accept_higher() + { + std::size_t tcp_left = 0; + std::size_t sctp_left = 0; + for (unsigned p = me_ + 1; p < parties_; ++p) + { + if (kind_[p] == transport::sctp) + ++sctp_left; + else + tcp_left += sockets_for(p); + } + std::map partial; + const auto deadline = setup_clock::now() + opt_.limits.accept; + while (tcp_left + sctp_left > 0) + { + pollfd pfds[2]{}; + int nfds = 0; + if (tcp_left > 0) + { + pfds[nfds].fd = acceptor_->native_handle(); + pfds[nfds].events = POLLIN; + ++nfds; + } + if (sctp_left > 0) + { + pfds[nfds].fd = sctp_fd(); + pfds[nfds].events = POLLIN; + ++nfds; + } + const int ms = detail::remaining_ms(deadline); + if (ms == 0) + throw std::system_error(std::make_error_code(std::errc::timed_out), + "party_session " + std::to_string(me_) + ": accept timed out " + "after " + std::to_string(opt_.limits.accept.count()) + + " ms (" + std::to_string(tcp_left + sctp_left) + + " connections missing)"); + const int rc = ::poll(pfds, static_cast(nfds), ms); + if (rc <= 0) + continue; + for (int k = 0; k < nfds; ++k) + { + if ((pfds[k].revents & POLLIN) == 0) + continue; + if (tcp_left > 0 && pfds[k].fd == acceptor_->native_handle()) + { + asio::ip::tcp::socket sock(*io_); + acceptor_->accept(sock); + accept_tcp(std::move(sock), partial, false, 0); + --tcp_left; + } + else if (sctp_left > 0) + { + accept_sctp(0, false); + --sctp_left; + } + } + } + } + + int sctp_fd() const { return sctp_ ? sctp_->native_handle() : -1; } + + void accept_tcp(asio::ip::tcp::socket sock, + std::map & partial, bool expect_one, + unsigned expect) + { + auto c = std::make_unique(std::move(sock)); + const auto deadline = setup_clock::now() + opt_.limits.handshake; + detail::secure(*c, *io_, tls_ptr(), true, opt_.policy.socket, + opt_.limits.handshake, "party_session " + std::to_string(me_) + " handshake"); + // The accepting side answers with the record for the announced peer. + const auto theirs = detail::recv_hello(*c, *io_, deadline, + "party_session handshake"); + const unsigned p = theirs.id; + if (p <= me_ || p >= parties_ || (expect_one && p != expect)) + throw std::runtime_error("party_session " + std::to_string(me_) + + ": unexpected connection from " + detail::id_name(p)); + detail::check_party(*c, opt_.security, p, "party " + std::to_string(p)); + auto mine = my_hello(p, theirs.lane); + mine.flags = c->sec.peer_auth == "key" ? detail::session_hello::verified_you : 0; + detail::send_hello(*c, *io_, mine, deadline, "party_session handshake"); + check_match(theirs, mine, "party " + std::to_string(p)); + c->sec.peer_verified_us = (theirs.flags & detail::session_hello::verified_you) != 0; + const std::string role = "p" + std::to_string(p); + if (kind_[p] == transport::mux) + { + if (links_[p]) + throw std::runtime_error("party_session: duplicate edge from party " + + std::to_string(p)); + sec_[p] = c->sec; + links_[p] = detail::mux_link(*io_, *c, me_, p, opt_.n_lanes, policy_[p]); + log_link_up("accept", role, kind_[p], opt_.n_lanes, 0, epoch_[p], c->fd, + policy_[p].socket, &sec_[p]); + detail::note_link(role, sec_[p]); + return; + } + auto & pp = partial[p]; + if (pp.conns.empty()) + pp.conns.resize(opt_.n_lanes); + if (theirs.lane >= opt_.n_lanes || pp.conns[theirs.lane]) + throw std::runtime_error("party_session: bad parallel lane " + + std::to_string(theirs.lane) + " from party " + std::to_string(p)); + pp.conns[theirs.lane] = std::move(c); + if (++pp.got == opt_.n_lanes) + adopt_parallel(p, pp.conns, "accept"); + if (pp.got == opt_.n_lanes) + partial.erase(p); + } + + /// @brief Build a parallel link from one connection per lane. + void adopt_parallel(unsigned p, std::vector> & cs, + const char * how) + { + std::vector fds; + std::vector secs; + for (auto & c : cs) + { + fds.push_back(c->fd); + secs.push_back(c->sec); + } + sec_[p] = secs.front(); + for (const auto & s : secs) + sec_[p].peer_verified_us = sec_[p].peer_verified_us && s.peer_verified_us; + links_[p] = detail::parallel_link(*io_, cs, policy_[p]); + const std::string role = "p" + std::to_string(p); + for (std::size_t k = 0; k < fds.size(); ++k) + log_link_up(how, role, kind_[p], opt_.n_lanes, static_cast(k), + epoch_[p], fds[k], policy_[p].socket, &secs[k]); + detail::note_link(role, sec_[p]); + } + + void accept_sctp(unsigned expect, bool expect_one) + { + const int fd = sctp_->accept(opt_.limits.accept); + std::uint8_t in[detail::session_hello::size]; + const auto deadline = setup_clock::now() + opt_.limits.handshake; + try + { + detail::recv_all_until(fd, in, sizeof(in), deadline, + "party_session sctp handshake"); + const auto theirs = detail::session_hello::unpack(in); + const unsigned p = theirs.id; + if (p <= me_ || p >= parties_ || (expect_one && p != expect)) + throw std::runtime_error("party_session: unexpected SCTP " + "association from " + detail::id_name(p)); + const auto mine = my_hello(p, 0); + std::uint8_t out[detail::session_hello::size]; + mine.pack(out); + detail::send_all_until(fd, out, sizeof(out), deadline, + "party_session sctp handshake"); + check_match(theirs, mine, "party " + std::to_string(p)); + sec_[p] = link_security{}; + links_[p] = std::make_unique(*io_, fd, + opt_.n_lanes, policy_[p]); + log_link_up("accept", "p" + std::to_string(p), transport::sctp, + opt_.n_lanes, 0, epoch_[p], fd, policy_[p].socket); + } + catch (...) + { + ::close(fd); + throw; + } + } + + void accept_one_edge(unsigned peer) + { + listen(published_); + if (kind_[peer] == transport::sctp) + { + accept_sctp(peer, true); + return; + } + std::map partial; + for (std::size_t k = 0; k < sockets_for(peer); ++k) + { + asio::ip::tcp::socket sock(*io_); + accept_until(*acceptor_, sock, opt_.limits.accept); + accept_tcp(std::move(sock), partial, true, peer); + } + } + + void connect_edge(unsigned peer) + { + const auto & addr = table_[peer]; + if (addr.port == 0) + throw std::logic_error("party_session: no address for party " + + std::to_string(peer)); + const std::string who = "party " + std::to_string(peer) + " at " + + addr.host + ":" + std::to_string(addr.port); + if (kind_[peer] == transport::sctp) + { + const int fd = connect_sctp(addr.host, addr.port, opt_.n_lanes, + opt_.limits.connect, policy_[peer].socket); + try + { + const auto mine = my_hello(peer, 0); + std::uint8_t out[detail::session_hello::size]; + std::uint8_t in[detail::session_hello::size]; + mine.pack(out); + exchange_record(fd, out, in, detail::session_hello::size, + opt_.limits.handshake, "sctp handshake with " + who); + const auto got = detail::session_hello::unpack(in); + if (got.id != peer) + throw std::runtime_error("party_session: " + who + " is " + + detail::id_name(got.id)); + check_match(got, mine, who); + sec_[peer] = link_security{}; + links_[peer] = std::make_unique(*io_, fd, + opt_.n_lanes, policy_[peer]); + log_link_up("connect", "p" + std::to_string(peer), transport::sctp, + opt_.n_lanes, 0, epoch_[peer], fd, policy_[peer].socket); + } + catch (...) + { + ::close(fd); + throw; + } + return; + } + std::vector> conns; + for (std::size_t k = 0; k < sockets_for(peer); ++k) + { + asio::ip::tcp::socket sock(*io_); + connect_until(sock, addr.host, addr.port, opt_.limits.connect); + auto c = std::make_unique(std::move(sock)); + const auto deadline = setup_clock::now() + opt_.limits.handshake; + detail::secure(*c, *io_, tls_ptr(), false, policy_[peer].socket, + opt_.limits.handshake, "handshake with " + who); + detail::check_party(*c, opt_.security, peer, who); + auto mine = my_hello(peer, static_cast(k)); + mine.flags = + c->sec.peer_auth == "key" ? detail::session_hello::verified_you : 0; + detail::send_hello(*c, *io_, mine, deadline, "handshake with " + who); + const auto got = detail::recv_hello(*c, *io_, deadline, + "handshake with " + who); + if (got.id != peer) + throw std::runtime_error("party_session: " + who + " is " + + detail::id_name(got.id)); + check_match(got, mine, who); + c->sec.peer_verified_us = (got.flags & detail::session_hello::verified_you) != 0; + conns.push_back(std::move(c)); + } + if (kind_[peer] == transport::mux) + { + auto & c = *conns.front(); + sec_[peer] = c.sec; + links_[peer] = detail::mux_link(*io_, c, me_, peer, opt_.n_lanes, + policy_[peer]); + const std::string role = "p" + std::to_string(peer); + log_link_up("connect", role, kind_[peer], opt_.n_lanes, 0, epoch_[peer], + c.fd, policy_[peer].socket, &sec_[peer]); + detail::note_link(role, sec_[peer]); + } + else + adopt_parallel(peer, conns, "connect"); + } + + asio::io_context * io_ = nullptr; + asio::io_context * dealer_io_ = nullptr; + unsigned me_ = 0; + unsigned parties_ = 0; + session_options opt_; + std::shared_ptr self_; +#if DPF_HAS_OPENSSL + std::shared_ptr tls_; +#endif + unsigned short published_ = 0; + std::vector table_; + std::vector epoch_; + std::vector kind_; + std::vector policy_; + std::unique_ptr acceptor_; + std::unique_ptr sctp_; + std::vector sec_; + std::vector> links_; + std::unique_ptr dealer_; + link_security dealer_sec_{}; + wire_policy dealer_policy_{}; + peer_address dealer_addr_{}; + std::uint32_t dealer_epoch_ = 0; + bool dealer_is_server_ = false; +}; + +/// @brief Dealer serving several parties, each on its own link and epoch. +/// @details Links are encrypted like party links; the dealer authenticates a +/// party whose key is in `opt.security.trusted[p]`. +class dealer_session +{ +public: + dealer_session(asio::io_context & io, unsigned served, session_options opt = {}) + : io_(&io), served_(served), opt_(std::move(opt)) + { + if (served == 0) + throw std::invalid_argument("dealer_session: serves no party"); + opt_.policy.validate(); + links_.resize(served); + sec_.resize(served); + epoch_.assign(served, 0); + if (opt_.security.encrypt) + { +#if DPF_HAS_OPENSSL + self_ = detail::link_identity(opt_.security, "dealer"); + tls_ = make_peer_tls_context(*self_); +#else + throw std::logic_error("dealer_session: built without OpenSSL; set " + "encryption=off for plaintext links"); +#endif + } + } + + unsigned short listen(unsigned short port = 0) + { + if (!acceptor_) + { + acceptor_ = std::make_unique(*io_); + open_listener(*acceptor_, port); + log_listen(acceptor_->local_endpoint().port(), false, opt_.security.encrypt); + } + return acceptor_->local_endpoint().port(); + } + + /// @brief Accept one link from every served party (any order). + void accept_parties() + { + listen(0); + for (unsigned k = 0; k < served_; ++k) + accept_any(false, 0); + } + + async_stream_array & party(unsigned p) + { + check(p); + if (!links_[p]) + throw std::logic_error("dealer_session: no link to party " + + std::to_string(p)); + return *links_[p]; + } + + stream_stats party_stats(unsigned p) const + { + check(p); + return links_[p] ? links_[p]->stats() : stream_stats{}; + } + + const link_security & party_security(unsigned p) const + { + check(p); + return sec_[p]; + } + + std::shared_ptr identity_key() const noexcept { return self_; } + + async_stream_array & reconnect(unsigned p) + { + check(p); + links_[p].reset(); + ++epoch_[p]; + accept_any(true, p); + return *links_[p]; + } + + std::function reconnector( + unsigned p) + { + return [this, p](const std::error_code &) { return &reconnect(p); }; + } + +private: + void check(unsigned p) const + { + if (p >= served_) + throw std::invalid_argument("dealer_session: bad party " + + std::to_string(p)); + } + + void accept_any(bool expect_one, unsigned expect) + { + asio::ip::tcp::socket sock(*io_); + accept_until(*acceptor_, sock, opt_.limits.accept); + detail::peer_conn c(std::move(sock)); + const auto deadline = setup_clock::now() + opt_.limits.handshake; +#if DPF_HAS_OPENSSL + detail::secure(c, *io_, tls_.get(), true, opt_.policy.socket, + opt_.limits.handshake, "dealer handshake"); +#else + detail::secure(c, *io_, nullptr, true, opt_.policy.socket, + opt_.limits.handshake, "dealer handshake"); +#endif + const auto theirs = detail::recv_hello(c, *io_, deadline, "dealer handshake"); + const unsigned p = theirs.id; + if (p >= served_ || (expect_one && p != expect) || (!expect_one && links_[p])) + throw std::runtime_error("dealer_session: unexpected " + + detail::id_name(p)); + detail::check_party(c, opt_.security, p, "party " + std::to_string(p)); + detail::session_hello mine; + mine.id = party_session::k_dealer_id; + mine.epoch = epoch_[p]; + mine.kind = static_cast(transport::mux); + mine.lanes = static_cast(opt_.n_lanes); + mine.flags = c.sec.peer_auth == "key" ? detail::session_hello::verified_you : 0; + detail::send_hello(c, *io_, mine, deadline, "dealer handshake"); + if (theirs.epoch != mine.epoch || theirs.lanes != mine.lanes + || theirs.kind != mine.kind) + throw std::runtime_error("dealer_session: party " + std::to_string(p) + + " disagrees on epoch, lanes, or transport"); + c.sec.peer_verified_us = (theirs.flags & detail::session_hello::verified_you) != 0; + sec_[p] = c.sec; + links_[p] = detail::mux_link(*io_, c, party_session::k_dealer_id, p, + opt_.n_lanes, opt_.policy); + const std::string role = "p" + std::to_string(p); + log_link_up("accept", role, transport::mux, opt_.n_lanes, 0, epoch_[p], c.fd, + opt_.policy.socket, &sec_[p]); + detail::note_link(role, sec_[p]); + } + + asio::io_context * io_ = nullptr; + unsigned served_ = 0; + session_options opt_; + std::shared_ptr self_; +#if DPF_HAS_OPENSSL + std::shared_ptr tls_; +#endif + std::unique_ptr acceptor_; + std::vector sec_; + std::vector> links_; + std::vector epoch_; +}; + +} // namespace net +} // namespace dpf + +#endif diff --git a/include/dpf/net/party_tape_io.hpp b/include/dpf/net/party_tape_io.hpp new file mode 100644 index 0000000..ca9db16 --- /dev/null +++ b/include/dpf/net/party_tape_io.hpp @@ -0,0 +1,217 @@ +/// @file dpf/net/party_tape_io.hpp +/// @brief Deal / accept a `dpf::beavers::party_tape` over a framed channel. +#ifndef LIBDPF_INCLUDE_DPF_NET_PARTY_TAPE_IO_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_PARTY_TAPE_IO_HPP__ + +#include +#include +#include +#include + +#include "dpf/beaver.hpp" +#include "dpf/net/channel.hpp" +#include "dpf/net/trio.hpp" + +namespace dpf +{ +namespace net +{ +namespace detail +{ + +template +void send_ring_vec(channel & c, const std::vector & v) +{ + static_assert(std::is_trivially_copyable_v, + "party_tape ring must be trivially copyable"); + std::uint64_t n = v.size(); + c.send(msg::ring_vector, n); + if (n != 0) + c.send_vec(v.data(), v.size(), msg::ring_vector); +} + +template +std::vector recv_ring_vec(channel & c) +{ + auto n = c.recv(msg::ring_vector); + if (n == 0) + return {}; + return c.recv_vec(msg::ring_vector); +} + +inline void send_flags(channel & c, const std::vector & v) +{ + std::uint64_t n = v.size(); + c.send(msg::bytes, n); + if (n != 0) + c.send_bytes(msg::bytes, v); +} + +inline std::vector recv_flags(channel & c) +{ + auto n = c.recv(msg::bytes); + if (n == 0) + return {}; + auto body = c.recv_bytes(msg::bytes); + if (body.size() != n) + throw std::runtime_error("party_tape flag size mismatch"); + return body; +} + +} // namespace detail + +template +void send_party_tape(channel & c, const beavers::party_tape & tape) +{ + c.send(msg::beaver_tape, std::uint8_t{2}); + c.send(msg::beaver_tape, static_cast(tape.has_mac ? 1 : 0)); + detail::send_ring_vec(c, tape.lambda); + detail::send_flags(c, tape.lambda_ready); + detail::send_ring_vec(c, tape.monomial); + detail::send_flags(c, tape.monomial_ready); + detail::send_ring_vec(c, tape.bundles); + detail::send_flags(c, tape.bundles_ready); + detail::send_ring_vec(c, tape.dot_cross); + detail::send_flags(c, tape.dot_ready); + if (tape.has_mac) + { + detail::send_ring_vec(c, tape.lambda_tag); + detail::send_ring_vec(c, tape.monomial_tag); + detail::send_ring_vec(c, tape.bundles_tag); + detail::send_ring_vec(c, tape.dot_cross_tag); + } +} + +template +beavers::party_tape recv_party_tape(channel & c) +{ + const auto ver = c.recv(msg::beaver_tape); + beavers::party_tape tape; + if (ver >= 2) + tape.has_mac = c.recv(msg::beaver_tape) != 0; + tape.lambda = detail::recv_ring_vec(c); + tape.lambda_ready = detail::recv_flags(c); + tape.monomial = detail::recv_ring_vec(c); + tape.monomial_ready = detail::recv_flags(c); + tape.bundles = detail::recv_ring_vec(c); + tape.bundles_ready = detail::recv_flags(c); + tape.dot_cross = detail::recv_ring_vec(c); + tape.dot_ready = detail::recv_flags(c); + if (tape.has_mac) + { + tape.lambda_tag = detail::recv_ring_vec(c); + tape.monomial_tag = detail::recv_ring_vec(c); + tape.bundles_tag = detail::recv_ring_vec(c); + tape.dot_cross_tag = detail::recv_ring_vec(c); + } + return tape; +} + +/// @brief Dealer exports and sends each party's tape. +/// @tparam Ring Beaver ring +/// @param net the connected trio +/// @param s the sampled session +/// @throws std::logic_error if this process is not p2 +template +void send_party_tape(trio & net, role peer, const beavers::party_tape & tape) +{ + net.send_to(peer, msg::beaver_tape, std::uint8_t{2}); + net.send_to(peer, msg::beaver_tape, + static_cast(tape.has_mac ? 1 : 0)); + auto send_ring_vec = [&](const std::vector & v) { + const std::uint64_t n = v.size(); + net.send_to(peer, msg::ring_vector, n); + if (n != 0) + net.send_vec_to(peer, msg::ring_vector, v); + }; + auto send_flags = [&](const std::vector & v) { + const std::uint64_t n = v.size(); + net.send_to(peer, msg::bytes, n); + if (n != 0) + net.send_bytes_to(peer, msg::bytes, v.data(), v.size()); + }; + send_ring_vec(tape.lambda); + send_flags(tape.lambda_ready); + send_ring_vec(tape.monomial); + send_flags(tape.monomial_ready); + send_ring_vec(tape.bundles); + send_flags(tape.bundles_ready); + send_ring_vec(tape.dot_cross); + send_flags(tape.dot_ready); + if (tape.has_mac) + { + send_ring_vec(tape.lambda_tag); + send_ring_vec(tape.monomial_tag); + send_ring_vec(tape.bundles_tag); + send_ring_vec(tape.dot_cross_tag); + } +} + +template +beavers::party_tape recv_party_tape(trio & net, role peer) +{ + const auto ver = net.recv_from(peer, msg::beaver_tape); + beavers::party_tape tape; + if (ver >= 2) + tape.has_mac = net.recv_from(peer, msg::beaver_tape) != 0; + auto recv_ring_vec = [&]() { + const auto n = net.recv_from(peer, msg::ring_vector); + if (n == 0) + return std::vector{}; + return net.recv_vec_from(peer, msg::ring_vector); + }; + auto recv_flags = [&]() { + const auto n = net.recv_from(peer, msg::bytes); + if (n == 0) + return std::vector{}; + auto body = net.recv_bytes_from(peer, msg::bytes); + if (body.size() != n) + throw std::runtime_error("party_tape flag size mismatch"); + return body; + }; + tape.lambda = recv_ring_vec(); + tape.lambda_ready = recv_flags(); + tape.monomial = recv_ring_vec(); + tape.monomial_ready = recv_flags(); + tape.bundles = recv_ring_vec(); + tape.bundles_ready = recv_flags(); + tape.dot_cross = recv_ring_vec(); + tape.dot_ready = recv_flags(); + if (tape.has_mac) + { + tape.lambda_tag = recv_ring_vec(); + tape.monomial_tag = recv_ring_vec(); + tape.bundles_tag = recv_ring_vec(); + tape.dot_cross_tag = recv_ring_vec(); + } + return tape; +} + +template +void deal_session(trio & net, const beavers::session & s) +{ + if (net.self() != role::p2) + throw std::logic_error("deal_session is for the dealer"); + send_party_tape(net, role::p0, s.export_party(0)); + send_party_tape(net, role::p1, s.export_party(1)); +} + +/// @brief Computing party receives its tape from the dealer. +/// @tparam Ring Beaver ring +/// @param net the connected trio +/// @return this party's tape +/// @throws std::logic_error if this process is p2 +/// @throws std::runtime_error if a flag vector's length disagrees with its header +template +HEDLEY_WARN_UNUSED_RESULT +beavers::party_tape accept_session(trio & net) +{ + if (net.self() == role::p2) + throw std::logic_error("dealer does not accept_session"); + return recv_party_tape(net, role::p2); +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_PARTY_TAPE_IO_HPP__ diff --git a/include/dpf/net/policy.hpp b/include/dpf/net/policy.hpp new file mode 100644 index 0000000..186cb30 --- /dev/null +++ b/include/dpf/net/policy.hpp @@ -0,0 +1,177 @@ +/// @file dpf/net/policy.hpp +/// @brief Explicit transport, framing, socket, window, and deadline policy. +/// @details Library code never reads the environment. Every knob here is a +/// field the caller sets; `app::run_config::from_env` is the one place +/// that turns `DPF_*` variables into these values. +#ifndef LIBDPF_INCLUDE_DPF_NET_POLICY_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_POLICY_HPP__ + +#include +#include +#include +#include +#include + +namespace dpf +{ +namespace net +{ + +/// @brief Which byte transport carries a party-to-party edge. +enum class transport : unsigned char +{ + memory_sink, ///< in-process paired `memory_sink` (no stream arrays) + memory_stream, ///< in-process synchronous `stream_array` + async_memory, ///< in-process event-driven stream array + mux, ///< all lanes on one TCP connection + parallel, ///< one TCP connection per lane + sctp, ///< one SCTP association, lane i = SCTP stream i (Linux) + local ///< one unix-domain socket per lane (same host) +}; + +inline const char * transport_name(transport t) noexcept +{ + switch (t) + { + case transport::memory_sink: + return "memory"; + case transport::memory_stream: + return "stream"; + case transport::async_memory: + return "async"; + case transport::mux: + return "mux"; + case transport::parallel: + return "parallel"; + case transport::sctp: + return "sctp"; + case transport::local: + return "local"; + } + return "async"; +} + +/// @brief Parse a transport name. Unknown names throw. +inline transport parse_transport(const std::string & s) +{ + if (s == "memory") + return transport::memory_sink; + if (s == "stream") + return transport::memory_stream; + if (s == "async" || s == "async_memory") + return transport::async_memory; + if (s == "mux") + return transport::mux; + if (s == "parallel") + return transport::parallel; + if (s == "sctp") + return transport::sctp; + if (s == "local") + return transport::local; + throw std::invalid_argument("unknown transport: " + s + + " (memory|stream|async|mux|parallel|sctp|local)"); +} + +/// @brief True for transports that cross a kernel socket. +inline bool is_socket_transport(transport t) noexcept +{ + return t == transport::mux || t == transport::parallel + || t == transport::sctp || t == transport::local; +} + +/// @brief Whether round payloads on a lane carry a `{round,nbytes}` header. +/// @details `automatic` frames only when rounds outnumber lanes. `always` +/// frames even with one lane per round (to measure the header, or to +/// let partial prefixes and reconnect resume work on every round). +/// `never` requires at least one lane per round. +enum class framing_mode : unsigned char +{ + automatic, + always, + never +}; + +inline const char * framing_name(framing_mode m) noexcept +{ + switch (m) + { + case framing_mode::automatic: + return "auto"; + case framing_mode::always: + return "always"; + case framing_mode::never: + return "never"; + } + return "auto"; +} + +inline framing_mode parse_framing(const std::string & s) +{ + if (s == "auto" || s == "automatic") + return framing_mode::automatic; + if (s == "always" || s == "on") + return framing_mode::always; + if (s == "never" || s == "off") + return framing_mode::never; + throw std::invalid_argument("unknown framing: " + s + " (auto|always|never)"); +} + +/// @brief Options applied to every TCP socket a backend adopts. +/// @details Zero means "leave the kernel default". +struct socket_options +{ + bool no_delay = true; + /// Re-armed after every read and write: Linux clears it after one ACK. + bool quickack = true; + bool keepalive = true; + int keepalive_idle_s = 0; + int keepalive_interval_s = 0; + int keepalive_count = 0; + int send_buffer = 0; + int recv_buffer = 0; +}; + +/// @brief Per-connection wire policy for the async stream backends. +struct wire_policy +{ + /// Outstanding-byte high-water mark per lane (per connection on mux and + /// SCTP, per socket on parallel). `0` is unlimited. + std::size_t window_bytes = std::size_t{1} << 20; + /// Largest frame accepted from the peer. + std::size_t max_frame = std::size_t{16} << 20; + /// Split writes into frames of at most this many payload bytes and + /// round-robin them across lanes. `0` sends each write as one frame. + std::size_t chunk_bytes = std::size_t{64} << 10; + /// Frames and bytes gathered into one write syscall. + std::size_t coalesce_frames = 16; + std::size_t coalesce_bytes = std::size_t{256} << 10; + /// Drop the consumed prefix of an inbox once it passes this many bytes. + std::size_t compact_bytes = std::size_t{64} << 10; + socket_options socket{}; + + void validate() const + { + if (max_frame == 0) + throw std::invalid_argument("wire_policy: max_frame is 0"); + if (chunk_bytes > max_frame) + throw std::invalid_argument( + "wire_policy: chunk_bytes exceeds max_frame"); + if (coalesce_frames == 0) + throw std::invalid_argument("wire_policy: coalesce_frames is 0"); + } +}; + +/// @brief Bounds for session setup and for draining a write window. +struct deadlines +{ + std::chrono::milliseconds join{30000}; + std::chrono::milliseconds connect{30000}; + std::chrono::milliseconds accept{30000}; + std::chrono::milliseconds handshake{30000}; + std::chrono::milliseconds drain{30000}; +}; + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_POLICY_HPP__ diff --git a/include/dpf/net/round_lane.hpp b/include/dpf/net/round_lane.hpp new file mode 100644 index 0000000..05a827c --- /dev/null +++ b/include/dpf/net/round_lane.hpp @@ -0,0 +1,149 @@ +/// @file dpf/net/round_lane.hpp +/// @brief Round→lane mapping and wire framing when rounds share lanes. +/// @details A fixed pool of duplex streams can carry any number of exchange +/// rounds: lane = `round % n_lanes`. A framed lane prefixes each write +/// with a little-endian `{u16 round, u32 nbytes}` header, and the +/// receiver appends those bytes to that round's inbox. Unframed lanes +/// carry one round each (round == lane) with no header. +#ifndef LIBDPF_INCLUDE_DPF_NET_ROUND_LANE_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_ROUND_LANE_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "dpf/net/policy.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief On-wire header for a framed round payload on a shared lane. +struct round_lane_hdr +{ + static constexpr std::size_t size = 6; + + std::uint16_t round = 0; + std::uint32_t nbytes = 0; + + void pack(std::uint8_t * dst) const noexcept + { + dst[0] = static_cast(round & 0xffu); + dst[1] = static_cast((round >> 8) & 0xffu); + dst[2] = static_cast(nbytes & 0xffu); + dst[3] = static_cast((nbytes >> 8) & 0xffu); + dst[4] = static_cast((nbytes >> 16) & 0xffu); + dst[5] = static_cast((nbytes >> 24) & 0xffu); + } + + static round_lane_hdr unpack(const std::uint8_t * src) noexcept + { + round_lane_hdr h; + h.round = static_cast(src[0] | (src[1] << 8)); + h.nbytes = static_cast(src[2] | (src[3] << 8) | + (src[4] << 16) | (src[5] << 24)); + return h; + } +}; + +/// @brief Lane count used when a caller passes `0`. +inline constexpr std::size_t default_lanes = 8; +/// @brief Request one stream per round. +inline constexpr std::size_t lanes_one_per_round = static_cast(-1); +/// @brief Round ids travel as `u16`. +inline constexpr std::size_t max_rounds = 0xffffu; + +/// @brief Streams to open for `n_rounds`. `requested` 0 → `default_lanes`. +inline std::size_t lane_count_for_rounds(std::size_t n_rounds, + std::size_t requested = 0) +{ + if (n_rounds == 0) + return 1; + if (requested == lanes_one_per_round) + return n_rounds; + std::size_t want = requested == 0 ? default_lanes : requested; + if (want > n_rounds) + want = n_rounds; + return want == 0 ? 1 : want; +} + +/// @brief Lane index and whether the wire uses round headers. +struct round_lane_map +{ + std::size_t n_lanes = 1; + std::size_t n_rounds = 0; + bool framed = false; + + round_lane_map() = default; + + round_lane_map(std::size_t streams, std::size_t rounds, + framing_mode mode = framing_mode::automatic) + : n_lanes(streams == 0 ? 1 : streams), + n_rounds(rounds) + { + if (rounds > max_rounds) + throw std::invalid_argument("round_lane_map: " + + std::to_string(rounds) + " rounds exceed the u16 round id"); + switch (mode) + { + case framing_mode::automatic: + framed = rounds > n_lanes; + break; + case framing_mode::always: + framed = true; + break; + case framing_mode::never: + if (rounds > n_lanes) + throw std::invalid_argument("round_lane_map: framing never needs " + "one lane per round (" + std::to_string(rounds) + + " rounds, " + std::to_string(n_lanes) + " lanes)"); + framed = false; + break; + } + } + + std::size_t lane(std::uint16_t round) const + { + if (static_cast(round) >= n_rounds && n_rounds != 0) + throw std::out_of_range("round_lane_map round"); + if (!framed) + return static_cast(round); + return static_cast(round) % n_lanes; + } +}; + +/// @brief Build `hdr || payload` for a framed write. +inline std::vector pack_round_frame(std::uint16_t round, + const std::uint8_t * payload, std::size_t n) +{ + std::vector out(round_lane_hdr::size + n); + round_lane_hdr{round, static_cast(n)}.pack(out.data()); + if (n != 0) + std::memcpy(out.data() + round_lane_hdr::size, payload, n); + return out; +} + +/// @brief FNV-1a over a slot-width vector (plan shape fingerprint). +inline std::uint64_t slots_fingerprint(const std::vector & slots) +{ + std::uint64_t h = 14695981039346656037ull; + for (auto s : slots) + { + std::uint64_t v = static_cast(s); + for (int i = 0; i < 8; ++i) + { + h ^= (v >> (8 * i)) & 0xffu; + h *= 1099511628211ull; + } + } + return h; +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_ROUND_LANE_HPP__ diff --git a/include/dpf/net/round_sink.hpp b/include/dpf/net/round_sink.hpp new file mode 100644 index 0000000..8a91247 --- /dev/null +++ b/include/dpf/net/round_sink.hpp @@ -0,0 +1,238 @@ +/// @file dpf/net/round_sink.hpp +/// @brief Transport for round-batched protocol slots. +/// @details A session submits one slot per `(round, index)`. The sink writes +/// only a contiguous prefix of each round and demuxes the peer's +/// matching prefixes into that round's incoming buffer. Memory, +/// muxed-trio, and per-round stream sinks all implement this. +#ifndef LIBDPF_INCLUDE_DPF_NET_ROUND_SINK_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_ROUND_SINK_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace dpf +{ +namespace net +{ + +/// @brief Byte transport for one round of a count-sized batch. +class RoundSink +{ +public: + virtual ~RoundSink() = default; + + /// @brief How many protocol instances this sink was sized for. + virtual std::size_t count() const noexcept = 0; + + /// @brief How many interactive rounds this sink was sized for. + virtual std::size_t rounds() const noexcept = 0; + + /// @brief Slot width for `round`. Every index of that round uses it. + virtual std::size_t slot_bytes(std::uint16_t round) const = 0; + + /// @brief Store this party's outgoing slot. Index order on the wire is + /// enforced at flush time; submits may arrive out of order. + virtual void submit(std::uint16_t round, std::size_t index, + const std::uint8_t * bytes, std::size_t n) = 0; + + /// @brief True when the peer's slot for `(round, index)` is available. + virtual bool peer_ready(std::uint16_t round, std::size_t index) const = 0; + + /// @brief Copy the peer's slot into `out`. Requires `peer_ready`. + virtual void read_peer(std::uint16_t round, std::size_t index, + std::uint8_t * out, std::size_t n) const = 0; + + /// @brief Send every newly contiguous prefix and pull any peer prefixes. + virtual void flush() = 0; + + /// @brief Flush only `round`'s pending prefix (one barrier on that round). + /// @details `sink_exchange` and bit-AND layers call this so a stream sink + /// does not touch idle round channels. Default falls back to + /// `flush()` for sinks that only implement a global barrier. + virtual void flush_round(std::uint16_t /*round*/) + { + flush(); + } + + /// @brief Service non-blocking I/O. Memory sinks are a no-op. + virtual void poll() = 0; + + /// @brief Block (briefly) until I/O progresses, instead of busy-spinning. + /// @details Drive loops call this while waiting on a peer slot. The default + /// just `poll()`s and reports "no blocking wait happened" (`false`) + /// so existing sinks keep their old behaviour. An event-driven sink + /// (e.g. `async_round_sink`) overrides this to sleep in `epoll` via + /// `io_context::run_one()`, returning `true` when it ran a handler. + /// Returning `false` lets the caller fall back to its spin guard. + virtual bool wait_io() + { + poll(); + return false; + } + + /// @brief Wait up to `budget` for one completion. + /// @details Memory sinks ignore the budget and behave like `wait_io()`. + /// Async sinks sleep in `run_one_for`. + virtual bool wait_io_for(std::chrono::milliseconds) + { + return wait_io(); + } + + /// @brief True when `wait_io_for` sleeps until I/O arrives. Drive loops + /// yield instead of sleeping on sinks that cannot block. + virtual bool can_block() const noexcept { return false; } + + /// @brief False while an outbound window is full; pipelined sends pause. + virtual bool can_send_ahead() const noexcept { return true; } + + /// @brief Monotonic count of receive events (peer bytes plus zero-width + /// round announcements). Drive loops re-check readiness whenever it + /// moves, including when a `poll()` completed the read. + virtual std::uint64_t progress() const noexcept { return 0; } + + /// @brief Sinks that return the same key share one event loop, so blocking + /// in one's `wait_io_for` also completes the others' I/O. + virtual const void * wait_domain() const noexcept { return this; } +}; + +/// @brief Wait until `sink.peer_ready(round, index)`, for at most `budget`. +/// @details Sleeps in the sink's reactor when it can block and yields +/// otherwise, so a slow peer costs no CPU and a dead one fails on +/// time rather than after a spin count. +inline void wait_peer_ready(RoundSink & sink, std::uint16_t round, + std::size_t index, std::chrono::milliseconds budget, const char * what) +{ + const auto start = std::chrono::steady_clock::now(); + while (!sink.peer_ready(round, index)) + { + const auto waited = std::chrono::duration_cast( + std::chrono::steady_clock::now() - start); + if (waited >= budget) + throw std::runtime_error(std::string(what) + ": no peer bytes for " + + std::to_string(waited.count()) + " ms (budget " + + std::to_string(budget.count()) + " ms)"); + if (sink.can_block()) + sink.wait_io_for(std::min(budget - waited, std::chrono::milliseconds(1000))); + else if (!sink.wait_io()) + std::this_thread::yield(); + } +} + +/// @brief One round's local and peer slot storage with prefix-flush cursors. +class round_window +{ +public: + round_window() = default; + + round_window(std::size_t count, std::size_t slot_bytes) + : count_(count), + slot_bytes_(slot_bytes), + written_(count, false), + out_(count * slot_bytes), + in_(count * slot_bytes) + { } + + std::size_t count() const noexcept { return count_; } + std::size_t slot_bytes() const noexcept { return slot_bytes_; } + std::size_t next_unwritten() const noexcept { return next_unwritten_; } + std::size_t peer_filled() const noexcept { return peer_filled_; } + std::size_t flushed() const noexcept { return flushed_; } + + void submit(std::size_t index, const std::uint8_t * bytes, std::size_t n) + { + if (index >= count_) + throw std::out_of_range("round_window submit index"); + if (n != slot_bytes_) + throw std::invalid_argument("round_window submit size"); + if (written_[index]) + throw std::logic_error("round_window double submit"); + std::memcpy(out_.data() + index * slot_bytes_, bytes, n); + written_[index] = true; + while (next_unwritten_ < count_ && written_[next_unwritten_]) + ++next_unwritten_; + } + + bool peer_ready(std::size_t index) const noexcept + { + return index < peer_filled_; + } + + void read_peer(std::size_t index, std::uint8_t * out, std::size_t n) const + { + if (!peer_ready(index)) + throw std::logic_error("round_window peer not ready"); + if (n != slot_bytes_) + throw std::invalid_argument("round_window read size"); + std::memcpy(out, in_.data() + index * slot_bytes_, n); + } + + /// @brief Bytes of the contiguous prefix that have not been flushed yet. + const std::uint8_t * pending_out(std::size_t & begin, std::size_t & nslots) const + { + begin = flushed_; + if (next_unwritten_ <= flushed_) + { + nslots = 0; + return nullptr; + } + nslots = next_unwritten_ - flushed_; + return out_.data() + flushed_ * slot_bytes_; + } + + void mark_flushed(std::size_t nslots) + { + flushed_ += nslots; + if (flushed_ > next_unwritten_) + throw std::logic_error("round_window flushed past written"); + } + + /// @brief Outbound bytes starting at slot `slot` (retained for resends). + const std::uint8_t * out_at(std::size_t slot) const noexcept + { + return out_.data() + slot * slot_bytes_; + } + + /// @brief Append `nslots` peer slots starting at `peer_filled_`. + void accept_peer(const std::uint8_t * bytes, std::size_t nslots) + { + if (peer_filled_ + nslots > count_) + throw std::logic_error("round_window peer overrun"); + if (nslots != 0) + { + std::memcpy(in_.data() + peer_filled_ * slot_bytes_, bytes, + nslots * slot_bytes_); + } + peer_filled_ += nslots; + } + + /// @brief Accept peer slots that begin at an absolute index (mux frames). + void accept_peer_at(std::size_t begin, const std::uint8_t * bytes, + std::size_t nslots) + { + if (begin != peer_filled_) + throw std::logic_error("round_window peer gap"); + accept_peer(bytes, nslots); + } + +private: + std::size_t count_ = 0; + std::size_t slot_bytes_ = 0; + std::size_t next_unwritten_ = 0; + std::size_t flushed_ = 0; + std::size_t peer_filled_ = 0; + std::vector written_; + std::vector out_; + std::vector in_; +}; + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_ROUND_SINK_HPP__ diff --git a/include/dpf/net/secure_channel.hpp b/include/dpf/net/secure_channel.hpp new file mode 100644 index 0000000..51c2838 --- /dev/null +++ b/include/dpf/net/secure_channel.hpp @@ -0,0 +1,177 @@ +/// @file dpf/net/secure_channel.hpp +/// @brief Framed `channel` edges using the same peer TLS policy as `party_session`. +/// @details Mux paths go through `party_session`. Framed APIs (`tcp_pair`, +/// `trio`) keep length/tag framing but run the same `peer_security` +/// defaults: TLS 1.3 when `encrypt` is on, optional per-direction +/// authentication, socket tuning, and link logging. +#ifndef LIBDPF_INCLUDE_DPF_NET_SECURE_CHANNEL_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_SECURE_CHANNEL_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "dpf/log.hpp" +#include "dpf/net/channel.hpp" +#include "dpf/net/identity.hpp" +#include "dpf/net/link_log.hpp" +#include "dpf/net/policy.hpp" +#include "dpf/net/security.hpp" +#include "dpf/net/socket_tune.hpp" +#include "dpf/net/tls.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief This process's key for a party link, or a fresh one (logged). +inline std::shared_ptr resolve_peer_identity( + const peer_security & sec, const std::string & who) +{ + if (sec.self) + { + DPF_LOG(info, "security.identity").kv("who", who) + .kv("key", sec.self->key().base64()).kv("ephemeral", false) + .kv("trusted", sec.trusted.size()); + return sec.self; + } + auto id = std::make_shared(identity::generate()); + DPF_LOG(info, "security.identity").kv("who", who).kv("key", id->key().base64()) + .kv("ephemeral", true).kv("trusted", sec.trusted.size()); + if (log::first_time("security.no_identity." + log::role() + "." + who)) + DPF_LOG(warning, "security.no_identity").kv("who", who) + .kv("detail", "no identity key configured: links are encrypted to a fresh " + "key for this run, so peers cannot authenticate " + who); + return id; +} + +inline void note_channel_security(const std::string & peer_role, + const link_security & sec) +{ + if (!sec.encrypted) + return; + const std::string me = log::role().empty() ? std::string("this party") : log::role(); + if (sec.peer_auth == "none" + && log::first_time("security.unauthenticated." + me + "." + peer_role)) + DPF_LOG(warning, "security.unauthenticated").kv("peer", peer_role) + .kv("peer_key", sec.peer_key ? sec.peer_key->base64() : std::string("none")) + .kv("detail", "no key configured for " + peer_role + ": the link is " + "encrypted but " + peer_role + " is not authenticated"); +} + +/// @brief Adopt a TCP socket as a framed channel under `peer_security`. +inline channel secure_tcp_channel(asio::io_context & io, asio::ip::tcp::socket sock, + bool server, std::uint32_t peer_party, const peer_security & sec = {}, + const socket_options & so = {}, + std::chrono::milliseconds handshake = std::chrono::milliseconds(30000), + const std::string & peer_role = {}, const char * how = "connect") +{ + const std::string who = peer_role.empty() + ? ("party " + std::to_string(peer_party)) + : peer_role; + tune_tcp(sock, so); + if (!sec.encrypt) + { + const int fd = sock.native_handle(); + log_link_up(how, who, transport::mux, 1, 0, 0, fd, so, nullptr); + return channel(std::move(sock)); + } +#if DPF_HAS_OPENSSL + auto self = resolve_peer_identity(sec, log::role().empty() ? "channel" : log::role()); + auto ctx = make_peer_tls_context(*self); + auto tls = std::make_unique(std::move(sock), *ctx); + try + { + tls_handshake(io, *tls, server, handshake, who + " TLS"); + } + catch (const std::system_error & e) + { + throw std::runtime_error(std::string(e.what()) + + " (if the peer has encryption off, set it the same at both ends)"); + } + link_security desc = tls_describe(*tls); + try + { + check_peer(desc, sec, peer_party, who); + } + catch (...) + { + std::error_code e; + tls->lowest_layer().close(e); + throw; + } + note_channel_security(who, desc); + const int fd = tls->lowest_layer().native_handle(); + log_link_up(how, who, transport::mux, 1, 0, 0, fd, so, &desc); + return channel::from_tls(io, std::move(*tls), std::move(ctx)); +#else + (void)io; + (void)server; + (void)handshake; + (void)how; + throw std::logic_error("secure_tcp_channel: built without OpenSSL; set " + "encryption=off for plaintext links"); +#endif +} + +#if DPF_HAS_OPENSSL +/// @brief Adopt a unix-domain socket under the same peer TLS policy. +inline channel secure_local_channel(asio::io_context & io, + asio::local::stream_protocol::socket sock, bool server, + std::uint32_t peer_party, const peer_security & sec = {}, + std::chrono::milliseconds handshake = std::chrono::milliseconds(30000), + const std::string & peer_role = {}, const char * how = "connect") +{ + const std::string who = peer_role.empty() + ? ("party " + std::to_string(peer_party)) + : peer_role; + if (!sec.encrypt) + return channel(std::move(sock)); + auto self = resolve_peer_identity(sec, log::role().empty() ? "channel" : log::role()); + auto ctx = make_peer_tls_context(*self); + auto tls = std::make_unique(std::move(sock), *ctx); + try + { + tls_handshake(io, *tls, server, handshake, who + " TLS"); + } + catch (const std::system_error & e) + { + throw std::runtime_error(std::string(e.what()) + + " (if the peer has encryption off, set it the same at both ends)"); + } + link_security desc = tls_describe(*tls); + try + { + check_peer(desc, sec, peer_party, who); + } + catch (...) + { + std::error_code e; + tls->lowest_layer().close(e); + throw; + } + note_channel_security(who, desc); + (void)how; + return channel::from_tls_local(io, std::move(*tls), std::move(ctx)); +} +#else +inline channel secure_local_channel(asio::io_context &, + asio::local::stream_protocol::socket sock, bool, std::uint32_t, + const peer_security & sec = {}, std::chrono::milliseconds = {}, + const std::string & = {}, const char * = nullptr) +{ + if (sec.encrypt) + throw std::logic_error("secure_local_channel: built without OpenSSL; set " + "encryption=off for plaintext links"); + return channel(std::move(sock)); +} +#endif + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_SECURE_CHANNEL_HPP__ diff --git a/include/dpf/net/security.hpp b/include/dpf/net/security.hpp new file mode 100644 index 0000000..e9e10bc --- /dev/null +++ b/include/dpf/net/security.hpp @@ -0,0 +1,100 @@ +/// @file dpf/net/security.hpp +/// @brief What each link encrypts and whom it authenticates. +/// @details Party links run TLS 1.3 on every socket edge unless `encrypt` is +/// off. A party with no `self` key uses a fresh key for this +/// process, so peers can encrypt to it but cannot authenticate it. A +/// party authenticates exactly the peers whose keys it holds in +/// `trusted`; a peer without an entry is accepted unauthenticated and +/// the link logs that. Client links: the server always presents a +/// certificate and the client verifies it unless `verify` is off, +/// against a pinned key, a CA chain plus host name, or, when neither +/// is configured, the built-in development certificate (public, and +/// logged as providing no security). +#ifndef LIBDPF_INCLUDE_DPF_NET_SECURITY_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_SECURITY_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "dpf/net/identity.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief How one link was secured, for logs and callers. +struct link_security +{ + bool encrypted = false; + std::string protocol; ///< e.g. `TLSv1.3` + std::string cipher; ///< e.g. `TLS_AES_128_GCM_SHA256` + std::optional peer_key; + /// How this side authenticated the peer: `key` (a key it holds), `ca` + /// (CA chain and name), `development`, or `none`. + std::string peer_auth = "none"; + /// Whether the peer reported that it authenticated this side. + bool peer_verified_us = false; +}; + +/// @brief The dealer's id in handshakes and trust tables. +inline constexpr std::uint32_t dealer_id = 0xfffffffeu; + +/// @brief Party-to-party (and dealer) links. +struct peer_security +{ + /// TLS 1.3 on socket links; off leaves them plaintext. + bool encrypt = true; + /// This party's key; empty means a fresh key for this process. + std::shared_ptr self; + /// Keys this party checks, by party id (`party_session::k_dealer_id` for + /// the dealer). + std::map trusted; + + const public_key * trusted_key(std::uint32_t party) const + { + const auto it = trusted.find(party); + return it == trusted.end() ? nullptr : &it->second; + } +}; + +/// @brief What a client accepts from a server. +struct client_security +{ + /// Off accepts any certificate (logged as an error on every connect). + bool verify = true; + /// Accept a server presenting one of these raw keys. + std::vector pins; + /// PEM bundle for CA-issued server certificates; `system` uses OpenSSL's + /// default trust store. + std::string ca_file; + /// Name the CA-issued certificate must carry (default: the host dialed). + std::string server_name; + /// Optional client key, presented to servers that check clients. + std::shared_ptr self; + + bool configured() const noexcept { return !pins.empty() || !ca_file.empty(); } +}; + +/// @brief What a server presents to clients. +struct server_security +{ + /// PEM certificate chain and its private key (CA-issued certificates). + std::string cert_file; + std::string key_file; + /// Raw-key identity when no PEM files are set; with neither, the server + /// presents the development certificate. + std::shared_ptr self; + /// Client keys this server checks; a client without a matching key is + /// accepted unauthenticated and logged. + std::vector client_pins; +}; + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_SECURITY_HPP__ diff --git a/include/dpf/net/sink_exchange.hpp b/include/dpf/net/sink_exchange.hpp new file mode 100644 index 0000000..738c5cd --- /dev/null +++ b/include/dpf/net/sink_exchange.hpp @@ -0,0 +1,169 @@ +/// @file dpf/net/sink_exchange.hpp +/// @brief One-at-a-time typed exchange on a RoundSink (count lanes). +#ifndef LIBDPF_INCLUDE_DPF_NET_SINK_EXCHANGE_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_SINK_EXCHANGE_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/round_sink.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Advance through RoundSink rounds with trivially copyable slots. +class sink_exchange +{ +public: + sink_exchange(RoundSink & sink, std::size_t index = 0) + : sink_(&sink), index_(index) + { } + + std::uint16_t round() const noexcept { return round_; } + std::uint16_t & round_ref() noexcept { return round_; } + + template + T operator()(const T & mine) + { + static_assert(std::is_trivially_copyable_v, + "sink_exchange requires a trivially copyable type"); + if (!sink_) + throw std::logic_error("sink_exchange: no sink"); + if (round_ >= sink_->rounds()) + throw std::runtime_error("sink_exchange: out of rounds"); + const std::size_t slot = sink_->slot_bytes(round_); + if (sizeof(T) > slot) + throw std::runtime_error("sink_exchange: slot too small"); + std::vector buf(slot, 0); + if constexpr (sizeof(T) != 0) + std::memcpy(buf.data(), &mine, sizeof(T)); + sink_->submit(round_, index_, buf.data(), buf.size()); + sink_->flush_round(round_); + sink_->poll(); + if (!sink_->peer_ready(round_, index_)) + throw std::runtime_error("sink_exchange: peer missing"); + std::vector peer_buf(slot); + sink_->read_peer(round_, index_, peer_buf.data(), slot); + T peer{}; + if constexpr (sizeof(T) != 0) + std::memcpy(&peer, peer_buf.data(), sizeof(T)); + ++round_; + return peer; + } + +private: + RoundSink * sink_ = nullptr; + std::size_t index_ = 0; + std::uint16_t round_ = 0; +}; + +/// @brief Slot widths for a classic non-verifiable point walk of `depth` levels. +/// @details Per level: blind_msg, share_msg, advice_msg, and one 16-byte +/// bit-block product. Callers pad every slot to `max` so a single +/// sink sizing works for the whole walk. +inline std::vector point_walk_slot_bytes(std::size_t depth, + std::size_t max_slot) +{ + std::vector out; + out.reserve(depth * 4); + for (std::size_t i = 0; i < depth * 4; ++i) + out.push_back(max_slot); + return out; +} + +/// @brief Conservative RoundSink sizing for a Doerner–Shelat point or +/// comparison walk, including optional oblivious-hash AND layers. +/// @param depth tree depth (`dpf_type::depth`) +/// @param with_oblivious_hash verifiable non-reveal path (shared prefix hash) +/// @param lg_outputs `dpf_type::lg_outputs_per_leaf` — packed leaf mux cost + +/// Boyar–Peralta SubBytes AND-depth layers recorded by compose / party OH walks. +inline constexpr std::size_t ds_oh_subbytes_per_level = 10; +inline constexpr std::size_t ds_oh_and_layers_per_subbytes = 8; +inline constexpr std::size_t ds_oh_exchanges_per_level = + ds_oh_subbytes_per_level * ds_oh_and_layers_per_subbytes; +inline constexpr std::size_t ds_oh_slot_bytes = 4096; + +/// @brief Slot widths matching a composed DS walk (4 opens/level + OH layers). +/// @details Prefer this when sizing a sink for `composer::level_walk_ds` / +/// `level_walk_ds_sized`. `ds_walk_slot_bytes` stays the conservative +/// party oversize used by hand `dist_ds` paths. +inline std::vector compose_ds_slot_bytes(std::size_t depth, + std::size_t fss_slot_bytes, bool with_oblivious_hash, + std::size_t lg_outputs = 0) +{ + if (depth == 0) + throw std::invalid_argument("compose_ds_slot_bytes depth must be > 0"); + if (fss_slot_bytes == 0) + throw std::invalid_argument("compose_ds_slot_bytes slot must be > 0"); + std::vector out; + out.reserve(depth * (5 + (with_oblivious_hash ? ds_oh_exchanges_per_level : 0)) + + 64); + for (std::size_t level = 0; level < depth; ++level) + { + // blind, share, advice, AND round 1, AND round 2 — same as point_party. + for (int i = 0; i < 5; ++i) + out.push_back(fss_slot_bytes); + if (with_oblivious_hash) + { + for (std::size_t i = 0; i < ds_oh_exchanges_per_level; ++i) + out.push_back(ds_oh_slot_bytes); + } + } + if (lg_outputs > 0 && lg_outputs < 32) + { + const std::size_t mux_nodes = + 2 * ((std::size_t{1} << lg_outputs) - 1); + for (std::size_t i = 0; i < mux_nodes; ++i) + out.push_back(fss_slot_bytes); + } + return out; +} + +inline std::vector ds_walk_slot_bytes(std::size_t depth, + bool with_oblivious_hash, std::size_t lg_outputs = 0) +{ + // Envelope of the hand walk (typed frames, leaf extras) and a composed + // walk at 16-byte FSS slots. Every compose round fits in this sink; + // extra rounds keep the hand walk from running out of slots. + const auto composed = compose_ds_slot_bytes(depth, 16, with_oblivious_hash, + lg_outputs); + // Per level: blind, share, advice, two beaver_bit_block exchanges, plus + // reveal / leaf extras. Oblivious hash: 10 SubBytes × ~8 BP AND-depth + // layers (one schedule round each), not one round per AND gate. + std::size_t n = depth * 10 + 16; + // Packed leaf mux: two sink exchanges per internal node of a complete + // binary tree with 2^lg candidates. Verifiable non-reveal wildcards run + // a second mux for the payload vector — budget both. + if (lg_outputs > 0 && lg_outputs < 32) + { + const std::size_t mux = + 2 * ((std::size_t{1} << lg_outputs) - 1) + 8; + n += mux; + if (with_oblivious_hash) + n += mux; + } + std::size_t slot = 64; + if (with_oblivious_hash) + { + n += depth * ds_oh_exchanges_per_level; + // Packed mask bits for a full SubBytes AND layer across 8×16 bytes. + slot = ds_oh_slot_bytes; + } + std::vector out(std::max(n, composed.size()), slot); + for (std::size_t i = 0; i < composed.size(); ++i) + out[i] = std::max(out[i], composed[i]); + return out; +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_SINK_EXCHANGE_HPP__ diff --git a/include/dpf/net/socket_tune.hpp b/include/dpf/net/socket_tune.hpp new file mode 100644 index 0000000..7b4e737 --- /dev/null +++ b/include/dpf/net/socket_tune.hpp @@ -0,0 +1,135 @@ +/// @file dpf/net/socket_tune.hpp +/// @brief Apply `socket_options` to TCP and unix-domain sockets. +#ifndef LIBDPF_INCLUDE_DPF_NET_SOCKET_TUNE_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_SOCKET_TUNE_HPP__ + +#include +#include + +#include "dpf/net/asio_ns.hpp" + +#if defined(__linux__) +#include +#include +#include +#endif + +#include "dpf/net/policy.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Linux clears `TCP_QUICKACK` after one ACK. Call again after I/O. +inline void rearm_quickack(asio::ip::tcp::socket & sock) +{ +#if defined(TCP_QUICKACK) + std::error_code ec; + using quickack = + asio::detail::socket_option::boolean; + sock.set_option(quickack(true), ec); +#else + (void)sock; +#endif +} + +namespace detail +{ + +template +inline void apply_buffers(Socket & sock, const socket_options & o) +{ + std::error_code ec; + if (o.send_buffer > 0) + sock.set_option(asio::socket_base::send_buffer_size(o.send_buffer), ec); + if (o.recv_buffer > 0) + sock.set_option(asio::socket_base::receive_buffer_size(o.recv_buffer), + ec); +} + +} // namespace detail + +inline void tune_tcp(asio::ip::tcp::socket & sock, const socket_options & o = {}) +{ + std::error_code ec; + sock.set_option(asio::ip::tcp::no_delay(o.no_delay), ec); + sock.set_option(asio::socket_base::keep_alive(o.keepalive), ec); +#if defined(__linux__) + const int fd = sock.native_handle(); + if (o.keepalive && o.keepalive_idle_s > 0) + (void)::setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &o.keepalive_idle_s, + sizeof(o.keepalive_idle_s)); + if (o.keepalive && o.keepalive_interval_s > 0) + (void)::setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, + &o.keepalive_interval_s, sizeof(o.keepalive_interval_s)); + if (o.keepalive && o.keepalive_count > 0) + (void)::setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &o.keepalive_count, + sizeof(o.keepalive_count)); +#endif + detail::apply_buffers(sock, o); + if (o.quickack) + rearm_quickack(sock); +} + +namespace detail +{ + +template +struct is_layered_stream : std::false_type +{ +}; + +template +struct is_layered_stream> : std::true_type +{ +}; + +} // namespace detail + +/// @brief The socket under `s`: itself, or the TCP socket under a TLS stream. +template +inline auto & base_socket(S & s) +{ + if constexpr (detail::is_layered_stream::value) + return base_socket(s.next_layer()); + else + return s; +} + +inline void tune_stream(asio::ip::tcp::socket & sock, const socket_options & o = {}) +{ + tune_tcp(sock, o); +} + +template +inline void tune_stream(Socket & sock, const socket_options & o = {}) +{ + if constexpr (detail::is_layered_stream::value) + tune_stream(base_socket(sock), o); + else + detail::apply_buffers(sock, o); +} + +inline void rearm_stream(asio::ip::tcp::socket & sock, const socket_options & o) +{ + if (o.quickack) + rearm_quickack(sock); +} + +template +inline void rearm_stream(Socket & sock, const socket_options & o) +{ + if constexpr (detail::is_layered_stream::value) + rearm_stream(base_socket(sock), o); + else + { + (void)sock; + (void)o; + } +} + +} // namespace net +} // namespace dpf + +#endif diff --git a/include/dpf/net/stream_array.hpp b/include/dpf/net/stream_array.hpp new file mode 100644 index 0000000..98d7b55 --- /dev/null +++ b/include/dpf/net/stream_array.hpp @@ -0,0 +1,572 @@ +/// @file dpf/net/stream_array.hpp +/// @brief Indexed pack of duplex byte streams for dealer and online rounds. +/// @details `read` / `write` / `flush` are the only operations. Backends are +/// memory (tests), file (stored prep), and one-channel mux (TCP). +/// SCTP is a later backend: index `i` maps to association stream `i`. +/// Protocol code must not call TCP or SCTP sockets directly. +#ifndef LIBDPF_INCLUDE_DPF_NET_STREAM_ARRAY_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_STREAM_ARRAY_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/net/channel.hpp" +#include "dpf/net/policy.hpp" +#include "dpf/net/round_lane.hpp" +#include "dpf/net/round_sink.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Virtual base for N duplex streams. +class stream_array +{ +public: + virtual ~stream_array() = default; + + virtual std::size_t size() const noexcept = 0; + + virtual void write(std::size_t i, const void * src, std::size_t n) = 0; + virtual void read(std::size_t i, void * dst, std::size_t n) = 0; + virtual void flush(std::size_t i) = 0; + + void write_all(std::size_t i, const void * src, std::size_t n) + { + write(i, src, n); + flush(i); + } +}; + +// --------------------------------------------------------------------------- +// Memory +// --------------------------------------------------------------------------- + +struct memory_stream_hub +{ + std::size_t n = 0; + std::vector> a_to_b; + std::vector> b_to_a; + std::vector a_pos; + std::vector b_pos; + mutable std::mutex mu; + std::condition_variable cv; + + explicit memory_stream_hub(std::size_t streams) + : n(streams), + a_to_b(streams), + b_to_a(streams), + a_pos(streams, 0), + b_pos(streams, 0) + { + } +}; + +/// @brief One end of a paired in-process stream array. +class memory_stream_array : public stream_array +{ +public: + memory_stream_array(std::shared_ptr hub, bool side_a) + : hub_(std::move(hub)), side_a_(side_a) + { + if (!hub_) + throw std::invalid_argument("memory_stream_array needs a hub"); + } + + std::size_t size() const noexcept override { return hub_->n; } + + void write(std::size_t i, const void * src, std::size_t n) override + { + check(i); + { + std::lock_guard lock(hub_->mu); + auto & q = side_a_ ? hub_->a_to_b[i] : hub_->b_to_a[i]; + const auto * p = static_cast(src); + q.insert(q.end(), p, p + n); + } + hub_->cv.notify_all(); + } + + void read(std::size_t i, void * dst, std::size_t n) override + { + check(i); + std::unique_lock lock(hub_->mu); + auto & q = side_a_ ? hub_->b_to_a[i] : hub_->a_to_b[i]; + auto & pos = side_a_ ? hub_->b_pos[i] : hub_->a_pos[i]; + hub_->cv.wait(lock, [&] { return pos + n <= q.size(); }); + std::memcpy(dst, q.data() + pos, n); + pos += n; + } + + void flush(std::size_t) override {} + +private: + void check(std::size_t i) const + { + if (i >= hub_->n) + throw std::out_of_range("memory_stream_array index"); + } + + std::shared_ptr hub_; + bool side_a_ = true; +}; + +HEDLEY_WARN_UNUSED_RESULT +inline std::pair +make_memory_stream_pair(std::size_t streams) +{ + auto hub = std::make_shared(streams); + return {memory_stream_array(hub, true), memory_stream_array(hub, false)}; +} + +// --------------------------------------------------------------------------- +// File (one file per stream index) +// --------------------------------------------------------------------------- + +/// @brief Read-only or write-only file per stream. Dealer writes; online reads. +class file_stream_array : public stream_array +{ +public: + /// @brief Open `basename + "-" + i` for each index. + /// @param write_mode true for dealer output, false for online input. + file_stream_array(const std::string & basename, std::size_t streams, + bool write_mode) + : write_mode_(write_mode), files_(streams) + { + for (std::size_t i = 0; i < streams; ++i) + { + const auto path = basename + "-" + std::to_string(i); + files_[i].open(path, + write_mode ? (std::ios::binary | std::ios::trunc | std::ios::out) + : (std::ios::binary | std::ios::in)); + if (!files_[i]) + throw std::runtime_error("file_stream_array: " + path); + } + } + + std::size_t size() const noexcept override { return files_.size(); } + + void write(std::size_t i, const void * src, std::size_t n) override + { + if (!write_mode_) + throw std::logic_error("file_stream_array: write on read-only"); + check(i); + files_[i].write(static_cast(src), + static_cast(n)); + if (!files_[i]) + throw std::runtime_error("file_stream_array: write failed"); + } + + void read(std::size_t i, void * dst, std::size_t n) override + { + if (write_mode_) + throw std::logic_error("file_stream_array: read on write-only"); + check(i); + files_[i].read(static_cast(dst), static_cast(n)); + if (static_cast(files_[i].gcount()) != n) + throw std::runtime_error("file_stream_array: short read"); + } + + void flush(std::size_t i) override + { + check(i); + if (write_mode_) + files_[i].flush(); + } + +private: + void check(std::size_t i) const + { + if (i >= files_.size()) + throw std::out_of_range("file_stream_array index"); + } + + bool write_mode_ = false; + std::vector files_; +}; + +// --------------------------------------------------------------------------- +// Mux wire header (shared with async_mux_stream_array) +// --------------------------------------------------------------------------- + +#pragma pack(push, 1) +struct stream_frame_hdr +{ + std::uint16_t index = 0; + std::uint32_t length = 0; +}; +#pragma pack(pop) + +// Synchronous mux is `sync_stream_array` / `mux_stream_array` in +// dpf/net/sync_stream_array.hpp: a blocking face over the async mux backends +// (including TLS), so sync call sites share party_session encryption and +// wire policy. + +// --------------------------------------------------------------------------- +// RoundSink adapter (round → stream, with lane reuse when rounds > streams) +// --------------------------------------------------------------------------- + +/// @brief Multi-round RoundSink over a synchronous `stream_array`. +/// @details Same wire contract as `async_round_sink`: a plan-shape hello on +/// lane 0 (sent at construction, read before the first peer bytes), +/// unframed lanes when every round has its own lane, and framed +/// `{round, nbytes}` lanes otherwise (or when `framing` says so). A +/// framed round accepts partial instance prefixes. Call +/// `flush_round(r)` before starting another round's pending writes. +class stream_array_sink : public RoundSink +{ +public: + stream_array_sink(stream_array & streams, + std::vector slot_bytes_per_round, std::size_t count = 1, + framing_mode framing = framing_mode::automatic, bool hello = true) + : streams_(&streams), + count_(count), + slot_bytes_(std::move(slot_bytes_per_round)), + map_(streams.size(), slot_bytes_.size(), framing), + windows_(slot_bytes_.size()), + in_(slot_bytes_.size()), + in_filled_(slot_bytes_.size(), 0), + zero_seen_(slot_bytes_.size(), false), + announced_(slot_bytes_.size(), false), + hello_(hello) + { + if (streams_->size() == 0) + throw std::invalid_argument("stream_array_sink: empty streams"); + if (count_ == 0) + throw std::invalid_argument("stream_array_sink: count 0"); + for (std::size_t r = 0; r < slot_bytes_.size(); ++r) + { + windows_[r] = round_window(count_, slot_bytes_[r]); + in_[r].assign(count_ * slot_bytes_[r], 0); + } + if (hello_) + send_hello(); + } + + /// @brief Legacy single-round sink on stream `index` (no hello). + stream_array_sink(stream_array & streams, std::size_t index, std::size_t slot) + : streams_(&streams), + count_(1), + legacy_index_(index), + use_legacy_index_(true), + map_(1, 1) + { + slot_bytes_.push_back(slot); + windows_.emplace_back(count_, slot); + in_.emplace_back(count_ * slot, 0); + in_filled_.push_back(0); + zero_seen_.push_back(false); + announced_.push_back(false); + } + + std::size_t count() const noexcept override { return count_; } + std::size_t rounds() const noexcept override { return slot_bytes_.size(); } + bool framed() const noexcept { return map_.framed && !use_legacy_index_; } + + std::size_t slot_bytes(std::uint16_t round) const override + { + if (round >= slot_bytes_.size()) + throw std::out_of_range("stream_array_sink round"); + return slot_bytes_[round]; + } + + void submit(std::uint16_t round, std::size_t index, const std::uint8_t * bytes, + std::size_t n) override + { + window(round).submit(index, bytes, n); + } + + bool peer_ready(std::uint16_t round, std::size_t index) const override + { + if (round >= windows_.size()) + return false; + if (framed()) + { + if (slot_bytes_[round] == 0) + return zero_seen_[round]; + return in_filled_[round] >= (index + 1) * slot_bytes_[round]; + } + return window(round).peer_ready(index); + } + + void read_peer(std::uint16_t round, std::size_t index, std::uint8_t * out, + std::size_t n) const override + { + if (framed()) + { + if (!peer_ready(round, index)) + throw std::logic_error("stream_array_sink: peer not ready"); + if (n != slot_bytes_[round]) + throw std::invalid_argument("stream_array_sink read size"); + if (n != 0) + std::memcpy(out, in_[round].data() + index * n, n); + return; + } + window(round).read_peer(index, out, n); + } + + void flush() override + { + for (std::uint16_t r = 0; r < slot_bytes_.size(); ++r) + flush_round(r); + } + + void flush_round(std::uint16_t round) override + { + auto & win = window(round); + std::size_t begin = 0; + std::size_t nslots = 0; + const auto * pend = win.pending_out(begin, nslots); + const std::size_t sb = slot_bytes_[round]; + const std::size_t stream_i = stream_index(round); + const std::size_t nbytes = nslots * sb; + if (framed()) + { + const bool announce = sb == 0 && !announced_[round]; + if (nslots == 0 && !announce) + return; + auto frame = pack_round_frame(round, pend, nbytes); + streams_->write(stream_i, frame.data(), frame.size()); + streams_->flush(stream_i); + if (announce) + announced_[round] = true; + if (nslots != 0) + win.mark_flushed(nslots); + ensure_hello(); + while (sb == 0 ? !zero_seen_[round] + : in_filled_[round] < win.flushed() * sb) + pull_one_frame(stream_i); + return; + } + if (nslots != 0) + { + streams_->write(stream_i, pend, nbytes); + streams_->flush(stream_i); + win.mark_flushed(nslots); + } + if (nslots == 0) + return; + ensure_hello(); + std::vector peer(nbytes); + streams_->read(stream_i, peer.data(), peer.size()); + win.accept_peer_at(begin, peer.data(), nslots); + } + + void poll() override {} + +private: + static constexpr std::uint32_t k_magic = 0x48535044u; + static constexpr std::size_t k_fixed = 36; + + std::size_t stream_index(std::uint16_t round) const + { + if (use_legacy_index_) + return legacy_index_; + return map_.lane(round); + } + + static void put32(std::uint8_t * p, std::uint32_t v) + { + for (int i = 0; i < 4; ++i) + p[i] = static_cast((v >> (8 * i)) & 0xffu); + } + + static std::uint32_t get32(const std::uint8_t * p) + { + return static_cast(p[0]) | (static_cast(p[1]) << 8) + | (static_cast(p[2]) << 16) + | (static_cast(p[3]) << 24); + } + + void send_hello() + { + const std::size_t r = slot_bytes_.size(); + std::vector h(k_fixed + 4 * r, 0); + put32(h.data(), k_magic); + h[4] = 1; + h[6] = map_.framed ? 1 : 0; + put32(h.data() + 8, static_cast(r)); + put32(h.data() + 12, static_cast(map_.n_lanes)); + put32(h.data() + 16, static_cast(count_)); + const std::uint64_t fp = slots_fingerprint(slot_bytes_); + for (int i = 0; i < 8; ++i) + h[24 + i] = static_cast((fp >> (8 * i)) & 0xffu); + streams_->write(0, h.data(), h.size()); + streams_->flush(0); + } + + void ensure_hello() + { + if (!hello_ || hello_read_) + return; + hello_read_ = true; + std::uint8_t f[k_fixed]; + streams_->read(0, f, k_fixed); + if (get32(f) != k_magic) + throw std::runtime_error("stream_array_sink: peer did not send a " + "sink hello (both ends must use sinks with hello enabled)"); + const std::uint32_t pr = get32(f + 8); + const std::uint32_t pl = get32(f + 12); + const std::uint32_t pc = get32(f + 16); + const bool pfr = (f[6] & 1) != 0; + std::uint64_t pf = 0; + for (int i = 0; i < 8; ++i) + pf |= static_cast(f[24 + i]) << (8 * i); + std::string why; + if (pr != slot_bytes_.size()) + why += " rounds " + std::to_string(pr) + " vs " + + std::to_string(slot_bytes_.size()) + ";"; + else if (pf != slots_fingerprint(slot_bytes_)) + why += " slot widths differ;"; + if (pl != map_.n_lanes) + why += " lanes " + std::to_string(pl) + " vs " + + std::to_string(map_.n_lanes) + ";"; + if (pc != count_) + why += " instances " + std::to_string(pc) + " vs " + + std::to_string(count_) + ";"; + if (pfr != map_.framed) + why += std::string(" framing ") + (pfr ? "on" : "off") + " vs " + + (map_.framed ? "on" : "off") + ";"; + if (!why.empty()) + throw std::runtime_error( + "stream_array_sink: peer sink disagrees (peer vs this side):" + why); + std::vector rest(4 * pr); + if (!rest.empty()) + streams_->read(0, rest.data(), rest.size()); + } + + void pull_one_frame(std::size_t stream_i) + { + std::uint8_t raw[round_lane_hdr::size]; + streams_->read(stream_i, raw, round_lane_hdr::size); + const auto hdr = round_lane_hdr::unpack(raw); + if (hdr.round >= slot_bytes_.size() || map_.lane(hdr.round) != stream_i) + throw std::runtime_error("stream_array_sink: frame for round " + + std::to_string(hdr.round) + " on lane " + + std::to_string(stream_i)); + const std::size_t sb = slot_bytes_[hdr.round]; + if (hdr.nbytes == 0) + { + if (sb == 0) + zero_seen_[hdr.round] = true; + return; + } + if (sb == 0 || hdr.nbytes % sb != 0 + || in_filled_[hdr.round] + hdr.nbytes > count_ * sb) + throw std::runtime_error("stream_array_sink: round " + + std::to_string(hdr.round) + " frame of " + + std::to_string(hdr.nbytes) + " bytes does not fit"); + streams_->read(stream_i, in_[hdr.round].data() + in_filled_[hdr.round], + hdr.nbytes); + in_filled_[hdr.round] += hdr.nbytes; + } + + round_window & window(std::uint16_t round) + { + if (round >= windows_.size()) + throw std::out_of_range("stream_array_sink round"); + return windows_[round]; + } + + const round_window & window(std::uint16_t round) const + { + if (round >= windows_.size()) + throw std::out_of_range("stream_array_sink round"); + return windows_[round]; + } + + stream_array * streams_ = nullptr; + std::size_t count_ = 1; + std::size_t legacy_index_ = 0; + bool use_legacy_index_ = false; + std::vector slot_bytes_; + round_lane_map map_; + mutable std::vector windows_; + std::vector> in_; + std::vector in_filled_; + std::vector zero_seen_; + std::vector announced_; + bool hello_ = false; + bool hello_read_ = false; +}; + +/// @brief Map index `i` to SCTP stream `i` on one association. +/// @details Synchronous stub: this blocking `stream_array` face has no linked OS +/// backend, so its I/O throws. Protocol code should depend on +/// `stream_array` only; swap in a linked backend without API changes. +/// The real, event-driven SCTP backend already exists on Linux as +/// `dpf::net::async_sctp_stream_array` (see +/// `net/async_sctp_stream_array.hpp`, guarded by `DPF_HAS_LIBSCTP`). +/// It implements `dpf::net::async_stream_array`, still maps index `i` +/// to SCTP stream `i`, and drops in behind +/// `dpf::async::overlapped_byte_protocol` with no protocol changes. +/// Link `-lsctp`. Windows has no supported SCTP path (SctpDrv is +/// unstable), so the async class throws there. +struct sctp_association +{ + int fd = -1; +}; + +class sctp_stream_array : public stream_array +{ +public: + /// @brief Reserved for a linked backend (`libsctp` association fd). + explicit sctp_stream_array(sctp_association /*assoc*/) + { + throw std::logic_error("sctp_stream_array: not linked"); + } + + /// @brief Size-only stub: every I/O op throws until a backend is linked. + explicit sctp_stream_array(std::size_t streams) : n_(streams) + { + if (streams == 0) + throw std::invalid_argument("sctp_stream_array empty"); + } + + std::size_t size() const noexcept override { return n_; } + + void write(std::size_t, const void *, std::size_t) override + { + throw std::logic_error( + "sctp_stream_array: write — SCTP backend not linked (index i -> SCTP stream i)"); + } + + void read(std::size_t, void *, std::size_t) override + { + throw std::logic_error( + "sctp_stream_array: read — SCTP backend not linked (index i -> SCTP stream i)"); + } + + void flush(std::size_t) override + { + throw std::logic_error( + "sctp_stream_array: flush — SCTP backend not linked (index i -> SCTP stream i)"); + } + +private: + std::size_t n_ = 0; +}; + +} // namespace net +} // namespace dpf + +#endif diff --git a/include/dpf/net/stream_edge_mesh.hpp b/include/dpf/net/stream_edge_mesh.hpp new file mode 100644 index 0000000..da83a3c --- /dev/null +++ b/include/dpf/net/stream_edge_mesh.hpp @@ -0,0 +1,70 @@ +/// @file dpf/net/stream_edge_mesh.hpp +/// @brief Multi-edge `stream_array_sink` trio (peer / rss_next / dealer). +#ifndef LIBDPF_INCLUDE_DPF_NET_STREAM_EDGE_MESH_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_STREAM_EDGE_MESH_HPP__ + +#include +#include +#include +#include + +#include "dpf/net/edge_mesh.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/net/stream_mesh.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Owns up to three multi-round sinks bound to stream arrays. +struct stream_edge_sinks +{ + std::unique_ptr peer; + std::unique_ptr rss_next; + std::unique_ptr dealer; + + edge_mesh mesh() const + { + edge_mesh m; + m.sinks = {peer.get(), rss_next.get(), dealer.get()}; + return m; + } +}; + +/// @brief Build sinks from optional stream arrays and per-channel slot widths. +/// @details Null arrays or empty slot lists leave that edge unbound. +inline stream_edge_sinks make_stream_edge_sinks(stream_array * peer, + std::vector peer_slots, stream_array * rss, + std::vector rss_slots, stream_array * dealer, + std::vector dealer_slots, std::size_t lanes = 1) +{ + stream_edge_sinks out; + if (peer != nullptr && !peer_slots.empty()) + out.peer = std::make_unique(*peer, + std::move(peer_slots), lanes); + if (rss != nullptr && !rss_slots.empty()) + out.rss_next = std::make_unique(*rss, + std::move(rss_slots), lanes); + if (dealer != nullptr && !dealer_slots.empty()) + out.dealer = std::make_unique(*dealer, + std::move(dealer_slots), lanes); + return out; +} + +/// @brief RSS ring edge `(me → (me+1)%3)` on a 3-party stream clique. +inline stream_array & rss_next_ring_edge(memory_stream_clique & clique, + unsigned me) +{ + if (clique.parties != 3) + throw std::invalid_argument("rss_next_ring_edge: need 3 parties"); + if (me > 2) + throw std::invalid_argument("rss_next_ring_edge party"); + const unsigned next = static_cast((me + 1) % 3); + return clique.end(me, next); +} + +} // namespace net +} // namespace dpf + +#endif diff --git a/include/dpf/net/stream_mesh.hpp b/include/dpf/net/stream_mesh.hpp new file mode 100644 index 0000000..9429689 --- /dev/null +++ b/include/dpf/net/stream_mesh.hpp @@ -0,0 +1,123 @@ +/// @file dpf/net/stream_mesh.hpp +/// @brief Fully connected clique of `stream_array` duplex links. +#ifndef LIBDPF_INCLUDE_DPF_NET_STREAM_MESH_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_STREAM_MESH_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/net/stream_array.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Pairwise memory stream arrays for `n` parties (one hub per edge). +struct memory_stream_clique +{ + std::size_t parties = 0; + std::size_t streams_per_edge = 0; + std::vector> hubs; + std::vector> ends; + + static std::size_t pair_edge(std::size_t a, std::size_t b, std::size_t n) + { + if (a == b || a >= n || b >= n) + throw std::invalid_argument("memory_stream_clique pair"); + if (a > b) + std::swap(a, b); + std::size_t e = 0; + for (std::size_t i = 0; i < a; ++i) + e += n - 1 - i; + e += b - a - 1; + return e; + } + + /// @brief Duplex link from `from` toward `to` (same hub as `to`/`from`). + memory_stream_array & end(std::size_t from, std::size_t to) + { + const auto e = pair_edge(from, to, parties); + if (from < to) + return ends[e].first; + return ends[e].second; + } + + const memory_stream_array & end(std::size_t from, std::size_t to) const + { + const auto e = pair_edge(from, to, parties); + if (from < to) + return ends[e].first; + return ends[e].second; + } + + /// @brief Sum additive shares: send `mine` to every peer, add incoming. + /// @details Works for any `parties >= 2` (not only 3-party rings). + void declassify(unsigned me, const std::uint8_t * mine, std::size_t n, + std::uint8_t * sum_out) + { + if (parties < 2 || me >= parties) + throw std::invalid_argument("memory_stream_clique declassify party"); + for (unsigned peer = 0; peer < parties; ++peer) + { + if (peer == me) + continue; + end(me, peer).write(0, mine, n); + end(me, peer).flush(0); + } + std::memcpy(sum_out, mine, n); + for (unsigned peer = 0; peer < parties; ++peer) + { + if (peer == me) + continue; + std::vector got(n); + end(me, peer).read(0, got.data(), n); + for (std::size_t i = 0; i < n; i += 8) + { + std::uint64_t a = 0, b = 0; + const std::size_t k = std::min(8, n - i); + std::memcpy(&a, sum_out + i, k); + std::memcpy(&b, got.data() + i, k); + a += b; + std::memcpy(sum_out + i, &a, k); + } + } + } +}; + +HEDLEY_WARN_UNUSED_RESULT +inline memory_stream_clique make_memory_stream_clique(std::size_t n, + std::size_t streams_per_edge) +{ + if (n < 2) + throw std::invalid_argument("make_memory_stream_clique needs >= 2"); + if (streams_per_edge == 0) + throw std::invalid_argument("make_memory_stream_clique streams"); + memory_stream_clique c; + c.parties = n; + c.streams_per_edge = streams_per_edge; + const std::size_t n_edges = n * (n - 1) / 2; + c.hubs.reserve(n_edges); + c.ends.reserve(n_edges); + for (std::size_t e = 0; e < n_edges; ++e) + { + auto hub = std::make_shared(streams_per_edge); + c.hubs.push_back(hub); + c.ends.emplace_back(memory_stream_array(hub, true), + memory_stream_array(hub, false)); + } + return c; +} + +} // namespace net +} // namespace dpf + +#endif diff --git a/include/dpf/net/stream_sink.hpp b/include/dpf/net/stream_sink.hpp new file mode 100644 index 0000000..c06ba1e --- /dev/null +++ b/include/dpf/net/stream_sink.hpp @@ -0,0 +1,235 @@ +/// @file dpf/net/stream_sink.hpp +/// @brief RoundSink with one duplex channel per interactive round. +#ifndef LIBDPF_INCLUDE_DPF_NET_STREAM_SINK_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_STREAM_SINK_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/net/channel.hpp" +#include "dpf/net/round_sink.hpp" +#include "dpf/net/trio.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Prefix-flush RoundSink with an independent stream per round. +class stream_sink : public RoundSink +{ +public: + stream_sink(std::vector links, unsigned self_id, unsigned peer_id, + std::size_t count, std::vector slot_bytes) + : links_(std::move(links)), + self_id_(self_id), + peer_id_(peer_id), + count_(count), + slot_bytes_(std::move(slot_bytes)) + { + if (links_.size() != slot_bytes_.size()) + throw std::invalid_argument("stream_sink link count"); + windows_.reserve(slot_bytes_.size()); + for (std::size_t sb : slot_bytes_) + windows_.emplace_back(count_, sb); + } + + std::size_t count() const noexcept override { return count_; } + std::size_t rounds() const noexcept override { return slot_bytes_.size(); } + + std::size_t slot_bytes(std::uint16_t round) const override + { + if (round >= slot_bytes_.size()) + throw std::out_of_range("stream_sink round"); + return slot_bytes_[round]; + } + + void submit(std::uint16_t round, std::size_t index, + const std::uint8_t * bytes, std::size_t n) override + { + window(round).submit(index, bytes, n); + } + + bool peer_ready(std::uint16_t round, std::size_t index) const override + { + return window(round).peer_ready(index); + } + + void read_peer(std::uint16_t round, std::size_t index, std::uint8_t * out, + std::size_t n) const override + { + window(round).read_peer(index, out, n); + } + + void flush() override + { + // Global barrier: every round channel must rendezvous. Parties can have + // pending on different rounds (schedule_session holes / staggered + // indices); skipping idle links deadlocks the peer that still waits + // there. Lockstep callers should use flush_round to avoid O(rounds) + // exchanges on large sinks. + for (std::uint16_t r = 0; r < slot_bytes_.size(); ++r) + flush_one(r); + } + + void flush_round(std::uint16_t r) override + { + if (r >= slot_bytes_.size()) + throw std::out_of_range("stream_sink flush_round"); + flush_one(r); + } + + void poll() override {} + + std::uint64_t exchanges() const noexcept { return link_exchanges_; } + +private: + round_window & window(std::uint16_t round) + { + if (round >= windows_.size()) + throw std::out_of_range("stream_sink round"); + return windows_[round]; + } + + const round_window & window(std::uint16_t round) const + { + if (round >= windows_.size()) + throw std::out_of_range("stream_sink round"); + return windows_[round]; + } + + void flush_one(std::uint16_t r) + { + std::size_t begin = 0; + std::size_t nslots = 0; + const std::uint8_t * pending = windows_[r].pending_out(begin, nslots); + std::vector payload; + if (nslots != 0) + { + payload.resize(sizeof(std::uint32_t) * 2 + nslots * slot_bytes_[r]); + const std::uint32_t b = static_cast(begin); + const std::uint32_t c = static_cast(nslots); + std::memcpy(payload.data(), &b, 4); + std::memcpy(payload.data() + 4, &c, 4); + if (nslots * slot_bytes_[r] != 0) + std::memcpy(payload.data() + 8, pending, + nslots * slot_bytes_[r]); + windows_[r].mark_flushed(nslots); + } + else + { + // Peer may still be delivering; exchange an empty prefix header. + payload.resize(8, 0); + } + std::vector theirs; + if (self_id_ < peer_id_) + { + links_[r].send_bytes(msg::round_batch, payload); + theirs = links_[r].recv_bytes(msg::round_batch); + } + else + { + theirs = links_[r].recv_bytes(msg::round_batch); + links_[r].send_bytes(msg::round_batch, payload); + } + if (theirs.size() < 8) + throw std::runtime_error("stream_sink short frame"); + std::uint32_t pb = 0; + std::uint32_t pc = 0; + std::memcpy(&pb, theirs.data(), 4); + std::memcpy(&pc, theirs.data() + 4, 4); + const std::size_t body = static_cast(pc) * slot_bytes_[r]; + if (theirs.size() != 8 + body) + throw std::runtime_error("stream_sink size mismatch"); + if (pc != 0) + windows_[r].accept_peer_at(pb, theirs.data() + 8, pc); + ++link_exchanges_; + } + + std::vector links_; + unsigned self_id_ = 0; + unsigned peer_id_ = 0; + std::size_t count_ = 0; + std::vector slot_bytes_; + std::vector windows_; + std::uint64_t link_exchanges_ = 0; +}; + +inline std::string stream_link_path(const std::string & dir, role a, role b, + std::uint16_t round) +{ + if (to_u(a) > to_u(b)) + std::swap(a, b); + return dir + "/" + role_name(a) + "-" + role_name(b) + "-r" + + std::to_string(round); +} + +/// @brief Connect one unix-domain stream per round under `dir`. +inline stream_sink connect_stream_sink(role self, role peer, + const std::string & dir, std::size_t count, + std::vector slot_bytes, unsigned retries = 200) +{ + if (self == role::p2 || peer == role::p2) + throw std::invalid_argument("stream_sink is for computing parties"); + asio::io_context io; + std::vector links; + links.reserve(slot_bytes.size()); + using proto = asio::local::stream_protocol; + for (std::uint16_t r = 0; r < slot_bytes.size(); ++r) + { + const auto path = stream_link_path(dir, self, peer, r); + const bool accept = to_u(self) < to_u(peer); + bool opened = false; + for (unsigned i = 0; i < retries && !opened; ++i) + { + asio::error_code ec; + if (accept) + { + ::unlink(path.c_str()); + proto::endpoint ep(path); + proto::acceptor acc(io, ep); + proto::socket sock(io); + acc.accept(sock, ec); + if (!ec) + { + links.emplace_back(std::move(sock)); + opened = true; + } + } + else + { + proto::endpoint ep(path); + proto::socket sock(io); + sock.connect(ep, ec); + if (!ec) + { + links.emplace_back(std::move(sock)); + opened = true; + } + } + if (!opened) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + if (!opened) + throw std::runtime_error("stream_sink connect failed: " + path); + } + return stream_sink(std::move(links), to_u(self), to_u(peer), count, + std::move(slot_bytes)); +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_STREAM_SINK_HPP__ diff --git a/include/dpf/net/sync_stream_array.hpp b/include/dpf/net/sync_stream_array.hpp new file mode 100644 index 0000000..df4a850 --- /dev/null +++ b/include/dpf/net/sync_stream_array.hpp @@ -0,0 +1,111 @@ +/// @file dpf/net/sync_stream_array.hpp +/// @brief Blocking `stream_array` face over an `async_stream_array`. +/// @details Setup (TLS, windows, coalescing, reconnect) is the async +/// framework's job. This type only turns each `write` / `read` / +/// `flush` into one async call and pumps that stream's `io_context` +/// until it finishes, so older sync call sites share the same +/// encryption and wire policy as `party_session`. +#ifndef LIBDPF_INCLUDE_DPF_NET_SYNC_STREAM_ARRAY_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_SYNC_STREAM_ARRAY_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/async_stream_array.hpp" +#include "dpf/net/buffer_pool.hpp" +#include "dpf/net/stream_array.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief Synchronous view of an `async_stream_array` on one `io_context`. +class sync_stream_array final : public stream_array +{ +public: + /// @brief Non-owning: `streams` and its context must outlive this object. + explicit sync_stream_array(async_stream_array & streams) + : streams_(&streams), io_(&streams.context()) + { + if (streams_->size() == 0) + throw std::invalid_argument("sync_stream_array empty"); + } + + std::size_t size() const noexcept override { return streams_->size(); } + + void write(std::size_t i, const void * src, std::size_t n) override + { + check(i); + if (n == 0) + return; + auto buf = copy_buffer(src, n); + wait_op([&](auto done) { + streams_->async_write_owned(i, std::move(buf), std::move(done)); + }); + } + + void read(std::size_t i, void * dst, std::size_t n) override + { + check(i); + if (n == 0) + return; + wait_op([&](auto done) { + streams_->async_read(i, dst, n, std::move(done)); + }); + } + + /// @brief No-op: each `write` already waits for the bytes to leave. + void flush(std::size_t) override {} + + async_stream_array & async() noexcept { return *streams_; } + const async_stream_array & async() const noexcept { return *streams_; } + +private: + void check(std::size_t i) const + { + if (i >= streams_->size()) + throw std::out_of_range("sync_stream_array index " + + std::to_string(i)); + } + + template + void wait_op(Start start) + { + std::atomic done{false}; + std::error_code ec; + start([&](const std::error_code & e) { + ec = e; + done.store(true, std::memory_order_release); + }); + while (!done.load(std::memory_order_acquire)) + { + if (io_->stopped()) + io_->restart(); + io_->run_one(); + } + if (ec) + throw std::system_error(ec, "sync_stream_array"); + } + + async_stream_array * streams_ = nullptr; + asio::io_context * io_ = nullptr; +}; + +/// @brief Same face as the old fd-based mux: N lanes on one connection. +/// @details Built from an already-established framework link (typically a +/// `party_session` peer). Prefer this over constructing a mux from a +/// raw `channel` socket. +using mux_stream_array = sync_stream_array; + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_SYNC_STREAM_ARRAY_HPP__ diff --git a/include/dpf/net/tcp_mesh.hpp b/include/dpf/net/tcp_mesh.hpp new file mode 100644 index 0000000..e5e9439 --- /dev/null +++ b/include/dpf/net/tcp_mesh.hpp @@ -0,0 +1,140 @@ +/// @file dpf/net/tcp_mesh.hpp +/// @brief N-party TCP clique bootstrap via `party_session`. +/// @details Thin wrappers around `party_session::join` so sync and async mesh +/// helpers share TLS, wire policy, deadlines, and reconnect with the +/// rest of the framework. Prefer constructing a `party_session` +/// directly in new code. +#ifndef LIBDPF_INCLUDE_DPF_NET_TCP_MESH_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_TCP_MESH_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/net/mesh_rendezvous.hpp" +#include "dpf/net/party_session.hpp" +#include "dpf/net/policy.hpp" +#include "dpf/net/security.hpp" +#include "dpf/net/sync_stream_array.hpp" + +namespace dpf +{ +namespace net +{ + +/// @brief One party's view of a TCP mux clique backed by `party_session`. +struct async_tcp_mesh +{ + unsigned me = 0; + unsigned parties = 0; + std::unique_ptr session; + + async_stream_array & peer(unsigned p) + { + if (!session) + throw std::logic_error("async_tcp_mesh: not joined"); + return session->peer(p); + } + + bool has(unsigned p) const + { + return session && p < parties && p != me; + } + + party_session & sess() + { + if (!session) + throw std::logic_error("async_tcp_mesh: not joined"); + return *session; + } +}; + +/// @brief Sync mux clique view (same topology as `async_tcp_mesh`). +/// @details Owns the `io_context` and a sync facade per peer edge. +struct tcp_mesh +{ + unsigned me = 0; + unsigned parties = 0; + std::shared_ptr io; + std::unique_ptr session; + std::vector> links; + + mux_stream_array & peer(unsigned p) + { + if (p == me || p >= parties || !links[p]) + throw std::invalid_argument("tcp_mesh: bad peer"); + return *links[p]; + } + + party_session & sess() + { + if (!session) + throw std::logic_error("tcp_mesh: not joined"); + return *session; + } +}; + +inline session_options mesh_session_options(std::size_t nstreams, + const wire_policy & pol = {}, const deadlines & lim = {}, + const peer_security & sec = {}) +{ + session_options opt; + opt.n_lanes = nstreams; + opt.kind = transport::mux; + opt.policy = pol; + opt.limits = lim; + opt.security = sec; + return opt; +} + +/// @brief Party `me` joins an N-party async mux clique on `host`. +inline async_tcp_mesh join_async_tcp_mesh(asio::io_context & io, unsigned me, + unsigned n, const std::string & host, mesh_ports & ports, + std::size_t nstreams, const wire_policy & pol = {}, + const deadlines & lim = {}, const peer_security & sec = {}) +{ + if (nstreams == 0) + throw std::invalid_argument("join_async_tcp_mesh: nstreams"); + async_tcp_mesh mesh; + mesh.me = me; + mesh.parties = n; + mesh.session = std::make_unique(io, me, n, + mesh_session_options(nstreams, pol, lim, sec)); + mesh.session->join(host, ports, nstreams); + return mesh; +} + +/// @brief Sync variant: each edge is a `mux_stream_array` over the session. +inline tcp_mesh join_tcp_mesh(unsigned me, unsigned n, const std::string & host, + mesh_ports & ports, std::size_t nstreams, const wire_policy & pol = {}, + const deadlines & lim = {}, const peer_security & sec = {}) +{ + if (nstreams == 0) + throw std::invalid_argument("join_tcp_mesh: nstreams"); + tcp_mesh mesh; + mesh.me = me; + mesh.parties = n; + mesh.io = std::make_shared(); + mesh.session = std::make_unique(*mesh.io, me, n, + mesh_session_options(nstreams, pol, lim, sec)); + mesh.session->join(host, ports, nstreams); + mesh.links.resize(n); + for (unsigned peer = 0; peer < n; ++peer) + { + if (peer == me) + continue; + mesh.links[peer] = + std::make_unique(mesh.session->peer(peer)); + } + return mesh; +} + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_TCP_MESH_HPP__ diff --git a/include/dpf/net/tls.hpp b/include/dpf/net/tls.hpp new file mode 100644 index 0000000..8f9b138 --- /dev/null +++ b/include/dpf/net/tls.hpp @@ -0,0 +1,345 @@ +/// @file dpf/net/tls.hpp +/// @brief TLS 1.3 for party links and client links (OpenSSL through asio). +/// @details Only TLS 1.3 is offered, without session tickets or resumption. +/// The TLS layer accepts any certificate; the decision is made right +/// after the handshake, before any application byte is read: +/// `check_peer` compares a party's key with the one this side holds +/// for that party (none held means unauthenticated in that +/// direction), and `check_server` applies a client's pins, CA chain +/// and host name, or the development-certificate default. Every +/// blocking step here pumps the socket's `io_context` until it +/// completes or its budget runs out, then closes the socket. +#ifndef LIBDPF_INCLUDE_DPF_NET_TLS_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_TLS_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" +#include "dpf/net/connect.hpp" +#include "dpf/net/identity.hpp" +#include "dpf/net/security.hpp" + +#if DPF_HAS_OPENSSL +#include +#include +#include +#endif + +namespace dpf +{ +namespace net +{ + +#if DPF_HAS_OPENSSL + +using tls_stream = asio::ssl::stream; +using tls_local_stream = asio::ssl::stream; +using tls_context = asio::ssl::context; + +namespace detail +{ + +inline int tls_accept_any(int, X509_STORE_CTX *) { return 1; } + +inline void tls_common(SSL_CTX * c) +{ + if (SSL_CTX_set_min_proto_version(c, TLS1_3_VERSION) != 1 + || SSL_CTX_set_max_proto_version(c, TLS1_3_VERSION) != 1 + || SSL_CTX_set_ciphersuites(c, + "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:" + "TLS_AES_256_GCM_SHA384") + != 1) + throw std::runtime_error(openssl_error("tls: context")); + SSL_CTX_set_num_tickets(c, 0); + SSL_CTX_set_session_cache_mode(c, SSL_SESS_CACHE_OFF); + SSL_CTX_set_options(c, SSL_OP_NO_TICKET); +} + +inline void use_identity(SSL_CTX * c, const identity & id) +{ + if (SSL_CTX_use_certificate(c, id.cert()) != 1 + || SSL_CTX_use_PrivateKey(c, id.pkey()) != 1 + || SSL_CTX_check_private_key(c) != 1) + throw std::runtime_error(openssl_error("tls: identity")); +} + +/// @brief Run one async step on `s`, pumping `io`, for at most `budget`. +template +inline std::error_code tls_step(asio::io_context & io, Stream & s, + std::chrono::milliseconds budget, Start start) +{ + bool done = false; + std::error_code result; + start([&done, &result](const std::error_code & ec) { + result = ec; + done = true; + }); + const auto deadline = setup_clock::now() + budget; + bool expired = false; + while (!done) + { + if (!expired && setup_clock::now() >= deadline) + { + expired = true; + std::error_code e; + s.lowest_layer().cancel(e); + s.lowest_layer().close(e); + } + if (io.stopped()) + io.restart(); + io.run_one_for(std::chrono::milliseconds(10)); + } + // Running out of work stops `io`; leave it ready for the caller's run(). + if (io.stopped()) + io.restart(); + if (expired && result) + return std::make_error_code(std::errc::timed_out); + return result; +} + +inline std::string tls_failure(const std::string & what, const std::error_code & ec, + std::chrono::milliseconds budget) +{ + if (ec == std::errc::timed_out) + return what + ": no answer within " + std::to_string(budget.count()) + " ms"; + return what + ": " + ec.message(); +} + +} // namespace detail + +/// @brief Party links: both ends present `self` and request the peer's key. +inline std::shared_ptr make_peer_tls_context(const identity & self) +{ + auto ctx = std::make_shared(tls_context::tls); + SSL_CTX * c = ctx->native_handle(); + detail::tls_common(c); + detail::use_identity(c, self); + SSL_CTX_set_verify(c, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + detail::tls_accept_any); + return ctx; +} + +/// @brief Server side of client links. `development` reports whether the +/// development certificate is presented. +inline std::shared_ptr make_server_tls_context(const server_security & sec, + bool & development) +{ + auto ctx = std::make_shared(tls_context::tls); + SSL_CTX * c = ctx->native_handle(); + detail::tls_common(c); + development = false; + if (!sec.cert_file.empty()) + { + const std::string key = sec.key_file.empty() ? sec.cert_file : sec.key_file; + if (SSL_CTX_use_certificate_chain_file(c, sec.cert_file.c_str()) != 1 + || SSL_CTX_use_PrivateKey_file(c, key.c_str(), SSL_FILETYPE_PEM) != 1 + || SSL_CTX_check_private_key(c) != 1) + throw std::runtime_error(detail::openssl_error( + ("tls: server certificate '" + sec.cert_file + "'").c_str())); + } + else if (sec.self) + detail::use_identity(c, *sec.self); + else + { + detail::use_identity(c, identity::development()); + development = true; + } + // Client keys are optional; `check_client` reads whichever arrived. + SSL_CTX_set_verify(c, SSL_VERIFY_PEER, detail::tls_accept_any); + return ctx; +} + +/// @brief Client side of client links. Verification happens in `check_server`. +inline std::shared_ptr make_client_tls_context(const client_security & sec) +{ + auto ctx = std::make_shared(tls_context::tls); + SSL_CTX * c = ctx->native_handle(); + detail::tls_common(c); + if (sec.self) + detail::use_identity(c, *sec.self); + if (sec.ca_file == "system") + { + if (SSL_CTX_set_default_verify_paths(c) != 1) + throw std::runtime_error(detail::openssl_error("tls: system trust store")); + } + else if (!sec.ca_file.empty() + && SSL_CTX_load_verify_locations(c, sec.ca_file.c_str(), nullptr) != 1) + throw std::runtime_error(detail::openssl_error( + ("tls: CA file '" + sec.ca_file + "'").c_str())); + SSL_CTX_set_verify(c, SSL_VERIFY_PEER, detail::tls_accept_any); + return ctx; +} + +/// @brief Set the name a CA-issued server certificate must carry (and SNI). +template +inline void tls_expect_host(Stream & s, const std::string & name) +{ + if (name.empty()) + return; + SSL * ssl = s.native_handle(); + SSL_set_tlsext_host_name(ssl, name.c_str()); + if (SSL_set1_host(ssl, name.c_str()) != 1) + throw std::runtime_error(detail::openssl_error("tls: server name")); +} + +template +inline void tls_handshake(asio::io_context & io, Stream & s, bool server, + std::chrono::milliseconds budget, const std::string & what) +{ + const auto ec = detail::tls_step(io, s, budget, [&](auto h) { + s.async_handshake(server ? asio::ssl::stream_base::server + : asio::ssl::stream_base::client, + h); + }); + if (ec) + throw std::system_error(ec, detail::tls_failure(what + ": TLS handshake", ec, + budget)); +} + +template +inline void tls_write(asio::io_context & io, Stream & s, const void * p, + std::size_t n, std::chrono::milliseconds budget, const std::string & what) +{ + const auto ec = detail::tls_step(io, s, budget, [&](auto h) { + asio::async_write(s, asio::buffer(p, n), + [h](const std::error_code & e, std::size_t) { h(e); }); + }); + if (ec) + throw std::system_error(ec, detail::tls_failure(what, ec, budget)); +} + +template +inline void tls_read(asio::io_context & io, Stream & s, void * p, std::size_t n, + std::chrono::milliseconds budget, const std::string & what) +{ + const auto ec = detail::tls_step(io, s, budget, [&](auto h) { + asio::async_read(s, asio::buffer(p, n), + [h](const std::error_code & e, std::size_t) { h(e); }); + }); + if (ec) + throw std::system_error(ec, detail::tls_failure(what, ec, budget)); +} + +/// @brief The Ed25519 key in the peer's certificate, if it sent one. +template +inline std::optional tls_peer_key(Stream & s) +{ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + X509 * x = SSL_get1_peer_certificate(s.native_handle()); +#else + X509 * x = SSL_get_peer_certificate(s.native_handle()); +#endif + if (x == nullptr) + return std::nullopt; + std::optional out; + EVP_PKEY * k = X509_get0_pubkey(x); + public_key pk; + std::size_t n = public_key::size; + if (k != nullptr && EVP_PKEY_id(k) == EVP_PKEY_ED25519 + && EVP_PKEY_get_raw_public_key(k, pk.bytes.data(), &n) == 1 + && n == public_key::size) + out = pk; + X509_free(x); + return out; +} + +/// @brief Protocol, cipher, and peer key of an established stream. +template +inline link_security tls_describe(Stream & s) +{ + link_security out; + out.encrypted = true; + SSL * ssl = s.native_handle(); + out.protocol = SSL_get_version(ssl); + const char * cipher = SSL_get_cipher_name(ssl); + out.cipher = cipher != nullptr ? cipher : "unknown"; + out.peer_key = tls_peer_key(s); + return out; +} + +/// @brief Party link: authenticate `who` if this side holds its key. +/// @details Throws when a held key does not match. Otherwise fills +/// `sec.peer_auth` with `key` or `none`. +inline void check_peer(link_security & sec, const peer_security & policy, + std::uint32_t party, const std::string & who) +{ + const public_key * want = policy.trusted_key(party); + if (want == nullptr) + { + sec.peer_auth = "none"; + return; + } + if (!sec.peer_key || *sec.peer_key != *want) + throw std::runtime_error("security: " + who + " presented key " + + (sec.peer_key ? sec.peer_key->base64() : std::string("(not Ed25519)")) + + " but this side holds " + want->base64() + " for it"); + sec.peer_auth = "key"; +} + +/// @brief Client link: apply `policy` to the server behind `s`. +/// @details Accepts a pinned key, then a CA chain that matched the expected +/// name, then (only when neither is configured) the development +/// certificate. `verify` off accepts anything. +inline void check_server(link_security & sec, tls_stream & s, + const client_security & policy, const std::string & where) +{ + if (!policy.verify) + { + sec.peer_auth = "none"; + return; + } + if (sec.peer_key + && std::find(policy.pins.begin(), policy.pins.end(), *sec.peer_key) + != policy.pins.end()) + { + sec.peer_auth = "key"; + return; + } + if (!policy.ca_file.empty() && SSL_get_verify_result(s.native_handle()) == X509_V_OK) + { + sec.peer_auth = "ca"; + return; + } + if (!policy.configured() && sec.peer_key + && *sec.peer_key == identity::development().key()) + { + sec.peer_auth = "development"; + return; + } + std::string why; + if (!policy.ca_file.empty()) + why = std::string(" (CA check: ") + + X509_verify_cert_error_string(SSL_get_verify_result(s.native_handle())) + + ")"; + throw std::runtime_error("security: server " + where + " presented " + + (sec.peer_key ? "key " + sec.peer_key->base64() + : std::string("a certificate without an Ed25519 key")) + + ", which this client does not trust" + why + + "; pin it (client_pin=...), configure client_ca, or set client_verify=off"); +} + +/// @brief Server side: authenticate the client if it presented a pinned key. +inline void check_client(link_security & sec, const server_security & policy) +{ + sec.peer_auth = sec.peer_key + && std::find(policy.client_pins.begin(), policy.client_pins.end(), + *sec.peer_key) + != policy.client_pins.end() + ? "key" + : "none"; +} + +#endif // DPF_HAS_OPENSSL + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_TLS_HPP__ diff --git a/include/dpf/net/trio.hpp b/include/dpf/net/trio.hpp new file mode 100644 index 0000000..9f975fb --- /dev/null +++ b/include/dpf/net/trio.hpp @@ -0,0 +1,563 @@ +/// @file dpf/net/trio.hpp +/// @brief Dial/accept three-party (2+1) socket mesh for libdpf protocols. +/// @details Socket paths live under a driver-created directory: +/// `p0-p1`, `p0-p2`, `p1-p2`. The lower role accepts; the higher +/// dials. Helpers `deal` / `accept_deal` / `open_with` name the +/// protocol steps without exposing ASIO. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_NET_TRIO_HPP__ +#define LIBDPF_INCLUDE_DPF_NET_TRIO_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/net/channel.hpp" +#include "dpf/net/comm_hook.hpp" +#include "dpf/net/policy.hpp" +#include "dpf/net/round_sink.hpp" +#include "dpf/net/secure_channel.hpp" +#include "dpf/net/security.hpp" +#include "dpf/net/socket_tune.hpp" + +#include "hedley/hedley.h" + +namespace dpf +{ +namespace net +{ + +/// @brief Party roles in a (2+1) run. p2 is the dealer. +enum class role : unsigned +{ + p0 = 0, + p1 = 1, + p2 = 2, +}; + +HEDLEY_CONST +HEDLEY_NO_THROW +inline constexpr unsigned to_u(role r) noexcept +{ + return static_cast(r); +} + +HEDLEY_CONST +HEDLEY_NO_THROW +inline const char * role_name(role r) noexcept +{ + switch (r) + { + case role::p0: return "p0"; + case role::p1: return "p1"; + case role::p2: return "p2"; + } + return "?"; +} + +inline std::string link_path(const std::string & dir, role a, role b) +{ + if (to_u(a) > to_u(b)) + std::swap(a, b); + return dir + "/" + role_name(a) + "-" + role_name(b); +} + +/// @brief Connected view of the other two parties. +class trio +{ +public: + trio() = default; + + /// @brief Connect local unix-domain sockets under `dir`. + /// @param self this process's role + /// @param dir directory holding the three socket paths + /// @param retries dial/accept attempts before giving up + /// @param sec same peer TLS policy as `party_session` (default encrypt) + static trio connect_local(role self, const std::string & dir, + unsigned retries = 200, const peer_security & sec = {}, + const deadlines & lim = {}) + { + trio t; + t.self_ = self; + t.io_ = std::make_unique(); + for (unsigned other = 0; other < 3; ++other) + { + if (other == to_u(self)) + continue; + auto peer = static_cast(other); + t.link_[other] = connect_one(self, peer, dir, *t.io_, retries, sec, + lim); + } + return t; + } + + /// @brief Connect the p0–p1 socket only. The dealer link stays closed + /// until `install_inbox`. + static trio connect_pair(role self, const std::string & dir, + unsigned retries = 200, const peer_security & sec = {}, + const deadlines & lim = {}) + { + if (self == role::p2) + throw std::invalid_argument("connect_pair is p0 and p1"); + trio t; + t.self_ = self; + t.io_ = std::make_unique(); + const role peer = self == role::p0 ? role::p1 : role::p0; + t.link_[to_u(peer)] = connect_one(self, peer, dir, *t.io_, retries, sec, + lim); + return t; + } + + /// @brief Serve later `to(p2).recv` calls from a local frame buffer. + void install_inbox(std::vector frames) + { + if (self_ == role::p2) + throw std::logic_error("p2 has no dealer inbox"); + link_[to_u(role::p2)] = channel::from_inbox(std::move(frames)); + } + + /// @brief True when the installed dealer tape has been fully consumed. + HEDLEY_NO_THROW + bool dealer_inbox_done() const noexcept + { + if (self_ == role::p2) + return false; + return link_[to_u(role::p2)].inbox_done(); + } + + /// @brief Connect over TCP loopback. Ports are `base + 10*lo + hi`. + static trio connect_tcp(role self, std::uint16_t base_port, + const std::string & host = "127.0.0.1", unsigned retries = 200, + const peer_security & sec = {}, const deadlines & lim = {}, + const socket_options & so = {}) + { + trio t; + t.self_ = self; + t.io_ = std::make_unique(); + for (unsigned other = 0; other < 3; ++other) + { + if (other == to_u(self)) + continue; + auto peer = static_cast(other); + t.link_[other] = connect_one_tcp(self, peer, base_port, host, + *t.io_, retries, sec, lim, so); + } + return t; + } + + role self() const noexcept { return self_; } + + /// @brief Sum of byte and frame counters on the open links. + HEDLEY_NO_THROW + io_tally tally() const noexcept + { + io_tally sum; + for (const auto & link : link_) + { + if (link.open()) + sum += link.tally(); + } + return sum; + } + + /// @brief Counters on the link to `peer` only. + HEDLEY_NO_THROW + io_tally tally_to(role peer) const noexcept + { + if (peer == self_ || !link_[to_u(peer)].open()) + return {}; + return link_[to_u(peer)].tally(); + } + + /// @brief Bytes received from the dealer (p2). Empty for the dealer itself. + HEDLEY_NO_THROW + io_tally tally_from_p2() const noexcept + { + if (self_ == role::p2) + return {}; + return tally_to(role::p2); + } + + /// @brief Bytes with the other computing party (p0↔p1). + /// @details For p2 this is the sum of the links to p0 and p1. + HEDLEY_NO_THROW + io_tally tally_from_peer() const noexcept + { + if (self_ == role::p0) + return tally_to(role::p1); + if (self_ == role::p1) + return tally_to(role::p0); + io_tally sum; + sum += tally_to(role::p0); + sum += tally_to(role::p1); + return sum; + } + + /// @brief Zero counters on every open link. + HEDLEY_NO_THROW + void reset_tally() noexcept + { + for (auto & link : link_) + { + if (link.open()) + link.reset_tally(); + } + } + + /// @brief The open channel to `peer` (raw bypass; does not use the hook). + /// @param peer the other party + /// @return that channel + /// @throws std::invalid_argument if `peer` is this process + /// @throws std::logic_error if that link was not connected + channel & to(role peer) + { + if (peer == self_) + throw std::invalid_argument("trio::to(self)"); + auto & c = link_[to_u(peer)]; + if (!c.open()) + throw std::logic_error("trio link is not open"); + return c; + } + + /// @brief Install a replaceable transport for helpers and `batch`. + /// @details Non-owning. Null restores the framed mesh defaults. + void set_hook(comm_hook * hook) noexcept { hook_ = hook; } + + /// @brief Current hook, or null when helpers use the mesh directly. + HEDLEY_NO_THROW + comm_hook * hook() const noexcept { return hook_; } + + /// @brief One-way send through the hook (or the mesh when unset). + template + void send_to(role peer, msg tag, const T & value) + { + static_assert(std::is_trivially_copyable_v, + "trio::send_to requires a trivially copyable type"); + if (hook_) + { + hook_->send_bytes(*this, to_u(peer), tag, &value, sizeof(T)); + return; + } + to(peer).send(tag, value); + } + + /// @brief Homogeneous vector send through the hook (or the mesh). + template + void send_vec_to(role peer, msg tag, const std::vector & values) + { + static_assert(std::is_trivially_copyable_v, + "trio::send_vec_to requires a trivially copyable type"); + if (hook_) + { + const std::size_t nbytes = values.size() * sizeof(T); + hook_->send_bytes(*this, to_u(peer), tag, values.data(), nbytes); + return; + } + to(peer).send_vec(values, tag); + } + + /// @brief Untyped one-way send through the hook (or the mesh). + void send_bytes_to(role peer, msg tag, const void * data, std::size_t n) + { + if (hook_) + { + hook_->send_bytes(*this, to_u(peer), tag, data, n); + return; + } + to(peer).send_bytes(tag, data, n); + } + + /// @brief Untyped one-way receive through the hook (or the mesh). + HEDLEY_WARN_UNUSED_RESULT + std::vector recv_bytes_from(role peer, msg tag) + { + if (hook_) + return hook_->recv_bytes(*this, to_u(peer), tag); + return to(peer).recv_bytes(tag); + } + + /// @brief One-way receive through the hook (or the mesh when unset). + template + HEDLEY_WARN_UNUSED_RESULT + T recv_from(role peer, msg tag) + { + static_assert(std::is_trivially_copyable_v, + "trio::recv_from requires a trivially copyable type"); + if (hook_) + { + auto bytes = hook_->recv_bytes(*this, to_u(peer), tag); + if (bytes.size() != sizeof(T)) + throw std::runtime_error("trio::recv_from size mismatch"); + T value{}; + if constexpr (sizeof(T) != 0) + std::memcpy(&value, bytes.data(), sizeof(T)); + return value; + } + return to(peer).template recv(tag); + } + + /// @brief Homogeneous vector receive through the hook (or the mesh). + template + HEDLEY_WARN_UNUSED_RESULT + std::vector recv_vec_from(role peer, msg tag = msg::beaver_tape) + { + static_assert(std::is_trivially_copyable_v, + "trio::recv_vec_from requires a trivially copyable type"); + if (hook_) + { + auto bytes = hook_->recv_bytes(*this, to_u(peer), tag); + if constexpr (sizeof(T) == 0) + { + if (!bytes.empty()) + throw std::runtime_error("trio::recv_vec_from size"); + return {}; + } + if (bytes.size() % sizeof(T) != 0) + throw std::runtime_error("trio::recv_vec_from size mismatch"); + std::vector out(bytes.size() / sizeof(T)); + if (!out.empty()) + std::memcpy(out.data(), bytes.data(), bytes.size()); + return out; + } + return to(peer).template recv_vec(tag); + } + + /// @brief Round-batched peer sink. Default is a mux on the p0–p1 link. + /// @details Defined next to `mux_sink` so the default factory can build one. + std::unique_ptr batch(std::size_t count, + std::vector slot_bytes); + + /// @brief Dealer sends one side of a split to each computing party. + /// @tparam Split a type with `p0` and `p1` members + /// @param s the split + /// @throws std::logic_error if this process is not p2 + template + void deal(const Split & s) + { + if (self_ != role::p2) + throw std::logic_error("only the dealer may deal"); + send_to(role::p0, msg::beaver_tape, s.p0); + send_to(role::p1, msg::beaver_tape, s.p1); + } + + /// @brief Computing party receives its share of a dealt value. + /// @tparam Ring the dealt type + /// @return this party's share + /// @throws std::logic_error if this process is p2 + template + HEDLEY_WARN_UNUSED_RESULT + Ring accept_deal() + { + if (self_ == role::p2) + throw std::logic_error("dealer does not accept_deal"); + return recv_from(role::p2, msg::beaver_tape); + } + + /// @brief Open an additive share with the peer computing party. + /// @tparam Ring additive ring + /// @param peer the other computing party + /// @param mine this party's share + /// @return reconstructed public value (`mine + peer`) + /// @throws std::logic_error if either side is p2 + template + HEDLEY_WARN_UNUSED_RESULT + Ring open_with(role peer, const Ring & mine) + { + if (self_ == role::p2 || peer == role::p2) + throw std::logic_error("open_with is between p0 and p1"); + Ring theirs = exchange_with(peer, mine, msg::delta); + return static_cast(mine + theirs); + } + + /// @brief Exchange raw values (no algebra) with a peer. + /// @tparam T trivially copyable payload + /// @param peer the other party + /// @param mine this party's value + /// @param tag the message tag + /// @return the peer's value + template + HEDLEY_WARN_UNUSED_RESULT + T exchange_with(role peer, const T & mine, msg tag = msg::delta) + { + static_assert(std::is_trivially_copyable_v, + "trio::exchange_with requires a trivially copyable type"); + if (hook_) + { + auto bytes = hook_->exchange_bytes(*this, to_u(peer), tag, &mine, + sizeof(T)); + if (bytes.size() != sizeof(T)) + throw std::runtime_error("trio::exchange_with size mismatch"); + T theirs{}; + if constexpr (sizeof(T) != 0) + std::memcpy(&theirs, bytes.data(), sizeof(T)); + return theirs; + } + return to(peer).template exchange(to_u(self_), to_u(peer), mine, tag); + } + + /// @brief Exchange a homogeneous vector with a peer (one barrier). + /// @tparam T trivially copyable element + /// @param peer the other party + /// @param mine this party's values + /// @param tag the message tag + /// @return the peer's values + template + HEDLEY_WARN_UNUSED_RESULT + std::vector exchange_vec_with(role peer, const std::vector & mine, + msg tag = msg::ring_vector) + { + static_assert(std::is_trivially_copyable_v, + "trio::exchange_vec_with requires a trivially copyable type"); + if (mine.empty()) + return {}; + if (hook_) + { + const std::size_t nbytes = mine.size() * sizeof(T); + auto bytes = hook_->exchange_vec_bytes(*this, to_u(peer), tag, + mine.data(), nbytes); + if (bytes.size() != nbytes) + throw std::runtime_error("trio::exchange_vec_with size mismatch"); + std::vector theirs(mine.size()); + std::memcpy(theirs.data(), bytes.data(), nbytes); + return theirs; + } + return to(peer).template exchange_vec( + to_u(self_), to_u(peer), mine, tag); + } + + /// @brief Open additive shares packed into one vector exchange. + /// @tparam Ring additive ring + /// @param peer the other computing party + /// @param mine this party's shares + /// @return reconstructed public values (`mine[i] + peer[i]`) + template + HEDLEY_WARN_UNUSED_RESULT + std::vector open_vec_with(role peer, const std::vector & mine) + { + if (self_ == role::p2 || peer == role::p2) + throw std::logic_error("open_vec_with is between p0 and p1"); + auto theirs = exchange_vec_with(peer, mine); + std::vector out(mine.size()); + for (std::size_t i = 0; i < mine.size(); ++i) + out[i] = static_cast(mine[i] + theirs[i]); + return out; + } + +private: + role self_ = role::p0; + std::unique_ptr io_; + channel link_[3]; + comm_hook * hook_ = nullptr; + + static channel connect_one(role self, role peer, const std::string & dir, + asio::io_context & io, unsigned retries, const peer_security & sec, + const deadlines & lim) + { + using proto = asio::local::stream_protocol; + const bool accept = to_u(self) < to_u(peer); + const auto path = link_path(dir, self, peer); + const std::string who = role_name(peer); + if (accept) + { + ::unlink(path.c_str()); + proto::endpoint ep(path); + proto::acceptor acc(io, ep); + for (unsigned i = 0; i < retries; ++i) + { + asio::error_code ec; + proto::socket sock(io); + acc.accept(sock, ec); + if (!ec) + return secure_local_channel(io, std::move(sock), true, + to_u(peer), sec, lim.handshake, who, "accept"); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + throw std::runtime_error("trio accept failed: " + path); + } + proto::endpoint ep(path); + for (unsigned i = 0; i < retries; ++i) + { + asio::error_code ec; + proto::socket sock(io); + sock.connect(ep, ec); + if (!ec) + return secure_local_channel(io, std::move(sock), false, + to_u(peer), sec, lim.handshake, who, "connect"); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + throw std::runtime_error("trio connect failed: " + path); + } + + static std::uint16_t tcp_port(std::uint16_t base, role a, role b) + { + if (to_u(a) > to_u(b)) + std::swap(a, b); + return static_cast(base + 10u * to_u(a) + to_u(b)); + } + + static channel connect_one_tcp(role self, role peer, std::uint16_t base, + const std::string & host, asio::io_context & io, unsigned retries, + const peer_security & sec, const deadlines & lim, + const socket_options & so) + { + using tcp = asio::ip::tcp; + const bool accept = to_u(self) < to_u(peer); + const auto port = tcp_port(base, self, peer); + const std::string who = role_name(peer); + if (accept) + { + tcp::endpoint ep(tcp::v4(), port); + tcp::acceptor acc(io); + asio::error_code ec; + acc.open(ep.protocol(), ec); + acc.set_option(tcp::acceptor::reuse_address(true), ec); + acc.bind(ep, ec); + if (ec) + throw std::runtime_error("trio tcp bind: " + ec.message()); + acc.listen(1, ec); + for (unsigned i = 0; i < retries; ++i) + { + tcp::socket sock(io); + acc.accept(sock, ec); + if (!ec) + return secure_tcp_channel(io, std::move(sock), true, + to_u(peer), sec, so, lim.handshake, who, "accept"); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + throw std::runtime_error("trio tcp accept failed"); + } + tcp::resolver resolver(io); + auto endpoints = resolver.resolve(host, std::to_string(port)); + for (unsigned i = 0; i < retries; ++i) + { + asio::error_code ec; + tcp::socket sock(io); + asio::connect(sock, endpoints, ec); + if (!ec) + return secure_tcp_channel(io, std::move(sock), false, + to_u(peer), sec, so, lim.handshake, who, "connect"); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + throw std::runtime_error("trio tcp connect failed"); + } +}; + +} // namespace net +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_NET_TRIO_HPP__ diff --git a/include/dpf/nyble.hpp b/include/dpf/nyble.hpp index b293012..16419dc 100644 --- a/include/dpf/nyble.hpp +++ b/include/dpf/nyble.hpp @@ -26,6 +26,13 @@ namespace dpf { /// @brief 4-bit unsigned ring element, packed one nibble per lane +/// @note Not a DPF domain. A 4-bit index is `dpf::modint<4>` or `dpf::xint<4>`. +/// Scalar `+` and `-` wrap mod 16. A carry must not cross into the next +/// nibble. +/// @see dpf::bit +/// @see dpf::twobit +/// @see dpf::modint +/// @see dpf::packed enum class nyble : std::uint8_t { zero = 0 diff --git a/include/dpf/offset_wrapper.hpp b/include/dpf/offset_wrapper.hpp index 1f2bf4a..15ecdf3 100644 --- a/include/dpf/offset_wrapper.hpp +++ b/include/dpf/offset_wrapper.hpp @@ -1,5 +1,25 @@ /// @file dpf/offset_wrapper.hpp -/// @brief An output value shifted by a public offset. +/// @brief The input offset stored on a key. +/// @details A concrete input ignores the stored word. A wildcard input +/// plants a mask at keygen. Parties open `mask - alpha` with +/// `compute_and_get_share` and `reconstruct`. `operator()` throws +/// `std::runtime_error` ("offset not set") until that finishes. +/// +/// Additive blinding means evaluation uses tree coordinates +/// `x ↦ x + δ` once `δ` is ready (`offset_x`). Eager `eval_interval` +/// folds that map into the traversed range. Interval memoizers and +/// output buffers built from a key (`make_basic_interval_memoizer(dpf, +/// from, to)`, `make_output_buffer_for_interval(dpf, from, to)`) size +/// against those tree coordinates: leaf packing depends on alignment +/// after `δ`, so sizing only on the logical endpoints can undersize. +/// When `δ` is not yet known, use `defer_eval_interval` / +/// `defer_eval_full`: evaluate the full domain at identity, then after +/// assign materialize a view rotated by `offset_x(0)` (see +/// `deferred_rotated_subinterval`). +/// @see dpf::wildcard_value +/// @see dpf::leaf_wrapper +/// @see dpf::deferred_rotated_subinterval +/// @see dpf::defer_eval_interval /// @author Ryan Henry /// @copyright Copyright (c) 2019-2024 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license; diff --git a/include/dpf/online_session.hpp b/include/dpf/online_session.hpp new file mode 100644 index 0000000..8b69541 --- /dev/null +++ b/include/dpf/online_session.hpp @@ -0,0 +1,573 @@ +/// @file dpf/online_session.hpp +/// @brief Prep delivery and application sessions over any async link. +/// @details Every function here comes in two layers: a per-party function +/// that takes the links it should use (memory, unix, TCP, SCTP, +/// `party_session::dealer()`), and an in-process wrapper that builds +/// links from `run_config` and runs every party on a thread. +/// Prep travels as `u32 length || view` on lane 0. +#ifndef LIBDPF_INCLUDE_DPF_ONLINE_SESSION_HPP__ +#define LIBDPF_INCLUDE_DPF_ONLINE_SESSION_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/app_plans.hpp" +#include "dpf/mesh_apps.hpp" +#include "dpf/net/async_round_sink.hpp" +#include "dpf/net/async_stream_array.hpp" +#include "dpf/net/edge_mesh.hpp" +#include "dpf/net/party_session.hpp" +#include "dpf/prep_source.hpp" +#include "dpf/protocol.hpp" +#include "dpf/run_config.hpp" + +namespace dpf +{ +namespace session +{ + +struct shipped_prep +{ + prep::cursor party0; + prep::cursor party1; + std::size_t bytes0 = 0; + std::size_t bytes1 = 0; +}; + +namespace detail +{ + +/// @brief Pump `io` until `done` or `budget` passes. +inline void pump_until(asio::io_context & io, const std::atomic & done, + std::chrono::milliseconds budget, const char * what) +{ + const auto deadline = std::chrono::steady_clock::now() + budget; + while (!done.load(std::memory_order_acquire)) + { + const auto now = std::chrono::steady_clock::now(); + if (now >= deadline) + throw std::system_error(std::make_error_code(std::errc::timed_out), + std::string(what) + ": timed out after " + + std::to_string(budget.count()) + " ms"); + if (io.stopped()) + io.restart(); + io.run_one_for(std::min( + std::chrono::duration_cast(deadline - now), + std::chrono::milliseconds(50))); + } +} + +inline void run_session(protocol::schedule_session & sess, + std::chrono::milliseconds budget, const char * what) +{ + protocol::drive_options opt; + opt.wait_timeout = budget; + protocol::detail::run_session(sess, opt, what); +} + +} // namespace detail + +/// @brief Send one prep view on lane 0 of `link` (`u32 length || bytes`). +inline void send_prep(net::async_stream_array & link, + const std::vector & view, + std::chrono::milliseconds budget = std::chrono::milliseconds(30000)) +{ + auto frame = net::acquire_buffer(4 + view.size()); + net::detail::put_u32(frame->data(), static_cast(view.size())); + if (!view.empty()) + std::memcpy(frame->data() + 4, view.data(), view.size()); + auto done = std::make_shared>(false); + auto err = std::make_shared(); + link.async_write_owned(0, std::move(frame), + [done, err](const std::error_code & ec) { + *err = ec; + done->store(true, std::memory_order_release); + }); + detail::pump_until(link.context(), *done, budget, "send_prep"); + if (*err) + throw std::system_error(*err, "send_prep"); +} + +/// @brief Receive one prep view from lane 0 of `link`. +inline std::vector receive_prep(net::async_stream_array & link, + std::chrono::milliseconds budget = std::chrono::milliseconds(30000)) +{ + auto lenb = std::make_shared>(); + auto done = std::make_shared>(false); + auto err = std::make_shared(); + link.async_read(0, lenb->data(), 4, [done, err, lenb](const std::error_code & ec) { + *err = ec; + done->store(true, std::memory_order_release); + }); + detail::pump_until(link.context(), *done, budget, "receive_prep length"); + if (*err) + throw std::system_error(*err, "receive_prep length"); + auto body = std::make_shared>( + net::detail::get_u32(lenb->data())); + if (body->empty()) + return {}; + done->store(false); + link.async_read(0, body->data(), body->size(), + [done, err, body](const std::error_code & ec) { + *err = ec; + done->store(true, std::memory_order_release); + }); + detail::pump_until(link.context(), *done, budget, "receive_prep body"); + if (*err) + throw std::system_error(*err, "receive_prep body"); + return *body; +} + +/// @brief Dealer role: deal `d` and send each party its view. +inline std::pair deal_and_send( + net::async_stream_array & to_p0, net::async_stream_array & to_p1, + const prep::demand & d, + std::chrono::milliseconds budget = std::chrono::milliseconds(30000)) +{ + auto views = prep::deal_views(d); + send_prep(to_p0, views.first, budget); + send_prep(to_p1, views.second, budget); + return {views.first.size(), views.second.size()}; +} + +/// @brief Deal `d` and ship both views over links built from `cfg`. +/// @details Socket transports use a `dealer_session` that both parties +/// connect to with `party_session::connect_dealer`; in-process +/// transports use memory pairs. +inline shipped_prep ship_prep(const prep::demand & d, + const app::run_config & cfg = {}) +{ + std::exception_ptr err; + std::mutex err_mu; + auto note = [&] { + std::lock_guard lock(err_mu); + if (!err) + err = std::current_exception(); + }; + std::vector got0, got1; + const auto budget = cfg.wait_timeout.count() != 0 ? cfg.wait_timeout + : std::chrono::milliseconds(30000); + if (net::is_socket_transport(cfg.kind) && cfg.kind != net::transport::local) + { + asio::io_context io_d, io0, io1; + net::session_options so; + so.policy = cfg.policy; + so.limits = cfg.limits; + so.security = cfg.security; + std::atomic port{0}; + std::thread dealer([&] { + try + { + net::dealer_session ds(io_d, 2, so); + port.store(ds.listen()); + ds.accept_parties(); + deal_and_send(ds.party(0), ds.party(1), d, budget); + } + catch (...) + { + note(); + } + }); + auto party = [&](unsigned me, asio::io_context & io, + std::vector & out) { + try + { + const auto deadline = std::chrono::steady_clock::now() + cfg.limits.join; + while (port.load() == 0) + { + if (std::chrono::steady_clock::now() > deadline) + throw std::runtime_error("ship_prep: dealer never listened"); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + net::party_session ps(io, me, 2, so); + ps.connect_dealer(cfg.host, port.load()); + out = receive_prep(ps.dealer(), budget); + } + catch (...) + { + note(); + } + }; + std::thread p0([&] { party(0, io0, got0); }); + std::thread p1([&] { party(1, io1, got1); }); + dealer.join(); + p0.join(); + p1.join(); + } + else + { + asio::io_context io_d, io0, io1; + auto link0 = net::make_async_dual_memory_stream_pair(io_d, io0, 1); + auto link1 = net::make_async_dual_memory_stream_pair(io_d, io1, 1); + std::thread dealer([&] { + try + { + deal_and_send(link0.first, link1.first, d, budget); + } + catch (...) + { + note(); + } + }); + std::thread p0([&] { + try + { + got0 = receive_prep(link0.second, budget); + } + catch (...) + { + note(); + } + }); + std::thread p1([&] { + try + { + got1 = receive_prep(link1.second, budget); + } + catch (...) + { + note(); + } + }); + dealer.join(); + p0.join(); + p1.join(); + } + if (err) + std::rethrow_exception(err); + shipped_prep out; + out.bytes0 = got0.size(); + out.bytes1 = got1.size(); + out.party0 = prep::cursor(std::move(got0)); + out.party1 = prep::cursor(std::move(got1)); + return out; +} + +/// @brief One party of hushmap ADD: pad tape on `pad_link`, opens on `peer_link`. +inline void drive_hushmap_add_party(std::size_t layers, + net::async_stream_array & peer_link, net::async_stream_array & pad_link, + std::chrono::milliseconds budget = std::chrono::milliseconds(30000)) +{ + auto tape = std::make_shared>(); + auto rounds = protocol::hushmap_add_schedule(layers, tape); + net::async_round_sink peer_sink(peer_link, {8u, 8u}, 1); + net::async_round_sink pad_sink(pad_link, std::vector(layers, 24u), 1); + protocol::edge_mesh mesh; + mesh.sinks = {&peer_sink, nullptr, &pad_sink}; + protocol::schedule_session sess(1, mesh, std::move(rounds), false); + sess.submit(0); + detail::run_session(sess, budget, "hushmap_add"); +} + +/// @brief Both hushmap parties in one process over links from `cfg`. +inline void drive_hushmap_add(std::size_t layers, const app::run_config & cfg = {}) +{ + if (net::is_socket_transport(cfg.kind) && cfg.kind != net::transport::local) + { + auto ports = net::make_mesh_ports(2); + std::exception_ptr err; + std::mutex mu; + auto run = [&](unsigned me) { + try + { + asio::io_context io; + net::session_options so; + so.n_lanes = std::max(2, layers) + 2; + so.kind = cfg.kind; + so.policy = cfg.policy; + so.limits = cfg.limits; + so.security = cfg.security; + net::party_session ps(io, me, 2, so); + ps.join(cfg.host, ports); + net::async_stream_view peer(ps.peer(1 - me), 0, 2); + net::async_stream_view pad(ps.peer(1 - me), 2, + std::max(1, layers)); + drive_hushmap_add_party(layers, peer, pad, cfg.wait_timeout); + } + catch (...) + { + std::lock_guard lock(mu); + if (!err) + err = std::current_exception(); + } + }; + std::thread t0([&] { run(0); }); + std::thread t1([&] { run(1); }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); + return; + } + asio::io_context io0, io1; + auto peer = net::make_async_dual_memory_stream_pair(io0, io1, 2); + auto pad = net::make_async_dual_memory_stream_pair(io0, io1, + std::max(1, layers)); + std::exception_ptr err; + std::mutex mu; + auto run = [&](net::async_stream_array & pl, net::async_stream_array & dl) { + try + { + drive_hushmap_add_party(layers, pl, dl, cfg.wait_timeout); + } + catch (...) + { + std::lock_guard lock(mu); + if (!err) + err = std::current_exception(); + pl.close(); + dl.close(); + } + }; + std::thread t0([&] { run(peer.first, pad.first); }); + std::thread t1([&] { run(peer.second, pad.second); }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); +} + +/// @brief Star client over `links[i]` (edge `i` → server `i`). +inline void drive_star_client(const std::vector & links, + const std::vector & slots, + std::vector rounds, + std::chrono::milliseconds budget = std::chrono::milliseconds(30000), + const net::sink_options & so = {}) +{ + std::vector> sinks; + protocol::edge_mesh mesh; + mesh.sinks.resize(links.size()); + for (std::size_t i = 0; i < links.size(); ++i) + { + sinks.push_back( + std::make_unique(*links[i], slots, 1, so)); + mesh.sinks[i] = sinks.back().get(); + } + protocol::schedule_session sess(1, mesh, std::move(rounds), false); + sess.submit(0); + detail::run_session(sess, budget, "star client"); +} + +/// @brief One star server over `link`. +inline void drive_star_server(net::async_stream_array & link, + const std::vector & slots, + std::vector rounds, + std::chrono::milliseconds budget = std::chrono::milliseconds(30000), + const net::sink_options & so = {}) +{ + net::async_round_sink sink(link, slots, 1, so); + protocol::edge_mesh mesh; + mesh.sinks = {&sink}; + protocol::schedule_session sess(1, mesh, std::move(rounds), false); + sess.submit(0); + detail::run_session(sess, budget, "star server"); +} + +/// @brief Client and `n_servers` servers in one process on split-io memory. +inline void drive_async_star(std::size_t n_servers, + const std::vector & slots, + std::vector client_rounds, + const std::function(std::size_t)> & + server_rounds_for, + std::chrono::milliseconds budget = std::chrono::milliseconds(30000)) +{ + if (n_servers < 1) + throw std::invalid_argument("drive_async_star servers"); + asio::io_context io_client; + std::vector io_server(n_servers); + std::vector> + links; + links.reserve(n_servers); + for (std::size_t i = 0; i < n_servers; ++i) + links.push_back(net::make_async_dual_memory_stream_pair(io_client, + io_server[i], slots.size())); + std::exception_ptr err; + std::mutex err_mu; + auto note = [&] { + std::lock_guard lock(err_mu); + if (!err) + err = std::current_exception(); + }; + std::thread client([&] { + std::vector ls; + for (auto & l : links) + ls.push_back(&l.first); + try + { + drive_star_client(ls, slots, std::move(client_rounds), budget); + } + catch (...) + { + note(); + for (auto * l : ls) + l->close(); + } + }); + std::vector servers; + for (std::size_t i = 0; i < n_servers; ++i) + { + servers.emplace_back([&, i] { + try + { + drive_star_server(links[i].second, slots, server_rounds_for(i), + budget); + } + catch (...) + { + note(); + links[i].second.close(); + } + }); + } + client.join(); + for (auto & t : servers) + t.join(); + if (err) + std::rethrow_exception(err); +} + +/// @brief Client and `n_servers` servers, one thread each, over `cfg.kind`. +/// @details Every client-server edge is its own link and servers never connect +/// to each other: split-io memory for `async`, unix sockets for +/// `local`, and a two-party `party_session` per edge for `mux`, +/// `parallel`, and `sctp`. Lanes, framing, wire policy, deadlines, +/// and the per-round wait budget come from `cfg`. +inline void drive_async_star(std::size_t n_servers, + const std::vector & slots, + std::vector client_rounds, + const std::function(std::size_t)> & + server_rounds_for, + const app::run_config & cfg) +{ + if (n_servers < 1) + throw std::invalid_argument("drive_async_star servers"); + const bool sockets = cfg.kind == net::transport::mux + || cfg.kind == net::transport::parallel || cfg.kind == net::transport::sctp; + if (!sockets && cfg.kind != net::transport::async_memory + && cfg.kind != net::transport::local) + throw std::invalid_argument(std::string("drive_async_star: transport ") + + net::transport_name(cfg.kind) + + " is not an async link (use async|local|mux|parallel|sctp)"); + const std::size_t lanes = net::lane_count_for_rounds(slots.size(), cfg.n_lanes); + net::sink_options so; + so.framing = cfg.framing; + const auto budget = cfg.wait_timeout; + + asio::io_context io_client; + std::vector io_server(n_servers); + std::vector> client_end(n_servers); + std::vector> server_end(n_servers); + for (std::size_t i = 0; i < n_servers && !sockets; ++i) + { + if (cfg.kind == net::transport::async_memory) + { + auto pr = net::make_async_dual_memory_stream_pair(io_client, io_server[i], + lanes, cfg.policy.window_bytes); + client_end[i] = + std::make_unique(std::move(pr.first)); + server_end[i] = + std::make_unique(std::move(pr.second)); + } + else + { + auto pr = net::make_local_socket_pairs(io_client, io_server[i], lanes); + client_end[i] = std::make_unique( + io_client, std::move(pr.first), cfg.policy); + server_end[i] = std::make_unique( + io_server[i], std::move(pr.second), cfg.policy); + } + } + net::session_options sopt; + sopt.n_lanes = lanes; + sopt.kind = cfg.kind; + sopt.policy = cfg.policy; + sopt.limits = cfg.limits; + sopt.security = cfg.security; + std::vector ports; + ports.reserve(n_servers); + for (std::size_t i = 0; i < n_servers; ++i) + ports.push_back(net::make_mesh_ports(2)); + + std::exception_ptr err; + std::mutex err_mu; + auto note = [&] { + std::lock_guard lock(err_mu); + if (!err) + err = std::current_exception(); + }; + std::thread client([&] { + std::vector> sess; + std::vector ls; + try + { + for (std::size_t i = 0; i < n_servers; ++i) + { + if (sockets) + { + sess.push_back( + std::make_unique(io_client, 0, 2, sopt)); + sess.back()->join(cfg.host, ports[i]); + ls.push_back(&sess.back()->peer(1)); + } + else + ls.push_back(client_end[i].get()); + } + drive_star_client(ls, slots, std::move(client_rounds), budget, so); + } + catch (...) + { + note(); + for (auto * l : ls) + l->close(); + } + }); + std::vector servers; + for (std::size_t i = 0; i < n_servers; ++i) + { + servers.emplace_back([&, i] { + std::unique_ptr s; + net::async_stream_array * link = server_end[i].get(); + try + { + if (sockets) + { + s = std::make_unique(io_server[i], 1, 2, sopt); + s->join(cfg.host, ports[i]); + link = &s->peer(0); + } + drive_star_server(*link, slots, server_rounds_for(i), budget, so); + } + catch (...) + { + note(); + if (link != nullptr) + link->close(); + } + }); + } + client.join(); + for (auto & t : servers) + t.join(); + if (err) + std::rethrow_exception(err); +} + +} // namespace session +} // namespace dpf + +#endif diff --git a/include/dpf/ot_pack.hpp b/include/dpf/ot_pack.hpp new file mode 100644 index 0000000..745f51e --- /dev/null +++ b/include/dpf/ot_pack.hpp @@ -0,0 +1,404 @@ +/// @file dpf/ot_pack.hpp +/// @brief Consuming cursor over correlated B2A / bit / bit×ring pads. +/// @details Dealer mode builds one shared tape and splits it into party views. +/// Two parties each calling `dealer()` independently is unsupported; +/// use `sample_dealer_pair`. +#ifndef LIBDPF_INCLUDE_DPF_OT_PACK_HPP__ +#define LIBDPF_INCLUDE_DPF_OT_PACK_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" +#include "simde/simde/x86/avx2.h" + +#include "dpf/beaver.hpp" +#include "dpf/random.hpp" + +namespace dpf +{ +namespace ot +{ + +template +struct dabit +{ + std::uint8_t bit = 0; + Ring arith{}; +}; + +struct bit_triple +{ + std::uint8_t a = 0; + std::uint8_t b = 0; + std::uint8_t c = 0; +}; + +/// @brief Bit × ring triple: `(a0⊕a1)·(b0+b1) = c0+c1`. +template +struct bit_ring_triple +{ + std::uint8_t a = 0; ///< XOR share of the bit + Ring b{}; ///< Additive share of the scalar + Ring c{}; ///< Additive share of the product +}; + +struct b2a_slot +{ + std::uint8_t r = 0; + std::uint64_t add = 0; +}; + +template +struct dabit_pair +{ + dabit p0; + dabit p1; +}; + +struct bit_triple_pair +{ + bit_triple p0; + bit_triple p1; +}; + +template +struct bit_ring_triple_pair +{ + bit_ring_triple p0; + bit_ring_triple p1; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +dabit_pair sample_dabit_pair() +{ + struct pad + { + std::uint8_t bit() + { + return static_cast( + dpf::uniform_sample() & 1u); + } + simde__m128i block() + { + return dpf::uniform_sample(); + } + } p; + auto ba = beavers::sample_bit_arith(p); + dabit_pair out; + out.p0.bit = ba.xor0; + out.p0.arith = static_cast(ba.add0); + out.p1.bit = ba.xor1; + out.p1.arith = static_cast(ba.add1); + return out; +} + +HEDLEY_WARN_UNUSED_RESULT +inline bit_triple_pair sample_bit_triple_pair() +{ + const std::uint8_t a = static_cast( + dpf::uniform_sample() & 1u); + const std::uint8_t b = static_cast( + dpf::uniform_sample() & 1u); + const std::uint8_t c = static_cast(a & b); + const std::uint8_t a0 = static_cast( + dpf::uniform_sample() & 1u); + const std::uint8_t b0 = static_cast( + dpf::uniform_sample() & 1u); + const std::uint8_t c0 = static_cast( + dpf::uniform_sample() & 1u); + bit_triple_pair out; + out.p0 = {a0, b0, c0}; + out.p1 = {static_cast(a ^ a0), + static_cast(b ^ b0), + static_cast(c ^ c0)}; + return out; +} + +template +HEDLEY_WARN_UNUSED_RESULT +bit_ring_triple_pair sample_bit_ring_triple_pair() +{ + // a is XOR-shared with party 1 holding 0 so a0+a1 = a0⊕a1 in the ring. + const std::uint8_t a = static_cast( + dpf::uniform_sample() & 1u); + const Ring b = dpf::uniform_sample(); + const Ring c = static_cast(Ring{a} * b); + const Ring b0 = dpf::uniform_sample(); + const Ring c0 = dpf::uniform_sample(); + bit_ring_triple_pair out; + out.p0 = {a, b0, c0}; + out.p1 = {0, static_cast(b - b0), static_cast(c - c0)}; + return out; +} + +class pack +{ +public: + pack() = default; + + void load_b2a(std::vector slots) + { + mode_ = mode::pads; + b2a_ = std::move(slots); + b2a_pos_ = 0; + } + + void load_bits(std::vector bits) + { + mode_ = mode::pads; + bits_ = std::move(bits); + bit_pos_ = 0; + } + + template + void load_bit_ring(std::vector> triples) + { + mode_ = mode::pads; + bit_ring_.clear(); + bit_ring_.reserve(triples.size() * sizeof(bit_ring_triple)); + for (const auto & t : triples) + { + const auto * p = reinterpret_cast(&t); + bit_ring_.insert(bit_ring_.end(), p, p + sizeof(t)); + } + bit_ring_elem_ = sizeof(bit_ring_triple); + bit_ring_pos_ = 0; + } + + /// @brief One party's view of a pre-split correlated tape. + static pack from_party_view(int me, std::vector b2a, + std::vector bits, + std::vector bit_ring_bytes = {}, + std::size_t bit_ring_elem = 0) + { + pack p; + p.mode_ = mode::pads; + p.me_ = me; + p.b2a_ = std::move(b2a); + p.bits_ = std::move(bits); + p.bit_ring_ = std::move(bit_ring_bytes); + p.bit_ring_elem_ = bit_ring_elem; + return p; + } + + HEDLEY_WARN_UNUSED_RESULT + std::size_t remaining_b2a() const noexcept + { + return b2a_.size() > b2a_pos_ ? b2a_.size() - b2a_pos_ : 0; + } + + HEDLEY_WARN_UNUSED_RESULT + std::size_t remaining_bits() const noexcept + { + return bits_.size() > bit_pos_ ? bits_.size() - bit_pos_ : 0; + } + + HEDLEY_WARN_UNUSED_RESULT + std::size_t remaining_bit_ring() const noexcept + { + if (bit_ring_elem_ == 0) + return 0; + const std::size_t n = bit_ring_.size() / bit_ring_elem_; + return n > bit_ring_pos_ ? n - bit_ring_pos_ : 0; + } + + template + dabit take_dabit() + { + if (b2a_pos_ >= b2a_.size()) + throw std::runtime_error("ot_pack: no B2A slots left"); + const auto & s = b2a_[b2a_pos_++]; + dabit out; + out.bit = s.r; + out.arith = static_cast(s.add); + return out; + } + + bit_triple take_bit_triple() + { + if (bit_pos_ >= bits_.size()) + throw std::runtime_error("ot_pack: no bit triples left"); + return bits_[bit_pos_++]; + } + + template + bit_ring_triple take_bit_ring() + { + if (bit_ring_elem_ != sizeof(bit_ring_triple)) + throw std::runtime_error("ot_pack: bit_ring element size mismatch"); + if (remaining_bit_ring() == 0) + throw std::runtime_error("ot_pack: no bit×ring triples left"); + bit_ring_triple t{}; + std::memcpy(&t, bit_ring_.data() + bit_ring_pos_ * bit_ring_elem_, + sizeof(t)); + ++bit_ring_pos_; + return t; + } + + int party() const noexcept { return me_; } + + /// @brief Remember a party tape written by `fill_tape_ot_pair`. + template + void stash_party_tape(const beavers::party_tape & tape) + { + tape_elem_ = sizeof(Ring); + tape_lambda_ready_ = tape.lambda_ready; + tape_mono_ready_ = tape.monomial_ready; + tape_bundle_ready_ = tape.bundles_ready; + tape_dot_ready_ = tape.dot_ready; + tape_lambda_ = bytes_of(tape.lambda); + tape_mono_ = bytes_of(tape.monomial); + tape_bundle_ = bytes_of(tape.bundles); + tape_dot_ = bytes_of(tape.dot_cross); + has_tape_ = true; + } + + bool has_party_tape() const noexcept { return has_tape_; } + + /// @brief Serializable OT pad view for dealer / online streams. + struct wire + { + int me = 0; + std::vector b2a; + std::vector bits; + std::vector bit_ring; + std::size_t bit_ring_elem = 0; + }; + + HEDLEY_WARN_UNUSED_RESULT + wire export_wire() const + { + wire w; + w.me = me_; + w.b2a = b2a_; + w.bits = bits_; + w.bit_ring = bit_ring_; + w.bit_ring_elem = bit_ring_elem_; + return w; + } + + static pack from_wire(wire w) + { + pack p; + p.mode_ = mode::pads; + p.me_ = w.me; + p.b2a_ = std::move(w.b2a); + p.bits_ = std::move(w.bits); + p.bit_ring_ = std::move(w.bit_ring); + p.bit_ring_elem_ = w.bit_ring_elem; + return p; + } + + template + beavers::party_tape load_party_tape() const + { + if (!has_tape_ || tape_elem_ != sizeof(Ring)) + throw std::runtime_error( + "ot_pack: no stashed party tape for this ring"); + beavers::party_tape t; + t.lambda_ready = tape_lambda_ready_; + t.monomial_ready = tape_mono_ready_; + t.bundles_ready = tape_bundle_ready_; + t.dot_ready = tape_dot_ready_; + t.lambda = vec_of(tape_lambda_); + t.monomial = vec_of(tape_mono_); + t.bundles = vec_of(tape_bundle_); + t.dot_cross = vec_of(tape_dot_); + return t; + } + +private: + template + static std::vector bytes_of(const std::vector & v) + { + std::vector out(v.size() * sizeof(Ring)); + if (!out.empty()) + std::memcpy(out.data(), v.data(), out.size()); + return out; + } + + template + static std::vector vec_of(const std::vector & b) + { + if (b.size() % sizeof(Ring) != 0) + throw std::runtime_error("ot_pack: tape byte size"); + std::vector out(b.size() / sizeof(Ring)); + if (!out.empty()) + std::memcpy(out.data(), b.data(), b.size()); + return out; + } + enum class mode : unsigned char { empty, pads }; + mode mode_ = mode::empty; + int me_ = 0; + std::vector b2a_; + std::vector bits_; + std::vector bit_ring_; + std::size_t bit_ring_elem_ = 0; + std::size_t b2a_pos_ = 0; + std::size_t bit_pos_ = 0; + std::size_t bit_ring_pos_ = 0; + bool has_tape_ = false; + std::size_t tape_elem_ = 0; + std::vector tape_lambda_ready_; + std::vector tape_mono_ready_; + std::vector tape_bundle_ready_; + std::vector tape_dot_ready_; + std::vector tape_lambda_; + std::vector tape_mono_; + std::vector tape_bundle_; + std::vector tape_dot_; +}; + +/// @brief Sample correlated pads and return both party views. +template +HEDLEY_WARN_UNUSED_RESULT +std::pair sample_dealer_pair(std::size_t n_dabit, + std::size_t n_bit_triple = 0, std::size_t n_bit_ring = 0) +{ + std::vector b0, b1; + b0.reserve(n_dabit); + b1.reserve(n_dabit); + for (std::size_t i = 0; i < n_dabit; ++i) + { + auto d = sample_dabit_pair(); + b0.push_back({d.p0.bit, static_cast(d.p0.arith)}); + b1.push_back({d.p1.bit, static_cast(d.p1.arith)}); + } + std::vector t0, t1; + t0.reserve(n_bit_triple); + t1.reserve(n_bit_triple); + for (std::size_t i = 0; i < n_bit_triple; ++i) + { + auto tp = sample_bit_triple_pair(); + t0.push_back(tp.p0); + t1.push_back(tp.p1); + } + std::vector> r0, r1; + r0.reserve(n_bit_ring); + r1.reserve(n_bit_ring); + for (std::size_t i = 0; i < n_bit_ring; ++i) + { + auto rp = sample_bit_ring_triple_pair(); + r0.push_back(rp.p0); + r1.push_back(rp.p1); + } + auto pack0 = pack::from_party_view(0, std::move(b0), std::move(t0)); + auto pack1 = pack::from_party_view(1, std::move(b1), std::move(t1)); + if (n_bit_ring != 0) + { + pack0.load_bit_ring(std::move(r0)); + pack1.load_bit_ring(std::move(r1)); + } + return {std::move(pack0), std::move(pack1)}; +} + +} // namespace ot +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_OT_PACK_HPP__ diff --git a/include/dpf/output_buffer.hpp b/include/dpf/output_buffer.hpp index 57a5f40..bfc45e0 100644 --- a/include/dpf/output_buffer.hpp +++ b/include/dpf/output_buffer.hpp @@ -6,6 +6,7 @@ /// Trivially default-constructible slots are left uninitialized /// because evaluation overwrites every slot it is responsible for. /// +/// `bit` / `gf2`, `twobit` / `gf22`, and `nyble` / `gf24` slots are packed. /// `eval_interval` and recipe `eval_sequence` take the buffer by /// non-const reference. The returned iterable refers into it. /// @snippet evaluation/output_buffers.cpp output-buffer @@ -314,11 +315,21 @@ auto make_output_buffer_for_interval(InputT from, InputT to) make_output_buffer_for_interval(from, to)...); } +/// @brief Buffer sized for the tree walk of `[from, to]` after `offset_x`. +/// @details Matches `make_basic_interval_memoizer(dpf, from, to)`: leaf packing +/// depends on alignment once a wildcard offset is ready. template -inline auto make_output_buffer_for_interval(const DpfKey &, InputT from, InputT to) +inline auto make_output_buffer_for_interval(const DpfKey & dpf, InputT from, InputT to) { + using input_type = typename DpfKey::input_type; + if (dpf.offset_x.is_ready()) + { + return make_output_buffer_for_interval( + dpf.offset_x(static_cast(from)), + dpf.offset_x(static_cast(to))); + } return make_output_buffer_for_interval(from, to); } @@ -327,8 +338,15 @@ template -inline auto make_output_buffer_for_interval(const DpfKey &, InputT from, InputT to) +inline auto make_output_buffer_for_interval(const DpfKey & dpf, InputT from, InputT to) { + using input_type = typename DpfKey::input_type; + if (dpf.offset_x.is_ready()) + { + const auto tfrom = dpf.offset_x(static_cast(from)); + const auto tto = dpf.offset_x(static_cast(to)); + return make_output_buffer_for_interval(tfrom, tto); + } return make_output_buffer_for_interval(from, to); } @@ -382,6 +400,7 @@ template auto make_output_buffer_for_subsequence(ForwardIterator begin, ForwardIterator end, ReturnType return_type = ReturnType{}) { + (void)return_type; using dpf_type = DpfKey; using output_type = typename DpfKey::concrete_output_type; using buffer_elem = leaf_buffer_elem_t; @@ -447,6 +466,7 @@ template auto make_output_buffer_for_recipe_subsequence(const sequence_recipe & recipe, ReturnType return_type = ReturnType{}) { + (void)return_type; using dpf_type = DpfKey; using output_type = typename DpfKey::concrete_output_type; using buffer_elem = leaf_buffer_elem_t; diff --git a/include/dpf/p256.hpp b/include/dpf/p256.hpp new file mode 100644 index 0000000..6c405e9 --- /dev/null +++ b/include/dpf/p256.hpp @@ -0,0 +1,1103 @@ +/// @file dpf/p256.hpp +/// @brief NIST P-256 points as a DPF output group. +/// @details A point is 33 bytes in SEC1 compressed form. The identity is 33 +/// zero bytes. `p256{k}` is `k` times the generator, and +/// `p256::from_compressed` reads a 33-byte encoding. Leaf addition is +/// point addition on valid encodings. A PRG block is stretched to at +/// least 256 bits and hashed onto the curve via `from_seed`. There is +/// no point×point product. This is a point-function output; it also +/// supplies `from_seed` for comparison payloads. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_P256_HPP__ +#define LIBDPF_INCLUDE_DPF_P256_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" +#include "simde/simde/x86/avx2.h" + +#include "dpf/leaf_arithmetic.hpp" +#include "dpf/random.hpp" +#include "dpf/utils.hpp" + +namespace dpf +{ + +namespace p256_detail +{ + +struct fe +{ + std::uint64_t d[4]{}; +}; + +inline constexpr std::uint64_t P[4] = { + 0xffffffffffffffffull, + 0x00000000ffffffffull, + 0x0000000000000000ull, + 0xffffffff00000001ull, +}; + +inline constexpr std::uint64_t B[4] = { + 0x3bce3c3e27d2604bull, + 0x651d06b0cc53b0f6ull, + 0xb3ebbd55769886bcull, + 0x5ac635d8aa3a93e7ull, +}; + +inline constexpr std::uint64_t GX[4] = { + 0xf4a13945d898c296ull, + 0x77037d812deb33a0ull, + 0xf8bce6e563a440f2ull, + 0x6b17d1f2e12c4247ull, +}; + +inline constexpr std::uint64_t GY[4] = { + 0xcbb6406837bf51f5ull, + 0x2bce33576b315eceull, + 0x8ee7eb4a7c0f9e16ull, + 0x4fe342e2fe1a7f9bull, +}; + +inline constexpr std::uint64_t N[4] = { + 0xf3b9cac2fc632551ull, + 0xbce6faada7179e84ull, + 0xffffffffffffffffull, + 0xffffffff00000000ull, +}; + +inline constexpr std::uint64_t EXP_P_PLUS_1_OVER_4[4] = { + 0x0000000000000000ull, + 0x0000000040000000ull, + 0x4000000000000000ull, + 0x3fffffffc0000000ull, +}; + +inline constexpr std::uint64_t EXP_P_MINUS_1_OVER_2[4] = { + 0xffffffffffffffffull, + 0x000000007fffffffull, + 0x8000000000000000ull, + 0x7fffffff80000000ull, +}; + +inline constexpr std::uint64_t EXP_P_MINUS_2[4] = { + 0xfffffffffffffffdull, + 0x00000000ffffffffull, + 0x0000000000000000ull, + 0xffffffff00000001ull, +}; + +struct affine +{ + fe x{}; + fe y{}; + bool inf = true; +}; + +HEDLEY_ALWAYS_INLINE +int fe_cmp(const fe &a, const fe &b) noexcept +{ + for (int i = 3; i >= 0; --i) + { + if (a.d[i] < b.d[i]) + return -1; + if (a.d[i] > b.d[i]) + return 1; + } + return 0; +} + +HEDLEY_ALWAYS_INLINE +int limbs_cmp(const std::uint64_t *a, const std::uint64_t *b, int n) noexcept +{ + for (int i = n - 1; i >= 0; --i) + { + if (a[i] < b[i]) + return -1; + if (a[i] > b[i]) + return 1; + } + return 0; +} + +HEDLEY_ALWAYS_INLINE +bool fe_is_zero(const fe &a) noexcept +{ + return (a.d[0] | a.d[1] | a.d[2] | a.d[3]) == 0; +} + +/// @brief Conditionally subtract `P` when `a` is in `[P, 2P)`. +HEDLEY_ALWAYS_INLINE +fe fe_sub_p_if_ge(fe a) noexcept +{ + if (fe_cmp(a, fe{{P[0], P[1], P[2], P[3]}}) >= 0) + { + unsigned borrow = 0; + for (int i = 0; i < 4; ++i) + { + const unsigned __int128 need = + static_cast(P[i]) + borrow; + const unsigned __int128 cur = a.d[i]; + if (cur >= need) + { + a.d[i] = static_cast(cur - need); + borrow = 0; + } + else + { + a.d[i] = static_cast( + (cur + (static_cast(1) << 64)) - need); + borrow = 1; + } + } + } + return a; +} + +HEDLEY_ALWAYS_INLINE +void u512_add_u64(std::uint64_t x[8], int limb, std::uint64_t v) noexcept +{ + unsigned __int128 sum = + static_cast(x[limb]) + v; + x[limb] = static_cast(sum); + unsigned __int128 carry = sum >> 64; + for (int i = limb + 1; carry && i < 8; ++i) + { + sum = static_cast(x[i]) + carry; + x[i] = static_cast(sum); + carry = sum >> 64; + } +} + +HEDLEY_ALWAYS_INLINE +void u512_add_shifted(std::uint64_t x[8], const std::uint64_t h[4], + int bit_shift) noexcept +{ + const int limb = bit_shift >> 6; + const int bit = bit_shift & 63; + for (int i = 0; i < 4; ++i) + { + if (bit == 0) + u512_add_u64(x, limb + i, h[i]); + else + { + u512_add_u64(x, limb + i, + static_cast(h[i] << bit)); + if (limb + i + 1 < 8) + u512_add_u64(x, limb + i + 1, h[i] >> (64 - bit)); + } + } +} + +HEDLEY_ALWAYS_INLINE +bool u512_sub(std::uint64_t x[8], const std::uint64_t y[8]) noexcept +{ + unsigned borrow = 0; + for (int i = 0; i < 8; ++i) + { + const unsigned __int128 need = + static_cast(y[i]) + borrow; + const unsigned __int128 cur = x[i]; + if (cur >= need) + { + x[i] = static_cast(cur - need); + borrow = 0; + } + else + { + x[i] = static_cast( + (cur + (static_cast(1) << 64)) - need); + borrow = 1; + } + } + return borrow != 0; +} + +HEDLEY_ALWAYS_INLINE +void u512_add_p_at(std::uint64_t x[8], int limb) noexcept +{ + unsigned __int128 carry = 0; + for (int i = 0; i < 4; ++i) + { + carry += static_cast(x[limb + i]) + P[i]; + x[limb + i] = static_cast(carry); + carry >>= 64; + } + for (int i = limb + 4; carry && i < 8; ++i) + { + carry += x[i]; + x[i] = static_cast(carry); + carry >>= 64; + } +} + +/// @brief Fast NIST P-256 reduction of a 512-bit little-endian product. +/// @details `2^256 ≡ 2^224 - 2^192 - 2^96 + 1 (mod p)`. Shifts are applied +/// as full `__int128` limb writes so carry propagation, not a second +/// half-limb store, moves the high bits. +inline fe fe_reduce_wide(const std::uint64_t z[8]) noexcept +{ + __int128 t[10]{}; + auto add = [&](int i, __int128 v) { t[i] += v; }; + for (int i = 0; i < 4; ++i) + { + add(i, static_cast<__int128>(z[i])); + add(i, static_cast<__int128>(z[4 + i])); + } + for (int i = 0; i < 4; ++i) + { + const __int128 h = static_cast<__int128>(z[4 + i]); + // +H << 224 and -H << 192 and -H << 96 (carry moves overflow). + add(i + 3, h << 32); + add(i + 3, -h); + add(i + 1, -(h << 32)); + } + for (int pass = 0; pass < 6; ++pass) + { + for (int i = 0; i < 9; ++i) + { + const __int128 c = t[i] >> 64; + t[i] = static_cast(t[i]); + t[i + 1] += c; + } + if (t[4] == 0 && t[5] == 0 && t[6] == 0 && t[7] == 0 + && t[8] == 0 && t[9] == 0) + break; + __int128 high[6] = {t[4], t[5], t[6], t[7], t[8], t[9]}; + t[4] = t[5] = t[6] = t[7] = t[8] = t[9] = 0; + for (int i = 0; i < 6; ++i) + { + const __int128 h = high[i]; + if (h == 0) + continue; + // h * 2^{256+64*i} ≡ h*2^{64*i} * (1+2^224-2^192-2^96) + add(i, h); + add(i + 3, h << 32); + add(i + 3, -h); + add(i + 1, -(h << 32)); + } + } + for (int i = 0; i < 4; ++i) + { + const __int128 c = t[i] >> 64; + t[i] = static_cast(t[i]); + t[i + 1] += c; + } + for (int guard = 0; guard < 6; ++guard) + { + if (t[4] == 0 && t[0] >= 0 && t[1] >= 0 && t[2] >= 0 && t[3] >= 0) + break; + if (t[4] != 0 || t[5] != 0) + { + __int128 high[2] = {t[4], t[5]}; + t[4] = t[5] = 0; + for (int i = 0; i < 2; ++i) + { + const __int128 h = high[i]; + if (h == 0) + continue; + add(i, h); + add(i + 3, h << 32); + add(i + 3, -h); + add(i + 1, -(h << 32)); + } + for (int i = 0; i < 4; ++i) + { + const __int128 c = t[i] >> 64; + t[i] = static_cast(t[i]); + t[i + 1] += c; + } + continue; + } + add(0, static_cast<__int128>(P[0])); + add(1, static_cast<__int128>(P[1])); + add(2, static_cast<__int128>(P[2])); + add(3, static_cast<__int128>(P[3])); + for (int i = 0; i < 4; ++i) + { + const __int128 c = t[i] >> 64; + t[i] = static_cast(t[i]); + t[i + 1] += c; + } + } + fe out{{static_cast(t[0]), + static_cast(t[1]), + static_cast(t[2]), + static_cast(t[3])}}; + out = fe_sub_p_if_ge(out); + out = fe_sub_p_if_ge(out); + return out; +} + +HEDLEY_ALWAYS_INLINE +fe fe_add(fe a, fe b) noexcept +{ + unsigned __int128 carry = 0; + fe r{}; + for (int i = 0; i < 4; ++i) + { + carry += static_cast(a.d[i]) + b.d[i]; + r.d[i] = static_cast(carry); + carry >>= 64; + } + if (carry) + { + std::uint64_t z[8] = {r.d[0], r.d[1], r.d[2], r.d[3], 1, 0, 0, 0}; + return fe_reduce_wide(z); + } + return fe_sub_p_if_ge(r); +} + +HEDLEY_ALWAYS_INLINE +fe fe_neg(fe a) noexcept +{ + if (fe_is_zero(a)) + return a; + fe r{}; + unsigned borrow = 0; + for (int i = 0; i < 4; ++i) + { + const unsigned __int128 need = + static_cast(a.d[i]) + borrow; + const unsigned __int128 cur = P[i]; + if (cur >= need) + { + r.d[i] = static_cast(cur - need); + borrow = 0; + } + else + { + r.d[i] = static_cast( + (cur + (static_cast(1) << 64)) - need); + borrow = 1; + } + } + return r; +} + +HEDLEY_ALWAYS_INLINE +fe fe_sub(fe a, fe b) noexcept +{ + fe r{}; + unsigned borrow = 0; + for (int i = 0; i < 4; ++i) + { + const unsigned __int128 need = + static_cast(b.d[i]) + borrow; + const unsigned __int128 cur = a.d[i]; + if (cur >= need) + { + r.d[i] = static_cast(cur - need); + borrow = 0; + } + else + { + r.d[i] = static_cast( + (cur + (static_cast(1) << 64)) - need); + borrow = 1; + } + } + if (borrow) + { + unsigned __int128 carry = 0; + for (int i = 0; i < 4; ++i) + { + carry += static_cast(r.d[i]) + P[i]; + r.d[i] = static_cast(carry); + carry >>= 64; + } + } + return r; +} + +HEDLEY_ALWAYS_INLINE +fe fe_mul(fe a, fe b) noexcept +{ + std::uint64_t z[8]{}; + for (int i = 0; i < 4; ++i) + { + unsigned __int128 carry = 0; + for (int j = 0; j < 4; ++j) + { + const unsigned __int128 cur = + static_cast(z[i + j]) + + static_cast(a.d[i]) * b.d[j] + + carry; + z[i + j] = static_cast(cur); + carry = cur >> 64; + } + z[i + 4] = static_cast(carry); + } + return fe_reduce_wide(z); +} + +HEDLEY_ALWAYS_INLINE +fe fe_pow(fe a, const std::uint64_t exp[4]) noexcept +{ + fe result{{1, 0, 0, 0}}; + for (int bit = 255; bit >= 0; --bit) + { + result = fe_mul(result, result); + const unsigned limb = static_cast(bit >> 6); + const unsigned off = static_cast(bit & 63); + if ((exp[limb] >> off) & 1u) + result = fe_mul(result, a); + } + return result; +} + +HEDLEY_ALWAYS_INLINE +bool fe_is_square(fe a) noexcept +{ + if (fe_is_zero(a)) + return true; + const fe leg = fe_pow(a, EXP_P_MINUS_1_OVER_2); + return leg.d[0] == 1 && leg.d[1] == 0 && leg.d[2] == 0 && leg.d[3] == 0; +} + +HEDLEY_ALWAYS_INLINE +fe fe_sqrt(fe a) noexcept +{ + return fe_pow(a, EXP_P_PLUS_1_OVER_4); +} + +HEDLEY_ALWAYS_INLINE +fe fe_inv(fe a) noexcept +{ + return fe_pow(a, EXP_P_MINUS_2); +} + +HEDLEY_ALWAYS_INLINE +fe curve_rhs(fe x) noexcept +{ + const fe x2 = fe_mul(x, x); + const fe x3 = fe_mul(x2, x); + const fe three = fe_add(x, fe_add(x, x)); + fe rhs = fe_sub(x3, three); + fe b{{B[0], B[1], B[2], B[3]}}; + return fe_add(rhs, b); +} + +HEDLEY_ALWAYS_INLINE +void fe_from_be(fe &out, const std::uint8_t be[32]) noexcept +{ + for (int i = 0; i < 4; ++i) + { + std::uint64_t v = 0; + for (int j = 0; j < 8; ++j) + v = (v << 8) | be[i * 8 + j]; + out.d[3 - i] = v; + } +} + +HEDLEY_ALWAYS_INLINE +void fe_to_be(std::uint8_t be[32], const fe &a) noexcept +{ + for (int i = 0; i < 4; ++i) + { + const std::uint64_t v = a.d[3 - i]; + for (int j = 0; j < 8; ++j) + be[i * 8 + j] = static_cast(v >> (56 - 8 * j)); + } +} + +HEDLEY_ALWAYS_INLINE +affine generator_point() noexcept +{ + affine g; + g.inf = false; + for (int i = 0; i < 4; ++i) + { + g.x.d[i] = GX[i]; + g.y.d[i] = GY[i]; + } + return g; +} + +HEDLEY_ALWAYS_INLINE +affine point_neg(affine a) noexcept +{ + if (!a.inf) + a.y = fe_neg(a.y); + return a; +} + +HEDLEY_ALWAYS_INLINE +fe fe_sqr(fe a) noexcept +{ + return fe_mul(a, a); +} + +/// @brief Jacobian coordinates `(X : Y : Z)` for `x=X/Z^2`, `y=Y/Z^3`. +struct jacobian +{ + fe X{}; + fe Y{}; + fe Z{}; +}; + +HEDLEY_ALWAYS_INLINE +bool jac_is_inf(const jacobian &p) noexcept +{ + return fe_is_zero(p.Z); +} + +HEDLEY_ALWAYS_INLINE +jacobian jac_from_affine(affine a) noexcept +{ + if (a.inf) + return {}; + return jacobian{a.x, a.y, fe{{1, 0, 0, 0}}}; +} + +HEDLEY_ALWAYS_INLINE +affine jac_to_affine(jacobian p) noexcept +{ + if (jac_is_inf(p)) + return {}; + const fe zi = fe_inv(p.Z); + const fe zi2 = fe_sqr(zi); + const fe zi3 = fe_mul(zi2, zi); + affine r; + r.inf = false; + r.x = fe_mul(p.X, zi2); + r.y = fe_mul(p.Y, zi3); + return r; +} + +/// @brief Jacobian doubling for short-Weierstrass with `a = -3` (P-256). +HEDLEY_ALWAYS_INLINE +jacobian jac_double(jacobian p) noexcept +{ + if (jac_is_inf(p) || fe_is_zero(p.Y)) + return {}; + const fe yy = fe_sqr(p.Y); + const fe yyyy = fe_sqr(yy); + const fe zz = fe_sqr(p.Z); + // S = 4*X*Y^2 + const fe s = fe_mul(fe_add(p.X, p.X), fe_add(yy, yy)); + // M = 3*(X+Z^2)*(X-Z^2) + const fe xz = fe_add(p.X, zz); + const fe xd = fe_sub(p.X, zz); + const fe m = fe_mul(fe_add(xd, fe_add(xd, xd)), xz); + const fe m2 = fe_sqr(m); + jacobian r; + r.X = fe_sub(m2, fe_add(s, s)); + // 8*Y^4 + fe eight_yyyy = fe_add(yyyy, yyyy); + eight_yyyy = fe_add(eight_yyyy, eight_yyyy); + eight_yyyy = fe_add(eight_yyyy, eight_yyyy); + r.Y = fe_sub(fe_mul(m, fe_sub(s, r.X)), eight_yyyy); + // Z3 = 2*Y*Z = (Y+Z)^2 - Y^2 - Z^2 + r.Z = fe_sub(fe_sub(fe_sqr(fe_add(p.Y, p.Z)), yy), zz); + return r; +} + +/// @brief Mixed Jacobian–affine addition. +HEDLEY_ALWAYS_INLINE +jacobian jac_add_mixed(jacobian p, affine q) noexcept +{ + if (q.inf) + return p; + if (jac_is_inf(p)) + return jac_from_affine(q); + const fe z1z1 = fe_sqr(p.Z); + const fe u2 = fe_mul(q.x, z1z1); + const fe s2 = fe_mul(q.y, fe_mul(p.Z, z1z1)); + const fe h = fe_sub(u2, p.X); + const fe r = fe_sub(s2, p.Y); + if (fe_is_zero(h)) + { + if (fe_is_zero(r)) + return jac_double(p); + return {}; + } + const fe h2 = fe_sqr(h); + const fe h3 = fe_mul(h2, h); + const fe v = fe_mul(p.X, h2); + const fe r2 = fe_sqr(r); + jacobian out; + out.X = fe_sub(fe_sub(r2, h3), fe_add(v, v)); + out.Y = fe_sub(fe_mul(r, fe_sub(v, out.X)), fe_mul(p.Y, h3)); + out.Z = fe_mul(h, p.Z); + return out; +} + +HEDLEY_ALWAYS_INLINE +affine point_add(affine a, affine b) noexcept +{ + if (a.inf) + return b; + if (b.inf) + return a; + // One mixed add + one inversion beats two affine inversions when both + // inputs are finite; keep the classical path for the equal-x branch. + if (fe_cmp(a.x, b.x) == 0) + { + if (fe_cmp(a.y, b.y) != 0 || fe_is_zero(a.y)) + return {}; + return jac_to_affine(jac_double(jac_from_affine(a))); + } + return jac_to_affine(jac_add_mixed(jac_from_affine(a), b)); +} + +HEDLEY_ALWAYS_INLINE +affine point_sub(affine a, affine b) noexcept +{ + return point_add(a, point_neg(b)); +} + +HEDLEY_ALWAYS_INLINE +affine point_scalarmul_limbs(affine g, const std::uint64_t k[4]) noexcept +{ + if (g.inf) + return {}; + // 4-bit window with an affine odd/even table. Doublings stay in Jacobian + // so the ladder uses one field inversion (final map) instead of one per add. + affine table[16]{}; + table[1] = g; + const affine two = jac_to_affine(jac_double(jac_from_affine(g))); + table[2] = two; + for (int i = 3; i < 16; ++i) + table[i] = jac_to_affine(jac_add_mixed(jac_from_affine(table[i - 1]), g)); + jacobian r{}; + bool started = false; + for (int bit = 255; bit >= 0; bit -= 4) + { + if (started) + { + r = jac_double(r); + r = jac_double(r); + r = jac_double(r); + r = jac_double(r); + } + unsigned nibble = 0; + for (int j = 0; j < 4; ++j) + { + const int b = bit - j; + if (b < 0) + break; + const unsigned limb = static_cast(b >> 6); + const unsigned off = static_cast(b & 63); + nibble <<= 1; + if ((k[limb] >> off) & 1u) + nibble |= 1u; + } + if (nibble != 0) + { + r = jac_add_mixed(r, table[nibble]); + started = true; + } + } + return jac_to_affine(r); +} + +HEDLEY_ALWAYS_INLINE +affine point_scalarmul(affine g, unsigned __int128 k) noexcept +{ + std::uint64_t limbs[4] = { + static_cast(k), + static_cast(k >> 64), + 0, 0}; + return point_scalarmul_limbs(g, limbs); +} + +/// @brief Expand `src` to at least 256 bits via SHA-256(src ‖ counter). +HEDLEY_ALWAYS_INLINE +void stretch_seed(std::uint8_t *dst, std::size_t dst_n, + const void *src, std::size_t src_n) noexcept +{ + std::size_t off = 0; + std::uint32_t counter = 0; + while (off < dst_n) + { + class SHA256 h; + h.add(src, src_n); + const unsigned char ctr[4] = { + static_cast(counter), + static_cast(counter >> 8), + static_cast(counter >> 16), + static_cast(counter >> 24)}; + h.add(ctr, sizeof(ctr)); + unsigned char block[SHA256::HashBytes]; + h.getHash(block); + const std::size_t take = + dst_n - off < sizeof(block) ? dst_n - off : sizeof(block); + std::memcpy(dst + off, block, take); + off += take; + ++counter; + } +} + +HEDLEY_ALWAYS_INLINE +void hash_to_curve(const std::uint8_t *data, std::size_t n, affine &out) noexcept +{ + std::uint8_t be[32]{}; + const std::size_t take = n < 32 ? n : 32; + std::memcpy(be, data, take); + for (std::size_t i = 32; i < n; ++i) + be[i & 31] ^= data[i]; + fe x; + fe_from_be(x, be); + fe p{{P[0], P[1], P[2], P[3]}}; + if (fe_cmp(x, p) >= 0) + x = fe_sub(x, p); + const fe one{{1, 0, 0, 0}}; + for (;;) + { + const fe rhs = curve_rhs(x); + if (fe_is_square(rhs)) + { + fe y = fe_sqrt(rhs); + if ((y.d[0] & 1u) != 0) + y = fe_neg(y); + out.inf = false; + out.x = x; + out.y = y; + return; + } + x = fe_add(x, one); + } +} + +HEDLEY_ALWAYS_INLINE +bool decode_compressed(const std::uint8_t enc[33], affine &out) noexcept +{ + bool zeros = true; + for (int i = 0; i < 33; ++i) + zeros = zeros && enc[i] == 0; + if (zeros) + { + out = affine{}; + return true; + } + if (enc[0] != 0x02 && enc[0] != 0x03) + return false; + fe x; + fe_from_be(x, enc + 1); + fe p{{P[0], P[1], P[2], P[3]}}; + if (fe_cmp(x, p) >= 0) + return false; + const fe rhs = curve_rhs(x); + if (!fe_is_square(rhs)) + return false; + fe y = fe_sqrt(rhs); + const bool odd = (y.d[0] & 1u) != 0; + if (odd != (enc[0] == 0x03)) + y = fe_neg(y); + if (fe_cmp(fe_mul(y, y), rhs) != 0) + return false; + out.inf = false; + out.x = x; + out.y = y; + return true; +} + +/// @brief Decode a stored leaf/share encoding. Invalid claimings throw. +HEDLEY_ALWAYS_INLINE +affine decode_strict(const std::uint8_t *bytes, std::size_t n) +{ + std::uint8_t enc[33]{}; + const std::size_t take = n < 33 ? n : 33; + std::memcpy(enc, bytes, take); + affine out; + if (!decode_compressed(enc, out)) + throw std::invalid_argument("p256: not a P-256 point"); + return out; +} + +HEDLEY_ALWAYS_INLINE +void encode_point(std::uint8_t enc[33], affine p) noexcept +{ + std::memset(enc, 0, 33); + if (p.inf) + return; + enc[0] = (p.y.d[0] & 1u) ? 0x03 : 0x02; + fe_to_be(enc + 1, p.x); +} + +} // namespace p256_detail + +/// @brief NIST P-256 point, SEC1-compressed in 33 bytes. +class p256 +{ + public: + static constexpr std::size_t encoded_size = 33; + static constexpr bool dpf_point_group = true; + /// @brief Leaf PRG bytes are mapped through `from_seed` before storage. + static constexpr bool dpf_curve_point = true; + + /// @brief The identity (point at infinity). + HEDLEY_ALWAYS_INLINE + constexpr p256() noexcept = default; + + /// @brief `scalar` times the generator. A negative scalar negates the point. + /// @tparam T integral scalar, at most 128 bits + /// @param scalar the multiplier of the generator + template >> + explicit p256(T scalar) + { + bool neg = false; + unsigned __int128 mag = 0; + if constexpr (std::is_signed_v) + { + if (scalar < 0) + { + neg = true; + using U = std::make_unsigned_t; + mag = static_cast(0) - static_cast(scalar); + } + else + { + mag = static_cast>(scalar); + } + } + else + { + mag = static_cast(scalar); + } + auto point = p256_detail::point_scalarmul( + p256_detail::generator_point(), mag); + if (neg) + point = p256_detail::point_neg(point); + p256_detail::encode_point(enc_, point); + } + + /// @brief The conventional generator. + /// @return the generator + HEDLEY_ALWAYS_INLINE + static p256 generator() + { + p256 g; + p256_detail::encode_point(g.enc_, p256_detail::generator_point()); + return g; + } + + /// @brief Decode a 33-byte SEC1 compressed point. 33 zero bytes are the identity. + /// @param in the compressed encoding + /// @return the point + static p256 from_compressed(const std::uint8_t (&in)[encoded_size]) + { + p256_detail::affine point; + if (!p256_detail::decode_compressed(in, point)) + throw std::invalid_argument("p256::from_compressed: not a P-256 point"); + p256 out; + p256_detail::encode_point(out.enc_, point); + return out; + } + + /// @brief Decode a 33-byte SEC1 compressed point. + /// @param in the compressed encoding + /// @return the point + static p256 from_compressed(const std::array &in) + { + std::uint8_t raw[encoded_size]; + std::memcpy(raw, in.data(), encoded_size); + return from_compressed(raw); + } + + /// @brief Map a PRG block to a curve point. + /// @details Stretches the seed to at least 256 bits, then hashes onto the + /// curve. Leaf and arithmetic paths require a valid encoding; + /// use this for masks, not for decoding peer points. + /// @param bytes the PRG output + /// @param n the number of bytes available + /// @return the curve point + static p256 from_seed(const void * bytes, std::size_t n) noexcept + { + std::uint8_t wide[64]{}; + p256_detail::stretch_seed(wide, sizeof(wide), bytes, n); + p256_detail::affine point; + p256_detail::hash_to_curve(wide, sizeof(wide), point); + p256 out; + p256_detail::encode_point(out.enc_, point); + return out; + } + + /// @brief The 33-byte encoding. + /// @return the encoding + HEDLEY_ALWAYS_INLINE + const std::uint8_t *bytes() const noexcept { return enc_; } + + /// @brief True for the identity. + /// @return whether this is the identity + HEDLEY_ALWAYS_INLINE + bool is_identity() const noexcept + { + std::uint8_t z = 0; + for (std::size_t i = 0; i < encoded_size; ++i) + z |= enc_[i]; + return z == 0; + } + + /// @brief Point addition. + /// @param a left addend + /// @param b right addend + /// @return `a + b` on the curve + friend p256 operator+(p256 a, p256 b) + { + const auto pa = p256_detail::decode_strict(a.enc_, encoded_size); + const auto pb = p256_detail::decode_strict(b.enc_, encoded_size); + p256 out; + p256_detail::encode_point(out.enc_, p256_detail::point_add(pa, pb)); + return out; + } + + /// @brief Point negation. + /// @param a the point to negate + /// @return `-a` + friend p256 operator-(p256 a) + { + const auto pa = p256_detail::decode_strict(a.enc_, encoded_size); + p256 out; + p256_detail::encode_point(out.enc_, p256_detail::point_neg(pa)); + return out; + } + + /// @brief Point subtraction. + /// @param a minuend + /// @param b subtrahend + /// @return `a - b` on the curve + friend p256 operator-(p256 a, p256 b) + { + return a + (-b); + } + + /// @brief Encoding equality. + /// @param a left point + /// @param b right point + /// @return `true` when the encodings match + friend bool operator==(p256 a, p256 b) noexcept + { + return std::memcmp(a.enc_, b.enc_, encoded_size) == 0; + } + + /// @brief Encoding inequality. + /// @param a left point + /// @param b right point + /// @return `true` when the encodings differ + friend bool operator!=(p256 a, p256 b) noexcept + { + return !(a == b); + } + + /// @brief Write the 33-byte encoding in hexadecimal. + /// @param os the output stream + /// @param a the point to write + /// @return `os` + friend std::ostream & operator<<(std::ostream &os, p256 a) + { + const auto flags = os.flags(); + os << std::hex; + for (std::size_t i = 0; i < encoded_size; ++i) + { + const unsigned byte = a.enc_[i]; + os << "0123456789abcdef"[byte >> 4] << "0123456789abcdef"[byte & 0xf]; + } + os.flags(flags); + return os; + } + + private: + std::uint8_t enc_[encoded_size]{}; +}; + +namespace leaf_arithmetic +{ + +namespace detail +{ + +template +HEDLEY_ALWAYS_INLINE +Leaf p256_leaf_combine(const Leaf &a, const Leaf &b, bool subtract) +{ + unsigned char ab[sizeof(Leaf)]; + unsigned char bb[sizeof(Leaf)]; + unsigned char cb[sizeof(Leaf)]; + std::memcpy(ab, &a, sizeof(Leaf)); + std::memcpy(bb, &b, sizeof(Leaf)); + const auto pa = p256_detail::decode_strict(ab, sizeof(Leaf)); + const auto pb = p256_detail::decode_strict(bb, sizeof(Leaf)); + const auto pc = subtract ? p256_detail::point_sub(pa, pb) + : p256_detail::point_add(pa, pb); + std::memset(cb, 0, sizeof(cb)); + p256_detail::encode_point(cb, pc); + Leaf out{}; + std::memcpy(&out, cb, sizeof(Leaf)); + return out; +} + +} // namespace detail + +template +struct add_t> +{ + auto operator()(const std::array &a, + const std::array &b) const + { + return detail::p256_leaf_combine(a, b, false); + } +}; + +template +struct subtract_t> +{ + auto operator()(const std::array &a, + const std::array &b) const + { + return detail::p256_leaf_combine(a, b, true); + } +}; + +template +struct multiply_t> +{ + template + Leaf operator()(const Leaf &, p256) const + { + static_assert(sizeof(NodeT) == 0, + "p256 has no point product; p256{k} is k times the generator"); + return Leaf{}; + } +}; + +} // namespace leaf_arithmetic + +/// @brief Sample a uniform curve point by rejection-sampling a scalar in `[0, n)`. +/// @return a curve point +template <> +HEDLEY_NO_THROW +inline auto uniform_sample() noexcept +{ + std::uint64_t k[4]{}; + for (;;) + { + k[0] = uniform_sample(); + k[1] = uniform_sample(); + k[2] = uniform_sample(); + k[3] = uniform_sample(); + if (p256_detail::limbs_cmp(k, p256_detail::N, 4) < 0) + break; + } + const auto point = p256_detail::point_scalarmul_limbs( + p256_detail::generator_point(), k); + if (point.inf) + return p256{}; + unsigned char enc[p256::encoded_size]; + p256_detail::encode_point(enc, point); + return p256::from_compressed(enc); +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_P256_HPP__ diff --git a/include/dpf/p256_scalar.hpp b/include/dpf/p256_scalar.hpp new file mode 100644 index 0000000..f2a724c --- /dev/null +++ b/include/dpf/p256_scalar.hpp @@ -0,0 +1,295 @@ +/// @file dpf/p256_scalar.hpp +/// @brief NIST P-256 scalar field as a comparison payload group. +/// @details Integers modulo the curve order +/// `0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551`. +/// This is the scalar field, not the point group in `p256.hpp`. +/// `from_seed`, `+`, and unary `-` select the payload-group path. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_P256_SCALAR_HPP__ +#define LIBDPF_INCLUDE_DPF_P256_SCALAR_HPP__ + +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/random.hpp" +#include "dpf/utils.hpp" + +namespace dpf +{ + +/// @brief Element of the NIST P-256 scalar field. +class p256_scalar +{ + public: + /// @brief Little-endian limbs of the group order \f$n\f$. + static constexpr std::uint64_t order[4] = { + 0xf3b9cac2fc632551ull, + 0xbce6faada7179e84ull, + 0xffffffffffffffffull, + 0xffffffff00000000ull, + }; + static constexpr bool dpf_point_group = true; + + HEDLEY_ALWAYS_INLINE + constexpr p256_scalar() noexcept = default; + + template >> + HEDLEY_ALWAYS_INLINE + constexpr p256_scalar(T v) noexcept + { + assign_integer(v); + } + + HEDLEY_ALWAYS_INLINE + constexpr p256_scalar(unsigned __int128 v) noexcept + { + std::uint64_t z[4] = { + static_cast(v), + static_cast(v >> 64), + 0, 0}; + if (ge_order(z)) + sub_order(z); + d_[0] = z[0]; + d_[1] = z[1]; + d_[2] = z[2]; + d_[3] = z[3]; + } + + /// @brief Canonical representative in `[0, n)`. + HEDLEY_ALWAYS_INLINE + static constexpr p256_scalar canonicalize(p256_scalar a) noexcept + { + std::uint64_t z[4] = {a.d_[0], a.d_[1], a.d_[2], a.d_[3]}; + if (ge_order(z)) + sub_order(z); + if (ge_order(z)) + sub_order(z); + return from_limbs(z); + } + + /// @brief Stretch a PRG block to ≥256 bits and rejection-sample into `[0, n)`. + HEDLEY_ALWAYS_INLINE + static p256_scalar from_seed(const void * bytes, std::size_t n) noexcept + { + for (std::uint32_t counter = 0; ; ++counter) + { + class SHA256 h; + h.add(bytes, n); + const unsigned char ctr[4] = { + static_cast(counter), + static_cast(counter >> 8), + static_cast(counter >> 16), + static_cast(counter >> 24)}; + h.add(ctr, sizeof(ctr)); + unsigned char block[SHA256::HashBytes]; + h.getHash(block); + std::uint64_t w[4]{}; + std::memcpy(w, block, sizeof(w)); + if (!ge_order(w)) + return from_limbs(w); + } + } + + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + constexpr std::uint64_t limb(std::size_t i) const noexcept { return d_[i]; } + + HEDLEY_ALWAYS_INLINE + friend constexpr p256_scalar operator+(p256_scalar a, p256_scalar b) noexcept + { + a = canonicalize(a); + b = canonicalize(b); + std::uint64_t z[4]{}; + unsigned __int128 carry = 0; + for (std::size_t i = 0; i < 4; ++i) + { + carry += static_cast(a.d_[i]) + b.d_[i]; + z[i] = static_cast(carry); + carry >>= 64; + } + if (carry != 0 || ge_order(z)) + sub_order(z); + if (ge_order(z)) + sub_order(z); + return from_limbs(z); + } + + HEDLEY_ALWAYS_INLINE + friend constexpr p256_scalar operator-(p256_scalar a) noexcept + { + a = canonicalize(a); + if (is_zero(a)) + return a; + std::uint64_t z[4]{}; + unsigned borrow = 0; + for (std::size_t i = 0; i < 4; ++i) + { + const unsigned __int128 diff = + static_cast(order[i]) - a.d_[i] - borrow; + z[i] = static_cast(diff); + borrow = (diff >> 64) ? 1u : 0u; + } + return from_limbs(z); + } + + HEDLEY_ALWAYS_INLINE + friend constexpr p256_scalar operator-(p256_scalar a, p256_scalar b) noexcept + { + return a + (-b); + } + + HEDLEY_ALWAYS_INLINE + friend constexpr bool operator==(p256_scalar a, p256_scalar b) noexcept + { + a = canonicalize(a); + b = canonicalize(b); + return a.d_[0] == b.d_[0] && a.d_[1] == b.d_[1] + && a.d_[2] == b.d_[2] && a.d_[3] == b.d_[3]; + } + + HEDLEY_ALWAYS_INLINE + friend constexpr bool operator!=(p256_scalar a, p256_scalar b) noexcept + { + return !(a == b); + } + + private: + std::uint64_t d_[4]{}; + + HEDLEY_ALWAYS_INLINE + static constexpr bool is_zero(p256_scalar a) noexcept + { + return (a.d_[0] | a.d_[1] | a.d_[2] | a.d_[3]) == 0; + } + + HEDLEY_ALWAYS_INLINE + static constexpr bool ge_order(const std::uint64_t z[4]) noexcept + { + for (std::size_t i = 4; i-- > 0; ) + { + if (z[i] > order[i]) + return true; + if (z[i] < order[i]) + return false; + } + return true; + } + + HEDLEY_ALWAYS_INLINE + static constexpr void sub_order(std::uint64_t z[4]) noexcept + { + unsigned borrow = 0; + for (std::size_t i = 0; i < 4; ++i) + { + const unsigned __int128 diff = + static_cast(z[i]) - order[i] - borrow; + z[i] = static_cast(diff); + borrow = (diff >> 64) ? 1u : 0u; + } + } + + HEDLEY_ALWAYS_INLINE + static constexpr p256_scalar from_limbs(const std::uint64_t z[4]) noexcept + { + p256_scalar out; + out.d_[0] = z[0]; + out.d_[1] = z[1]; + out.d_[2] = z[2]; + out.d_[3] = z[3]; + return out; + } + + template + HEDLEY_ALWAYS_INLINE + constexpr void assign_integer(T v) noexcept + { + bool neg = false; + unsigned __int128 mag = 0; + if constexpr (std::is_signed_v) + { + if (v < 0) + { + neg = true; + using U = std::make_unsigned_t; + mag = static_cast(0) - static_cast(v); + } + else + { + mag = static_cast>(v); + } + } + else + { + mag = static_cast(v); + } + std::uint64_t z[4] = { + static_cast(mag), + static_cast(mag >> 64), + 0, 0}; + if (ge_order(z)) + sub_order(z); + *this = from_limbs(z); + if (neg) + *this = -*this; + } +}; + +namespace utils +{ + +template <> +struct bitlength_of + : std::integral_constant +{ }; + +template <> +struct has_characteristic_two : std::false_type +{ }; + +} // namespace utils + +/// @brief Sample a uniform scalar by rejection into `[0, n)`. +template <> +HEDLEY_NO_THROW +inline auto uniform_sample() noexcept +{ + for (;;) + { + std::uint64_t z[4] = { + uniform_sample(), + uniform_sample(), + uniform_sample(), + uniform_sample(), + }; + bool ge = true; + for (std::size_t i = 4; i-- > 0; ) + { + if (z[i] > p256_scalar::order[i]) + { + ge = true; + break; + } + if (z[i] < p256_scalar::order[i]) + { + ge = false; + break; + } + } + if (!ge) + { + p256_scalar out; + std::memcpy(&out, z, sizeof(z)); + return out; + } + } +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_P256_SCALAR_HPP__ diff --git a/include/dpf/packed_array.hpp b/include/dpf/packed_array.hpp index b5b76e8..b77c050 100644 --- a/include/dpf/packed_array.hpp +++ b/include/dpf/packed_array.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "hedley/hedley.h" @@ -32,8 +33,8 @@ template class dynamic_packed_array { static constexpr std::size_t lane_bits = utils::packed_lane_bits_v; - static_assert(lane_bits == 2 || lane_bits == 4, - "dynamic_packed_array lanes are 2 or 4 bits"); + static_assert(lane_bits == 1 || lane_bits == 2 || lane_bits == 4, + "dynamic_packed_array lanes are 1, 2, or 4 bits"); static constexpr std::size_t lanes_per_word = 64u / lane_bits; static constexpr unsigned lane_mask = (1u << lane_bits) - 1u; @@ -54,6 +55,9 @@ class dynamic_packed_array lane_ref(word_type * word, unsigned shift) noexcept : word_{word}, shift_{shift} {} + HEDLEY_NO_THROW + lane_ref(const lane_ref &) noexcept = default; + HEDLEY_NO_THROW HEDLEY_ALWAYS_INLINE operator LaneT() const noexcept @@ -65,8 +69,14 @@ class dynamic_packed_array HEDLEY_ALWAYS_INLINE lane_ref & operator=(LaneT value) noexcept { - const auto val = static_cast( - static_cast(value) & lane_mask); + const unsigned bits = [](LaneT v) { + if constexpr (std::is_enum_v || std::is_integral_v) + return static_cast(v); + else + return static_cast( + static_cast(v)); + }(value); + const auto val = static_cast(bits & lane_mask); *word_ = (*word_ & ~(static_cast(lane_mask) << shift_)) | (val << shift_); return *this; @@ -333,6 +343,9 @@ class packed_share_output : public dynamic_packed_array HEDLEY_NO_THROW explicit reference(typename lanes::reference lane) noexcept : lane_{lane} {} + HEDLEY_NO_THROW + reference(const reference &) noexcept = default; + HEDLEY_NO_THROW operator share_type() const noexcept { diff --git a/include/dpf/packed_lane.hpp b/include/dpf/packed_lane.hpp index 738691b..9e1c30f 100644 --- a/include/dpf/packed_lane.hpp +++ b/include/dpf/packed_lane.hpp @@ -1,6 +1,8 @@ /// @file dpf/packed_lane.hpp -/// @brief Extract and deposit one `dpf::bit`, `dpf::twobit`, or `dpf::nyble` -/// lane in a leaf node. Lane 0 is the low bits of the first byte. +/// @brief Extract and deposit one sub-byte lane in a leaf node. +/// Lane 0 is the low bits of the first byte. Widths are 1 +/// (`dpf::bit`, `dpf::gf2`), 2 (`dpf::twobit`, `dpf::gf22`), or 4 +/// (`dpf::nyble`, `dpf::gf24`). #ifndef LIBDPF_INCLUDE_DPF_PACKED_LANE_HPP__ #define LIBDPF_INCLUDE_DPF_PACKED_LANE_HPP__ @@ -8,6 +10,7 @@ #include #include #include +#include #include "hedley/hedley.h" @@ -20,6 +23,21 @@ namespace dpf namespace packed { +/// @brief Low bits of one lane as an unsigned integer. +/// @details Enums convert directly. Class lanes such as `gf2n` expose +/// `integral_type` and an explicit conversion to it. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +HEDLEY_PURE +constexpr unsigned lane_unsigned(LaneT value) noexcept +{ + if constexpr (std::is_enum_v || std::is_integral_v) + return static_cast(value); + else + return static_cast(static_cast(value)); +} + template HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -59,7 +77,7 @@ void deposit_lane(LeafT & leaf, std::size_t lane, LaneT value) noexcept const std::size_t bit = lane * bits; assert(bit / 8u < sizeof(LeafT)); const unsigned shift = static_cast(bit % 8u); - const unsigned val = static_cast(value) & mask; + const unsigned val = lane_unsigned(value) & mask; unsigned char & cell = bytes[bit / 8u]; cell = static_cast((cell & ~(mask << shift)) | (val << shift)); } diff --git a/include/dpf/packed_lane_arithmetic.hpp b/include/dpf/packed_lane_arithmetic.hpp index 9423b94..7ee7767 100644 --- a/include/dpf/packed_lane_arithmetic.hpp +++ b/include/dpf/packed_lane_arithmetic.hpp @@ -164,6 +164,7 @@ inline simde__m256i mul_low_nibbles(simde__m256i a, simde__m256i b) noexcept } // namespace detail +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). template HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -175,6 +176,7 @@ NodeT add_mod2(const NodeT & a, const NodeT & b) noexcept }); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). template HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -186,6 +188,7 @@ NodeT sub_mod2(const NodeT & a, const NodeT & b) noexcept }); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). template HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -198,6 +201,7 @@ NodeT mul_mod2(const NodeT & a, dpf::twobit k) noexcept }); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). template HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -209,6 +213,7 @@ NodeT mullo_mod2(const NodeT & a, const NodeT & b) noexcept }); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). template HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -220,6 +225,7 @@ NodeT add_mod4(const NodeT & a, const NodeT & b) noexcept }); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). template HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -231,6 +237,7 @@ NodeT sub_mod4(const NodeT & a, const NodeT & b) noexcept }); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). template HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -243,6 +250,7 @@ NodeT mul_mod4(const NodeT & a, dpf::nyble k) noexcept }); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). template HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -254,6 +262,7 @@ NodeT mullo_mod4(const NodeT & a, const NodeT & b) noexcept }); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -270,6 +279,7 @@ simde__m128i add_epi2(simde__m128i a, simde__m128i b) noexcept return simde_mm_or_si128(bit0, simde_mm_slli_epi16(bit1, 1)); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -286,6 +296,7 @@ simde__m256i add_epi2(simde__m256i a, simde__m256i b) noexcept return simde_mm256_or_si256(bit0, simde_mm256_slli_epi16(bit1, 1)); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -302,6 +313,7 @@ simde__m128i sub_epi2(simde__m128i a, simde__m128i b) noexcept return simde_mm_or_si128(bit0, simde_mm_slli_epi16(bit1, 1)); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -318,6 +330,7 @@ simde__m256i sub_epi2(simde__m256i a, simde__m256i b) noexcept return simde_mm256_or_si256(bit0, simde_mm256_slli_epi16(bit1, 1)); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -334,6 +347,7 @@ simde__m128i mullo_epi2(simde__m128i a, simde__m128i b) noexcept return simde_mm_or_si128(bit0, simde_mm_slli_epi16(bit1, 1)); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -350,6 +364,7 @@ simde__m256i mullo_epi2(simde__m256i a, simde__m256i b) noexcept return simde_mm256_or_si256(bit0, simde_mm256_slli_epi16(bit1, 1)); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -360,6 +375,7 @@ simde__m128i mul_epi2(simde__m128i a, dpf::twobit k) noexcept return detail::shuffle_nibbles(detail::nibble_lut(lut), a); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -370,6 +386,7 @@ simde__m256i mul_epi2(simde__m256i a, dpf::twobit k) noexcept return detail::shuffle_nibbles(detail::nibble_lut256(lut), a); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -385,6 +402,7 @@ simde__m128i add_epi4(simde__m128i a, simde__m128i b) noexcept simde_mm_and_si128(lo, lo_m), simde_mm_and_si128(hi, hi_m)); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -400,6 +418,7 @@ simde__m256i add_epi4(simde__m256i a, simde__m256i b) noexcept simde_mm256_and_si256(lo, lo_m), simde_mm256_and_si256(hi, hi_m)); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -415,6 +434,7 @@ simde__m128i sub_epi4(simde__m128i a, simde__m128i b) noexcept simde_mm_and_si128(lo, lo_m), simde_mm_and_si128(hi, hi_m)); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -430,6 +450,7 @@ simde__m256i sub_epi4(simde__m256i a, simde__m256i b) noexcept simde_mm256_and_si256(lo, lo_m), simde_mm256_and_si256(hi, hi_m)); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -443,6 +464,7 @@ simde__m128i mullo_epi4(simde__m128i a, simde__m128i b) noexcept return simde_mm_or_si128(lo, simde_mm_slli_epi16(hi, 4)); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -456,6 +478,7 @@ simde__m256i mullo_epi4(simde__m256i a, simde__m256i b) noexcept return simde_mm256_or_si256(lo, simde_mm256_slli_epi16(hi, 4)); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -466,6 +489,7 @@ simde__m128i mul_epi4(simde__m128i a, dpf::nyble k) noexcept return detail::shuffle_nibbles(detail::nibble_lut(lut), a); } +/// \complexity O(sizeof node / lane bits) packed operations. A carry stays inside the lane (`add_mod2` / `add_epi2` are 2-bit, `add_mod4` / `add_epi4` are nibbles). HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE diff --git a/include/dpf/pad_graphs.hpp b/include/dpf/pad_graphs.hpp new file mode 100644 index 0000000..1f12851 --- /dev/null +++ b/include/dpf/pad_graphs.hpp @@ -0,0 +1,144 @@ +/// @file dpf/pad_graphs.hpp +/// @brief Setup / pad protocols as real `schedule_round` lists. +#ifndef LIBDPF_INCLUDE_DPF_PAD_GRAPHS_HPP__ +#define LIBDPF_INCLUDE_DPF_PAD_GRAPHS_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "dpf/protocol.hpp" + +namespace dpf +{ +namespace protocol +{ + +/// @brief Dealer Beaver / Du-Atallah blinding tape: one delivery round per triple. +inline std::vector dealer_tape_graph(std::size_t n_triples, + std::size_t slot_bytes, + const std::shared_ptr> & tape) +{ + return make_pad_rounds(n_triples, slot_bytes, tape, edge_channel::dealer); +} + +/// @brief Du-Atallah 3PC multiply: P2 blinds (offline) + one P0↔P1 exchange. +/// @details Round 0 on dealer edge carries (X0,Y0,…) tokens; round 1 on peer +/// exchanges blinded shares. Bodies are schedule-shaped stubs that +/// XOR into `tape` so PIRsona / hushmap can splice them before online. +inline std::vector du_atallah_mul_graph( + const std::shared_ptr> & tape, + std::size_t slot_bytes = 24) +{ + auto dealer = make_pad_rounds(1, slot_bytes, tape, edge_channel::dealer); + auto peer = make_pad_rounds(1, slot_bytes, tape, edge_channel::peer); + peer[0].sink_round = 0; + return splice_rounds(std::move(dealer), std::move(peer)); +} + +/// @brief Key-ship: one round delivering `key_bytes` on `edge` (PIR upload seed). +inline std::vector key_ship_graph(std::size_t key_bytes, + edge_id edge = edge_peer) +{ + std::vector rounds(1); + rounds[0].slot_bytes = key_bytes; + rounds[0].edge = edge; + rounds[0].channel = edge <= edge_dealer + ? static_cast(edge) + : edge_channel::peer; + rounds[0].recv = receive_rule::copy_peer; + rounds[0].sink_round = 0; + rounds[0].produce = [key_bytes](std::size_t, const std::uint8_t *, + std::size_t, std::uint8_t * out) { + if (out != nullptr && key_bytes != 0) + std::memset(out, 0x5a, key_bytes); + }; + return rounds; +} + +/// @brief Server end of one star spoke: absorb upload, produce answer. +inline std::vector star_server_reply_rounds( + std::size_t query_bytes, std::size_t answer_bytes, + std::vector answer) +{ + std::vector sr(2); + sr[0].slot_bytes = query_bytes; + sr[0].edge = edge_peer; + sr[0].sink_round = 0; + sr[0].produce = [query_bytes](std::size_t, const std::uint8_t *, std::size_t, + std::uint8_t * out) { + if (out != nullptr && query_bytes != 0) + std::memset(out, 0, query_bytes); + }; + sr[1].slot_bytes = answer_bytes; + sr[1].edge = edge_peer; + sr[1].sink_round = 1; + sr[1].produce = [answer = std::move(answer), answer_bytes](std::size_t, + const std::uint8_t *, std::size_t, + std::uint8_t * out) { + if (out == nullptr) + return; + if (answer.size() >= answer_bytes) + std::memcpy(out, answer.data(), answer_bytes); + else + std::memset(out, 0, answer_bytes); + }; + return sr; +} + +/// @brief Client star: upload then answer on each of `n_servers` edges. +/// @details Rounds `[0, n)` upload on edge i; rounds `[n, 2n)` answer on edge i. +inline std::vector star_upload_answer_graph( + std::size_t n_servers, std::size_t query_bytes, std::size_t answer_bytes, + const std::shared_ptr>> & queries, + const std::shared_ptr>> & answers) +{ + if (n_servers < 2) + throw std::invalid_argument("star_upload_answer_graph servers"); + std::vector rounds(2 * n_servers); + for (std::size_t i = 0; i < n_servers; ++i) + { + auto & up = rounds[i]; + up.slot_bytes = query_bytes; + up.edge = static_cast(i); + up.recv = receive_rule::copy_peer; + up.sink_round = 0; + up.produce = [i, query_bytes, queries](std::size_t, const std::uint8_t *, + std::size_t, std::uint8_t * out) { + if (out == nullptr) + return; + if (queries && i < queries->size() + && (*queries)[i].size() >= query_bytes) + std::memcpy(out, (*queries)[i].data(), query_bytes); + else + std::memset(out, static_cast(i + 1), query_bytes); + }; + auto & ans = rounds[n_servers + i]; + ans.slot_bytes = answer_bytes; + ans.edge = static_cast(i); + ans.recv = receive_rule::copy_peer; + ans.sink_round = 1; + ans.produce = [i, answer_bytes, answers](std::size_t, + const std::uint8_t * peer, std::size_t peer_n, + std::uint8_t * out) { + if (out == nullptr) + return; + if (answers && i < answers->size() + && (*answers)[i].size() >= answer_bytes) + std::memcpy(out, (*answers)[i].data(), answer_bytes); + else if (peer != nullptr && peer_n >= answer_bytes) + std::memcpy(out, peer, answer_bytes); + else + std::memset(out, 0, answer_bytes); + }; + } + return rounds; +} + +} // namespace protocol +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_PAD_GRAPHS_HPP__ diff --git a/include/dpf/parallel_bit_iterable.hpp b/include/dpf/parallel_bit_iterable.hpp index 91d7904..52143b7 100644 --- a/include/dpf/parallel_bit_iterable.hpp +++ b/include/dpf/parallel_bit_iterable.hpp @@ -156,17 +156,39 @@ class parallel_const_bit_iterator HEDLEY_ALWAYS_INLINE value_type operator*() const noexcept { - value_type ret; - simde_type temp = helper::bit_and(all_vecs_[element_cnt_], vec_mask_); - std::memcpy(ret.data(), &temp, bytes_per_batch); - return ret; + value_type ret{}; + // One element per word (batches 1..4 with uint64 words): the in-place + // bit is just `word & mask`. Skip the SIMD rebuild + memcpy used for + // wider batches that pack several element lanes per word. + if constexpr (word_mask_path) + { + for (std::size_t i = 0; i < batch_size; ++i) + ret[i] = static_cast(cur_word_[i] & word_mask_); + return ret; + } + else + { + simde_type temp = helper::bit_and(all_vecs_[element_cnt_], vec_mask_); + std::memcpy(ret.data(), &temp, bytes_per_batch); + return ret; + } } HEDLEY_NO_THROW HEDLEY_ALWAYS_INLINE parallel_const_bit_iterator & operator++() noexcept { - if (HEDLEY_UNLIKELY(!(word_mask_ <<= 1))) + if constexpr (word_mask_path) + { + if (HEDLEY_UNLIKELY(!(word_mask_ <<= 1))) + { + word_mask_ = word_lsb; + std::transform(iter_.begin(), iter_.end(), cur_word_.begin(), + [](auto & it) { return *(++it); }); + } + return *this; + } + else if (HEDLEY_UNLIKELY(!(word_mask_ <<= 1))) { word_mask_ = word_lsb; element_mask_ = element_lsb; @@ -205,7 +227,17 @@ class parallel_const_bit_iterator HEDLEY_ALWAYS_INLINE parallel_const_bit_iterator & operator--() noexcept { - if (HEDLEY_UNLIKELY(!(word_mask_ >>= 1))) + if constexpr (word_mask_path) + { + if (HEDLEY_UNLIKELY(!(word_mask_ >>= 1))) + { + word_mask_ = word_msb; + std::transform(iter_.begin(), iter_.end(), cur_word_.begin(), + [](auto & it) { return *(--it); }); + } + return *this; + } + else if (HEDLEY_UNLIKELY(!(word_mask_ >>= 1))) { word_mask_ = word_msb; element_mask_ = element_msb; @@ -260,6 +292,11 @@ class parallel_const_bit_iterator static constexpr word_type word_msb = word_lsb << (bits_per_word-1); static constexpr element_type element_lsb = element_type(1); static constexpr element_type element_msb = element_lsb << (bits_per_element-1); + // Batches 1..4 use one uint64 element per word; the parallel lane is then + // exactly `cur_word & word_mask` (same encoding as the SIMD path). + static constexpr bool word_mask_path = + (elements_per_word == 1) + && std::is_same_v; template word_array dereferencing_initializer_impl( @@ -282,8 +319,9 @@ class parallel_const_bit_iterator element_mask_{element_lsb}, element_cnt_{0}, cur_word_{dereferencing_initializer(arr)}, - vec_mask_{helper::get_mask()}, - all_vecs_{helper::build_vecs(cur_word_.data(), batch_size)} + vec_mask_{word_mask_path ? simde_type{} : helper::get_mask()}, + all_vecs_{word_mask_path ? simde_array{} + : helper::build_vecs(cur_word_.data(), batch_size)} { } word_pointer_array iter_; diff --git a/include/dpf/party_run.hpp b/include/dpf/party_run.hpp new file mode 100644 index 0000000..69cdd26 --- /dev/null +++ b/include/dpf/party_run.hpp @@ -0,0 +1,368 @@ +/// @file dpf/party_run.hpp +/// @brief Run one protocol as threads on a memory clique, or as TCP peers. +#ifndef LIBDPF_INCLUDE_DPF_PARTY_RUN_HPP__ +#define LIBDPF_INCLUDE_DPF_PARTY_RUN_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/net/channel.hpp" +#include "dpf/net/connect.hpp" +#include "dpf/net/edge_mesh.hpp" +#include "dpf/net/memory_sink.hpp" +#include "dpf/net/party_session.hpp" +#include "dpf/net/secure_channel.hpp" +#include "dpf/net/security.hpp" +#include "dpf/net/socket_tune.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/net/stream_mesh.hpp" +#include "dpf/net/sync_stream_array.hpp" +#include "dpf/net/tcp_mesh.hpp" + +namespace dpf +{ +namespace run +{ + +/// @brief Two parties, two threads, one memory pair. `fn(party, sink)`. +template +void threads_2(const std::vector & slots, Fn fn) +{ + auto sinks = net::make_memory_sink_pair(1, slots); + std::exception_ptr err; + std::mutex err_mu; + auto note = [&](std::exception_ptr e) { + std::lock_guard lock(err_mu); + if (!err) + err = std::move(e); + }; + std::thread t0([&] { + try + { + fn(0u, std::ref(sinks.first)); + } + catch (...) + { + note(std::current_exception()); + } + }); + std::thread t1([&] { + try + { + fn(1u, std::ref(sinks.second)); + } + catch (...) + { + note(std::current_exception()); + } + }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); +} + +/// @brief `n` parties. `fn(party, clique)` so a party can `end(me, peer)`. +template +void threads_on_clique(std::size_t n, const std::vector & slots, + Fn fn) +{ + if (n < 2) + throw std::invalid_argument("threads_on_clique needs >= 2"); + auto clique = net::make_memory_clique(n, 1, slots); + std::vector ts; + std::mutex err_mu; + std::exception_ptr err; + for (std::size_t p = 0; p < n; ++p) + { + ts.emplace_back([&, p] { + try + { + fn(static_cast(p), clique); + } + catch (...) + { + std::lock_guard lock(err_mu); + if (!err) + err = std::current_exception(); + } + }); + } + for (auto & t : ts) + t.join(); + if (err) + std::rethrow_exception(err); +} + +/// @brief `n` parties on a memory clique. `fn(party, mesh)`. +template +void threads_clique(std::size_t n, const std::vector & slots, Fn fn) +{ + if (n < 2) + throw std::invalid_argument("threads_clique needs >= 2"); + auto clique = net::make_memory_clique(n, 1, slots); + std::vector ts; + std::mutex err_mu; + std::exception_ptr err; + for (std::size_t p = 0; p < n; ++p) + { + ts.emplace_back([&, p] { + try + { + auto mesh = clique.mesh_for(p); + fn(static_cast(p), mesh); + } + catch (...) + { + std::lock_guard lock(err_mu); + if (!err) + err = std::current_exception(); + } + }); + } + for (auto & t : ts) + t.join(); + if (err) + std::rethrow_exception(err); +} + +/// @brief Sum additive shares on a 3-party ring. Each party sends its share to +/// the other two and adds what it receives. +inline void declassify_ring(net::memory_clique & clique, unsigned me, + const std::uint8_t * mine, std::size_t n, std::uint8_t * sum_out, + std::chrono::milliseconds budget = std::chrono::milliseconds(30000)) +{ + if (clique.roles != 3) + throw std::invalid_argument("declassify_ring is a 3-party open"); + for (unsigned peer = 0; peer < 3; ++peer) + { + if (peer == me) + continue; + clique.end(me, peer).submit(0, 0, mine, n); + clique.end(me, peer).flush(); + } + std::memcpy(sum_out, mine, n); + for (unsigned peer = 0; peer < 3; ++peer) + { + if (peer == me) + continue; + auto & sink = clique.end(me, peer); + net::wait_peer_ready(sink, 0, 0, budget, "declassify_ring"); + std::vector got(n); + sink.read_peer(0, 0, got.data(), n); + for (std::size_t i = 0; i < n; i += 8) + { + std::uint64_t a = 0, b = 0; + const std::size_t k = std::min(8, n - i); + std::memcpy(&a, sum_out + i, k); + std::memcpy(&b, got.data() + i, k); + a += b; + std::memcpy(sum_out + i, &a, k); + } + } +} + +/// @brief Listen or connect, then hand the caller a framed `net::channel`. +/// @details Party 0 binds `port` (0 picks an ephemeral port written back). +/// The other party connects to `host:port`. The link uses the same +/// `peer_security` defaults as `party_session` (TLS 1.3 unless +/// encryption is off). Usable from threads or separate processes. +template +void tcp_pair(unsigned party, std::string host, std::atomic & port, + Fn fn, const net::deadlines & lim = {}, + const net::peer_security & sec = {}, const net::socket_options & so = {}) +{ + asio::io_context io; + const unsigned peer = party == 0 ? 1u : 0u; + if (party == 0) + { + asio::ip::tcp::acceptor acc(io); + net::open_listener(acc, port.load()); + port.store(acc.local_endpoint().port()); + asio::ip::tcp::socket sock(io); + net::accept_until(acc, sock, lim.accept); + auto ch = net::secure_tcp_channel(io, std::move(sock), true, peer, sec, so, + lim.handshake, "p" + std::to_string(peer), "accept"); + fn(ch); + } + else + { + const auto deadline = net::setup_clock::now() + lim.join; + while (port.load() == 0) + { + if (net::setup_clock::now() >= deadline) + throw std::runtime_error("tcp_pair: party 0 never published a port"); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + asio::ip::tcp::socket sock(io); + net::connect_until(sock, host, port.load(), lim.connect); + auto ch = net::secure_tcp_channel(io, std::move(sock), false, peer, sec, so, + lim.handshake, "p" + std::to_string(peer), "connect"); + fn(ch); + } +} + +/// @brief TCP pair that exposes a `mux_stream_array` with `streams` indexes. +/// @details Joins a 2-party `party_session` (same encryption and wire policy +/// as other mux edges). Party 0 publishes its listen port on `port`; +/// party 1 waits for it. `fn(party, mux_stream_array &)`. +template +void tcp_pair_mux(unsigned party, std::string host, + std::atomic & port, std::size_t streams, Fn fn, + const net::session_options & opt = {}) +{ + if (streams == 0) + throw std::invalid_argument("tcp_pair_mux: streams"); + asio::io_context io; + net::session_options so = opt; + so.n_lanes = streams; // `streams` is authoritative; opt sets security/policy + net::party_session sess(io, party, 2, so); + if (party == 0) + port.store(sess.listen(port.load())); + else + { + const auto deadline = net::setup_clock::now() + so.limits.join; + while (port.load() == 0) + { + if (net::setup_clock::now() >= deadline) + throw std::runtime_error( + "tcp_pair_mux: party 0 never published a port"); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + } + const unsigned short p0 = port.load(); + std::vector table = { + {host, p0}, + {host, party == 0 ? p0 : static_cast(0)}}; + sess.join(table); + net::mux_stream_array mux(sess.peer(1 - party)); + fn(party, mux); +} + +/// @brief Two threads, each with one end of a memory stream array. +template +void threads_2_streams(std::size_t streams, Fn fn) +{ + auto ends = net::make_memory_stream_pair(streams); + std::exception_ptr err; + std::mutex err_mu; + auto note = [&](std::exception_ptr e) { + std::lock_guard lock(err_mu); + if (!err) + err = std::move(e); + }; + std::thread t0([&] { + try + { + fn(0u, std::ref(ends.first)); + } + catch (...) + { + note(std::current_exception()); + } + }); + std::thread t1([&] { + try + { + fn(1u, std::ref(ends.second)); + } + catch (...) + { + note(std::current_exception()); + } + }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); +} + +/// @brief N-party open on a pairwise stream clique (one stream per edge). +inline void declassify_streams(net::memory_stream_clique & clique, unsigned me, + const std::uint8_t * mine, std::size_t n, std::uint8_t * sum_out) +{ + clique.declassify(me, mine, n, sum_out); +} + +/// @brief `n` threads join a localhost TCP mux clique; `fn(party, tcp_mesh &)`. +template +void threads_on_tcp_mesh(unsigned n, std::size_t streams, Fn fn) +{ + if (n < 2) + throw std::invalid_argument("threads_on_tcp_mesh needs >= 2"); + auto ports = net::make_mesh_ports(n); + std::vector ts; + std::mutex err_mu; + std::exception_ptr err; + for (unsigned p = 0; p < n; ++p) + { + ts.emplace_back([&, p] { + try + { + auto mesh = net::join_tcp_mesh(p, n, "127.0.0.1", ports, streams); + fn(p, mesh); + } + catch (...) + { + std::lock_guard lock(err_mu); + if (!err) + err = std::current_exception(); + } + }); + } + for (auto & t : ts) + t.join(); + if (err) + std::rethrow_exception(err); +} + +/// @brief `n` threads join an async TCP mux clique; `fn(party, io, async_tcp_mesh &)`. +template +void threads_on_async_tcp_mesh(unsigned n, std::size_t streams, Fn fn) +{ + if (n < 2) + throw std::invalid_argument("threads_on_async_tcp_mesh needs >= 2"); + auto ports = net::make_mesh_ports(n); + std::vector ts; + std::mutex err_mu; + std::exception_ptr err; + for (unsigned p = 0; p < n; ++p) + { + ts.emplace_back([&, p] { + try + { + asio::io_context io; + auto mesh = + net::join_async_tcp_mesh(io, p, n, "127.0.0.1", ports, streams); + fn(p, io, mesh); + } + catch (...) + { + std::lock_guard lock(err_mu); + if (!err) + err = std::current_exception(); + } + }); + } + for (auto & t : ts) + t.join(); + if (err) + std::rethrow_exception(err); +} + +} // namespace run +} // namespace dpf + +#endif diff --git a/include/dpf/party_runner.hpp b/include/dpf/party_runner.hpp new file mode 100644 index 0000000..8e0e3a9 --- /dev/null +++ b/include/dpf/party_runner.hpp @@ -0,0 +1,763 @@ +/// @file dpf/party_runner.hpp +/// @brief Run a composed protocol as 2 or 3 parties, in one process or many. +/// @details The layout of edges comes from the plan: a 2PC peer edge between +/// parties 0 and 1, an RSS ring (each party sends to the previous one +/// and receives from the next), and dealer edges from party 2 to +/// parties 0 and 1. Every pair of parties shares one link; each +/// logical edge uses its own lane range on it. +/// +/// `run_parties` drives all parties on threads over the transport in +/// `run_config` (in-process async memory, unix sockets, TCP mux, +/// parallel TCP, or SCTP). `run_node` drives one party of a +/// multi-process run from a static `host:port` table +/// (`--party=1 --peers=a:9000,b:9000,c:9000`). +#ifndef LIBDPF_INCLUDE_DPF_PARTY_RUNNER_HPP__ +#define LIBDPF_INCLUDE_DPF_PARTY_RUNNER_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__linux__) +#include +#include +#endif + +#include "dpf/net/asio_ns.hpp" + +#include "dpf/compose.hpp" +#include "dpf/compose_async.hpp" +#include "dpf/experiment.hpp" +#include "dpf/log.hpp" +#include "dpf/net/async_round_sink.hpp" +#include "dpf/net/async_stream_array.hpp" +#include "dpf/net/io_pool.hpp" +#include "dpf/net/party_session.hpp" +#include "dpf/prg_count.hpp" +#include "dpf/random.hpp" +#include "dpf/run_config.hpp" +#include "dpf/thread_work.hpp" + +namespace dpf +{ +namespace app +{ + +using party_values = std::vector>; + +/// @brief Lane ranges of each logical edge on a pair's link. +struct edge_layout +{ + std::size_t parties = 2; + std::vector peer_slots; + std::vector ring_slots; + std::vector dealer_slots; + std::size_t peer_lanes = 0; + std::size_t ring_lanes = 0; + std::size_t dealer_lanes = 0; + std::size_t peer_off = 0; + std::size_t ring_off = 0; + std::size_t dealer_off = 0; + std::size_t pair_lanes = 1; +}; + +inline edge_layout layout_for(const protocol::plan & p, std::size_t parties, + const run_config & cfg) +{ + if (parties < 2 || parties > 3) + throw std::invalid_argument("run_parties: 2 or 3 parties (got " + + std::to_string(parties) + ")"); + edge_layout L; + L.parties = parties; + const auto s = protocol::slot_bytes_by_channel(p); + L.peer_slots = s.peer; + L.ring_slots = s.rss_next; + L.dealer_slots = s.dealer; + auto lanes = [&](const std::vector & v) { + return v.empty() ? std::size_t{0} + : net::lane_count_for_rounds(v.size(), cfg.n_lanes); + }; + L.peer_lanes = lanes(s.peer); + L.ring_lanes = lanes(s.rss_next); + L.dealer_lanes = lanes(s.dealer); + if (L.dealer_lanes != 0 && parties < 3) + throw std::invalid_argument("run_parties: the plan has dealer waves; " + "pass a plan for party 2 (the dealer) as well"); + L.ring_off = L.peer_lanes; + L.dealer_off = L.peer_lanes + L.ring_lanes; + L.pair_lanes = std::max(1, L.dealer_off + L.dealer_lanes); + return L; +} + +/// @brief One party's sinks over its links (`to[p]` = link to party `p`). +class party_edges +{ +public: + party_edges(unsigned me, const edge_layout & L, + const std::vector & to, std::size_t instances, + const net::sink_options & so) + { + const unsigned n = static_cast(L.parties); + auto view = [&](unsigned other, std::size_t off, + std::size_t lanes) -> net::async_stream_array & { + if (other >= to.size() || to[other] == nullptr) + throw std::logic_error("party " + std::to_string(me) + + " has no link to party " + std::to_string(other)); + views_.push_back( + std::make_unique(*to[other], off, lanes)); + return *views_.back(); + }; + net::sink_options single = so; + net::sink_options split = so; + split.reconnect = nullptr; + if (L.peer_lanes != 0 && me < 2) + peer_ = std::make_unique( + view(1 - me, L.peer_off, L.peer_lanes), L.peer_slots, instances, + single); + if (L.ring_lanes != 0) + { + const unsigned next = (me + 1) % n; + const unsigned prev = (me + n - 1) % n; + auto & out = view(prev, L.ring_off, L.ring_lanes); + if (next == prev) + ring_ = std::make_unique(out, L.ring_slots, + instances, single); + else + ring_ = std::make_unique(out, + view(next, L.ring_off, L.ring_lanes), L.ring_slots, instances, + split); + } + if (L.dealer_lanes != 0) + { + if (me < 2) + dealer_ = std::make_unique( + view(2, L.dealer_off, L.dealer_lanes), L.dealer_slots, + instances, single); + else + { + dealer_ = std::make_unique( + view(0, L.dealer_off, L.dealer_lanes), L.dealer_slots, + instances, single); + dealer_p1_ = std::make_unique( + view(1, L.dealer_off, L.dealer_lanes), L.dealer_slots, + instances, single); + } + } + } + + protocol::edge_mesh mesh() const + { + protocol::edge_mesh m; + m.sinks = {peer_.get(), ring_.get(), dealer_.get(), dealer_p1_.get()}; + return m; + } + + std::vector sinks() const + { + std::vector out; + for (auto * s : {peer_.get(), ring_.get(), dealer_.get(), dealer_p1_.get()}) + if (s != nullptr) + out.push_back(s); + return out; + } + +private: + std::vector> views_; + std::unique_ptr peer_; + std::unique_ptr ring_; + std::unique_ptr dealer_; + std::unique_ptr dealer_p1_; +}; + +/// @brief Summed counters over a party's distinct links. +inline net::stream_stats sum_stats(const std::vector & to) +{ + net::stream_stats t; + for (auto * l : to) + { + if (l == nullptr) + continue; + const auto s = l->stats(); + t.bytes_out += s.bytes_out; + t.bytes_in += s.bytes_in; + t.payload_out += s.payload_out; + t.payload_in += s.payload_in; + t.frames_out += s.frames_out; + t.frames_in += s.frames_in; + t.write_calls += s.write_calls; + } + return t; +} + +/// @brief Drive party `me`'s plan over its links. +inline void drive_party(unsigned me, const protocol::plan & plan, + party_values & values, const std::map & kernels, + const std::vector & to, const run_config & cfg, + const protocol::round_probe * probe = nullptr, net::io_pool * pool = nullptr, + protocol::cell_fn cell = nullptr) +{ + const auto L = layout_for(plan, to.size(), cfg); + net::sink_options so; + so.framing = cfg.framing; + if (cfg.wait_timeout.count() != 0) + so.drain_timeout = cfg.wait_timeout; + party_edges edges(me, L, to, cfg.instances, so); + auto opt = cfg.drive(); + opt.probe = probe; + opt.cell = cell; + if (pool != nullptr) + { + opt.workers = pool; + for (auto * l : to) + if (l != nullptr) + { + opt.pump = &l->context(); + break; + } + } + auto mesh = edges.mesh(); + if (edges.sinks().empty()) + { + protocol::detail::finish_steps(plan, {}, mesh, values, kernels, me, + cfg.instances, opt); + return; + } + protocol::drive_via_schedule(plan, mesh, values, kernels, me, opt); +} + +namespace detail +{ + +inline void pin_thread(int cpu) +{ +#if defined(__linux__) + if (cpu < 0) + return; + cpu_set_t set; + CPU_ZERO(&set); + CPU_SET(static_cast(cpu), &set); + const int rc = pthread_setaffinity_np(pthread_self(), sizeof(set), &set); + if (rc != 0) + DPF_LOG(warning, "pin.failed").kv("cpu", cpu).kv("error", std::strerror(rc)); + else + DPF_LOG(debug, "pin").kv("cpu", cpu); +#else + if (cpu >= 0) + DPF_LOG(warning, "pin.failed").kv("cpu", cpu).kv("error", "not supported"); +#endif +} + +/// @brief Holds every party until all have finished setup, so no party's +/// clock starts while another is still connecting or spawning. +class start_gate +{ +public: + explicit start_gate(std::size_t parties) : left_(parties) {} + + /// @brief False when another party failed before arriving. + bool arrive_and_wait() + { + std::unique_lock lock(mu_); + if (broken_) + return false; + if (--left_ == 0) + { + cv_.notify_all(); + return true; + } + cv_.wait(lock, [this] { return left_ == 0 || broken_; }); + return !broken_; + } + + /// @brief Release waiters; they return false. + void fail() + { + std::lock_guard lock(mu_); + if (left_ != 0) + broken_ = true; + cv_.notify_all(); + } + +private: + std::mutex mu_; + std::condition_variable cv_; + std::size_t left_ = 0; + bool broken_ = false; +}; + +/// @brief Thrown by a party released from the gate because another failed. +struct gate_broken : std::runtime_error +{ + gate_broken() + : std::runtime_error("run_parties: another party failed during setup") + { + } +}; + +inline std::string error_text(const std::exception_ptr & e) +{ + try + { + std::rethrow_exception(e); + } + catch (const std::exception & x) + { + return x.what(); + } + catch (...) + { + return "non-standard exception"; + } +} + +/// @brief This thread's wall time, CPU time, symmetric-key blocks, and random +/// bytes from construction to `done`. Other threads are not included. +struct party_meter +{ + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + std::uint64_t cpu0 = dpf::thread_cpu_ns(); + prg::counts sym0 = prg::snapshot(); + std::uint64_t rnd0 = random_bytes_count(); + std::uint64_t wall_ns = 0; + std::uint64_t cpu_ns = 0; + prg::counts sym{}; + std::uint64_t random_bytes = 0; + + void done() + { + wall_ns = static_cast(std::chrono::duration_cast< + std::chrono::nanoseconds>(std::chrono::steady_clock::now() - t0).count()); + cpu_ns = dpf::thread_cpu_ns() - cpu0; + const auto now = prg::snapshot(); + for (std::size_t k = 0; k < now.size(); ++k) + sym[k] = now[k] - sym0[k]; + random_bytes = random_bytes_count() - rnd0; + } +}; + +inline void log_plan(unsigned me, const protocol::plan & p, const edge_layout & L, + const run_config & cfg) +{ + std::size_t bytes = 0; + for (auto b : p.slot_bytes_all()) + bytes += b; + DPF_LOG(info, "plan").kv("party", me).kv("parties", L.parties) + .kv("rounds", p.rounds()).kv("waves", p.waves()).kv("slot_bytes", bytes) + .kv("peer_rounds", L.peer_slots.size()).kv("ring_rounds", L.ring_slots.size()) + .kv("dealer_rounds", L.dealer_slots.size()).kv("peer_lanes", L.peer_lanes) + .kv("ring_lanes", L.ring_lanes).kv("dealer_lanes", L.dealer_lanes) + .kv("pair_lanes", L.pair_lanes).kv("instances", cfg.instances) + .kv("framing", net::framing_name(cfg.framing)) + .kv("pipeline", cfg.pipeline_credit); +} + +inline void log_party_done(unsigned me, const party_meter & m, + const net::stream_stats & w, std::size_t compute_threads) +{ + if (!log::enabled(log::level::info)) + return; + log::record rec(log::level::info, "party.done"); + std::uint64_t protocol_blocks = 0; + for (std::size_t k = 0; k < 2 * prg::primitive_count; ++k) + protocol_blocks += m.sym[k]; + rec.kv("party", me).kv("wall_ns", m.wall_ns).kv("cpu_ns", m.cpu_ns) + .kv("counted_threads", compute_threads == 0 ? "party" : "party+pool") + .kv("sym_blocks", protocol_blocks); + for (std::size_t u = 0; u < prg::purpose_count; ++u) + for (std::size_t q = 0; q < prg::primitive_count; ++q) + { + const auto n = m.sym[u * prg::primitive_count + q]; + if (n == 0) + continue; + const std::string key = std::string("sym.") + + prg::purpose_name(static_cast(u)) + "." + + prg::primitive_name(static_cast(q)); + rec.kv(key.c_str(), n); + } + rec.kv("random_bytes", m.random_bytes).kv("wire_out", w.bytes_out) + .kv("wire_in", w.bytes_in).kv("payload_out", w.payload_out) + .kv("payload_in", w.payload_in).kv("frames_out", w.frames_out) + .kv("frames_in", w.frames_in).kv("write_calls", w.write_calls); +} + +} // namespace detail + +/// @brief What one `run_parties` call measured. +struct parties_result +{ + std::vector wire; ///< per party, summed over links + std::uint64_t party0_wall_ns = 0; + /// Each party's drive time on its own thread (party 0 is `party0_wall_ns`). + std::vector party_wall_ns; +}; + +/// @brief Drive every party's plan on its own thread over `cfg.kind`. +/// @details `plans[i]` and `values[i]` belong to party `i` (2 or 3 parties). +/// Link setup is outside the timed region, and every party waits at +/// a start gate until all have finished setup. A party that fails +/// closes its links so the others fail fast. When `ex` is set, party +/// 0's thread records its round probe and wall/CPU/PRG timing there. +/// When `seeds` (default `ex`) is set, party `i` draws from +/// `seeds->derive_party(i)`, so the run replays from that master; +/// the parties' noted seeds are folded into `ex`. +inline parties_result run_parties(const std::vector & plans, + std::vector & values, + const std::map & kernels = {}, + const run_config & cfg = {}, experiment * ex = nullptr, + protocol::cell_fn cell = nullptr, const experiment * seeds = nullptr) +{ + if (seeds == nullptr) + seeds = ex; + const std::size_t n = plans.size(); + if (n < 2 || n > 3) + throw std::invalid_argument("run_parties: 2 or 3 plans"); + if (values.size() < n) + values.resize(n); + std::size_t pair_lanes = 1; + for (std::size_t i = 0; i < n; ++i) + pair_lanes = std::max(pair_lanes, layout_for(plans[i], n, cfg).pair_lanes); + + std::vector> ios; + for (std::size_t i = 0; i < n; ++i) + ios.push_back(std::make_unique()); + std::vector> to(n, + std::vector(n, nullptr)); + std::vector> owned; + + const bool sockets = cfg.kind == net::transport::mux + || cfg.kind == net::transport::parallel || cfg.kind == net::transport::sctp; + if (cfg.kind == net::transport::async_memory) + { + for (std::size_t a = 0; a < n; ++a) + for (std::size_t b = a + 1; b < n; ++b) + { + auto pr = net::make_async_dual_memory_stream_pair(*ios[a], *ios[b], + pair_lanes, cfg.policy.window_bytes); + owned.push_back(std::make_unique( + std::move(pr.first))); + to[a][b] = owned.back().get(); + owned.push_back(std::make_unique( + std::move(pr.second))); + to[b][a] = owned.back().get(); + } + } + else if (cfg.kind == net::transport::local) + { + for (std::size_t a = 0; a < n; ++a) + for (std::size_t b = a + 1; b < n; ++b) + { + auto pr = net::make_local_socket_pairs(*ios[a], *ios[b], pair_lanes); + owned.push_back(std::make_unique( + *ios[a], std::move(pr.first), cfg.policy)); + to[a][b] = owned.back().get(); + owned.push_back(std::make_unique( + *ios[b], std::move(pr.second), cfg.policy)); + to[b][a] = owned.back().get(); + } + } + else if (!sockets) + throw std::invalid_argument(std::string("run_parties: transport ") + + net::transport_name(cfg.kind) + + " is not an async link (use async|local|mux|parallel|sctp)"); + + DPF_LOG(info, "parties.start").kv("parties", n) + .kv("transport", net::transport_name(cfg.kind)) + .kv("host", sockets ? cfg.host : std::string("in-process")) + .kv("pair_lanes", pair_lanes).kv("instances", cfg.instances) + .kv("compute_threads", cfg.compute_threads) + .kv("cpu0", cfg.cpu[0]).kv("cpu1", cfg.cpu[1]).kv("cpu2", cfg.cpu[2]) + .kv("experiment", ex != nullptr ? ex->name() : std::string("none")) + .kv("draws", seeds != nullptr ? "derived from the master" : "os entropy"); + + auto ports = net::make_mesh_ports(static_cast(n)); + parties_result result; + result.wire.resize(n); + result.party_wall_ns.assign(n, 0); + std::mutex err_mu; + std::exception_ptr err; + std::size_t failures = 0; + detail::start_gate gate(n); + std::vector> party_seeds(n); + std::vector ts; + for (std::size_t i = 0; i < n; ++i) + { + ts.emplace_back([&, i] { + const log::role_scope role("p" + std::to_string(i)); + detail::pin_thread(cfg.cpu[i]); + auto work = asio::make_work_guard(*ios[i]); + std::unique_ptr session; + auto links = to[i]; + try + { + if (sockets) + { + net::session_options so; + so.n_lanes = pair_lanes; + so.kind = cfg.kind; + so.policy = cfg.policy; + so.limits = cfg.limits; + so.security = cfg.security; + session = std::make_unique(*ios[i], + static_cast(i), static_cast(n), so); + session->join(cfg.host, ports); + for (std::size_t p = 0; p < n; ++p) + if (p != i) + links[p] = &session->peer(static_cast(p)); + } + std::unique_ptr pool; + if (cfg.compute_threads != 0) + pool = std::make_unique(1, cfg.compute_threads); + if (log::enabled(log::level::info)) + detail::log_plan(static_cast(i), plans[i], + layout_for(plans[i], n, cfg), cfg); + std::optional stream; + if (seeds != nullptr) + stream.emplace(seeds->derive_party(static_cast(i))); + if (!gate.arrive_and_wait()) + throw detail::gate_broken(); + experiment * mine = i == 0 ? ex : nullptr; + protocol::round_probe probe{}; + if (mine != nullptr) + { + probe = mine->probe(); + mine->begin_timing(); + } + detail::party_meter meter; + const auto t0 = std::chrono::steady_clock::now(); + drive_party(static_cast(i), plans[i], values[i], kernels, + links, cfg, mine != nullptr ? &probe : nullptr, pool.get(), + cell); + const auto t1 = std::chrono::steady_clock::now(); + meter.done(); + if (mine != nullptr) + mine->end_timing(); + result.party_wall_ns[i] = static_cast( + std::chrono::duration_cast(t1 - t0) + .count()); + if (i == 0) + result.party0_wall_ns = result.party_wall_ns[i]; + result.wire[i] = sum_stats(links); + detail::log_party_done(static_cast(i), meter, result.wire[i], + cfg.compute_threads); + if (stream) + party_seeds[i] = stream->seeds(); + } + catch (...) + { + const auto e = std::current_exception(); + bool released = false; + try + { + std::rethrow_exception(e); + } + catch (const detail::gate_broken &) + { + released = true; + } + catch (...) + { + } + gate.fail(); + if (!released) + DPF_LOG(error, "party.failed").kv("party", i) + .kv("what", detail::error_text(e)); + { + std::lock_guard lock(err_mu); + if (!released) + { + ++failures; + if (!err) + err = e; + } + } + for (auto * l : links) + if (l != nullptr) + l->close(); + } + work.reset(); + }); + } + for (auto & t : ts) + t.join(); + if (err) + { + DPF_LOG(error, "parties.failed").kv("parties", n).kv("failed", failures) + .kv("rethrown", detail::error_text(err)); + std::rethrow_exception(err); + } + if (ex != nullptr && seeds != nullptr) + for (std::size_t i = 0; i < n; ++i) + ex->fold_seeds("p" + std::to_string(i), party_seeds[i]); + if (log::enabled(log::level::info)) + { + const auto slowest = *std::max_element(result.party_wall_ns.begin(), + result.party_wall_ns.end()); + DPF_LOG(info, "parties.done").kv("parties", n) + .kv("p0_wall_ns", result.party0_wall_ns).kv("max_wall_ns", slowest); + } + return result; +} + +/// @brief One node of a multi-process run. +struct node_args +{ + unsigned party = 0; + std::vector peers; + run_config cfg; + /// The transport that was asked for when it was not a network socket and + /// `mux` ran instead (empty otherwise). + std::string replaced_transport; +}; + +namespace detail +{ + +inline unsigned long parse_count(const std::string & what, const std::string & v) +{ + std::size_t pos = 0; + unsigned long x = 0; + try + { + x = std::stoul(v, &pos, 10); + } + catch (const std::exception &) + { + pos = 0; + } + if (v.empty() || pos != v.size()) + throw std::invalid_argument(what + " needs a number, got '" + v + "'"); + return x; +} + +} // namespace detail + +/// @brief Parse `--party=i --peers=host:port,host:port[,host:port]` plus any +/// `run_config` keys (`--transport=mux --lanes=4 ...`). +inline node_args parse_node_args(int argc, char ** argv, + run_config base = run_config::from_env()) +{ + node_args a; + a.cfg = base; + bool have_party = false; + for (const auto & arg : a.cfg.apply_args(argc, argv)) + { + if (arg.rfind("--party=", 0) == 0) + { + a.party = static_cast(detail::parse_count("--party", arg.substr(8))); + have_party = true; + } + else if (arg.rfind("--peers=", 0) == 0) + { + std::string list = arg.substr(8); + std::size_t start = 0; + while (start <= list.size()) + { + const auto comma = list.find(',', start); + const std::string item = list.substr(start, + comma == std::string::npos ? std::string::npos : comma - start); + const auto colon = item.rfind(':'); + if (colon == std::string::npos) + throw std::invalid_argument("--peers entry '" + item + + "' needs host:port"); + const auto port = detail::parse_count("--peers port", item.substr(colon + 1)); + if (port > 65535) + throw std::invalid_argument("--peers entry '" + item + + "' has a port above 65535"); + a.peers.push_back(net::peer_address{item.substr(0, colon), + static_cast(port)}); + if (comma == std::string::npos) + break; + start = comma + 1; + } + } + else + throw std::invalid_argument("unknown argument '" + arg + "'"); + } + if (!have_party || a.peers.size() < 2) + throw std::invalid_argument( + "usage: --party=i --peers=host:port,host:port[,host:port] [--key=value]"); + if (a.party >= a.peers.size()) + throw std::invalid_argument("--party is outside --peers"); + if (!net::is_socket_transport(a.cfg.kind) || a.cfg.kind == net::transport::local) + { + a.replaced_transport = net::transport_name(a.cfg.kind); + a.cfg.kind = net::transport::mux; + } + return a; +} + +/// @brief Join the static table and drive this node's party. +inline net::stream_stats run_node(const node_args & a, const protocol::plan & plan, + party_values & values, + const std::map & kernels = {}) +{ + const std::size_t n = a.peers.size(); + const auto L = layout_for(plan, n, a.cfg); + const log::role_scope role("p" + std::to_string(a.party)); + if (!a.replaced_transport.empty()) + DPF_LOG(warning, "config.override").kv("key", "transport") + .kv("requested", a.replaced_transport).kv("used", "mux") + .kv("detail", "a node needs a network transport"); + if (log::enabled(log::level::info)) + { + std::string table; + for (std::size_t p = 0; p < n; ++p) + table += (p == 0 ? "" : ",") + a.peers[p].host + ":" + + std::to_string(a.peers[p].port); + DPF_LOG(info, "node.start").kv("party", a.party).kv("parties", n) + .kv("transport", net::transport_name(a.cfg.kind)).kv("peers", table) + .kv("compute_threads", a.cfg.compute_threads); + detail::log_plan(a.party, plan, L, a.cfg); + } + asio::io_context io; + auto work = asio::make_work_guard(io); + net::session_options so; + so.n_lanes = L.pair_lanes; + so.kind = a.cfg.kind; + so.policy = a.cfg.policy; + so.limits = a.cfg.limits; + so.security = a.cfg.security; + net::party_session session(io, a.party, static_cast(n), so); + session.join(a.peers); + std::vector links(n, nullptr); + for (std::size_t p = 0; p < n; ++p) + if (p != a.party) + links[p] = &session.peer(static_cast(p)); + std::unique_ptr pool; + if (a.cfg.compute_threads != 0) + pool = std::make_unique(1, a.cfg.compute_threads); + detail::party_meter meter; + try + { + drive_party(a.party, plan, values, kernels, links, a.cfg, nullptr, pool.get()); + } + catch (...) + { + DPF_LOG(error, "party.failed").kv("party", a.party) + .kv("what", detail::error_text(std::current_exception())); + throw; + } + meter.done(); + const auto wire = sum_stats(links); + detail::log_party_done(a.party, meter, wire, a.cfg.compute_threads); + return wire; +} + +} // namespace app +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_PARTY_RUNNER_HPP__ diff --git a/include/dpf/path_memoizer.hpp b/include/dpf/path_memoizer.hpp index fcd3adf..a019b39 100644 --- a/include/dpf/path_memoizer.hpp +++ b/include/dpf/path_memoizer.hpp @@ -30,6 +30,7 @@ #include "dpf/utils.hpp" #include "dpf/secret_share.hpp" +#include "dpf/verifiable.hpp" namespace dpf { @@ -67,6 +68,7 @@ struct path_memoizer_base /// written for the current input. Callers pass this object to `eval_point`; /// they do not call `assign_x` themselves. /// @tparam DpfKey DPF key type +/// \complexity O(n) nodes, one per level (`arr_` has `depth + 1` slots). `assign_x` is O(1) after a common-prefix XOR. template struct alignas(alignof(typename path_memoizer_key_t::interior_node)) basic_path_memoizer final @@ -170,6 +172,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) /// @brief A single interior node. Every `assign_x` restarts at the root. /// @tparam DpfKey DPF key type +/// \complexity O(1) space (one node). Every `assign_x` restarts at the root, so `eval_point` still walks n levels. template struct nonmemoizing_path_memoizer final : public path_memoizer_base> @@ -271,27 +274,72 @@ void path_note_filled_to(PathMemoizer & path, std::size_t level) } /// @brief Walk interior nodes so `path[0..to_level]` is valid for `x`. +/// @details When `pi` is non-null and the key is verifiable, each newly +/// traversed node is folded into the proof token (LightShark-style +/// path authentication on aggregate walks). When `fold_cached` is +/// true, nodes already held by the memoizer are hashed into `pi` +/// without re-expanding the PRG — required after `init_proof` on a +/// warm path. Leave `fold_cached` false when continuing one +/// accumulator that already contains those nodes. /// @tparam DpfKey DPF key type /// @tparam PathMemoizer path memoizer type /// @param dpf the DPF key /// @param x the `x` /// @param path the root-to-leaf path /// @param to_level the `to_level` +/// @param pi optional VDPF proof accumulator +/// @param fold_cached whether to fold memoized prefix nodes into a fresh token template void ensure_level(const DpfKey & dpf, typename DpfKey::input_type x, - PathMemoizer & path, std::size_t to_level) + PathMemoizer & path, std::size_t to_level, proof_token * pi = nullptr, + bool fold_cached = false) { auto level_index = path_resume_for_level(path, dpf, x, to_level); - DPF_UNROLL_LOOP - for (auto mask = dpf.msb_mask >> (level_index - 1); - level_index <= to_level; ++level_index, mask >>= 1) + if constexpr (DpfKey::is_verifiable) { - bool bit = !!(mask & x); - auto cw = dpf.correction_word(level_index - 1, bit); - const bool is_last = DpfKey::tree::is_last_level(level_index - 1, - dpf.depth); - path[level_index] = - DpfKey::traverse_interior(path[level_index - 1], cw, bit, is_last); + if (pi != nullptr && fold_cached && level_index > 1) + { + for (std::size_t li = 1; li < level_index && li <= to_level; ++li) + { + const auto x_bits = static_cast( + utils::to_integral_type{}(x) + >> (utils::bitlength_of_v + - li)); + detail::vdpf::fold_node(*pi, li - 1, x_bits, path[li], + dpf.correction_seeds()[li - 1]); + } + } + } + // Resume past `to_level` means the spine is already valid. Do not form + // `msb_mask >> (level_index - 1)` in that case: for a full-width domain + // (`to_level == input_bits`) that shift is exactly the type width (UB). + if (level_index <= to_level) + { + DPF_UNROLL_LOOP + for (auto mask = dpf.msb_mask >> (level_index - 1); + level_index <= to_level; ++level_index, mask >>= 1) + { + bool bit = !!(mask & x); + auto cw = dpf.correction_word(level_index - 1, bit); + const bool is_last = DpfKey::tree::is_last_level(level_index - 1, + dpf.depth); + path[level_index] = + DpfKey::traverse_interior(path[level_index - 1], cw, bit, + is_last); + if constexpr (DpfKey::is_verifiable) + { + if (pi != nullptr) + { + const auto x_bits = static_cast( + utils::to_integral_type{}(x) + >> (utils::bitlength_of_v + - level_index)); + detail::vdpf::fold_node(*pi, level_index - 1, x_bits, + path[level_index], + dpf.correction_seeds()[level_index - 1]); + } + } + } } path_note_filled_to(path, to_level); } diff --git a/include/dpf/path_sketch.hpp b/include/dpf/path_sketch.hpp new file mode 100644 index 0000000..7ced5f4 --- /dev/null +++ b/include/dpf/path_sketch.hpp @@ -0,0 +1,241 @@ +/// @file dpf/path_sketch.hpp +/// @brief VIDPF-style path-consistency sketches for incremental / IDPF keys. +/// @details Leaf one-hot is `sketch_fold` in verifiable.hpp. This header +/// checks that prefix payloads form a single spine: each depth is +/// weight-1 (or a single nonzero weight), and each parent equals the +/// sum of its children. Used by Poplar / Mastic one-time verification. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_PATH_SKETCH_HPP__ +#define LIBDPF_INCLUDE_DPF_PATH_SKETCH_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/dpf_key.hpp" +#include "dpf/eval_target.hpp" +#include "dpf/eval_walk.hpp" +#include "dpf/fp61.hpp" +#include "dpf/verifiable.hpp" + +namespace dpf +{ + +namespace detail +{ +namespace path_sketch_impl +{ + +template +HEDLEY_ALWAYS_INLINE +fp61 value_to_fp61(const Y & y) noexcept +{ + if constexpr (std::is_same_v, fp61>) + return y; + else + return fp61{static_cast(y)}; +} + +template +struct has_raw_method : std::false_type +{ }; + +template +struct has_raw_method().raw())>> + : std::true_type +{ }; + +template +HEDLEY_ALWAYS_INLINE +fp61 share_to_fp61(const Share & s) noexcept +{ + if constexpr (std::is_same_v, fp61>) + return s; + else if constexpr (std::is_integral_v>) + return fp61{static_cast(s)}; + else if constexpr (has_raw_method>::value) + return value_to_fp61(s.raw()); + else + return value_to_fp61(s); +} + +} // namespace path_sketch_impl +} // namespace detail + +/// @brief Weight-1 sketch of the `2^N` prefix shares at output `I`. +/// @details Opens to a valid `sketch_fold` iff exactly one prefix is nonzero +/// (unit path) or a single weight w sits on one prefix (weighted +/// IDPF). Consumes `2^N` challenges from `rs`. +template +sketch_share sketch_path_level(out_t, const KeyT & key, + const fp61 * rs, std::size_t n) +{ + static_assert(is_multilevel_key_v, + "sketch_path_level: key must be multilevel / idpf"); + constexpr std::size_t nprefix = std::size_t{1} << N; + if (rs == nullptr || n < nprefix) + throw std::invalid_argument("sketch_path_level: need 2^N challenges"); + + auto [buf, it] = eval_prefixes(out_t{}, key); + (void)buf; + std::vector ys; + ys.reserve(nprefix); + std::size_t i = 0; + for (auto a = std::begin(it); a != std::end(it) && i < nprefix; ++a, ++i) + ys.push_back(detail::path_sketch_impl::share_to_fp61(*a)); + if (ys.size() != nprefix) + throw std::runtime_error("sketch_path_level: prefix count mismatch"); + return sketch_fold(ys, std::vector(rs, rs + nprefix)); +} + +/// @brief Random linear check that parent[p] = left[2p] + right[2p+1]. +/// @details Parent slot `I` has prefix length `N`; child is slot `I+1` with +/// length `N+1`. Consumes `2^N` challenges. Opens to 0 when the +/// two levels are consistent. +template +fp61 sketch_path_parent(out_t, out_t, const KeyT & key, + const fp61 * gamma, std::size_t n) +{ + static_assert(is_multilevel_key_v, + "sketch_path_parent: key must be multilevel / idpf"); + constexpr std::size_t nparent = std::size_t{1} << N; + if (gamma == nullptr || n < nparent) + throw std::invalid_argument("sketch_path_parent: need 2^N challenges"); + + auto [bp, ip] = eval_prefixes(out_t{}, key); + auto [bc, ic] = eval_prefixes(out_t{}, key); + (void)bp; + (void)bc; + + std::vector parents; + std::vector children; + parents.reserve(nparent); + children.reserve(nparent * 2); + for (auto a = std::begin(ip); a != std::end(ip); ++a) + parents.push_back(detail::path_sketch_impl::share_to_fp61(*a)); + for (auto a = std::begin(ic); a != std::end(ic); ++a) + children.push_back(detail::path_sketch_impl::share_to_fp61(*a)); + if (parents.size() != nparent || children.size() != nparent * 2) + throw std::runtime_error("sketch_path_parent: prefix count mismatch"); + + fp61 gap{}; + for (std::size_t p = 0; p < nparent; ++p) + { + const fp61 rel = parents[p] - children[2 * p] - children[2 * p + 1]; + gap = gap + gamma[p] * rel; + } + return gap; +} + +/// @brief Whether two parent-gap shares open to zero. +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +bool sketch_path_verify_parent(fp61 g0, fp61 g1) noexcept +{ + return (g0 - g1).raw() == 0; +} + +namespace detail +{ +namespace path_sketch_impl +{ + +template +struct verify_levels +{ + template + static bool run(const K0 & k0, const K1 & k1, const fp61 *& rs, + std::size_t & left) + { + constexpr std::size_t N = I + 1; + constexpr std::size_t nprefix = std::size_t{1} << N; + if (left < nprefix) + return false; + const auto s0 = sketch_path_level(out_t{}, k0, rs, left); + const auto s1 = sketch_path_level(out_t{}, k1, rs, left); + if (!sketch_verify(s0, s1)) + return false; + rs += nprefix; + left -= nprefix; + + if constexpr (I + 1 < Depth) + { + constexpr std::size_t nparent = std::size_t{1} << N; + if (left < nparent) + return false; + const fp61 g0 = sketch_path_parent(out_t{}, + out_t{}, k0, rs, left); + const fp61 g1 = sketch_path_parent(out_t{}, + out_t{}, k1, rs, left); + if (!sketch_path_verify_parent(g0, g1)) + return false; + rs += nparent; + left -= nparent; + return verify_levels::run(k0, k1, rs, left); + } + return true; + } +}; + +} // namespace path_sketch_impl +} // namespace detail + +/// @brief One-time VIDPF path check for an IDPF of consecutive depths 1..Depth. +/// @details Challenge layout, consumed in order for I = 0 .. Depth-1: +/// - `2^(I+1)` challenges for the weight-1 sketch at `out` +/// - if I+1 < Depth: `2^(I+1)` challenges for the parent relation +/// between `out` and `out` +/// @tparam Depth number of IDPF prefix slots (`idpf` with Depth betas) +template +bool verify_idpf_path(const Key0 & k0, const Key1 & k1, + const fp61 * rs, std::size_t n) +{ + static_assert(Depth >= 1, "verify_idpf_path: Depth >= 1"); + static_assert(is_multilevel_key_v && is_multilevel_key_v, + "verify_idpf_path: multilevel keys"); + if (!same_public_part(k0, k1)) + return false; + if (rs == nullptr) + return false; + const fp61 * cursor = rs; + std::size_t left = n; + return detail::path_sketch_impl::verify_levels::run( + k0, k1, cursor, left); +} + +/// @brief Convenience overload taking a contiguous challenge vector. +template +bool verify_idpf_path(const Key0 & k0, const Key1 & k1, + const std::vector & rs) +{ + return verify_idpf_path(k0, k1, rs.data(), rs.size()); +} + +/// @brief How many fp61 challenges `verify_idpf_path` consumes. +HEDLEY_CONST +HEDLEY_ALWAYS_INLINE +constexpr std::size_t path_sketch_challenge_count(std::size_t depth) noexcept +{ + std::size_t n = 0; + for (std::size_t i = 0; i < depth; ++i) + { + const std::size_t nprefix = std::size_t{1} << (i + 1); + n += nprefix; + if (i + 1 < depth) + n += nprefix; + } + return n; +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_PATH_SKETCH_HPP__ diff --git a/include/dpf/placement.hpp b/include/dpf/placement.hpp index 689af87..fbacd99 100644 --- a/include/dpf/placement.hpp +++ b/include/dpf/placement.hpp @@ -107,6 +107,13 @@ struct extractable static constexpr bool is_extractable_tag = true; }; +/// @brief Phantom pack element: keep a beaver-backed leaf so the payload can +/// be rewritten without regenerating the path to `α`. +struct updatable +{ + static constexpr bool is_updatable_tag = true; +}; + template struct is_verifiable_tag : std::false_type { }; @@ -127,6 +134,64 @@ template inline constexpr bool is_extractable_tag_v = is_extractable_tag>::value; +template +struct is_updatable_tag : std::false_type +{ }; +template <> +struct is_updatable_tag : std::true_type +{ }; +template +inline constexpr bool is_updatable_tag_v = + is_updatable_tag>::value; + +/// @brief Compile-time switch for verifiable / extractable / output-MAC checks. +/// @details Default `auth_profile<>` is semi-honest: no correction seeds and +/// no leaf XOF. `verifiable` and `extractable` become phantom tags +/// for `make_dpf_profile`. `output_mac` stays on the profile for +/// Beaver and carry sessions; key generation does not consume it. +template +struct auth_profile +{ + static constexpr bool verifiable = Verifiable; + static constexpr bool extractable = Extractable; + static constexpr bool output_mac = OutputMac; +}; + +using semi_honest = auth_profile; +using checked = auth_profile; + +/// @brief Tuple of phantom tags requested by `Profile` (may be empty). +/// @tparam Profile an `auth_profile` specialization +/// @return `verifiable` and/or `extractable`, or an empty tuple. +/// `Profile::output_mac` is not a key tag. +template +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr auto key_tags_tuple() noexcept +{ + if constexpr (Profile::verifiable && Profile::extractable) + return std::tuple{verifiable{}, extractable{}}; + else if constexpr (Profile::verifiable) + return std::tuple{verifiable{}}; + else if constexpr (Profile::extractable) + return std::tuple{extractable{}}; + else + return std::tuple{}; +} + +/// @brief Alias for `key_tags_tuple` (use with `std::apply` / `make_dpf_profile`). +/// @tparam Profile an `auth_profile` specialization +/// @return the same tuple as `key_tags_tuple()` +/// @see key_tags_tuple +template +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr auto key_tags() noexcept +{ + return key_tags_tuple(); +} + namespace detail { namespace incr @@ -145,10 +210,12 @@ struct unwrap_placed_output using type = T; }; -template +template struct placed { static constexpr std::size_t prefix = N; + /// @brief When true, party 0 absorbs `addend` (eq / eq_at if_false) at eval. + static constexpr bool has_public_addend = PublicAddend; /// @brief Stored argument type (may be `arith_beta`). using stored_type = OutputT; /// @brief Key / leaf payload type (`T` when stored is `arith_beta`). @@ -158,11 +225,19 @@ struct placed }; template struct is_placed : std::false_type {}; -template -struct is_placed> : std::true_type {}; +template +struct is_placed> : std::true_type {}; template inline constexpr bool is_placed_v = is_placed>::value; +template +struct any_public_addend : std::false_type {}; +template +struct any_public_addend> + : std::bool_constant<(Ps::has_public_addend || ...)> {}; +template +inline constexpr bool any_public_addend_v = any_public_addend::value; + /// @brief Heavy-hitters incremental point function: one payload per prefix length. /// @details `levels[i]` is the bit length of slot `i`. /// @tparam LevelSeq level seq @@ -470,10 +545,10 @@ struct normalize_one static constexpr bool is_verifiable = false; static constexpr bool is_extractable = false; }; -template -struct normalize_one> +template +struct normalize_one> { - using placed_tuple = std::tuple>; + using placed_tuple = std::tuple>; static constexpr std::size_t cmp_depth = 0; static constexpr std::size_t cmp_out_bits = 0; static constexpr bool cmp_wild = false; @@ -520,6 +595,18 @@ struct normalize_one static constexpr bool is_verifiable = false; static constexpr bool is_extractable = true; }; +template +struct normalize_one +{ + using placed_tuple = std::tuple<>; + static constexpr std::size_t cmp_depth = 0; + static constexpr std::size_t cmp_out_bits = 0; + static constexpr bool cmp_wild = false; + static constexpr std::size_t cmp_block = 0; + static constexpr bool cmp_idcf = false; + static constexpr bool is_verifiable = false; + static constexpr bool is_extractable = false; +}; template struct normalize_pack @@ -561,7 +648,8 @@ struct normalize_pack template inline constexpr bool is_classic_pack_v = !((is_placed_v || is_cmp_channel_tag_v - || is_verifiable_tag_v || is_extractable_tag_v) || ...); + || is_verifiable_tag_v || is_extractable_tag_v + || is_updatable_tag_v) || ...); } // namespace incr } // namespace detail diff --git a/include/dpf/pprf.hpp b/include/dpf/pprf.hpp new file mode 100644 index 0000000..e594974 --- /dev/null +++ b/include/dpf/pprf.hpp @@ -0,0 +1,408 @@ +/// @file dpf/pprf.hpp +/// @brief GGM puncturable PRF on the library AES-128 PRG. +/// @details A master seed evaluates at every domain point. `puncture` at a +/// single `α` returns one sibling seed per level so evaluation +/// everywhere except `α` costs O(n) PRG calls. `puncture` over a +/// set `H` returns the copath of that set: every node whose parent +/// lies on a path to `H` and which itself does not. Shared prefixes +/// are stored once. The programmed leaf values are stored beside the +/// puncture when the holder of the master asks for them; an audit +/// opening of a replica-seed pool leaves them out (`program_hidden = +/// false`). Complexity of the set walk is O(|H| · n) PRG expansions +/// and at most |H| · n published nodes; the domain is never +/// materialized. One-point and set forms agree on `{α}`. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_DPF_PPRF_HPP__ +#define LIBDPF_INCLUDE_DPF_PPRF_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" +#include "dpf/utils.hpp" + +namespace dpf +{ + +/// @brief Master key for a puncturable PRF over `InputT`. +/// @tparam InputT domain type (`uint32_t`, `simde_uint128`, ...) +/// @tparam PRG exterior/interior PRG; defaults to AES-128 +template +struct pprf_master +{ + using input_type = InputT; + using prg = PRG; + using block_type = typename PRG::block_type; + static constexpr std::size_t bitlength = utils::bitlength_of_v; + + block_type root{}; +}; + +/// @brief Punctured key: sibling seed per level, optional programmed leaf. +template +struct pprf_punctured +{ + using input_type = InputT; + using prg = PRG; + using block_type = typename PRG::block_type; + static constexpr std::size_t bitlength = utils::bitlength_of_v; + + input_type alpha{}; + /// @brief `siblings[i]` is the seed for the sibling of the path bit at + /// level `i` (MSB = 0). + std::array siblings{}; + /// @brief Path bit taken toward `alpha` at each level (1 = right). + std::array path_bits{}; + /// @brief When set, `pprf_eval` at `alpha` returns this leaf. + std::optional programmed{}; +}; + +/// @brief One published node on the copath of a hidden set. +/// @details `level` is the number of path bits from the root (`0` only for the +/// empty-`H` root). `prefix` holds those bits right-aligned, so the +/// top `level` bits of a domain point `x` match when +/// `(x >> (n - level)) == prefix`. +template +struct pprf_copath_node +{ + using input_type = InputT; + using prg = PRG; + using block_type = typename PRG::block_type; + + std::size_t level{}; + input_type prefix{}; + block_type seed{}; +}; + +/// @brief Copath of a hidden set: sorted unique points plus published nodes. +/// @details Empty `hidden` publishes the root so every domain point evaluates. +/// A full-domain `hidden` publishes nothing. When `programmed` is +/// non-empty it has one leaf per hidden point, in the same order as +/// `hidden`. A live seed is never among `nodes`. +template +struct pprf_copath +{ + using input_type = InputT; + using prg = PRG; + using block_type = typename PRG::block_type; + static constexpr std::size_t bitlength = utils::bitlength_of_v; + + std::vector hidden{}; + std::vector> nodes{}; + std::vector programmed{}; +}; + +/// @brief Sample a fresh master seed. +template +HEDLEY_WARN_UNUSED_RESULT +HEDLEY_NO_THROW +pprf_master make_pprf_master() noexcept +{ + pprf_master m; + m.root = dpf::uniform_sample(); + return m; +} + +namespace detail +{ +namespace pprf_impl +{ + +/// @brief Path bit of `x` at `level` (0 = MSB). +template +HEDLEY_CONST +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +constexpr bool path_bit(InputT x, std::size_t level) noexcept +{ + constexpr std::size_t n = utils::bitlength_of_v; + constexpr auto to_int = utils::to_integral_type{}; + using integral_t = typename utils::to_integral_type::integral_type; + const integral_t xi = static_cast(to_int(x)); + const std::size_t shift = n - 1 - level; + return static_cast(utils::shift_right(xi, shift) & integral_t{1}); +} + +/// @brief Split `seed` into left (pos 0) and right (pos 1) children. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +void expand_children(typename PRG::block_type seed, + typename PRG::block_type & left, typename PRG::block_type & right) noexcept +{ + // Match DPF interior: pos 0 = left child, pos 1 = right child. + left = PRG::eval(seed, 0); + right = PRG::eval(seed, 1); +} + +/// @brief Top `level` path bits of `x`, right-aligned. +template +HEDLEY_CONST +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +constexpr InputT path_prefix(InputT x, std::size_t level) noexcept +{ + if (level == 0) + return InputT{}; + constexpr std::size_t n = utils::bitlength_of_v; + constexpr auto to_int = utils::to_integral_type{}; + using integral_t = typename utils::to_integral_type::integral_type; + const integral_t xi = static_cast(to_int(x)); + return static_cast(utils::shift_right(xi, n - level)); +} + +/// @brief Whether `x` lies under the node `(level, prefix)`. +template +HEDLEY_CONST +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +constexpr bool prefix_matches(InputT x, std::size_t level, + InputT prefix) noexcept +{ + return path_prefix(x, level) == prefix; +} + +/// @brief Recursively publish the copath of `hidden[lo, hi)` under `seed`. +/// @details `hidden` must be sorted unique. Emits at most one node per +/// off-path sibling; shared prefixes are visited once. When +/// `program_hidden` is set, appends leaf seeds in sorted `hidden` +/// order. +template +void collect_copath(typename PRG::block_type seed, std::size_t level, + InputT prefix, const std::vector & hidden, std::size_t lo, + std::size_t hi, bool program_hidden, + std::vector> & nodes, + std::vector & programmed) +{ + constexpr std::size_t n = utils::bitlength_of_v; + if (lo == hi) + return; + if (level == n) + { + if (program_hidden) + programmed.push_back(seed); + return; + } + + // `hidden` is sorted by domain value, so MSB-first path order matches. + std::size_t mid = lo; + while (mid < hi && !path_bit(hidden[mid], level)) + ++mid; + + typename PRG::block_type left{}, right{}; + expand_children(seed, left, right); + + const InputT left_prefix = + static_cast((static_cast(prefix) << 1) | InputT{0}); + const InputT right_prefix = + static_cast((static_cast(prefix) << 1) | InputT{1}); + + const bool left_on_path = mid > lo; + const bool right_on_path = hi > mid; + + // Match the one-point walk: publish the off-path sibling, then descend. + if (left_on_path && right_on_path) + { + collect_copath(left, level + 1, left_prefix, hidden, lo, + mid, program_hidden, nodes, programmed); + collect_copath(right, level + 1, right_prefix, hidden, mid, + hi, program_hidden, nodes, programmed); + } + else if (left_on_path) + { + nodes.push_back( + pprf_copath_node{level + 1, right_prefix, right}); + collect_copath(left, level + 1, left_prefix, hidden, lo, + mid, program_hidden, nodes, programmed); + } + else + { + nodes.push_back( + pprf_copath_node{level + 1, left_prefix, left}); + collect_copath(right, level + 1, right_prefix, hidden, mid, + hi, program_hidden, nodes, programmed); + } +} + +} // namespace pprf_impl +} // namespace detail + +/// @brief Evaluate the master at `x`. Returns one AES block (the leaf seed). +template +HEDLEY_WARN_UNUSED_RESULT +HEDLEY_NO_THROW +typename PRG::block_type pprf_eval(const pprf_master & master, + InputT x) noexcept +{ + using block = typename PRG::block_type; + constexpr std::size_t n = pprf_master::bitlength; + block cur = master.root; + for (std::size_t level = 0; level < n; ++level) + { + block left{}, right{}; + detail::pprf_impl::expand_children(cur, left, right); + cur = detail::pprf_impl::path_bit(x, level) ? right : left; + } + return cur; +} + +/// @brief Puncture `master` at `alpha`. Optionally program `F(alpha)`. +/// @param program_alpha when true (default), store `F(α)` beside the siblings +template +HEDLEY_WARN_UNUSED_RESULT +HEDLEY_NO_THROW +pprf_punctured puncture(const pprf_master & master, + InputT alpha, bool program_alpha = true) noexcept +{ + using block = typename PRG::block_type; + constexpr std::size_t n = pprf_master::bitlength; + pprf_punctured out{}; + out.alpha = alpha; + block cur = master.root; + for (std::size_t level = 0; level < n; ++level) + { + block left{}, right{}; + detail::pprf_impl::expand_children(cur, left, right); + const bool bit = detail::pprf_impl::path_bit(alpha, level); + out.path_bits[level] = static_cast(bit); + out.siblings[level] = bit ? left : right; // keep the off-path child + cur = bit ? right : left; + } + if (program_alpha) + out.programmed = cur; + return out; +} + +/// @brief Evaluate a punctured key. At `alpha` returns the programmed leaf +/// when present; otherwise throws `std::invalid_argument`. +template +HEDLEY_WARN_UNUSED_RESULT +typename PRG::block_type pprf_eval(const pprf_punctured & key, + InputT x) +{ + using block = typename PRG::block_type; + constexpr std::size_t n = pprf_punctured::bitlength; + if (x == key.alpha) + { + if (!key.programmed.has_value()) + throw std::invalid_argument( + "pprf_eval: punctured point has no programmed value"); + return *key.programmed; + } + + // First level where x diverges from alpha; expand from that sibling. + for (std::size_t level = 0; level < n; ++level) + { + const bool xbit = detail::pprf_impl::path_bit(x, level); + const bool abit = static_cast(key.path_bits[level]); + if (xbit == abit) + continue; + block cur = key.siblings[level]; + for (std::size_t j = level + 1; j < n; ++j) + { + block left{}, right{}; + detail::pprf_impl::expand_children(cur, left, right); + cur = detail::pprf_impl::path_bit(x, j) ? right : left; + } + return cur; + } + throw std::logic_error("pprf_eval: path didn't diverge from alpha"); +} + +/// @brief Puncture `master` at every point in `[first, last)`. +/// @details Duplicate points are collapsed. Empty `H` publishes the root. +/// Full-domain `H` publishes nothing. Shared path prefixes are +/// stored once. Visits O(|H| · n) nodes and emits at most |H| · n. +/// @param program_hidden defaults to `false` so an audit opening does not +/// carry the live seeds; set `true` to store `F(h)` for each `h ∈ H` +/// @return sorted unique `hidden`, the published copath, and optional leaves +template +HEDLEY_WARN_UNUSED_RESULT +pprf_copath puncture(const pprf_master & master, + ForwardIt first, ForwardIt last, bool program_hidden = false) +{ + pprf_copath out{}; + out.hidden.assign(first, last); + std::sort(out.hidden.begin(), out.hidden.end()); + out.hidden.erase(std::unique(out.hidden.begin(), out.hidden.end()), + out.hidden.end()); + + if (out.hidden.empty()) + { + out.nodes.push_back( + pprf_copath_node{0, InputT{}, master.root}); + return out; + } + + if (program_hidden) + out.programmed.reserve(out.hidden.size()); + + detail::pprf_impl::collect_copath(master.root, 0, InputT{}, + out.hidden, 0, out.hidden.size(), program_hidden, out.nodes, + out.programmed); + return out; +} + +/// @brief Evaluate a set-punctured key at `x`. +/// @details Expands from the deepest copath node whose prefix matches `x`, +/// using the same child split as the one-point eval. A hidden `x` +/// returns the programmed leaf when one was stored, and throws +/// `std::invalid_argument` otherwise. Throws the same when no +/// published node covers `x` (full-domain puncture). +template +HEDLEY_WARN_UNUSED_RESULT +typename PRG::block_type pprf_eval(const pprf_copath & key, + InputT x) +{ + using block = typename PRG::block_type; + constexpr std::size_t n = pprf_copath::bitlength; + + const auto hit = std::lower_bound(key.hidden.begin(), key.hidden.end(), x); + if (hit != key.hidden.end() && *hit == x) + { + if (key.programmed.empty()) + throw std::invalid_argument( + "pprf_eval: hidden point has no programmed value"); + const auto idx = static_cast( + std::distance(key.hidden.begin(), hit)); + return key.programmed[idx]; + } + + const pprf_copath_node * best = nullptr; + for (const auto & node : key.nodes) + { + if (node.level == 0 + || detail::pprf_impl::prefix_matches(x, node.level, node.prefix)) + { + if (best == nullptr || node.level > best->level) + best = &node; + } + } + if (best == nullptr) + throw std::invalid_argument("pprf_eval: no copath node covers point"); + + block cur = best->seed; + for (std::size_t level = best->level; level < n; ++level) + { + block left{}, right{}; + detail::pprf_impl::expand_children(cur, left, right); + cur = detail::pprf_impl::path_bit(x, level) ? right : left; + } + return cur; +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_PPRF_HPP__ diff --git a/include/dpf/ppvc.hpp b/include/dpf/ppvc.hpp index 015a015..cdf903a 100644 --- a/include/dpf/ppvc.hpp +++ b/include/dpf/ppvc.hpp @@ -12,7 +12,8 @@ /// `verify` checks the opened Naor roots. Correction words travel with the /// opened key. `check_well_formed` checks both keys of a replica the /// committer still holds, and `audit` reruns generation from a seed. -/// Evaluation walks the domain, so the input bitlength is at most 16. +/// Evaluation stores one entry per domain point, so the input bitlength +/// is at most 20. The full-domain walk is `eval_full`. /// The manual is [Point-programmable vector commitments](@ref ppvc_manual). /// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license; @@ -38,6 +39,7 @@ #include "dpf/bit.hpp" #include "dpf/dpf_key.hpp" +#include "dpf/eval_full.hpp" #include "dpf/eval_point.hpp" #include "dpf/prg.hpp" #include "dpf/random.hpp" @@ -79,7 +81,7 @@ struct ppvc static_assert(m_bits % 8 == 0, "ppvc Naor string must be a whole number of bytes"); static_assert(domain_bits >= dpf::lg_outputs_per_leaf_v, "ppvc domain must cover one packed leaf"); - static_assert(domain_bits <= 16, "ppvc evaluation materializes the domain"); + static_assert(domain_bits <= 20, "ppvc evaluation materializes one entry per domain point"); /// @brief `m`-bit string, the codomain of Naor's `G`. struct naor_string @@ -221,18 +223,31 @@ struct ppvc const std::size_t hidden = index_of(st.i); std::array u{}; - for (std::size_t j = 0; j < Width; ++j) - u[j] = bit_at(key_of(st, j, 0), hidden); - value_type target = tau; - if (mu == 1) + if (mu == 0) { + for (std::size_t j = 0; j < Width; ++j) + u[j] = bit_at(key_of(st, j, 0), hidden); + } + else + { + std::array, Width> columns{}; + for (std::size_t j = 0; j < Width; ++j) + columns[j] = full_bits(key_of(st, j, 0)); value_type off_sum = 0; for (std::size_t y = 0; y < domain_size; ++y) { + value_type column = 0; + for (std::size_t j = 0; j < Width; ++j) + { + if (columns[j][y] != 0) + column |= value_type{1} << j; + } if (y == hidden) - continue; - off_sum = (off_sum + column_at(st, 0, y)) & value_mask(); + for (std::size_t j = 0; j < Width; ++j) + u[j] = columns[j][y] != 0; + else + off_sum = (off_sum + column) & value_mask(); } target = (tau - off_sum) & value_mask(); } @@ -271,15 +286,20 @@ struct ppvc /// @brief One-sided vector in the hidden indexing, one entry per domain point. static std::vector eval(const opening & op) { + std::array, Width> columns{}; + for (std::size_t j = 0; j < Width; ++j) + { + if (!op.keys[j]) + throw std::invalid_argument("ppvc: opening is missing a key"); + columns[j] = full_bits(*op.keys[j]); + } std::vector x(domain_size); for (std::size_t y = 0; y < domain_size; ++y) { value_type column = 0; for (std::size_t j = 0; j < Width; ++j) { - if (!op.keys[j]) - throw std::invalid_argument("ppvc: opening is missing a key"); - if (bit_at(*op.keys[j], y)) + if (columns[j][y] != 0) column |= value_type{1} << j; } x[y] = column; @@ -347,11 +367,13 @@ struct ppvc if (!shared_corrections(left, right)) return false; + const auto left_bits = full_bits(left); + const auto right_bits = full_bits(right); int spikes = 0; std::size_t where = 0; for (std::size_t y = 0; y < domain_size; ++y) { - if (bit_at(left, y) != bit_at(right, y)) + if (left_bits[y] != right_bits[y]) { ++spikes; where = y; @@ -498,15 +520,17 @@ struct ppvc } HEDLEY_WARN_UNUSED_RESULT - static value_type column_at(const state & st, unsigned side, std::size_t index) + static std::vector full_bits(const bare_key & key) { - value_type column = 0; - for (std::size_t j = 0; j < Width; ++j) - { - if (bit_at(key_of(st, j, side), index)) - column |= value_type{1} << j; - } - return column; + auto evaluated = dpf::eval_full(key); + std::vector bits; + bits.reserve(domain_size); + for (auto it = std::cbegin(evaluated.second); + it != std::cend(evaluated.second); ++it) + bits.push_back(static_cast(*it) ? std::uint8_t{1} : std::uint8_t{0}); + if (bits.size() != domain_size) + throw std::logic_error("ppvc: full-domain evaluation has the wrong length"); + return bits; } HEDLEY_WARN_UNUSED_RESULT diff --git a/include/dpf/prep_source.hpp b/include/dpf/prep_source.hpp new file mode 100644 index 0000000..cd92faf --- /dev/null +++ b/include/dpf/prep_source.hpp @@ -0,0 +1,349 @@ +/// @file dpf/prep_source.hpp +/// @brief Preprocess views as a byte stream: dealer, file, or 2PC channel. +/// @details Online code reads one party's view. It does not sample the other +/// party's share. `deal_views` is the dealer. `setup_2pc_sampled` is +/// the flagged semi-honest 2PC setup (see `revealing.hpp`). +#ifndef LIBDPF_INCLUDE_DPF_PREP_SOURCE_HPP__ +#define LIBDPF_INCLUDE_DPF_PREP_SOURCE_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/net/channel.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/ot_pack.hpp" +#include "dpf/protocol_factory.hpp" +#include "dpf/random.hpp" + +namespace dpf +{ +namespace prep +{ + +struct demand +{ + std::uint16_t limb = 8; + std::uint32_t ring_triples = 0; + std::uint32_t dabits = 0; + std::uint32_t bit_triples = 0; +}; + +inline constexpr std::uint32_t k_magic = 0x31525050u; // 'PPR1' LE + +/// @brief Cursor over one party's prep view. +class cursor +{ +public: + cursor() = default; + + explicit cursor(std::vector bytes) + : bytes_(std::move(bytes)) + { + if (bytes_.size() < 18) + throw std::runtime_error("prep cursor: short header"); + std::uint32_t magic = 0; + read_pod(magic); + if (magic != k_magic) + throw std::runtime_error("prep cursor: bad magic"); + std::uint16_t limb = 0; + read_pod(limb); + limb_ = limb; + read_pod(n_ring_); + read_pod(n_dabit_); + read_pod(n_bit_); + if (limb_ == 0 || limb_ > 8) + throw std::runtime_error("prep cursor: limb must be 1..8"); + } + + std::uint16_t limb() const noexcept { return limb_; } + + void take_ring(std::uint8_t * a, std::uint8_t * b, std::uint8_t * c) + { + if (ring_used_ >= n_ring_) + throw std::runtime_error("prep cursor: ring triple exhausted"); + std::memcpy(a, bytes_.data() + pos_, limb_); + pos_ += limb_; + std::memcpy(b, bytes_.data() + pos_, limb_); + pos_ += limb_; + std::memcpy(c, bytes_.data() + pos_, limb_); + pos_ += limb_; + ++ring_used_; + } + + ot::dabit take_dabit() + { + if (dabit_used_ >= n_dabit_) + throw std::runtime_error("prep cursor: dabit exhausted"); + ot::dabit d; + d.bit = bytes_[pos_++]; + std::uint64_t arith = 0; + std::memcpy(&arith, bytes_.data() + pos_, limb_); + pos_ += limb_; + d.arith = arith; + ++dabit_used_; + return d; + } + + ot::bit_triple take_bit() + { + if (bit_used_ >= n_bit_) + throw std::runtime_error("prep cursor: bit triple exhausted"); + ot::bit_triple t; + t.a = bytes_[pos_++]; + t.b = bytes_[pos_++]; + t.c = bytes_[pos_++]; + ++bit_used_; + return t; + } + +private: + template + void read_pod(T & out) + { + if (pos_ + sizeof(T) > bytes_.size()) + throw std::runtime_error("prep cursor: truncated header"); + std::memcpy(&out, bytes_.data() + pos_, sizeof(T)); + pos_ += sizeof(T); + } + + std::vector bytes_; + std::size_t pos_ = 0; + std::uint16_t limb_ = 8; + std::uint32_t n_ring_ = 0; + std::uint32_t n_dabit_ = 0; + std::uint32_t n_bit_ = 0; + std::uint32_t ring_used_ = 0; + std::uint32_t dabit_used_ = 0; + std::uint32_t bit_used_ = 0; +}; + +namespace detail +{ + +inline void append(std::vector & o, const void * p, std::size_t n) +{ + const auto * b = static_cast(p); + o.insert(o.end(), b, b + n); +} + +inline std::uint64_t limb_mask(std::uint16_t limb) +{ + if (limb >= 8) + return ~std::uint64_t{0}; + return (std::uint64_t{1} << (8u * limb)) - 1u; +} + +inline void store_limb(std::vector & o, std::uint64_t v, + std::uint16_t limb) +{ + v &= limb_mask(limb); + append(o, &v, limb); +} + +} // namespace detail + +/// @brief Dealer writes both parties' views. Neither view contains the other. +HEDLEY_WARN_UNUSED_RESULT +inline std::pair, std::vector> +deal_views(const demand & d) +{ + if (d.limb == 0 || d.limb > 8) + throw std::invalid_argument("prep limb must be 1..8"); + std::vector p0, p1; + auto header = [&](std::vector & o) { + detail::append(o, &k_magic, 4); + detail::append(o, &d.limb, 2); + detail::append(o, &d.ring_triples, 4); + detail::append(o, &d.dabits, 4); + detail::append(o, &d.bit_triples, 4); + }; + header(p0); + header(p1); + for (std::uint32_t i = 0; i < d.ring_triples; ++i) + { + const auto a = dpf::uniform_sample() & detail::limb_mask(d.limb); + const auto b = dpf::uniform_sample() & detail::limb_mask(d.limb); + const auto c = (a * b) & detail::limb_mask(d.limb); + const auto a0 = dpf::uniform_sample() & detail::limb_mask(d.limb); + const auto b0 = dpf::uniform_sample() & detail::limb_mask(d.limb); + const auto c0 = dpf::uniform_sample() & detail::limb_mask(d.limb); + detail::store_limb(p0, a0, d.limb); + detail::store_limb(p0, b0, d.limb); + detail::store_limb(p0, c0, d.limb); + detail::store_limb(p1, a - a0, d.limb); + detail::store_limb(p1, b - b0, d.limb); + detail::store_limb(p1, c - c0, d.limb); + } + for (std::uint32_t i = 0; i < d.dabits; ++i) + { + auto bit = ot::sample_dabit_pair(); + p0.push_back(bit.p0.bit); + detail::store_limb(p0, bit.p0.arith, d.limb); + p1.push_back(bit.p1.bit); + detail::store_limb(p1, bit.p1.arith, d.limb); + } + for (std::uint32_t i = 0; i < d.bit_triples; ++i) + { + auto t = ot::sample_bit_triple_pair(); + p0.push_back(t.p0.a); + p0.push_back(t.p0.b); + p0.push_back(t.p0.c); + p1.push_back(t.p1.a); + p1.push_back(t.p1.b); + p1.push_back(t.p1.c); + } + return {std::move(p0), std::move(p1)}; +} + +inline void write_file(const std::string & path, const std::vector & bytes) +{ + std::ofstream out(path, std::ios::binary); + if (!out) + throw std::runtime_error("prep write_file: " + path); + out.write(reinterpret_cast(bytes.data()), + static_cast(bytes.size())); + if (!out) + throw std::runtime_error("prep write_file failed"); +} + +HEDLEY_WARN_UNUSED_RESULT +inline std::vector read_file(const std::string & path) +{ + std::ifstream in(path, std::ios::binary); + if (!in) + throw std::runtime_error("prep read_file: " + path); + return std::vector(std::istreambuf_iterator(in), + std::istreambuf_iterator()); +} + +/// @brief Party 0 samples both views and sends party 1's. See `revealing.hpp`. +HEDLEY_WARN_UNUSED_RESULT +inline std::vector setup_2pc_sampled(net::channel & ch, + unsigned party, const demand & d) +{ + if (party > 1) + throw std::invalid_argument("setup_2pc_sampled party"); + if (party == 0) + { + auto views = deal_views(d); + ch.send_vec(views.second, net::msg::beaver_tape); + return std::move(views.first); + } + return ch.recv_vec(net::msg::beaver_tape); +} + +/// @brief Write dealer views onto two stream arrays (stream 0 = full blob). +/// @details Convenience over `deal_views`. Online parties read stream 0 into a +/// `cursor`. Prefer `factory::make_dealer` with per-kind functors when +/// the protocol is assembled from round factories. +inline void deal_to_streams(const demand & d, net::stream_array & party0, + net::stream_array & party1) +{ + if (party0.size() < 1 || party1.size() < 1) + throw std::invalid_argument("deal_to_streams: need stream 0"); + auto views = deal_views(d); + party0.write(0, views.first.data(), views.first.size()); + party0.flush(0); + party1.write(0, views.second.data(), views.second.size()); + party1.flush(0); +} + +/// @brief Fill a memory pair with dealer views; return both read ends. +HEDLEY_WARN_UNUSED_RESULT +inline std::pair +deal_memory_pair(const demand & d) +{ + auto hubs0 = std::make_shared(1); + auto hubs1 = std::make_shared(1); + net::memory_stream_array write0(hubs0, true); + net::memory_stream_array write1(hubs1, true); + deal_to_streams(d, write0, write1); + return {net::memory_stream_array(hubs0, false), + net::memory_stream_array(hubs1, false)}; +} + +/// @brief Read a full prep blob from stream `index` into a cursor. +HEDLEY_WARN_UNUSED_RESULT +inline cursor cursor_from_stream(net::stream_array & streams, std::size_t index, + std::size_t nbytes) +{ + std::vector bytes(nbytes); + streams.read(index, bytes.data(), nbytes); + return cursor(std::move(bytes)); +} + +/// @brief Deal atom-by-atom (ring / dabit / bit) onto successive stream indexes. +/// @details Stream 0 holds all ring triples when `ring_triples > 0`, then the +/// next used index holds dabits, then bit triples. Online code that +/// expects a packed `cursor` should keep using `deal_to_streams`. +inline void deal_atoms(const demand & d, net::stream_array & party0, + net::stream_array & party1) +{ + std::size_t need = (d.ring_triples ? 1u : 0u) + (d.dabits ? 1u : 0u) + + (d.bit_triples ? 1u : 0u); + if (need == 0) + return; + if (party0.size() < need || party1.size() < need) + throw std::invalid_argument("deal_atoms: not enough streams"); + std::size_t idx = 0; + if (d.ring_triples) + { + factory::make_dealer(party0, party1, d.ring_triples, + [limb = d.limb] { return factory::deal_ring_triple(limb); }); + ++idx; + } + if (d.dabits) + { + // make_dealer always starts at stream 0; shift by writing via a + // one-stream alias when dabits are not the first kind. + if (idx == 0) + { + factory::make_dealer(party0, party1, d.dabits, + [limb = d.limb] { return factory::deal_dabit(limb); }); + } + else + { + for (std::uint32_t i = 0; i < d.dabits; ++i) + { + auto v = factory::deal_dabit(d.limb); + party0.write(idx, &v.first, sizeof(v.first)); + party1.write(idx, &v.second, sizeof(v.second)); + } + party0.flush(idx); + party1.flush(idx); + } + ++idx; + } + if (d.bit_triples) + { + if (idx == 0) + { + factory::make_dealer(party0, party1, d.bit_triples, + [] { return factory::deal_bit_triple(); }); + } + else + { + for (std::uint32_t i = 0; i < d.bit_triples; ++i) + { + auto v = factory::deal_bit_triple(); + party0.write(idx, &v.first, sizeof(v.first)); + party1.write(idx, &v.second, sizeof(v.second)); + } + party0.flush(idx); + party1.flush(idx); + } + } +} + +} // namespace prep +} // namespace dpf + +#endif diff --git a/include/dpf/prg.hpp b/include/dpf/prg.hpp index cf401e8..3c76728 100644 --- a/include/dpf/prg.hpp +++ b/include/dpf/prg.hpp @@ -10,11 +10,11 @@ #include "hedley/hedley.h" -#include #include #include #include +#include "dpf/prg_count.hpp" #include "dpf/prg_aes.hpp" #include "dpf/prg_aes_ccr.hpp" #include "dpf/prg_chacha.hpp" @@ -68,6 +68,7 @@ auto expand_as_share(typename PRG::block_type seed, } // namespace detail +/// \complexity `ceil(sizeof(T) / sizeof(block_type))` PRG evaluations (`expand_raw`), then a copy. template template HEDLEY_NO_THROW @@ -76,6 +77,7 @@ auto aes::expand(block_type seed, psnip_uint32_t pos) noexcept return detail::expand_as_share, T, Party>(seed, pos); } +/// \complexity `ceil(sizeof(T) / sizeof(block_type))` PRG evaluations (`expand_raw`), then a copy. template HEDLEY_NO_THROW auto dummy::expand(block_type seed, psnip_uint32_t pos) noexcept @@ -83,6 +85,7 @@ auto dummy::expand(block_type seed, psnip_uint32_t pos) noexcept return detail::expand_as_share(seed, pos); } +/// \complexity `ceil(sizeof(T) / sizeof(block_type))` PRG evaluations (`expand_raw`), then a copy. template HEDLEY_NO_THROW auto lowmc128::expand(block_type seed, psnip_uint32_t pos) noexcept @@ -90,6 +93,7 @@ auto lowmc128::expand(block_type seed, psnip_uint32_t pos) noexcept return detail::expand_as_share(seed, pos); } +/// \complexity `ceil(sizeof(T) / sizeof(block_type))` PRG evaluations (`expand_raw`), then a copy. template HEDLEY_NO_THROW auto aes128_ccr::expand(block_type seed, psnip_uint32_t pos) noexcept @@ -97,6 +101,7 @@ auto aes128_ccr::expand(block_type seed, psnip_uint32_t pos) noexcept return detail::expand_as_share(seed, pos); } +/// \complexity `ceil(sizeof(T) / sizeof(block_type))` PRG evaluations (`expand_raw`), then a copy. template template HEDLEY_NO_THROW @@ -105,6 +110,9 @@ auto chacha::expand(block_type seed, psnip_uint32_t pos) noexcept return detail::expand_as_share, T, Party>(seed, pos); } +/// @brief PRG adapter that exposes the shared TLS eval counter. +/// @details Counting lives in the concrete `PRG::eval` paths via +/// `note_eval`. This wrapper forwards and reports `eval_count()`. template struct counter_wrapper final { @@ -114,7 +122,6 @@ struct counter_wrapper final HEDLEY_ALWAYS_INLINE static block_type eval(block_type seed, psnip_uint32_t pos) noexcept { - count_.fetch_add(1, std::memory_order::memory_order_relaxed); return PRG::eval(seed, pos); } @@ -122,7 +129,6 @@ struct counter_wrapper final HEDLEY_ALWAYS_INLINE static auto eval01(block_type seed) noexcept { - count_.fetch_add(2, std::memory_order::memory_order_relaxed); return PRG::eval01(seed); } @@ -130,12 +136,6 @@ struct counter_wrapper final static void eval(block_type seed, block_type * HEDLEY_RESTRICT output, psnip_uint32_t count, psnip_uint32_t pos = 0) { - if (count > 1 && - pos > static_cast(~static_cast(0)) - (count - 1u)) - { - throw std::invalid_argument("prg lane index is out of range"); - } - count_.fetch_add(count, std::memory_order::memory_order_relaxed); PRG::eval(seed, output, count, pos); } @@ -146,7 +146,6 @@ struct counter_wrapper final block_type * HEDLEY_RESTRICT left, block_type * HEDLEY_RESTRICT right) noexcept { - count_.fetch_add(8, std::memory_order::memory_order_relaxed); PRG::eval01_x4(seeds, left, right); } @@ -156,7 +155,6 @@ struct counter_wrapper final static void eval_x4(const block_type * HEDLEY_RESTRICT seeds, block_type * HEDLEY_RESTRICT output, psnip_uint32_t pos = 0) noexcept { - count_.fetch_add(4, std::memory_order::memory_order_relaxed); PRG::eval_x4(seeds, output, pos); } @@ -166,7 +164,6 @@ struct counter_wrapper final static void eval_x8(const block_type * HEDLEY_RESTRICT seeds, block_type * HEDLEY_RESTRICT output, psnip_uint32_t pos = 0) noexcept { - count_.fetch_add(8, std::memory_order::memory_order_relaxed); PRG::eval_x8(seeds, output, pos); } @@ -175,10 +172,6 @@ struct counter_wrapper final HEDLEY_ALWAYS_INLINE static auto expand(block_type seed, psnip_uint32_t pos = 0) noexcept { - count_.fetch_add( - static_cast( - (sizeof(T) + sizeof(block_type) - 1) / sizeof(block_type)), - std::memory_order::memory_order_relaxed); return detail::expand_as_share(seed, pos); } @@ -186,11 +179,15 @@ struct counter_wrapper final HEDLEY_ALWAYS_INLINE static std::size_t count() noexcept { - return count_; + return static_cast(eval_count()); } - private: - inline static std::atomic_size_t count_{0}; + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + static void reset() noexcept + { + reset_eval_count(); + } }; // struct counter_wrapper } // namespace prg diff --git a/include/dpf/prg_aes.hpp b/include/dpf/prg_aes.hpp index cc43e6e..8d3f8a0 100644 --- a/include/dpf/prg_aes.hpp +++ b/include/dpf/prg_aes.hpp @@ -18,6 +18,7 @@ #include "simde/simde/x86/avx2.h" #include "portable-snippets/exact-int/exact-int.h" +#include "dpf/prg_count.hpp" #include "dpf/utils.hpp" namespace dpf @@ -44,19 +45,28 @@ struct aes final { using block_type = simde__m128i; + static constexpr primitive counted_as = + AesKey::rounds == 14 ? primitive::aes256 : primitive::aes128; + HEDLEY_NO_THROW HEDLEY_ALWAYS_INLINE static void require_block_aligned(const void * p) noexcept { + (void)p; assert(p == nullptr || reinterpret_cast(p) % alignof(block_type) == 0); } + /// @brief One AES block in Matyas–Meyer–Oseas mode. + /// @param seed the PRG seed + /// @param pos the block counter mixed into the first round key + /// @return the 128-bit block + /// \complexity One block: `key.rounds - 1` `aesenc` calls plus one `aesenclast`. `rounds` is 10 for `aes128` and 14 for `aes256`. HEDLEY_NO_THROW HEDLEY_ALWAYS_INLINE - HEDLEY_PURE static block_type eval(block_type seed, psnip_uint32_t pos) noexcept { + note_eval(1, counted_as); block_type rd_key0 = simde_mm_xor_si128(key.rd_key[0], simde_mm_set_epi64x(0, pos)); block_type output = simde_mm_xor_si128(seed, rd_key0); @@ -73,9 +83,9 @@ struct aes final HEDLEY_NO_THROW HEDLEY_ALWAYS_INLINE - HEDLEY_PURE static auto eval01(block_type seed) noexcept { + note_eval(2, counted_as); block_type rd_key00 = key.rd_key[0]; block_type rd_key01 = simde_mm_xor_si128(rd_key00, simde_mm_set_epi64x(0, 1)); @@ -99,6 +109,99 @@ HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") HEDLEY_PRAGMA(GCC diagnostic pop) } + /// @brief Four independent MMO blocks, round-major so `aesenc` throughput + /// covers the latency of a single `eval`. + /// @param seeds four PRG seeds + /// @param pos lane index for each seed (`0` or `1` for a tree child) + /// @param out four blocks, same order as `seeds` + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + static void eval_indep4(const block_type seeds[4], const psnip_uint32_t pos[4], + block_type out[4]) noexcept + { + note_eval(4, counted_as); + block_type o0, o1, o2, o3; + { + const block_type k0 = key.rd_key[0]; + o0 = simde_mm_xor_si128(seeds[0], + simde_mm_xor_si128(k0, simde_mm_set_epi64x(0, pos[0]))); + o1 = simde_mm_xor_si128(seeds[1], + simde_mm_xor_si128(k0, simde_mm_set_epi64x(0, pos[1]))); + o2 = simde_mm_xor_si128(seeds[2], + simde_mm_xor_si128(k0, simde_mm_set_epi64x(0, pos[2]))); + o3 = simde_mm_xor_si128(seeds[3], + simde_mm_xor_si128(k0, simde_mm_set_epi64x(0, pos[3]))); + } +HEDLEY_PRAGMA(GCC unroll(14)) + for (std::size_t j = 1; j < key.rounds; ++j) + { + const block_type rk = key.rd_key[j]; + o0 = simde_mm_aesenc_si128(o0, rk); + o1 = simde_mm_aesenc_si128(o1, rk); + o2 = simde_mm_aesenc_si128(o2, rk); + o3 = simde_mm_aesenc_si128(o3, rk); + } + const block_type last = key.rd_key[key.rounds]; + o0 = simde_mm_xor_si128(simde_mm_aesenclast_si128(o0, last), seeds[0]); + o1 = simde_mm_xor_si128(simde_mm_aesenclast_si128(o1, last), seeds[1]); + o2 = simde_mm_xor_si128(simde_mm_aesenclast_si128(o2, last), seeds[2]); + o3 = simde_mm_xor_si128(simde_mm_aesenclast_si128(o3, last), seeds[3]); + out[0] = o0; + out[1] = o1; + out[2] = o2; + out[3] = o3; + } + + /// @brief Eight independent MMO blocks. Zen's AES unit retires two + /// `aesenc`s per cycle at four-cycle latency, so eight in flight + /// fills it; four does not. + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + static void eval_indep8(const block_type seeds[8], const psnip_uint32_t pos[8], + block_type out[8]) noexcept + { + note_eval(8, counted_as); + const block_type k0 = key.rd_key[0]; + block_type o0 = simde_mm_xor_si128(seeds[0], + simde_mm_xor_si128(k0, simde_mm_set_epi64x(0, pos[0]))); + block_type o1 = simde_mm_xor_si128(seeds[1], + simde_mm_xor_si128(k0, simde_mm_set_epi64x(0, pos[1]))); + block_type o2 = simde_mm_xor_si128(seeds[2], + simde_mm_xor_si128(k0, simde_mm_set_epi64x(0, pos[2]))); + block_type o3 = simde_mm_xor_si128(seeds[3], + simde_mm_xor_si128(k0, simde_mm_set_epi64x(0, pos[3]))); + block_type o4 = simde_mm_xor_si128(seeds[4], + simde_mm_xor_si128(k0, simde_mm_set_epi64x(0, pos[4]))); + block_type o5 = simde_mm_xor_si128(seeds[5], + simde_mm_xor_si128(k0, simde_mm_set_epi64x(0, pos[5]))); + block_type o6 = simde_mm_xor_si128(seeds[6], + simde_mm_xor_si128(k0, simde_mm_set_epi64x(0, pos[6]))); + block_type o7 = simde_mm_xor_si128(seeds[7], + simde_mm_xor_si128(k0, simde_mm_set_epi64x(0, pos[7]))); +HEDLEY_PRAGMA(GCC unroll(14)) + for (std::size_t j = 1; j < key.rounds; ++j) + { + const block_type rk = key.rd_key[j]; + o0 = simde_mm_aesenc_si128(o0, rk); + o1 = simde_mm_aesenc_si128(o1, rk); + o2 = simde_mm_aesenc_si128(o2, rk); + o3 = simde_mm_aesenc_si128(o3, rk); + o4 = simde_mm_aesenc_si128(o4, rk); + o5 = simde_mm_aesenc_si128(o5, rk); + o6 = simde_mm_aesenc_si128(o6, rk); + o7 = simde_mm_aesenc_si128(o7, rk); + } + const block_type last = key.rd_key[key.rounds]; + out[0] = simde_mm_xor_si128(simde_mm_aesenclast_si128(o0, last), seeds[0]); + out[1] = simde_mm_xor_si128(simde_mm_aesenclast_si128(o1, last), seeds[1]); + out[2] = simde_mm_xor_si128(simde_mm_aesenclast_si128(o2, last), seeds[2]); + out[3] = simde_mm_xor_si128(simde_mm_aesenclast_si128(o3, last), seeds[3]); + out[4] = simde_mm_xor_si128(simde_mm_aesenclast_si128(o4, last), seeds[4]); + out[5] = simde_mm_xor_si128(simde_mm_aesenclast_si128(o5, last), seeds[5]); + out[6] = simde_mm_xor_si128(simde_mm_aesenclast_si128(o6, last), seeds[6]); + out[7] = simde_mm_xor_si128(simde_mm_aesenclast_si128(o7, last), seeds[7]); + } + /// @brief Round-major multi-block MMO. Positions use the same lane as /// `eval` / `eval01` (`set_epi64x(0, pos)`). The first AddRoundKey /// includes `rd_key[0]` so this matches the one-block `eval` for any @@ -142,6 +245,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) return; } + note_eval(count, counted_as); auto whitened = simde_mm_xor_si128(seed, key.rd_key[0]); DPF_UNROLL_LOOP for (psnip_uint32_t i = 0; i < count; ++i) @@ -180,6 +284,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) block_type * HEDLEY_RESTRICT left, block_type * HEDLEY_RESTRICT right) noexcept { + note_eval(8, counted_as); require_block_aligned(seeds); require_block_aligned(left); require_block_aligned(right); @@ -215,6 +320,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) static void eval_x4(const block_type * HEDLEY_RESTRICT seeds, block_type * HEDLEY_RESTRICT output, psnip_uint32_t pos) noexcept { + note_eval(4, counted_as); require_block_aligned(seeds); require_block_aligned(output); const block_type * HEDLEY_RESTRICT s = @@ -249,6 +355,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) static void eval_x8(const block_type * HEDLEY_RESTRICT seeds, block_type * HEDLEY_RESTRICT output, psnip_uint32_t pos) noexcept { + note_eval(8, counted_as); require_block_aligned(seeds); require_block_aligned(output); const block_type * HEDLEY_RESTRICT s = diff --git a/include/dpf/prg_aes_ccr.hpp b/include/dpf/prg_aes_ccr.hpp index 2663095..0f2fc17 100644 --- a/include/dpf/prg_aes_ccr.hpp +++ b/include/dpf/prg_aes_ccr.hpp @@ -8,6 +8,7 @@ /// `eval01(s)` returns the Half-Tree children `{H(s), H(s)⊕s}`. That /// expand is **not** a drop-in for BGI `make_dpf`; use it only with /// Half-Tree `tree_traits` (see `dpf/tree_traits.hpp`). +/// @note Following Guo, Yang, Wang, Zhang, Xie, Zhang, and Liu, ePrint 2022/1431: mid-level children are `{H(s), H(s)⊕s}`. /// @see dpf/tree_traits.hpp /// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license; diff --git a/include/dpf/prg_chacha.hpp b/include/dpf/prg_chacha.hpp index cf21d40..4c482ea 100644 --- a/include/dpf/prg_chacha.hpp +++ b/include/dpf/prg_chacha.hpp @@ -26,6 +26,8 @@ #include "simde/simde/x86/avx2.h" #include "portable-snippets/exact-int/exact-int.h" +#include "dpf/prg_count.hpp" + namespace dpf { @@ -284,10 +286,16 @@ struct chacha final using block_type = simde__m128i; static constexpr unsigned rounds = Rounds; + /// @brief One 128-bit lane of a ChaCha block. + /// @param seed the PRG seed + /// @param pos lane index; the block counter is `pos >> 2` + /// @return that lane + /// \complexity One ChaCha block: `Rounds/2` double-rounds, eight quarter-rounds each (`chacha_detail::block`). HEDLEY_NO_THROW HEDLEY_ALWAYS_INLINE static block_type eval(block_type seed, psnip_uint32_t pos) noexcept { + note_eval(1, primitive::chacha); std::uint32_t key[8]; chacha_detail::seed_key(seed, key); std::uint8_t buf[64]; @@ -303,6 +311,7 @@ struct chacha final HEDLEY_ALWAYS_INLINE static auto eval01(block_type seed) noexcept { + note_eval(2, primitive::chacha); std::uint32_t key[8]; chacha_detail::seed_key(seed, key); std::uint8_t buf[64]; @@ -348,6 +357,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) return; } + note_eval(count, primitive::chacha); std::uint32_t key[8]; chacha_detail::seed_key(seed, key); psnip_uint32_t i = 0; diff --git a/include/dpf/prg_count.hpp b/include/dpf/prg_count.hpp new file mode 100644 index 0000000..13b4b09 --- /dev/null +++ b/include/dpf/prg_count.hpp @@ -0,0 +1,169 @@ +/// @file dpf/prg_count.hpp +/// @brief Thread-local counters of symmetric-key block invocations. +/// @details Each concrete block primitive (fixed-key AES-128 or AES-256 in +/// Matyas–Meyer–Oseas mode, ChaCha, LowMC) calls +/// `note_eval(n, primitive)` once per batch of `n` blocks. The count +/// is filed under the thread's current `purpose`: +/// +/// - `expand`: PRG work, such as tree expansion, leaf conversion, and +/// label or column generation. This is the default. +/// - `hash`: correlation-robust hashing, such as IKNP row hashes, +/// garbled-gate hashes, and verification hashes. +/// - `harness`: blocks the measurement machinery computes for itself, +/// such as the `experiment` seed stream. +/// +/// `eval_count()` is the protocol total: `expand` plus `hash` over +/// every primitive. Harness blocks are never part of it. +/// `count(purpose, primitive)` reads one cell and `snapshot()` reads +/// all of them. Call sites set the purpose with `purpose_scope`. +/// The counters are per thread, so work on another thread (a compute +/// pool, another party) is not included. Reset around a timed region +/// with `reset_eval_count`. The increment is one TLS add. +#ifndef LIBDPF_INCLUDE_DPF_PRG_COUNT_HPP__ +#define LIBDPF_INCLUDE_DPF_PRG_COUNT_HPP__ + +#include +#include +#include + +#include "hedley/hedley.h" + +namespace dpf +{ +namespace prg +{ + +/// @brief Which block primitive produced a counted block. +enum class primitive : unsigned char +{ + aes128 = 0, + aes256 = 1, + chacha = 2, + lowmc = 3 +}; + +inline constexpr std::size_t primitive_count = 4; + +/// @brief Why the block was computed. +enum class purpose : unsigned char +{ + expand = 0, + hash = 1, + harness = 2 +}; + +inline constexpr std::size_t purpose_count = 3; + +inline const char * primitive_name(primitive p) noexcept +{ + switch (p) + { + case primitive::aes128: + return "aes128"; + case primitive::aes256: + return "aes256"; + case primitive::chacha: + return "chacha"; + case primitive::lowmc: + return "lowmc"; + } + return "aes128"; +} + +inline const char * purpose_name(purpose u) noexcept +{ + switch (u) + { + case purpose::expand: + return "expand"; + case purpose::hash: + return "hash"; + case purpose::harness: + return "harness"; + } + return "expand"; +} + +/// @brief Every cell, indexed `purpose * primitive_count + primitive`. +using counts = std::array; + +namespace detail +{ + +inline thread_local std::uint64_t eval_counts_tls[purpose_count * primitive_count] = {}; +/// First cell of the current purpose's row (`purpose * primitive_count`). +inline thread_local std::size_t purpose_row_tls = 0; + +} // namespace detail + +/// @brief Record `n` block invocations of `p` on this thread. +HEDLEY_ALWAYS_INLINE +void note_eval(std::uint64_t n = 1, primitive p = primitive::aes128) noexcept +{ + detail::eval_counts_tls[detail::purpose_row_tls + static_cast(p)] += n; +} + +/// @brief Zero every counter on this thread. +HEDLEY_ALWAYS_INLINE +void reset_eval_count() noexcept +{ + for (auto & c : detail::eval_counts_tls) + c = 0; +} + +/// @brief Blocks of `p` computed for `u` since the last reset on this thread. +HEDLEY_ALWAYS_INLINE +std::uint64_t count(purpose u, primitive p) noexcept +{ + return detail::eval_counts_tls[static_cast(u) * primitive_count + + static_cast(p)]; +} + +/// @brief Protocol blocks (`expand` + `hash`, every primitive) since the last +/// reset on this thread. +HEDLEY_ALWAYS_INLINE +std::uint64_t eval_count() noexcept +{ + std::uint64_t total = 0; + for (std::size_t i = 0; i < 2 * primitive_count; ++i) + total += detail::eval_counts_tls[i]; + return total; +} + +/// @brief Every cell on this thread. +inline counts snapshot() noexcept +{ + counts out{}; + for (std::size_t i = 0; i < out.size(); ++i) + out[i] = detail::eval_counts_tls[i]; + return out; +} + +/// @brief Add cells counted on another thread (a compute-pool task this +/// thread waited for) to this thread's cells. +inline void absorb(const counts & delta) noexcept +{ + for (std::size_t i = 0; i < delta.size(); ++i) + detail::eval_counts_tls[i] += delta[i]; +} + +/// @brief File this thread's block invocations under `u` until the scope ends. +class purpose_scope +{ +public: + explicit purpose_scope(purpose u) noexcept : prev_(detail::purpose_row_tls) + { + detail::purpose_row_tls = static_cast(u) * primitive_count; + } + ~purpose_scope() { detail::purpose_row_tls = prev_; } + purpose_scope(const purpose_scope &) = delete; + purpose_scope & operator=(const purpose_scope &) = delete; + +private: + std::size_t prev_; +}; + +} // namespace prg +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_PRG_COUNT_HPP__ diff --git a/include/dpf/prg_lowmc.hpp b/include/dpf/prg_lowmc.hpp index 9b67ad6..5208f89 100644 --- a/include/dpf/prg_lowmc.hpp +++ b/include/dpf/prg_lowmc.hpp @@ -19,6 +19,7 @@ #include "lowmc/LowMC.h" #include "lowmc/LowMC.cpp" +#include "dpf/prg_count.hpp" namespace dpf { @@ -36,6 +37,7 @@ struct lowmc128 final HEDLEY_ALWAYS_INLINE static block_type eval(block_type seed, psnip_uint32_t pos) noexcept { + note_eval(1, primitive::lowmc); block_type in = simde_mm_xor_si128(seed, simde_mm_set_epi64x(0, pos)); return simde_mm_xor_si128(permute(in), seed); } diff --git a/include/dpf/protocol.hpp b/include/dpf/protocol.hpp new file mode 100644 index 0000000..d6d3613 --- /dev/null +++ b/include/dpf/protocol.hpp @@ -0,0 +1,706 @@ +/// @file dpf/protocol.hpp +/// @brief Count-sized batch sessions over a RoundSink. +/// @details Interactive rounds share one instance index across a PRG lane, +/// a dealer cursor, and a round window. `two_move_session` is the +/// typed custom-protocol helper. `schedule_session` drives a flat +/// round list: ready instances run `produce` on this thread; others +/// wait while the scan continues. Flush sends the largest unflushed +/// prefix. Mixed FSS / ABY2.0 / Beaver / RSS strands lower onto this +/// loop with `plan_to_schedule` in `compose.hpp`. +#ifndef LIBDPF_INCLUDE_DPF_PROTOCOL_HPP__ +#define LIBDPF_INCLUDE_DPF_PROTOCOL_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dpf/net/dealer_cursor.hpp" +#include "dpf/net/edge_mesh.hpp" +#include "dpf/net/round_sink.hpp" +#include "dpf/prg_count.hpp" +#include "dpf/random.hpp" +#include "dpf/thread_work.hpp" + +namespace dpf +{ +namespace protocol +{ + +using net::empty_pad; +using net::dealer_cursor; +using net::RoundSink; +using net::edge_id; +using net::edge_mesh; +using net::edge_peer; +using net::edge_rss_next; +using net::edge_dealer; +using net::edge_dealer_p1; + +namespace detail +{ + +template +constexpr bool is_empty_pad_v = std::is_same_v, empty_pad>; + +} // namespace detail + +/// @brief Named trio edges (aliases of `net::edge_*` for existing call sites). +enum class edge_channel : unsigned char +{ + peer = 0, + rss_next = 1, + dealer = 2 +}; + +/// @brief How `produce` / the finish step interpret peer bytes for a round. +enum class receive_rule : unsigned char +{ + domain_open = 0, ///< Domain algebra (`a`/`fss` sum, `b` subtract, `y` copy) + copy_peer = 1, ///< Client upload / answer, dealer delivery + beaver = 2, ///< Authenticated / classic Beaver δ apply + xor_bytes = 3, + field_sum = 4, + any_two = 5, ///< Any-two Shamir-style reconstruct + verify_sketch = 6, + verify_proof = 7, + eq_check = 8, ///< PSI / equality tag check + ring_next = 9 ///< Directional RSS ring: copy bytes, do not reconstruct +}; + +/// @brief Setup vs online for byte tallies and cost reports. +enum class phase : unsigned char +{ + online = 0, + setup = 1 +}; + +/// @brief Direction of a schedule round on a duplex edge. +enum class round_dir : unsigned char +{ + duplex = 0, ///< Submit and expect a peer slot (default) + send_next = 1, ///< Submit on next edge; no peer payload required to advance + recv_prev = 2 ///< Wait for prev party's send; produce may be empty +}; + +/// @brief One RoundSink exchange observed by a live probe. +struct round_event +{ + std::uint16_t round = 0; + edge_id edge = edge_peer; + edge_channel channel = edge_channel::peer; + phase round_phase = phase::online; + /// Slot bytes this round submits. + std::size_t bytes_out = 0; + /// Slot bytes this round receives on `channel` (0 for `send_next` rounds). + std::size_t bytes_in = 0; + /// Time in `produce` and `submit`; waiting for the peer is not included. + std::uint64_t wall_ns = 0; + std::uint64_t cpu_ns = 0; + std::uint64_t prg_evals = 0; + std::uint64_t random_bytes = 0; +}; + +/// @brief Accumulated setup / online bytes from `round_event`s. +struct phase_tally +{ + std::uint64_t setup_bytes_out = 0; + std::uint64_t setup_bytes_in = 0; + std::uint64_t online_bytes_out = 0; + std::uint64_t online_bytes_in = 0; + + phase_tally & operator+=(const round_event & ev) noexcept + { + if (ev.round_phase == phase::setup) + { + setup_bytes_out += ev.bytes_out; + setup_bytes_in += ev.bytes_in; + } + else + { + online_bytes_out += ev.bytes_out; + online_bytes_in += ev.bytes_in; + } + return *this; + } +}; + +/// @brief Optional live probe installed on `drive_options` / `schedule_session`. +struct round_probe +{ + void * ctx = nullptr; + void (*fn)(void * ctx, const round_event & ev) = nullptr; + + void operator()(const round_event & ev) const + { + if (fn != nullptr) + fn(ctx, ev); + } +}; + +/// @brief One interactive round in a type-erased schedule. +struct schedule_round +{ + std::size_t slot_bytes = 0; + edge_id edge = edge_peer; + edge_channel channel = edge_channel::peer; ///< mirrors `edge` for trio APIs + receive_rule recv = receive_rule::domain_open; + phase round_phase = phase::online; + round_dir dir = round_dir::duplex; + /// @brief Index on the chosen channel's RoundSink (0..that sink's rounds). + std::uint16_t sink_round = 0; + /// @brief Longest wait for this round's peer bytes (0 = edge / drive default). + std::chrono::milliseconds timeout{0}; + /// @brief After the previous round's peer arrives: return false to send + /// nothing and mark the instance done (branch after an open). + std::function branch; + /// @brief Jump after open: return next schedule index, or nullopt = done. + /// Default (empty) advances to `round + 1`. + std::function(std::size_t index, + const std::uint8_t * peer, std::size_t peer_n)> next; + /// @brief Write this party's slot for `index`. `peer` is the previous + /// round's peer slot (nullptr / 0 on round 0). + std::function produce; +}; + +/// @brief Trio adapter → `edge_mesh` (peer / rss_next / dealer at ids 0..2). +struct edge_sinks +{ + RoundSink * peer = nullptr; + RoundSink * rss_next = nullptr; + RoundSink * dealer = nullptr; + + RoundSink & at(edge_channel c) const + { + return mesh().at(static_cast(c)); + } + + edge_mesh mesh() const + { + edge_mesh m; + m.sinks = {peer, rss_next, dealer}; + return m; + } +}; + +/// @brief Concatenate two round lists, preserving each round's sink_round. +inline std::vector splice_rounds(std::vector head, + std::vector tail) +{ + head.reserve(head.size() + tail.size()); + for (auto & r : tail) + head.push_back(std::move(r)); + return head; +} + +/// @brief Opaque pad / setup frames as schedule rounds (IKNP, dealer tape, …). +/// @details Each frame exchanges `slot_bytes` into `tape` (XOR of peer into the +/// running lane). Splice before the online plan so setup is rounds in +/// the list, not a count added after `plan::rounds()`. +inline std::vector make_pad_rounds(std::size_t n_rounds, + std::size_t slot_bytes, + const std::shared_ptr> & tape, + edge_channel channel = edge_channel::peer) +{ + if (slot_bytes == 0 && n_rounds != 0) + throw std::invalid_argument("make_pad_rounds slot_bytes"); + if (tape) + { + const std::size_t need = n_rounds * slot_bytes; + if (tape->size() < need) + tape->assign(need, 0); + } + std::vector out(n_rounds); + for (std::size_t r = 0; r < n_rounds; ++r) + { + out[r].slot_bytes = slot_bytes; + out[r].channel = channel; + out[r].edge = static_cast(channel); + out[r].recv = receive_rule::xor_bytes; + out[r].round_phase = phase::setup; + out[r].dir = round_dir::send_next; + out[r].sink_round = static_cast(r); + out[r].produce = [r, slot_bytes, tape](std::size_t /*index*/, + const std::uint8_t * peer, std::size_t peer_n, + std::uint8_t * out_slot) { + if (slot_bytes == 0 || out_slot == nullptr) + return; + const std::size_t off = r * slot_bytes; + std::memset(out_slot, static_cast(r + 1), slot_bytes); + if (tape && tape->size() >= off + slot_bytes) + std::memcpy(tape->data() + off, out_slot, slot_bytes); + // `peer` is the previous round's slot — fold it into that round's tape. + if (r > 0 && peer != nullptr && peer_n >= slot_bytes && tape) + { + const std::size_t prev = (r - 1) * slot_bytes; + if (tape->size() >= prev + slot_bytes) + { + for (std::size_t i = 0; i < slot_bytes; ++i) + (*tape)[prev + i] = static_cast( + (*tape)[prev + i] ^ peer[i]); + } + } + }; + } + return out; +} + +/// @brief Drive a list of schedule rounds on an `edge_mesh`. +/// @details Ready instances run `produce` on this thread; others are skipped +/// until `peer_ready`. Flush sends the largest unflushed prefix per +/// live edge. Peer/out scratch is thread_local (no per-ready alloc). +class schedule_session +{ +public: + schedule_session(std::size_t count, RoundSink & peer, + std::vector rounds, std::size_t pipeline_credit = 0) + : schedule_session(count, edge_mesh{{&peer}}, std::move(rounds), + /*rebase_single=*/true, nullptr, pipeline_credit) + { + } + + schedule_session(std::size_t count, edge_sinks sinks, + std::vector rounds, std::size_t pipeline_credit = 0) + : schedule_session(count, sinks.mesh(), std::move(rounds), + /*rebase_single=*/sinks.rss_next == nullptr + && sinks.dealer == nullptr, + nullptr, pipeline_credit) + { + } + + schedule_session(std::size_t count, edge_mesh mesh, + std::vector rounds, bool rebase_single = false, + const round_probe * probe = nullptr, std::size_t pipeline_credit = 0) + : count_(count), + mesh_(std::move(mesh)), + rounds_(std::move(rounds)), + round_of_(count, 0), + mark_(count, 0), + done_(count, false), + submitted_(rounds_.size() * count, false), + probe_(probe), + pipeline_credit_(pipeline_credit) + { + if (!mesh_.has(edge_peer) && mesh_.size() == 0) + throw std::invalid_argument("schedule_session empty mesh"); + // Sync channel ↔ edge for trio-named rounds. + for (auto & r : rounds_) + { + if (r.edge == edge_peer + && r.channel != edge_channel::peer) + r.edge = static_cast(r.channel); + else if (r.edge <= edge_dealer) + r.channel = static_cast(r.edge); + } + if (rebase_single && mesh_.has(edge_peer) + && !mesh_.has(edge_rss_next) && !mesh_.has(edge_dealer) + && mesh_.size() <= 3) + { + auto & peer = mesh_.at(edge_peer); + if (peer.count() != count_) + throw std::invalid_argument("schedule_session count mismatch"); + if (peer.rounds() != rounds_.size()) + throw std::invalid_argument("schedule_session rounds mismatch"); + for (std::uint16_t r = 0; r < rounds_.size(); ++r) + { + rounds_[r].edge = edge_peer; + rounds_[r].channel = edge_channel::peer; + rounds_[r].sink_round = r; + if (peer.slot_bytes(r) != rounds_[r].slot_bytes) + throw std::invalid_argument("schedule_session slot mismatch"); + } + } + else + { + for (std::uint16_t r = 0; r < rounds_.size(); ++r) + { + auto & sink = mesh_.at(rounds_[r].edge); + if (sink.count() != count_) + throw std::invalid_argument("schedule_session edge count"); + const auto sr = rounds_[r].sink_round; + if (static_cast(sr) >= sink.rounds() + || sink.slot_bytes(sr) != rounds_[r].slot_bytes) + throw std::invalid_argument("schedule_session edge slot"); + } + } + } + + std::size_t count() const noexcept { return count_; } + std::size_t rounds() const noexcept { return rounds_.size(); } + edge_mesh & mesh() noexcept { return mesh_; } + const edge_mesh & mesh() const noexcept { return mesh_; } + + /// @brief Changes whenever instance `index` enters a new round or finishes. + std::uint64_t mark(std::size_t index) const { return mark_.at(index); } + std::uint16_t current_round(std::size_t index) const + { + return round_of_.at(index); + } + edge_id current_edge(std::size_t index) const + { + const auto r = round_of_.at(index); + return r < rounds_.size() ? rounds_[r].edge : edge_peer; + } + std::chrono::milliseconds current_timeout(std::size_t index) const + { + const auto r = round_of_.at(index); + return r < rounds_.size() ? rounds_[r].timeout + : std::chrono::milliseconds(0); + } + + /// @brief Kick instance `index` into round 0 (no peer bytes yet). + void submit(std::size_t index) + { + if (index >= count_) + throw std::out_of_range("schedule_session submit"); + if (submitted_at(0, index)) + throw std::logic_error("schedule_session already submitted"); + run_round(index, 0, nullptr, 0); + } + + void drive() + { + bool progress = true; + while (progress) + { + progress = false; + mesh_.flush_all(); + const std::uint64_t received = mesh_.progress_total(); + for (std::size_t i = 0; i < count_; ++i) + { + if (done_[i]) + continue; + // Pipeline: submit independent future rounds up to credit. + if (pipeline_credit_ > 0) + { + const auto cur = static_cast(round_of_[i]); + for (std::size_t ahead = 1; ahead <= pipeline_credit_; + ++ahead) + { + const std::size_t cand = + static_cast(cur) + ahead; + if (cand >= rounds_.size() || submitted_at( + static_cast(cand), i)) + break; + if (rounds_[cand].dir != round_dir::send_next + && rounds_[cand].dir != round_dir::duplex) + break; + // Independent: produce must not require peer bytes. + if (cand > 0 && rounds_[cand].dir != round_dir::send_next) + break; + if (!mesh_.at(rounds_[cand].edge).can_send_ahead()) + break; + run_round(i, static_cast(cand), nullptr, + 0); + progress = true; + } + } + const auto r = static_cast(round_of_[i]); + if (!submitted_at(r, i)) + continue; + std::optional nxt; + auto & prev_sink = mesh_.at(rounds_[r].edge); + const auto prev_sr = rounds_[r].sink_round; + if (static_cast(r) + 1 >= rounds_.size() + && !rounds_[r].next) + { + done_[i] = true; + ++mark_[i]; + progress = true; + continue; + } + const bool needs_peer = + rounds_[r].dir != round_dir::send_next; + if (needs_peer && !prev_sink.peer_ready(prev_sr, i)) + continue; + auto & peer_buf = scratch_peer(); + peer_buf.clear(); + if (needs_peer) + { + peer_buf.resize(rounds_[r].slot_bytes); + if (!peer_buf.empty()) + prev_sink.read_peer(prev_sr, i, peer_buf.data(), + peer_buf.size()); + } + if (rounds_[r].next) + nxt = rounds_[r].next(i, peer_buf.empty() ? nullptr + : peer_buf.data(), + peer_buf.size()); + else if (static_cast(r) + 1 < rounds_.size()) + nxt = static_cast(r + 1); + else + { + done_[i] = true; + ++mark_[i]; + progress = true; + continue; + } + if (!nxt) + { + done_[i] = true; + ++mark_[i]; + progress = true; + continue; + } + if (*nxt >= rounds_.size()) + throw std::out_of_range("schedule_session next"); + if (submitted_at(*nxt, i)) + { + // Already pipelined; just advance cursor. + round_of_[i] = *nxt; + ++mark_[i]; + progress = true; + continue; + } + run_round(i, *nxt, peer_buf.empty() ? nullptr : peer_buf.data(), + peer_buf.size()); + progress = true; + } + mesh_.flush_all(); + // A read that completed inside that poll must not wait for the + // caller's next blocking wait. + if (mesh_.progress_total() != received) + progress = true; + } + } + + const phase_tally & tally() const noexcept { return tally_; } + + bool done(std::size_t index) const + { + if (index >= count_) + throw std::out_of_range("schedule_session done"); + return done_[index]; + } + +private: + static std::vector & scratch_peer() + { + thread_local std::vector buf; + return buf; + } + static std::vector & scratch_out() + { + thread_local std::vector buf; + return buf; + } + + bool submitted_at(std::uint16_t round, std::size_t index) const + { + return submitted_[static_cast(round) * count_ + index]; + } + + void mark_submitted(std::uint16_t round, std::size_t index) + { + submitted_[static_cast(round) * count_ + index] = true; + } + + void run_round(std::size_t index, std::uint16_t round, + const std::uint8_t * peer, std::size_t peer_n) + { + auto & step = rounds_[round]; + if (step.branch && !step.branch(index, peer, peer_n)) + { + done_[index] = true; + round_of_[index] = round; + ++mark_[index]; + return; + } + if (!step.produce) + throw std::logic_error("schedule_session missing produce"); + const std::uint64_t prg0 = prg::eval_count(); + const std::uint64_t rnd0 = random_bytes_count(); + const std::uint64_t wall0 = probe_ != nullptr ? probe_wall_ns_() : 0; + const std::uint64_t cpu0 = probe_ != nullptr ? probe_cpu_ns_() : 0; + auto & out = scratch_out(); + out.assign(step.slot_bytes, 0); + step.produce(index, peer, peer_n, out.empty() ? nullptr : out.data()); + auto & sink = mesh_.at(step.edge); + sink.submit(step.sink_round, index, out.empty() ? nullptr : out.data(), + out.size()); + mark_submitted(round, index); + round_of_[index] = round; + ++mark_[index]; + { + round_event ev; + ev.round = round; + ev.edge = step.edge; + ev.channel = step.channel; + ev.round_phase = step.round_phase; + ev.bytes_out = out.size(); + ev.bytes_in = step.dir == round_dir::send_next ? 0 : step.slot_bytes; + ev.wall_ns = probe_ != nullptr ? probe_wall_ns_() - wall0 : 0; + ev.cpu_ns = probe_ != nullptr ? probe_cpu_ns_() - cpu0 : 0; + ev.prg_evals = prg::eval_count() - prg0; + ev.random_bytes = random_bytes_count() - rnd0; + tally_ += ev; + if (probe_ != nullptr && probe_->fn != nullptr) + (*probe_)(ev); + } + // Done only when there is no further default successor and no jump. + if (!step.next && static_cast(round) + 1 >= rounds_.size()) + done_[index] = true; + } + + static std::uint64_t probe_wall_ns_() + { + using clock = std::chrono::steady_clock; + return static_cast( + std::chrono::duration_cast( + clock::now().time_since_epoch()) + .count()); + } + + static std::uint64_t probe_cpu_ns_() + { + if (have_thread_cpu_clock()) + return thread_cpu_ns(); + return probe_wall_ns_(); + } + + std::size_t count_; + edge_mesh mesh_; + std::vector rounds_; + std::vector round_of_; + std::vector mark_; + std::vector done_; + std::vector submitted_; + const round_probe * probe_ = nullptr; + std::size_t pipeline_credit_ = 0; + phase_tally tally_{}; +}; + +/// @brief Two-move batch: `(in, blind) -> (fwd, swap)` then +/// `(fwd, peer, blind, corr) -> out`. +template +class two_move_session +{ +public: + two_move_session(std::size_t count, RoundSink & peer, + dealer_cursor & dealer, Prg & prg, Move0 move0, Move1 move1) + : count_(count), + peer_(peer), + dealer_(dealer), + prg_(prg), + move0_(std::move(move0)), + move1_(std::move(move1)), + fwds_(count), + outs_(count), + have_in_(count, false), + have_swap_(count, false), + have_out_(count, false) + { + if (peer_.count() != count || peer_.rounds() < 1) + throw std::invalid_argument("two_move_session sink size"); + if (peer_.slot_bytes(0) != sizeof(Swap)) + throw std::invalid_argument("two_move_session slot"); + } + + template + void submit(std::size_t index, Input in) + { + if (index >= count_ || have_in_[index]) + throw std::logic_error("two_move_session submit"); + have_in_[index] = true; + Blind blind{}; + if constexpr (!detail::is_empty_pad_v) + blind = prg_.template at<0>(static_cast(index)); + auto [fwd, swap] = move0_(in, blind); + fwds_[index] = std::move(fwd); + static_assert(std::is_trivially_copyable_v, + "two_move_session swap must be trivially copyable"); + peer_.submit(0, index, reinterpret_cast(&swap), + sizeof(Swap)); + have_swap_[index] = true; + } + + void drive() + { + for (;;) + { + peer_.flush(); + peer_.poll(); + bool progress = false; + for (std::size_t i = 0; i < count_; ++i) + { + if (!have_swap_[i] || have_out_[i]) + continue; + if (!peer_.peer_ready(0, i)) + continue; + Swap peer_swap{}; + peer_.read_peer(0, i, + reinterpret_cast(&peer_swap), sizeof(Swap)); + Blind blind{}; + if constexpr (!detail::is_empty_pad_v) + { + if constexpr (Prg::stream_count > 1) + blind = prg_.template at<1>( + static_cast(i)); + else + blind = prg_.template at<0>( + static_cast(i)); + } + Corr corr{}; + if constexpr (!detail::is_empty_pad_v) + corr = dealer_.template at(0, i); + outs_[i] = move1_(fwds_[i], peer_swap, blind, corr); + have_out_[i] = true; + progress = true; + } + peer_.flush(); + if (!progress) + break; + } + for (std::size_t i = 0; i < count_; ++i) + { + if (have_in_[i] && !have_out_[i]) + throw std::logic_error("two_move_session stuck"); + } + } + + Output take(std::size_t index) const + { + if (index >= count_ || !have_out_[index]) + throw std::logic_error("two_move_session take"); + return outs_[index]; + } + +private: + std::size_t count_; + RoundSink & peer_; + dealer_cursor & dealer_; + Prg & prg_; + Move0 move0_; + Move1 move1_; + std::vector fwds_; + std::vector outs_; + std::vector have_in_; + std::vector have_swap_; + std::vector have_out_; +}; + +template +auto make_two_move_session(std::size_t count, RoundSink & peer, + dealer_cursor & dealer, Prg & prg, Move0 move0, Move1 move1) +{ + return two_move_session( + count, peer, dealer, prg, std::move(move0), std::move(move1)); +} + +} // namespace protocol +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_PROTOCOL_HPP__ diff --git a/include/dpf/protocol_factory.hpp b/include/dpf/protocol_factory.hpp new file mode 100644 index 0000000..7ae80b2 --- /dev/null +++ b/include/dpf/protocol_factory.hpp @@ -0,0 +1,756 @@ +/// @file dpf/protocol_factory.hpp +/// @brief Dealer and online factories over `net::stream_array`. +/// @details A dealer functor writes one view per party on stream `i`. An online +/// factory reads blinds from a dealer array and swaps messages on a +/// peer array. Both arrays are the same type so the backend can change +/// without rewriting the protocol. +#ifndef LIBDPF_INCLUDE_DPF_PROTOCOL_FACTORY_HPP__ +#define LIBDPF_INCLUDE_DPF_PROTOCOL_FACTORY_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/net/asio_ns.hpp" +#include "dpf/edabit.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/ot_pack.hpp" +#include "dpf/random.hpp" + +namespace dpf +{ +namespace factory +{ + +namespace detail +{ + +template +void write_pod(net::stream_array & a, std::size_t i, const T & v) +{ + static_assert(std::is_trivially_copyable_v, + "factory view must be trivially copyable"); + a.write(i, &v, sizeof(T)); +} + +template +T read_pod(net::stream_array & a, std::size_t i) +{ + static_assert(std::is_trivially_copyable_v, + "factory view must be trivially copyable"); + T v{}; + a.read(i, &v, sizeof(T)); + return v; +} + +template +void exchange_pod(net::stream_array & peer, std::size_t i, const T & mine, + T & theirs) +{ + static_assert(std::is_trivially_copyable_v, + "factory message must be trivially copyable"); + peer.write(i, &mine, sizeof(T)); + peer.flush(i); + peer.read(i, &theirs, sizeof(T)); +} + +} // namespace detail + +// --------------------------------------------------------------------------- +// Dealer functors (prep atoms) +// --------------------------------------------------------------------------- + +struct ring_triple_view +{ + std::uint8_t a[8]{}; + std::uint8_t b[8]{}; + std::uint8_t c[8]{}; + std::uint16_t limb = 8; +}; + +struct dabit_view +{ + std::uint8_t bit = 0; + std::uint8_t arith[8]{}; + std::uint16_t limb = 8; +}; + +struct bit_triple_view +{ + std::uint8_t a = 0; + std::uint8_t b = 0; + std::uint8_t c = 0; +}; + +inline std::pair +deal_ring_triple(std::uint16_t limb) +{ + if (limb == 0 || limb > 8) + throw std::invalid_argument("deal_ring_triple limb"); + const std::uint64_t mask = limb >= 8 + ? ~std::uint64_t{0} + : ((std::uint64_t{1} << (8u * limb)) - 1u); + const auto a = dpf::uniform_sample() & mask; + const auto b = dpf::uniform_sample() & mask; + const auto c = (a * b) & mask; + const auto a0 = dpf::uniform_sample() & mask; + const auto b0 = dpf::uniform_sample() & mask; + const auto c0 = dpf::uniform_sample() & mask; + ring_triple_view v0{}, v1{}; + v0.limb = limb; + v1.limb = limb; + std::memcpy(v0.a, &a0, limb); + std::memcpy(v0.b, &b0, limb); + std::memcpy(v0.c, &c0, limb); + const auto a1 = (a - a0) & mask; + const auto b1 = (b - b0) & mask; + const auto c1 = (c - c0) & mask; + std::memcpy(v1.a, &a1, limb); + std::memcpy(v1.b, &b1, limb); + std::memcpy(v1.c, &c1, limb); + return {v0, v1}; +} + +inline std::pair deal_dabit(std::uint16_t limb) +{ + if (limb == 0 || limb > 8) + throw std::invalid_argument("deal_dabit limb"); + auto pair = ot::sample_dabit_pair(); + dabit_view v0{}, v1{}; + v0.limb = limb; + v1.limb = limb; + v0.bit = pair.p0.bit; + v1.bit = pair.p1.bit; + std::memcpy(v0.arith, &pair.p0.arith, limb); + std::memcpy(v1.arith, &pair.p1.arith, limb); + return {v0, v1}; +} + +inline std::pair deal_bit_triple() +{ + auto t = ot::sample_bit_triple_pair(); + return {{t.p0.a, t.p0.b, t.p0.c}, {t.p1.a, t.p1.b, t.p1.c}}; +} + +// --------------------------------------------------------------------------- +// make_dealer +// --------------------------------------------------------------------------- + +/// @brief Run each functor `count` times; write view0/view1 on stream `i`. +template +void make_dealer(net::stream_array & party0, net::stream_array & party1, + std::size_t count, Fs &&... fs) +{ + if (party0.size() < sizeof...(Fs) || party1.size() < sizeof...(Fs)) + throw std::invalid_argument("make_dealer: not enough streams"); + std::size_t stream = 0; + auto run_one = [&](auto && f) { + for (std::size_t j = 0; j < count; ++j) + { + auto views = f(); + using V0 = std::decay_t; + using V1 = std::decay_t; + static_assert(std::is_trivially_copyable_v + && std::is_trivially_copyable_v, + "make_dealer views must be trivially copyable"); + if (sizeof(V0) != sizeof(V1)) + throw std::logic_error("make_dealer: unequal view sizes"); + detail::write_pod(party0, stream, views.first); + detail::write_pod(party1, stream, views.second); + } + party0.flush(stream); + party1.flush(stream); + ++stream; + }; + (run_one(std::forward(fs)), ...); +} + +/// @brief Like `make_dealer`, but the functor receives PRG lanes and the index. +template +void make_dealer_prg(net::stream_array & party0, net::stream_array & party1, + std::size_t count, Prg0 & prg0, Prg1 & prg1, F && f, + std::size_t stream = 0) +{ + if (party0.size() <= stream || party1.size() <= stream) + throw std::invalid_argument("make_dealer_prg: stream index"); + for (std::size_t j = 0; j < count; ++j) + { + auto views = f(prg0, prg1, j); + using V0 = std::decay_t; + using V1 = std::decay_t; + static_assert(std::is_trivially_copyable_v + && std::is_trivially_copyable_v, + "make_dealer_prg views must be trivially copyable"); + if (sizeof(V0) != sizeof(V1)) + throw std::logic_error("make_dealer_prg: unequal view sizes"); + detail::write_pod(party0, stream, views.first); + detail::write_pod(party1, stream, views.second); + } + party0.flush(stream); + party1.flush(stream); +} + +/// @brief Three-party dealer. Functors return `std::array`. +template +void make_dealer(net::stream_array & party0, net::stream_array & party1, + net::stream_array & party2, std::size_t count, Fs &&... fs) +{ + if (party0.size() < sizeof...(Fs) || party1.size() < sizeof...(Fs) + || party2.size() < sizeof...(Fs)) + throw std::invalid_argument("make_dealer 3p: not enough streams"); + std::size_t stream = 0; + auto run_one = [&](auto && f) { + for (std::size_t j = 0; j < count; ++j) + { + auto views = f(); + using Arr = std::decay_t; + static_assert(std::tuple_size_v == 3, + "3-party dealer functor must return array/tuple of 3"); + using V = std::decay_t(views))>; + static_assert(std::is_trivially_copyable_v, + "make_dealer views must be trivially copyable"); + detail::write_pod(party0, stream, std::get<0>(views)); + detail::write_pod(party1, stream, std::get<1>(views)); + detail::write_pod(party2, stream, std::get<2>(views)); + } + party0.flush(stream); + party1.flush(stream); + party2.flush(stream); + ++stream; + }; + (run_one(std::forward(fs)), ...); +} + +// --------------------------------------------------------------------------- +// Online protocol (blocking round list) +// --------------------------------------------------------------------------- + +struct gmw_and_blind +{ + std::uint8_t a = 0; + std::uint8_t b = 0; + std::uint8_t c = 0; +}; + +struct gmw_and_msg +{ + std::uint8_t d = 0; + std::uint8_t e = 0; +}; + +struct gmw_and_keep +{ + gmw_and_blind blind{}; + gmw_and_msg mine{}; +}; + +/// @brief Round 0: `(p,q), blind -> {msg, keep}`. +struct gmw_and_round0 +{ + std::pair operator()( + std::pair pq, gmw_and_blind blind) const + { + gmw_and_msg m{}; + m.d = static_cast((pq.first ^ blind.a) & 1u); + m.e = static_cast((pq.second ^ blind.b) & 1u); + return {m, gmw_and_keep{blind, m}}; + } +}; + +/// @brief Round 1: finish AND from peer masks. +struct gmw_and_round1 +{ + unsigned party = 0; + + std::uint8_t operator()(gmw_and_keep keep, gmw_and_msg peer, + gmw_and_blind /*unused_blind*/, gmw_and_blind /*corr*/) const + { + const std::uint8_t d_open = + static_cast(keep.mine.d ^ peer.d); + const std::uint8_t e_open = + static_cast(keep.mine.e ^ peer.e); + ot::bit_triple t{keep.blind.a, keep.blind.b, keep.blind.c}; + return edabit::and_finish(t, d_open, e_open, party); + } +}; + +/// @brief Two-round online object: round0 produces a peer message; round1 +/// consumes the peer reply. Blinds come from `dealer[0]` (round0 only +/// for GMW AND). +template +class two_round_protocol +{ +public: + two_round_protocol(std::size_t count, net::stream_array & peer, + net::stream_array & dealer, Round0 r0, Round1 r1) + : count_(count), + peer_(&peer), + dealer_(&dealer), + r0_(std::move(r0)), + r1_(std::move(r1)) + { + if (peer_->size() < 1 || dealer_->size() < 1) + throw std::invalid_argument("two_round_protocol: empty arrays"); + } + + template + auto operator()(std::size_t index, const Input & input) + { + if (index >= count_) + throw std::out_of_range("protocol index"); + using Blind = gmw_and_blind; + Blind blind = detail::read_pod(*dealer_, 0); + auto step0 = r0_(input, blind); + using Msg = std::decay_t; + Msg peer_msg{}; + detail::exchange_pod(*peer_, 0, step0.first, peer_msg); + Blind unused{}; + return r1_(step0.second, peer_msg, unused, unused); + } + +private: + std::size_t count_ = 0; + net::stream_array * peer_ = nullptr; + net::stream_array * dealer_ = nullptr; + Round0 r0_; + Round1 r1_; +}; + +template +class protocol_factory +{ +public: + protocol_factory(Round0 r0, Round1 r1) + : r0_(std::move(r0)), r1_(std::move(r1)) + { + } + + two_round_protocol create(std::size_t count, + net::stream_array & peer, net::stream_array & dealer) const + { + return two_round_protocol(count, peer, dealer, r0_, + r1_); + } + +private: + Round0 r0_; + Round1 r1_; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +protocol_factory, std::decay_t> +make_protocol_factory(Round0 && r0, Round1 && r1) +{ + return protocol_factory, std::decay_t>( + std::forward(r0), std::forward(r1)); +} + +/// @brief Dealer functor writing `gmw_and_blind` shares on stream 0. +inline auto make_gmw_and_dealer_functor() +{ + return [] { + auto t = deal_bit_triple(); + gmw_and_blind v0{t.first.a, t.first.b, t.first.c}; + gmw_and_blind v1{t.second.a, t.second.b, t.second.c}; + return std::pair{v0, v1}; + }; +} + +// --------------------------------------------------------------------------- +// Byte-oriented N-round online runner +// --------------------------------------------------------------------------- + +struct round_spec +{ + std::size_t blind_bytes = 0; + std::size_t msg_bytes = 0; +}; + +struct byte_round +{ + std::size_t blind_bytes = 0; + std::size_t msg_bytes = 0; + std::function(std::vector & state, + const std::uint8_t * blind, std::size_t nb)> + produce; + std::function & state, const std::uint8_t * peer, + std::size_t nm, const std::uint8_t * blind, std::size_t nb)> + finish; +}; + +/// @brief Run `rounds` in order: blind from `dealer[r]`, message on `peer[r]`. +class byte_protocol +{ +public: + byte_protocol(std::size_t count, net::stream_array & peer, + net::stream_array & dealer, std::vector rounds) + : count_(count), + peer_(&peer), + dealer_(&dealer), + rounds_(std::move(rounds)) + { + if (peer_->size() < rounds_.size() || dealer_->size() < rounds_.size()) + throw std::invalid_argument("byte_protocol: not enough streams"); + for (const auto & r : rounds_) + { + if (!r.produce || !r.finish) + throw std::invalid_argument("byte_protocol: missing callbacks"); + } + } + + std::vector operator()(std::size_t index, + std::vector state) + { + if (index >= count_) + throw std::out_of_range("byte_protocol index"); + (void)index; + for (std::size_t r = 0; r < rounds_.size(); ++r) + { + const auto & spec = rounds_[r]; + std::vector blind(spec.blind_bytes); + if (spec.blind_bytes != 0) + dealer_->read(r, blind.data(), spec.blind_bytes); + auto outbound = spec.produce(state, blind.data(), blind.size()); + if (outbound.size() != spec.msg_bytes) + throw std::logic_error("byte_protocol: produce size"); + peer_->write(r, outbound.data(), outbound.size()); + peer_->flush(r); + std::vector inbound(spec.msg_bytes); + peer_->read(r, inbound.data(), inbound.size()); + spec.finish(state, inbound.data(), inbound.size(), blind.data(), + blind.size()); + } + return state; + } + + std::size_t count() const noexcept { return count_; } + std::size_t rounds() const noexcept { return rounds_.size(); } + +private: + std::size_t count_ = 0; + net::stream_array * peer_ = nullptr; + net::stream_array * dealer_ = nullptr; + std::vector rounds_; +}; + +class byte_protocol_factory +{ +public: + explicit byte_protocol_factory(std::vector rounds) + : rounds_(std::move(rounds)) + { + } + + byte_protocol create(std::size_t count, net::stream_array & peer, + net::stream_array & dealer) const + { + return byte_protocol(count, peer, dealer, rounds_); + } + +private: + std::vector rounds_; +}; + +HEDLEY_WARN_UNUSED_RESULT +inline byte_protocol_factory make_byte_protocol_factory( + std::vector rounds) +{ + return byte_protocol_factory(std::move(rounds)); +} + +// --------------------------------------------------------------------------- +// Async-shaped byte protocol (blocking today; completion hook for later I/O) +// --------------------------------------------------------------------------- + +/// @brief Same round shape as `byte_round`; used by `async_byte_protocol`. +struct async_byte_round +{ + std::size_t blind_bytes = 0; + std::size_t msg_bytes = 0; + std::function(std::vector & state, + const std::uint8_t * blind, std::size_t nb)> + produce; + std::function & state, const std::uint8_t * peer, + std::size_t nm, const std::uint8_t * blind, std::size_t nb)> + finish; +}; + +/// @brief Blocking runner with an optional per-round completion callback. +/// @details This keeps the legacy synchronous shape: rounds run on the calling +/// thread and the callback is a progress hook. For TRUE overlapped, +/// event-driven I/O with no busy-waiting and no blocking protocol +/// calls, use `dpf::async::overlapped_byte_protocol` in +/// `dpf/async_protocol.hpp`, which drives the same `async_byte_round` +/// list over an `async_stream_array` and completes via an +/// `asio::io_context`. +class async_byte_protocol +{ +public: + using on_round_complete_fn = std::function; + + async_byte_protocol(std::size_t count, net::stream_array & peer, + net::stream_array & dealer, std::vector rounds, + on_round_complete_fn on_round_complete = {}) + : count_(count), + peer_(&peer), + dealer_(&dealer), + rounds_(std::move(rounds)), + on_round_complete_(std::move(on_round_complete)) + { + if (peer_->size() < rounds_.size() || dealer_->size() < rounds_.size()) + throw std::invalid_argument("async_byte_protocol: not enough streams"); + for (const auto & r : rounds_) + { + if (!r.produce || !r.finish) + throw std::invalid_argument("async_byte_protocol: missing callbacks"); + } + } + + std::vector operator()(std::size_t index, + std::vector state) + { + if (index >= count_) + throw std::out_of_range("async_byte_protocol index"); + (void)index; + for (std::size_t r = 0; r < rounds_.size(); ++r) + { + const auto & spec = rounds_[r]; + std::vector blind(spec.blind_bytes); + if (spec.blind_bytes != 0) + dealer_->read(r, blind.data(), spec.blind_bytes); + auto outbound = spec.produce(state, blind.data(), blind.size()); + if (outbound.size() != spec.msg_bytes) + throw std::logic_error("async_byte_protocol: produce size"); + peer_->write(r, outbound.data(), outbound.size()); + peer_->flush(r); + std::vector inbound(spec.msg_bytes); + peer_->read(r, inbound.data(), inbound.size()); + spec.finish(state, inbound.data(), inbound.size(), blind.data(), + blind.size()); + if (on_round_complete_) + on_round_complete_(r); + } + return state; + } + + std::size_t count() const noexcept { return count_; } + std::size_t rounds() const noexcept { return rounds_.size(); } + +private: + std::size_t count_ = 0; + net::stream_array * peer_ = nullptr; + net::stream_array * dealer_ = nullptr; + std::vector rounds_; + on_round_complete_fn on_round_complete_; +}; + +class async_byte_protocol_factory +{ +public: + explicit async_byte_protocol_factory(std::vector rounds) + : rounds_(std::move(rounds)) + { + } + + async_byte_protocol create(std::size_t count, net::stream_array & peer, + net::stream_array & dealer, + async_byte_protocol::on_round_complete_fn on_round_complete = {}) const + { + return async_byte_protocol(count, peer, dealer, rounds_, + std::move(on_round_complete)); + } + +private: + std::vector rounds_; +}; + +HEDLEY_WARN_UNUSED_RESULT +inline async_byte_protocol_factory make_async_byte_protocol_factory( + std::vector rounds) +{ + return async_byte_protocol_factory(std::move(rounds)); +} + +// --------------------------------------------------------------------------- +// Beaver ring multiply (open d, e; finish locally) +// --------------------------------------------------------------------------- + +struct beaver_mul_input +{ + std::uint64_t x = 0; + std::uint64_t y = 0; +}; + +struct beaver_mul_keep +{ + std::uint64_t x = 0; + std::uint64_t y = 0; + std::uint64_t a = 0; + std::uint64_t b = 0; + std::uint64_t c = 0; + std::uint64_t d_open = 0; + std::uint64_t d_mine = 0; + std::uint64_t e_mine = 0; +}; + +/// @brief Round 0: open `d = x - a` on peer stream 0. +struct beaver_mul_round0 +{ + std::uint16_t limb = 8; + + std::pair, beaver_mul_keep> operator()( + beaver_mul_input in, ring_triple_view blind) const + { + if (blind.limb != limb) + throw std::invalid_argument("beaver_mul_round0 limb"); + std::uint64_t a = 0, b = 0, c = 0; + std::memcpy(&a, blind.a, limb); + std::memcpy(&b, blind.b, limb); + std::memcpy(&c, blind.c, limb); + const std::uint64_t mask = limb >= 8 + ? ~std::uint64_t{0} + : ((std::uint64_t{1} << (8u * limb)) - 1u); + const std::uint64_t d = (in.x - a) & mask; + std::vector msg(limb); + std::memcpy(msg.data(), &d, limb); + beaver_mul_keep keep{}; + keep.x = in.x & mask; + keep.y = in.y & mask; + keep.a = a; + keep.b = b; + keep.c = c; + keep.d_mine = d; + return {std::move(msg), keep}; + } +}; + +/// @brief Round 1: open `e = y - b`, finish product share. +struct beaver_mul_round1 +{ + std::uint16_t limb = 8; + unsigned party = 0; + + std::uint64_t operator()(beaver_mul_keep keep, std::vector peer_e, + ring_triple_view /*unused*/) const + { + if (peer_e.size() != limb) + throw std::invalid_argument("beaver_mul_round1 msg"); + const std::uint64_t mask = limb >= 8 + ? ~std::uint64_t{0} + : ((std::uint64_t{1} << (8u * limb)) - 1u); + std::uint64_t e_peer = 0; + std::memcpy(&e_peer, peer_e.data(), limb); + const std::uint64_t e_open = (keep.e_mine + e_peer) & mask; + std::uint64_t z = (keep.c + keep.d_open * keep.b + e_open * keep.a) & mask; + if (party == 0) + z = (z + keep.d_open * e_open) & mask; + return z; + } +}; + +/// @brief Two-round beaver multiply: blind triple on dealer stream 0 only. +template +class beaver_mul_protocol +{ +public: + beaver_mul_protocol(std::size_t count, net::stream_array & peer, + net::stream_array & dealer, Round0 r0, Round1 r1, std::uint16_t limb) + : count_(count), + peer_(&peer), + dealer_(&dealer), + r0_(std::move(r0)), + r1_(std::move(r1)), + limb_(limb) + { + if (peer_->size() < 2 || dealer_->size() < 1) + throw std::invalid_argument("beaver_mul_protocol streams"); + } + + std::uint64_t operator()(std::size_t index, beaver_mul_input input) + { + if (index >= count_) + throw std::out_of_range("beaver_mul_protocol index"); + ring_triple_view blind{}; + blind.limb = limb_; + dealer_->read(0, &blind, sizeof(blind)); + auto step0 = r0_(input, blind); + peer_->write(0, step0.first.data(), step0.first.size()); + peer_->flush(0); + std::vector peer_d(limb_); + peer_->read(0, peer_d.data(), limb_); + std::uint64_t d_peer = 0; + std::memcpy(&d_peer, peer_d.data(), limb_); + const std::uint64_t mask = limb_ >= 8 + ? ~std::uint64_t{0} + : ((std::uint64_t{1} << (8u * limb_)) - 1u); + auto keep = step0.second; + keep.d_open = (keep.d_mine + d_peer) & mask; + const std::uint64_t e = (keep.y - keep.b) & mask; + keep.e_mine = e; + std::vector msg_e(limb_); + std::memcpy(msg_e.data(), &e, limb_); + peer_->write(1, msg_e.data(), limb_); + peer_->flush(1); + std::vector peer_e(limb_); + peer_->read(1, peer_e.data(), limb_); + ring_triple_view unused{}; + return r1_(keep, std::move(peer_e), unused); + } + +private: + std::size_t count_ = 0; + net::stream_array * peer_ = nullptr; + net::stream_array * dealer_ = nullptr; + Round0 r0_; + Round1 r1_; + std::uint16_t limb_ = 8; +}; + +class beaver_mul_factory +{ +public: + beaver_mul_factory(beaver_mul_round0 r0, beaver_mul_round1 r1) + : r0_(std::move(r0)), r1_(std::move(r1)) + { + } + + beaver_mul_protocol create( + std::size_t count, net::stream_array & peer, net::stream_array & dealer) const + { + return beaver_mul_protocol( + count, peer, dealer, r0_, r1_, r0_.limb); + } + +private: + beaver_mul_round0 r0_; + beaver_mul_round1 r1_; +}; + +HEDLEY_WARN_UNUSED_RESULT +inline beaver_mul_factory make_beaver_mul_factory(beaver_mul_round0 r0, + beaver_mul_round1 r1) +{ + return beaver_mul_factory(std::move(r0), std::move(r1)); +} + +inline auto make_beaver_mul_dealer_functor() +{ + return [limb = std::uint16_t{8}] { + return deal_ring_triple(limb); + }; +} + +} // namespace factory +} // namespace dpf + +#endif diff --git a/include/dpf/protocol_roles.hpp b/include/dpf/protocol_roles.hpp new file mode 100644 index 0000000..3aedb61 --- /dev/null +++ b/include/dpf/protocol_roles.hpp @@ -0,0 +1,68 @@ +/// @file dpf/protocol_roles.hpp +/// @brief Thin helpers for dealer, preprocess, and online roles. +/// @details Three modes: +/// - **Dealer** — sample prep and write per-party views (files or streams). +/// - **Preprocess** — exchange dealer output over the network (e.g. mux TCP). +/// - **Online** — parties read prep and run interactive rounds on peer streams. +#ifndef LIBDPF_INCLUDE_DPF_PROTOCOL_ROLES_HPP__ +#define LIBDPF_INCLUDE_DPF_PROTOCOL_ROLES_HPP__ + +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/net/channel.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/prep_source.hpp" + +namespace dpf +{ +namespace roles +{ + +/// @brief Dealer mode: write `basename-p0`, `basename-p1` prep blobs. +inline void dealer_write_files(const std::string & basename, + const prep::demand & d) +{ + auto views = prep::deal_views(d); + prep::write_file(basename + "-p0", views.first); + prep::write_file(basename + "-p1", views.second); +} + +/// @brief Preprocess mode: party 0 deals into mux streams; party 1 receives. +/// @details Party 0 writes its view locally and ships party 1's view on stream 0. +inline std::vector preprocess_from_dealer_mux(net::channel & ch, + unsigned party, const prep::demand & d, net::stream_array & local_out) +{ + if (local_out.size() < 1) + throw std::invalid_argument("preprocess_from_dealer_mux: need stream 0"); + if (party == 0) + { + auto views = prep::deal_views(d); + local_out.write(0, views.first.data(), views.first.size()); + local_out.flush(0); + ch.send_vec(views.second, net::msg::beaver_tape); + return std::move(views.first); + } + auto got = ch.recv_vec(net::msg::beaver_tape); + local_out.write(0, got.data(), got.size()); + local_out.flush(0); + return got; +} + +/// @brief Online mode: open prep cursors from dealer files (`basename-p0/p1`). +HEDLEY_WARN_UNUSED_RESULT +inline std::pair online_open_file_array( + const std::string & basename) +{ + return {prep::cursor(prep::read_file(basename + "-p0")), + prep::cursor(prep::read_file(basename + "-p1"))}; +} + +} // namespace roles +} // namespace dpf + +#endif diff --git a/include/dpf/random.hpp b/include/dpf/random.hpp index 28bf447..c5ce6c9 100644 --- a/include/dpf/random.hpp +++ b/include/dpf/random.hpp @@ -10,10 +10,11 @@ #include +#include #include #include +#include #include -#include #include #include #include @@ -31,11 +32,19 @@ namespace dpf namespace detail { +/// @brief Thread-local count of bytes delivered by `uniform_fill`. +inline thread_local std::uint64_t random_bytes_tls = 0; + /// @brief When set, `uniform_fill` copies from this hook and does not read the /// system RNG. Used to feed the same beaver coins to dealer `make_dpf` and /// Doerner–Shelat gen. Null in normal use. inline thread_local void (*uniform_bytes_hook)(void *, std::size_t) = nullptr; +/// @brief State for `uniform_bytes_hook`, set and read by the hook's owner +/// (`experiment` keeps itself here). Travels with the hook when another thread +/// adopts this one's draws (`dpf/thread_work.hpp`). +inline thread_local void * uniform_bytes_ctx = nullptr; + template HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -170,6 +179,20 @@ inline entropy_source & entropy() } // namespace detail +/// @brief Zero the thread-local random-byte counter. +HEDLEY_ALWAYS_INLINE +void reset_random_bytes_count() noexcept +{ + detail::random_bytes_tls = 0; +} + +/// @brief Bytes filled by `uniform_fill` since the last reset on this thread. +HEDLEY_ALWAYS_INLINE +std::uint64_t random_bytes_count() noexcept +{ + return detail::random_bytes_tls; +} + template HEDLEY_NO_THROW auto & uniform_fill(T & buf) noexcept // NOLINT(runtime/references) @@ -186,12 +209,17 @@ auto & uniform_fill(T & buf) noexcept // NOLINT(runtime/references) } else { - if (detail::fill_from_hook(buf)) return buf; + if (detail::fill_from_hook(buf)) + { + detail::random_bytes_tls += sizeof(buf); + return buf; + } #if defined(LIBDPF_USE_ARC4RANDOM) arc4random_buf(&buf, sizeof(buf)); #else detail::entropy().read(&buf, sizeof(buf)); #endif + detail::random_bytes_tls += sizeof(buf); return buf; } } @@ -214,24 +242,82 @@ auto additively_share(T secret) noexcept { using T_ = std::remove_cv_t>; T_ tmp = uniform_sample(); - // Signed subtraction overflows for extreme shares. Subtract in the - // unsigned width and copy the bits back so the group is mod 2^n. - T_ other; - if constexpr (std::is_integral_v && std::is_signed_v) - { - using U = std::make_unsigned_t; - U diff = static_cast(static_cast(secret)) - static_cast(tmp); - std::memcpy(&other, &diff, sizeof(other)); - } - else - { - other = static_cast(static_cast(secret) - tmp); - } + T_ other = detail::group_sub(static_cast(secret), tmp); return std::make_pair( additive_share::from_raw(tmp), additive_share::from_raw(other)); } +/// @brief Uniform (3,3)-additive sharing of `secret`. +/// @details Two components are uniform. The third is `secret` minus those +/// two in the share group, so the three shares sum to `secret`. +/// @tparam T value type +/// @param secret the cleartext secret +/// @return shares for parties 0, 1, and 2 +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +auto additively_share3(T secret) noexcept +{ + using T_ = std::remove_cv_t>; + const T_ a = uniform_sample(); + const T_ b = uniform_sample(); + const T_ c = detail::group_sub( + detail::group_sub(static_cast(secret), a), b); + return std::make_tuple( + additive3_share::from_raw(a), + additive3_share::from_raw(b), + additive3_share::from_raw(c)); +} + +/// @brief Uniform (2,3)-replicated sharing of `secret`. +/// @details The underlying (3,3) components are a uniform additive split. +/// Each party receives its component and the next party's. +/// @tparam T value type +/// @param secret the cleartext secret +/// @return shares for parties 0, 1, and 2 +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +auto share_replicated(T secret) noexcept +{ + using T_ = std::remove_cv_t>; + const T_ x0 = uniform_sample(); + const T_ x1 = uniform_sample(); + const T_ x2 = detail::group_sub( + detail::group_sub(static_cast(secret), x0), x1); + return make_replicated_shares(x0, x1, x2); +} + +namespace shamir +{ + +/// @brief Uniform `(K,N)` Shamir sharing of `secret`. +/// @details Coefficients of `x, ..., x^{K-1}` are `uniform_sample`. The +/// shares are `deal`. Threshold 1 draws nothing: every share +/// equals `secret`. `shamir3::share_secret` is the `(2,3)` case on +/// `fp61`, reindexed to points `1`, `2`, and `3`. +/// @tparam K shares required to reconstruct +/// @tparam N shareholders +/// @tparam T field type. Opening needs `detail::shamir_field` +/// @param secret the cleartext secret +/// @return one share per party `0 .. N-1` +/// \complexity O(NK) field operations, plus `K-1` field samples. No messages. +template +HEDLEY_WARN_UNUSED_RESULT +HEDLEY_NO_THROW +auto share_secret(T secret) noexcept +{ + using T_ = std::remove_cv_t>; + constexpr std::size_t degree = access::degree; + std::array coeff{}; + for (std::size_t i = 0; i < degree; ++i) + coeff[i] = uniform_sample(); + return deal(static_cast(secret), coeff); +} + +} // namespace shamir + } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_RANDOM_HPP__ diff --git a/include/dpf/revealing.hpp b/include/dpf/revealing.hpp new file mode 100644 index 0000000..e57772f --- /dev/null +++ b/include/dpf/revealing.hpp @@ -0,0 +1,32 @@ +/// @file dpf/revealing.hpp +/// @brief Conversions that still publish more than a masked opening. +/// @details Paths with a semi-honest alternative have been removed +/// (`a2b_party` / opened edaBit bits, wrap-from-clear-bits). +/// What remains is flagged because the algorithm itself publishes it. +#ifndef LIBDPF_INCLUDE_DPF_REVEALING_HPP__ +#define LIBDPF_INCLUDE_DPF_REVEALING_HPP__ + +namespace dpf +{ +namespace revealing +{ + +/// @brief Leaks with no drop-in replacement in this tree. +/// @details +/// - `share_cmp::div_party_pair` publishes `floor(log2(den))` so Newton can +/// normalize. A magnitude-hiding division needs a different iteration. +/// - `prep::setup_2pc_sampled` lets party 0 sample both prep views and send +/// one. That is not OT extension; party 0 learns the correlation. Use +/// `prep::deal_views` when a third party can write the two views. +inline constexpr const char * known[] = { + "share_cmp::div_party_pair publishes floor(log2(denominator))", + "prep::setup_2pc_sampled: party 0 samples both views (not OT extension)", +}; + +inline constexpr unsigned known_count = + sizeof(known) / sizeof(known[0]); + +} // namespace revealing +} // namespace dpf + +#endif diff --git a/include/dpf/rss_seed.hpp b/include/dpf/rss_seed.hpp new file mode 100644 index 0000000..2dcfe54 --- /dev/null +++ b/include/dpf/rss_seed.hpp @@ -0,0 +1,217 @@ +/// @file dpf/rss_seed.hpp +/// @brief Pairwise PRG seeds for honest-majority 3PC RSS preprocessing. +/// @details Parties 0,1,2 hold keys `k01`, `k12`, `k20`. Party `i` derives +/// both components of a replicated random value, a zero-sharing, and +/// the local cross term of an RSS multiply with no message. +#ifndef LIBDPF_INCLUDE_DPF_RSS_SEED_HPP__ +#define LIBDPF_INCLUDE_DPF_RSS_SEED_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/buffered_prg.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" +#include "dpf/secret_share.hpp" + +namespace dpf +{ +namespace rss +{ + +using seed_block = typename prg::aes128::block_type; + +/// @brief Three pairwise master seeds. Role `i` holds seeds with `i±1 mod 3`. +struct seed_bundle +{ + seed_block k01{}; + seed_block k12{}; + seed_block k20{}; +}; + +/// @brief Sample three independent pairwise seeds (dealer / setup). +HEDLEY_WARN_UNUSED_RESULT +inline seed_bundle sample_seed_bundle() +{ + seed_bundle b; + b.k01 = randomness::sample_master_seed(); + b.k12 = randomness::sample_master_seed(); + b.k20 = randomness::sample_master_seed(); + return b; +} + +/// @brief Party `me`'s view: the two seeds it shares with its neighbors. +struct party_seeds +{ + unsigned me = 0; + seed_block with_prev{}; ///< shared with (me+2)%3 + seed_block with_next{}; ///< shared with (me+1)%3 + + static party_seeds from_bundle(const seed_bundle & b, unsigned me) + { + if (me > 2) + throw std::invalid_argument("rss party_seeds: me must be 0..2"); + party_seeds s; + s.me = me; + if (me == 0) + { + s.with_prev = b.k20; + s.with_next = b.k01; + } + else if (me == 1) + { + s.with_prev = b.k01; + s.with_next = b.k12; + } + else + { + s.with_prev = b.k12; + s.with_next = b.k20; + } + return s; + } +}; + +namespace detail +{ + +template +T derive(seed_block master, std::uint32_t role, std::uint64_t index) +{ + randomness::lane_table table(master); + return table.value_at(role, index); +} + +inline seed_block pair_seed(unsigned a, unsigned b, const seed_bundle & bundle) +{ + const unsigned lo = a < b ? a : b; + const unsigned hi = a < b ? b : a; + if (lo == 0 && hi == 1) + return bundle.k01; + if (lo == 1 && hi == 2) + return bundle.k12; + if (lo == 0 && hi == 2) + return bundle.k20; + throw std::invalid_argument("rss pair_seed: bad pair"); +} + +} // namespace detail + +/// @brief Replicated random `r` at `index`. Party `me` holds `(r_me, r_{me+1})`. +template +HEDLEY_WARN_UNUSED_RESULT +replicated_share random_replicated0(const party_seeds & s, std::uint64_t index) +{ + if (s.me != 0) + throw std::invalid_argument("random_replicated0: wrong party"); + // r0 from k20 (parties 2,0), r1 from k01 (parties 0,1) + const T r0 = detail::derive(s.with_prev, 0, index); + const T r1 = detail::derive(s.with_next, 1, index); + return replicated_share::from_raw(r0, r1); +} + +template +HEDLEY_WARN_UNUSED_RESULT +replicated_share random_replicated1(const party_seeds & s, std::uint64_t index) +{ + if (s.me != 1) + throw std::invalid_argument("random_replicated1: wrong party"); + const T r1 = detail::derive(s.with_prev, 1, index); + const T r2 = detail::derive(s.with_next, 2, index); + return replicated_share::from_raw(r1, r2); +} + +template +HEDLEY_WARN_UNUSED_RESULT +replicated_share random_replicated2(const party_seeds & s, std::uint64_t index) +{ + if (s.me != 2) + throw std::invalid_argument("random_replicated2: wrong party"); + const T r2 = detail::derive(s.with_prev, 2, index); + const T r0 = detail::derive(s.with_next, 0, index); + return replicated_share::from_raw(r2, r0); +} + +/// @brief Party-erased random replicated share. +template +HEDLEY_WARN_UNUSED_RESULT +std::pair random_replicated_components(const party_seeds & s, + std::uint64_t index) +{ + if (s.me == 0) + { + auto sh = random_replicated0(s, index); + return {sh.own, sh.next}; + } + if (s.me == 1) + { + auto sh = random_replicated1(s, index); + return {sh.own, sh.next}; + } + auto sh = random_replicated2(s, index); + return {sh.own, sh.next}; +} + +/// @brief Zero-sharing for reshare: party `i` holds `z_i` with sum zero. +/// @details `z_i = r_i - r_{i-1}` where `r` is a common pairwise stream on +/// each edge; the three differences cancel. +template +HEDLEY_WARN_UNUSED_RESULT +T zero_share(const party_seeds & s, std::uint64_t index) +{ + // On edge with_next: parties me and next share stream role 0 → value α + // On edge with_prev: parties me and prev share stream role 0 → value β + // z_me = α - β so sum over the ring is zero. + const T alpha = detail::derive(s.with_next, 10u + s.me, index); + const T beta = detail::derive(s.with_prev, 10u + ((s.me + 2) % 3), index); + return static_cast(alpha - beta); +} + +/// @brief Local y-component of an RSS multiply before neighbor refresh. +/// @details Party `i` holds `(x_i, x_{i+1})` and `(y_i, y_{i+1})`. The local +/// product factor is `x_i*y_i + x_i*y_{i+1} + x_{i+1}*y_i` plus a +/// zero-mask so the three factors sum to `xy` after refresh. +template +HEDLEY_WARN_UNUSED_RESULT +T rss_mul_local(const party_seeds & s, T x_own, T x_next, T y_own, T y_next, + std::uint64_t index) +{ + const T cross = static_cast( + x_own * y_own + x_own * y_next + x_next * y_own); + const T mask = zero_share(s, index); + return static_cast(cross + mask); +} + +/// @brief Full dealer view: derive every party's components for tests. +template +struct replicated_triple +{ + replicated_share p0; + replicated_share p1; + replicated_share p2; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +replicated_triple random_replicated_all(const seed_bundle & b, + std::uint64_t index) +{ + auto s0 = party_seeds::from_bundle(b, 0); + auto s1 = party_seeds::from_bundle(b, 1); + auto s2 = party_seeds::from_bundle(b, 2); + return replicated_triple{ + random_replicated0(s0, index), + random_replicated1(s1, index), + random_replicated2(s2, index)}; +} + +} // namespace rss +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_RSS_SEED_HPP__ diff --git a/include/dpf/run_config.hpp b/include/dpf/run_config.hpp new file mode 100644 index 0000000..3a53147 --- /dev/null +++ b/include/dpf/run_config.hpp @@ -0,0 +1,506 @@ +/// @file dpf/run_config.hpp +/// @brief One explicit configuration for harness runs, sweeps, and nodes. +/// @details Everything the harness decides is a field here: transport, host, +/// lanes, framing, instances, wire policy (window, chunking, +/// coalescing, socket options), pipelining, wait budgets, compute +/// threads, warmup and trials, CPU pins, and setup deadlines. +/// `from_env()` and `apply_args()` both go through `set(key, value)`, +/// so `DPF_LANES=4` and `--lanes=4` mean the same thing, and an +/// unknown key or value throws. The run log is configured the same +/// way (`log_level`, `log`, `log_seeds`) and applied by +/// `app::start_logging`. So is link security: `encryption`, +/// `identity` (this party's key file), `peer.N` / `dealer_key` (keys +/// this party checks), and the `client_*` / `server_*` keys for client +/// links. `config=FILE` (or `DPF_CONFIG`) applies a file of +/// `key = value` lines through the same parser. +#ifndef LIBDPF_INCLUDE_DPF_RUN_CONFIG_HPP__ +#define LIBDPF_INCLUDE_DPF_RUN_CONFIG_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "dpf/compose.hpp" +#include "dpf/log.hpp" +#include "dpf/net/identity.hpp" +#include "dpf/net/policy.hpp" +#include "dpf/net/round_lane.hpp" +#include "dpf/net/security.hpp" + +namespace dpf +{ +namespace app +{ + +struct run_config +{ + net::transport kind = net::transport::async_memory; + /// Address the socket transports connect to (in-process runs bind all + /// interfaces and connect here, so a NIC address exercises the NIC path). + std::string host = "127.0.0.1"; + std::size_t n_lanes = 0; + net::framing_mode framing = net::framing_mode::automatic; + /// RoundSink batch width: protocol instances carried per round. + std::size_t instances = 1; + net::wire_policy policy{}; + /// Rounds a session may submit ahead of its current one, while that edge's + /// window has room. Only rounds whose bytes do not depend on the peer + /// qualify; compose plans are fully dependent, so overlap them with + /// `instances` instead. + std::size_t pipeline_credit = 0; + std::chrono::milliseconds wait_timeout{30000}; + /// Kernels run on a compute pool of this size (0 = inline on the party + /// thread). + std::size_t compute_threads = 0; + std::size_t warmup = 0; + std::size_t trials = 1; + /// Pin party threads to CPUs (-1 = no pin). + int cpu[3] = {-1, -1, -1}; + net::deadlines limits{}; + /// Run-log threshold, sinks (`stderr`, `syslog`, `file:PATH`, `none`, + /// comma-separated), and how seeds are printed (`full`, `hash`, `off`). + log::level log_level = log::level::info; + std::string log_sinks = "stderr"; + log::seed_policy log_seeds = log::seed_policy::full; + /// Party links: TLS 1.3 unless `encryption=off`; this party's key + /// (`identity`) and the keys it checks (`peer.N`, `dealer_key`). + net::peer_security security{}; + /// Client links: what a client accepts (`client_*`) and what a server + /// presents (`server_*`). + net::client_security client{}; + net::server_security server{}; + + protocol::drive_options drive() const + { + protocol::drive_options o; + o.n_lanes = n_lanes; + o.framing = framing; + o.pipeline_credit = pipeline_credit; + o.wait_timeout = wait_timeout; + return o; + } + + void set(const std::string & key, const std::string & v) + { + if (key == "transport") + kind = net::parse_transport(v); + else if (key == "host") + host = v; + else if (key == "lanes") + n_lanes = v == "per_round" ? net::lanes_one_per_round : num(key, v); + else if (key == "framing") + framing = net::parse_framing(v); + else if (key == "instances") + instances = positive(key, v); + else if (key == "window") + policy.window_bytes = num(key, v); + else if (key == "max_frame") + policy.max_frame = positive(key, v); + else if (key == "chunk") + policy.chunk_bytes = num(key, v); + else if (key == "coalesce_frames") + policy.coalesce_frames = positive(key, v); + else if (key == "coalesce_bytes") + policy.coalesce_bytes = num(key, v); + else if (key == "compact") + policy.compact_bytes = num(key, v); + else if (key == "nodelay") + policy.socket.no_delay = flag(key, v); + else if (key == "quickack") + policy.socket.quickack = flag(key, v); + else if (key == "keepalive") + policy.socket.keepalive = flag(key, v); + else if (key == "keepalive_idle") + policy.socket.keepalive_idle_s = static_cast(num(key, v)); + else if (key == "keepalive_interval") + policy.socket.keepalive_interval_s = static_cast(num(key, v)); + else if (key == "keepalive_count") + policy.socket.keepalive_count = static_cast(num(key, v)); + else if (key == "sndbuf") + policy.socket.send_buffer = static_cast(num(key, v)); + else if (key == "rcvbuf") + policy.socket.recv_buffer = static_cast(num(key, v)); + else if (key == "pipeline") + pipeline_credit = num(key, v); + else if (key == "wait_ms") + wait_timeout = std::chrono::milliseconds(num(key, v)); + else if (key == "compute_threads") + compute_threads = num(key, v); + else if (key == "warmup") + warmup = num(key, v); + else if (key == "trials") + trials = positive(key, v); + else if (key == "cpu0" || key == "cpu1" || key == "cpu2") + cpu[key[3] - '0'] = v == "-1" ? -1 : static_cast(num(key, v)); + else if (key == "connect_ms") + limits.connect = std::chrono::milliseconds(num(key, v)); + else if (key == "accept_ms") + limits.accept = std::chrono::milliseconds(num(key, v)); + else if (key == "join_ms") + limits.join = std::chrono::milliseconds(num(key, v)); + else if (key == "handshake_ms") + limits.handshake = std::chrono::milliseconds(num(key, v)); + else if (key == "log_level") + log_level = log::parse_level(v); + else if (key == "log") + log_sinks = v; + else if (key == "log_seeds") + log_seeds = log::parse_seed_policy(v); + else if (key == "config") + load_file(v); + else if (key == "encryption") + security.encrypt = flag(key, v); + else if (key == "identity") + security.self = load_identity(key, v); + else if (key.rfind("peer.", 0) == 0) + security.trusted[party_index(key)] = parse_key(key, v); + else if (key == "dealer_key") + security.trusted[net::dealer_id] = parse_key(key, v); + else if (key == "client_verify") + client.verify = flag(key, v); + else if (key == "client_pin") + client.pins = parse_keys(key, v); + else if (key == "client_ca") + client.ca_file = v; + else if (key == "client_server_name") + client.server_name = v; + else if (key == "client_identity") + client.self = load_identity(key, v); + else if (key == "server_cert") + server.cert_file = v; + else if (key == "server_key") + server.key_file = v; + else if (key == "server_identity") + server.self = load_identity(key, v); + else if (key == "server_client_pin") + server.client_pins = parse_keys(key, v); + else + throw std::invalid_argument("run_config: unknown key '" + key + "'"); + policy.validate(); + } + + /// @brief `DPF_` for every key (`DPF_WIRE_WINDOW` for `window`; + /// `DPF_LANES=0` keeps its old meaning, one stream per round). + static run_config from_env() + { + run_config c; + c.merge_env(); + return c; + } + + void merge_env() + { + static const char * const keys[] = {"config", "encryption", "identity", + "transport", "host", "lanes", + "framing", "instances", "window", "max_frame", "chunk", + "coalesce_frames", "coalesce_bytes", "compact", "nodelay", "quickack", + "keepalive", "keepalive_idle", "keepalive_interval", "keepalive_count", + "sndbuf", "rcvbuf", "pipeline", "wait_ms", "compute_threads", + "warmup", "trials", "cpu0", "cpu1", "cpu2", "connect_ms", "accept_ms", + "join_ms", "handshake_ms", "log_level", "log", "log_seeds"}; + for (const char * k : keys) + { + std::string env = "DPF_"; + for (const char * p = k; *p != '\0'; ++p) + env += static_cast(*p >= 'a' && *p <= 'z' ? *p - 32 : *p); + if (std::string(k) == "window") + env = "DPF_WIRE_WINDOW"; + const char * v = std::getenv(env.c_str()); + if (v == nullptr || v[0] == '\0') + continue; + if (std::string(k) == "lanes" && std::string(v) == "0") + { + n_lanes = net::lanes_one_per_round; + continue; + } + set(k, v); + } + } + + /// @brief Apply `--key=value` arguments; returns the arguments it did not + /// recognise as `--key=value` (e.g. positional ones). + std::vector apply_args(int argc, char ** argv) + { + std::vector rest; + for (int i = 1; i < argc; ++i) + { + const std::string a = argv[i]; + const auto eq = a.find('='); + if (a.rfind("--", 0) != 0 || eq == std::string::npos) + { + rest.push_back(a); + continue; + } + const std::string key = a.substr(2, eq - 2); + if (key == "party" || key == "peers" || key == "dealer") + { + rest.push_back(a); + continue; + } + set(key, a.substr(eq + 1)); + } + return rest; + } + + /// @brief Every setting as text, for `config.csv` and bench output. + std::vector> describe() const + { + std::vector> kv; + kv.emplace_back("transport", net::transport_name(kind)); + kv.emplace_back("host", host); + kv.emplace_back("lanes", n_lanes == net::lanes_one_per_round + ? std::string("per_round") + : std::to_string(n_lanes == 0 ? net::default_lanes : n_lanes)); + kv.emplace_back("framing", net::framing_name(framing)); + kv.emplace_back("instances", std::to_string(instances)); + kv.emplace_back("window", std::to_string(policy.window_bytes)); + kv.emplace_back("max_frame", std::to_string(policy.max_frame)); + kv.emplace_back("chunk", std::to_string(policy.chunk_bytes)); + kv.emplace_back("coalesce_frames", std::to_string(policy.coalesce_frames)); + kv.emplace_back("coalesce_bytes", std::to_string(policy.coalesce_bytes)); + kv.emplace_back("compact", std::to_string(policy.compact_bytes)); + kv.emplace_back("nodelay", policy.socket.no_delay ? "1" : "0"); + kv.emplace_back("quickack", policy.socket.quickack ? "1" : "0"); + kv.emplace_back("keepalive", policy.socket.keepalive ? "1" : "0"); + kv.emplace_back("keepalive_idle", std::to_string(policy.socket.keepalive_idle_s)); + kv.emplace_back("keepalive_interval", + std::to_string(policy.socket.keepalive_interval_s)); + kv.emplace_back("keepalive_count", std::to_string(policy.socket.keepalive_count)); + kv.emplace_back("sndbuf", std::to_string(policy.socket.send_buffer)); + kv.emplace_back("rcvbuf", std::to_string(policy.socket.recv_buffer)); + kv.emplace_back("pipeline", std::to_string(pipeline_credit)); + kv.emplace_back("wait_ms", std::to_string(wait_timeout.count())); + kv.emplace_back("compute_threads", std::to_string(compute_threads)); + kv.emplace_back("warmup", std::to_string(warmup)); + kv.emplace_back("trials", std::to_string(trials)); + kv.emplace_back("cpu0", std::to_string(cpu[0])); + kv.emplace_back("cpu1", std::to_string(cpu[1])); + kv.emplace_back("cpu2", std::to_string(cpu[2])); + kv.emplace_back("connect_ms", std::to_string(limits.connect.count())); + kv.emplace_back("accept_ms", std::to_string(limits.accept.count())); + kv.emplace_back("join_ms", std::to_string(limits.join.count())); + kv.emplace_back("handshake_ms", std::to_string(limits.handshake.count())); + kv.emplace_back("log_level", log::level_name(log_level)); + kv.emplace_back("log", log_sinks); + kv.emplace_back("log_seeds", log::seed_policy_name(log_seeds)); + kv.emplace_back("encryption", security.encrypt ? "on" : "off"); + kv.emplace_back("identity", + security.self ? security.self->key().base64() : std::string("ephemeral")); + std::string trusted; + for (const auto & t : security.trusted) + trusted += (trusted.empty() ? "" : ",") + + (t.first == net::dealer_id ? std::string("dealer") + : std::to_string(t.first)); + kv.emplace_back("trusted", trusted.empty() ? std::string("none") : trusted); + kv.emplace_back("client_verify", client.verify ? "on" : "off"); + kv.emplace_back("client_pins", std::to_string(client.pins.size())); + kv.emplace_back("client_ca", client.ca_file.empty() ? std::string("none") + : client.ca_file); + kv.emplace_back("server_cert", !server.cert_file.empty() ? server.cert_file + : server.self ? std::string("identity") + : std::string("development")); + return kv; + } + + /// @brief One line: `key=value key=value ...`. + std::string summary() const + { + std::string out; + for (const auto & kv : describe()) + { + if (!out.empty()) + out += ' '; + out += kv.first + "=" + kv.second; + } + return out; + } + + /// @brief Apply `key = value` lines from `path` through `set`. `#` starts + /// a comment; relative paths in the file resolve against its + /// directory. Errors name the file and line. + void load_file(const std::string & path) + { + std::ifstream in(path); + if (!in) + throw std::invalid_argument("run_config: cannot read config '" + path + "'"); + const auto slash = path.find_last_of('/'); + const std::string dir = slash == std::string::npos ? std::string() + : path.substr(0, slash); + std::string line; + std::size_t lineno = 0; + while (std::getline(in, line)) + { + ++lineno; + const auto hash = line.find('#'); + if (hash != std::string::npos) + line.erase(hash); + line = trim(line); + if (line.empty()) + continue; + const auto eq = line.find('='); + const std::string where = path + ":" + std::to_string(lineno) + ": "; + if (eq == std::string::npos) + throw std::invalid_argument("run_config: " + where + + "expected key = value, got '" + line + "'"); + const std::string key = trim(line.substr(0, eq)); + const std::string value = trim(line.substr(eq + 1)); + if (key == "config") + throw std::invalid_argument("run_config: " + where + + "a config file cannot include another"); + try + { + set(key, resolve(dir, key, value)); + } + catch (const std::exception & e) + { + throw std::invalid_argument(where + e.what()); + } + } + } + +private: + static std::string trim(const std::string & s) + { + std::size_t b = 0; + std::size_t e = s.size(); + while (b < e && (s[b] == ' ' || s[b] == '\t' || s[b] == '\r')) + ++b; + while (e > b && (s[e - 1] == ' ' || s[e - 1] == '\t' || s[e - 1] == '\r')) + --e; + return s.substr(b, e - b); + } + + /// @brief Make paths in a config file relative to the file. + static std::string resolve(const std::string & dir, const std::string & key, + const std::string & value) + { + if (dir.empty() || value.empty()) + return value; + auto rel = [&](const std::string & p) { + return p.empty() || p[0] == '/' ? p : dir + "/" + p; + }; + const bool path_key = key == "identity" || key == "client_identity" + || key == "server_identity" || key == "server_cert" || key == "server_key" + || (key == "client_ca" && value != "system"); + if (path_key) + return rel(value); + const bool key_list = key.rfind("peer.", 0) == 0 || key == "dealer_key" + || key == "client_pin" || key == "server_client_pin"; + if (!key_list) + return value; + std::string out; + std::size_t start = 0; + while (start <= value.size()) + { + const auto comma = value.find(',', start); + std::string item = trim(value.substr(start, + comma == std::string::npos ? std::string::npos : comma - start)); + if (item.rfind("file:", 0) == 0) + item = "file:" + rel(item.substr(5)); + out += (out.empty() ? "" : ",") + item; + if (comma == std::string::npos) + break; + start = comma + 1; + } + return out; + } + + static std::uint32_t party_index(const std::string & key) + { + return static_cast(num(key, key.substr(5))); + } + + static net::public_key parse_key(const std::string & key, const std::string & v) + { + try + { + return net::public_key::parse(v); + } + catch (const std::exception & e) + { + throw std::invalid_argument("run_config: " + key + ": " + e.what()); + } + } + + static std::vector parse_keys(const std::string & key, + const std::string & v) + { + std::vector out; + std::size_t start = 0; + while (start <= v.size()) + { + const auto comma = v.find(',', start); + const std::string item = trim(v.substr(start, + comma == std::string::npos ? std::string::npos : comma - start)); + if (!item.empty()) + out.push_back(parse_key(key, item)); + if (comma == std::string::npos) + break; + start = comma + 1; + } + return out; + } + + static std::shared_ptr load_identity(const std::string & key, + const std::string & path) + { + try + { + return std::make_shared(net::identity::load(path)); + } + catch (const std::exception & e) + { + throw std::invalid_argument("run_config: " + key + ": " + e.what()); + } + } + + static std::size_t num(const std::string & key, const std::string & v) + { + std::size_t pos = 0; + unsigned long long x = 0; + try + { + x = std::stoull(v, &pos, 10); + } + catch (const std::exception &) + { + pos = 0; + } + if (pos != v.size() || v.empty()) + throw std::invalid_argument("run_config: " + key + + " needs a number, got '" + v + "'"); + return static_cast(x); + } + + static std::size_t positive(const std::string & key, const std::string & v) + { + const auto x = num(key, v); + if (x == 0) + throw std::invalid_argument("run_config: " + key + " must be > 0"); + return x; + } + + static bool flag(const std::string & key, const std::string & v) + { + if (v == "1" || v == "on" || v == "true") + return true; + if (v == "0" || v == "off" || v == "false") + return false; + throw std::invalid_argument("run_config: " + key + " needs 0/1, got '" + + v + "'"); + } +}; + +} // namespace app +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_RUN_CONFIG_HPP__ diff --git a/include/dpf/run_log.hpp b/include/dpf/run_log.hpp new file mode 100644 index 0000000..4bf329a --- /dev/null +++ b/include/dpf/run_log.hpp @@ -0,0 +1,512 @@ +/// @file dpf/run_log.hpp +/// @brief Configure the run log from a `run_config` and write the provenance +/// banner: build, host, command line, environment, configuration, time. +/// @details `app::start_logging(cfg)` applies `cfg.log_level`, `cfg.log_sinks`, +/// and `cfg.log_seeds` (see `dpf/log.hpp`), then writes these records +/// once per process, at `info`: +/// +/// - `ev=start`: program, executable, working directory, start time +/// (UTC and local with its offset), and the invocation id that +/// every later record and `runs.csv` row carries. +/// - `ev=build`: git revision (`LIBDPF_GIT_REV`, captured when the +/// build was configured; `unknown` for a bare compiler line), +/// compiler, language level, whether the build is optimized, +/// `NDEBUG`, the instruction-set extensions it targets, the entropy +/// source, and sanitizers. +/// - `ev=host`: hostname, kernel, machine, CPU model, online CPUs, +/// this process's CPU affinity, SMT, frequency governor, turbo, +/// memory, and load average. `ev=if` for each interface address +/// (link-local IPv6 skipped): name, address, MTU, and link speed. +/// - `ev=argv`: the command line, shell-quoted so it can be pasted. +/// - `ev=env`: each `DPF_*` and `LIBDPF_*` variable, and the few +/// others that change performance (`LD_PRELOAD`, `GLIBC_TUNABLES`, +/// allocator and sanitizer options). A name containing `SEED`, +/// `KEY`, `SECRET`, `TOKEN`, or `PASS` is printed under `log_seeds`. +/// - `ev=config`: every `run_config` setting. +/// +/// A later call reapplies the sinks, and writes `ev=config` again only +/// when a setting changed. `ev=end` at exit gives the elapsed time. +#ifndef LIBDPF_INCLUDE_DPF_RUN_LOG_HPP__ +#define LIBDPF_INCLUDE_DPF_RUN_LOG_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if defined(__linux__) +#include +#include +#include +#include +#include +#include +#endif + +#include "dpf/log.hpp" +#include "dpf/run_config.hpp" + +#ifndef LIBDPF_GIT_REV +#define LIBDPF_GIT_REV "unknown" +#endif + +extern char ** environ; + +namespace dpf +{ +namespace app +{ + +inline log::settings log_settings(const run_config & cfg) +{ + log::settings s; + s.threshold = cfg.log_level; + s.sinks = cfg.log_sinks; + s.seeds = cfg.log_seeds; + return s; +} + +namespace log_detail +{ + +inline std::string first_line(const std::string & path) +{ + std::ifstream in(path); + std::string line; + if (in) + std::getline(in, line); + return line; +} + +inline std::string shell_quote(const std::string & s) +{ + if (s.empty()) + return "''"; + bool plain = true; + for (char c : s) + { + const bool ok = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') + || (c >= '0' && c <= '9') || std::strchr("_-./:=,+@%", c) != nullptr; + plain = plain && ok; + } + if (plain) + return s; + std::string out = "'"; + for (char c : s) + { + if (c == '\'') + out += "'\\''"; + else + out += c; + } + out += '\''; + return out; +} + +/// @brief The command line from `/proc/self/cmdline` (no `argv` needed). +inline std::vector command_line() +{ + std::vector args; +#if defined(__linux__) + std::ifstream in("/proc/self/cmdline", std::ios::binary); + std::string arg; + char c = 0; + while (in.get(c)) + { + if (c == '\0') + { + args.push_back(arg); + arg.clear(); + } + else + arg += c; + } + if (!arg.empty()) + args.push_back(arg); +#endif + return args; +} + +inline std::string exe_path() +{ +#if defined(__linux__) + char buf[4096]; + const ssize_t n = ::readlink("/proc/self/exe", buf, sizeof(buf) - 1); + if (n > 0) + return std::string(buf, static_cast(n)); +#endif + return "unknown"; +} + +inline std::string cwd() +{ + char buf[4096]; + return ::getcwd(buf, sizeof(buf)) != nullptr ? std::string(buf) : std::string("unknown"); +} + +inline std::string local_time(std::time_t t) +{ + std::tm tm{}; + ::localtime_r(&t, &tm); + char buf[80]; + if (std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z %z", &tm) == 0) + return "unknown"; + return buf; +} + +inline std::string isa() +{ + std::string out; + auto add = [&out](const char * name) { + if (!out.empty()) + out += ','; + out += name; + }; +#if defined(__SSE4_2__) + add("sse4.2"); +#endif +#if defined(__AES__) + add("aes"); +#endif +#if defined(__PCLMUL__) + add("pclmul"); +#endif +#if defined(__AVX2__) + add("avx2"); +#endif +#if defined(__AVX512F__) + add("avx512f"); +#endif +#if defined(__VAES__) + add("vaes"); +#endif +#if defined(__VPCLMULQDQ__) + add("vpclmulqdq"); +#endif +#if defined(__BMI2__) + add("bmi2"); +#endif +#if defined(__ARM_NEON) + add("neon"); +#endif +#if defined(__ARM_FEATURE_CRYPTO) || defined(__ARM_FEATURE_AES) + add("armv8-crypto"); +#endif + return out.empty() ? std::string("baseline") : out; +} + +inline const char * entropy_source() noexcept +{ +#if defined(LIBDPF_USE_ARC4RANDOM) + return "arc4random"; +#elif defined(LIBDPF_USE_DEV_RANDOM) + return "/dev/random"; +#else + return "/dev/urandom"; +#endif +} + +inline std::string sanitizers() +{ + std::string out; +#if defined(__SANITIZE_ADDRESS__) + out += "address"; +#endif +#if defined(__SANITIZE_THREAD__) + out += out.empty() ? "thread" : ",thread"; +#endif +#if defined(__has_feature) +#if __has_feature(address_sanitizer) && !defined(__SANITIZE_ADDRESS__) + out += out.empty() ? "address" : ",address"; +#endif +#if __has_feature(thread_sanitizer) && !defined(__SANITIZE_THREAD__) + out += out.empty() ? "thread" : ",thread"; +#endif +#if __has_feature(undefined_behavior_sanitizer) + out += out.empty() ? "undefined" : ",undefined"; +#endif +#endif + return out.empty() ? std::string("none") : out; +} + +inline std::string cpu_model() +{ +#if defined(__linux__) + std::ifstream in("/proc/cpuinfo"); + std::string line; + while (std::getline(in, line)) + { + if (line.rfind("model name", 0) == 0 || line.rfind("Model", 0) == 0 + || line.rfind("Hardware", 0) == 0) + { + const auto colon = line.find(':'); + if (colon != std::string::npos) + { + auto v = line.substr(colon + 1); + while (!v.empty() && v.front() == ' ') + v.erase(v.begin()); + return v; + } + } + } +#endif + return "unknown"; +} + +inline std::string affinity() +{ +#if defined(__linux__) + cpu_set_t set; + CPU_ZERO(&set); + if (::sched_getaffinity(0, sizeof(set), &set) != 0) + return "unknown"; + std::string out; + int run_start = -1; + for (int c = 0; c <= CPU_SETSIZE; ++c) + { + const bool in = c < CPU_SETSIZE && CPU_ISSET(c, &set); + if (in && run_start < 0) + run_start = c; + if (!in && run_start >= 0) + { + if (!out.empty()) + out += ','; + out += std::to_string(run_start); + if (c - 1 > run_start) + out += "-" + std::to_string(c - 1); + run_start = -1; + } + } + return out; +#else + return "unknown"; +#endif +} + +inline std::string turbo() +{ + const auto no_turbo = first_line("/sys/devices/system/cpu/intel_pstate/no_turbo"); + if (!no_turbo.empty()) + return no_turbo == "0" ? "on" : "off"; + const auto boost = first_line("/sys/devices/system/cpu/cpufreq/boost"); + if (!boost.empty()) + return boost == "1" ? "on" : "off"; + return "unknown"; +} + +inline std::string or_unknown(std::string s) +{ + return s.empty() ? std::string("unknown") : s; +} + +inline bool secret_name(const std::string & name) +{ + for (const char * w : {"SEED", "KEY", "SECRET", "TOKEN", "PASS"}) + if (name.find(w) != std::string::npos) + return true; + return false; +} + +inline bool relevant_env(const std::string & name) +{ + if (name.rfind("DPF_", 0) == 0 || name.rfind("LIBDPF_", 0) == 0) + return true; + for (const char * n : {"LD_PRELOAD", "LD_LIBRARY_PATH", "GLIBC_TUNABLES", + "MALLOC_ARENA_MAX", "MALLOC_CONF", "ASAN_OPTIONS", "UBSAN_OPTIONS", + "TSAN_OPTIONS", "OMP_NUM_THREADS", "TZ"}) + if (name == n) + return true; + return false; +} + +struct banner_state +{ + std::mutex mu; + bool written = false; + std::string last_config; + std::chrono::steady_clock::time_point started{}; +}; + +inline banner_state & banner() +{ + static banner_state b; + return b; +} + +inline void log_config(const run_config & cfg) +{ + auto rec = log::record(log::level::info, "config"); + for (const auto & kv : cfg.describe()) + rec.kv(kv.first.c_str(), kv.second); +} + +inline void at_exit() +{ + const auto elapsed = std::chrono::steady_clock::now() - banner().started; + DPF_LOG(info, "end").kv("elapsed_ms", + std::chrono::duration(elapsed).count()); +} + +inline void write_banner(const run_config & cfg) +{ + const auto now = std::chrono::system_clock::now(); + const auto args = command_line(); + DPF_LOG(info, "start") + .kv("program", args.empty() ? std::string("unknown") : args.front()) + .kv("exe", exe_path()).kv("cwd", cwd()) + .kv("utc", log::detail::utc_text(now)) + .kv("local", local_time(std::chrono::system_clock::to_time_t(now))) + .kv("epoch_ns", static_cast( + std::chrono::duration_cast( + now.time_since_epoch()).count())) + .kv("ppid", static_cast(::getppid())); + +#if defined(NDEBUG) + const bool ndebug = true; +#else + const bool ndebug = false; +#endif +#if defined(__OPTIMIZE__) + const bool optimized = true; +#else + const bool optimized = false; +#endif +#if defined(__clang__) + const std::string compiler = std::string("clang ") + __clang_version__; +#elif defined(__GNUC__) + const std::string compiler = std::string("gcc ") + __VERSION__; +#elif defined(__VERSION__) + const std::string compiler = __VERSION__; +#else + const std::string compiler = "unknown"; +#endif + DPF_LOG(info, "build").kv("rev", LIBDPF_GIT_REV).kv("compiler", compiler) + .kv("cxx", static_cast(__cplusplus)).kv("optimized", optimized) + .kv("ndebug", ndebug).kv("isa", isa()).kv("entropy", entropy_source()) + .kv("sanitizers", sanitizers()).kv("compiled", __DATE__ " " __TIME__); + +#if defined(__linux__) + struct utsname u{}; + const bool have_uname = ::uname(&u) == 0; + char host[256] = {}; + (void)::gethostname(host, sizeof(host) - 1); + double load[3] = {0, 0, 0}; + const int nload = ::getloadavg(load, 3); + const long pages = ::sysconf(_SC_PHYS_PAGES); + const long page = ::sysconf(_SC_PAGESIZE); + DPF_LOG(info, "host").kv("hostname", host) + .kv("kernel", have_uname ? std::string(u.sysname) + " " + u.release + : std::string("unknown")) + .kv("machine", have_uname ? std::string(u.machine) : std::string("unknown")) + .kv("cpu", cpu_model()) + .kv("cpus_online", static_cast(::sysconf(_SC_NPROCESSORS_ONLN))) + .kv("affinity", affinity()) + .kv("smt", or_unknown(first_line("/sys/devices/system/cpu/smt/active"))) + .kv("governor", or_unknown(first_line( + "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"))) + .kv("turbo", turbo()) + .kv("mem_mib", pages > 0 && page > 0 + ? static_cast(pages) * page / (1024 * 1024) : 0LL) + .kv("load1", nload > 0 ? load[0] : -1.0); + + ifaddrs * ifs = nullptr; + if (::getifaddrs(&ifs) == 0) + { + for (auto * a = ifs; a != nullptr; a = a->ifa_next) + { + if (a->ifa_addr == nullptr) + continue; + const int fam = a->ifa_addr->sa_family; + if (fam != AF_INET && fam != AF_INET6) + continue; + if (fam == AF_INET6 && IN6_IS_ADDR_LINKLOCAL( + &reinterpret_cast(a->ifa_addr)->sin6_addr)) + continue; + char text[INET6_ADDRSTRLEN] = {}; + const void * src = fam == AF_INET + ? static_cast( + &reinterpret_cast(a->ifa_addr)->sin_addr) + : static_cast( + &reinterpret_cast(a->ifa_addr)->sin6_addr); + if (::inet_ntop(fam, src, text, sizeof(text)) == nullptr) + continue; + const std::string name = a->ifa_name == nullptr ? "" : a->ifa_name; + DPF_LOG(info, "if").kv("name", name).kv("addr", text) + .kv("up", (a->ifa_flags & IFF_UP) != 0) + .kv("loopback", (a->ifa_flags & IFF_LOOPBACK) != 0) + .kv("mtu", or_unknown(first_line("/sys/class/net/" + name + "/mtu"))) + .kv("speed_mbps", + or_unknown(first_line("/sys/class/net/" + name + "/speed"))); + } + ::freeifaddrs(ifs); + } +#endif + + std::string joined; + for (const auto & a : args) + { + if (!joined.empty()) + joined += ' '; + joined += shell_quote(a); + } + DPF_LOG(info, "argv").kv("argc", args.size()).kv("cmdline", joined); + + std::vector> env; + for (char ** e = environ; e != nullptr && *e != nullptr; ++e) + { + const std::string entry = *e; + const auto eq = entry.find('='); + if (eq == std::string::npos) + continue; + auto name = entry.substr(0, eq); + if (relevant_env(name)) + env.emplace_back(std::move(name), entry.substr(eq + 1)); + } + DPF_LOG(info, "env").kv("relevant", env.size()); + for (const auto & kv : env) + { + if (secret_name(kv.first)) + DPF_LOG(info, "env").kv("name", kv.first) + .seed("value", kv.second.data(), kv.second.size()); + else + DPF_LOG(info, "env").kv("name", kv.first).kv("value", kv.second); + } + DPF_LOG(info, "log").kv("level", log::level_name(cfg.log_level)) + .kv("sinks", cfg.log_sinks).kv("seeds", log::seed_policy_name(cfg.log_seeds)); +} + +} // namespace log_detail + +/// @brief Apply `cfg`'s log settings and write the provenance banner once. +inline void start_logging(const run_config & cfg) +{ + log::configure(log_settings(cfg)); + auto & b = log_detail::banner(); + std::lock_guard lock(b.mu); + const auto summary = cfg.summary(); + if (!b.written) + { + b.written = true; + b.started = std::chrono::steady_clock::now(); + log_detail::write_banner(cfg); + std::atexit(&log_detail::at_exit); + } + if (summary != b.last_config && log::enabled(log::level::info)) + { + b.last_config = summary; + log_detail::log_config(cfg); + } +} + +} // namespace app +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_RUN_LOG_HPP__ diff --git a/include/dpf/schedule_streams.hpp b/include/dpf/schedule_streams.hpp new file mode 100644 index 0000000..34f2ce9 --- /dev/null +++ b/include/dpf/schedule_streams.hpp @@ -0,0 +1,70 @@ +/// @file dpf/schedule_streams.hpp +/// @brief Run a `schedule_session` over a `stream_array` peer transport. +/// @details Builds a multi-round `stream_array_sink` from the schedule's slot +/// widths so existing `plan_to_schedule` / compose plans can drive +/// without a memory RoundSink. Prefer `drive_plan_on_streams` / +/// `drive_both_on_streams` in `compose.hpp` for full plans (they call +/// `drive_via_schedule`). Dealer pads still come from a +/// `dealer_cursor` or a separate dealer `stream_array`. +#ifndef LIBDPF_INCLUDE_DPF_SCHEDULE_STREAMS_HPP__ +#define LIBDPF_INCLUDE_DPF_SCHEDULE_STREAMS_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/net/stream_array.hpp" +#include "dpf/protocol.hpp" + +namespace dpf +{ +namespace protocol +{ + +/// @brief Slot widths for one stream index per schedule round. +HEDLEY_WARN_UNUSED_RESULT +inline std::vector slot_bytes_of( + const std::vector & rounds) +{ + std::vector out; + out.reserve(rounds.size()); + for (const auto & r : rounds) + out.push_back(r.slot_bytes); + return out; +} + +/// @brief Owning peer sink + schedule session for stream-array transport. +/// @details Requires `streams.size() >= rounds.size()`. +struct owning_schedule_on_streams +{ + std::unique_ptr sink; + schedule_session session; + + owning_schedule_on_streams(std::size_t count, net::stream_array & streams, + std::vector rounds) + : sink(std::make_unique(streams, + slot_bytes_of(rounds), count)), + session(count, *sink, std::move(rounds)) + { + } + + void submit(std::size_t index) { session.submit(index); } + void drive() { session.drive(); } +}; + +HEDLEY_WARN_UNUSED_RESULT +inline owning_schedule_on_streams make_owning_schedule_on_streams( + std::size_t count, net::stream_array & streams, + std::vector rounds) +{ + return owning_schedule_on_streams(count, streams, std::move(rounds)); +} + +} // namespace protocol +} // namespace dpf + +#endif diff --git a/include/dpf/secret_share.hpp b/include/dpf/secret_share.hpp index 02acd3a..2ebd54f 100644 --- a/include/dpf/secret_share.hpp +++ b/include/dpf/secret_share.hpp @@ -1,10 +1,16 @@ /// @file dpf/secret_share.hpp -/// @brief Thin (2,2) additive and subtractive secret-share wrappers. -/// @details Layout-identical to `T`. Party is a compile-time `0` or `1`. -/// Reconstruction: additive opens by sum, subtractive by -/// `share0 - share1`. Linear combinations of same-party shares are -/// supported; mixing additive with subtractive applies the correct -/// party coefficient. A plaintext absorbs on party 0 only. +/// @brief Thin secret-share wrappers. +/// @details (2,2)-additive and (2,2)-subtractive shares, and (3,3)-additive +/// shares, are layout-identical to `T`. A (2,3)-replicated share +/// holds two components of a (3,3)-additive sharing: party `i` +/// stores `(x_i, x_{i+1 mod 3})`. +/// Reconstruction: (2,2)-additive opens by sum, (2,2)-subtractive by +/// `share0 - share1`, (3,3)-additive by the sum of all three shares, +/// and (2,3)-replicated from any two parties. +/// Linear combinations of same-party, same-scheme shares are local. +/// Mixing (2,2)-additive with (2,2)-subtractive applies the party +/// coefficient. A public plaintext absorbs on party 0 for a one-word +/// share, and into component `x_0` for a replicated share. /// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license; /// see [LICENSE.md](@ref license) for details. @@ -12,15 +18,20 @@ #ifndef LIBDPF_INCLUDE_DPF_SECRET_SHARE_HPP__ #define LIBDPF_INCLUDE_DPF_SECRET_SHARE_HPP__ +#include #include #include #include +#include #include +#include +#include #include #include #include "hedley/hedley.h" +#include "dpf/shamir.hpp" #include "dpf/twiddle.hpp" namespace dpf @@ -29,8 +40,23 @@ namespace dpf /// @brief Sharing scheme tag. enum class sharing : unsigned char { + /// (2,2) additive: `s = s0 + s1`. additive = 0, - subtractive = 1 + /// (2,2) subtractive: `s = s0 - s1`. + subtractive = 1, + /// (3,3) additive: `s = s0 + s1 + s2`. Every share is required. + additive3 = 2, + /// (2,3) replicated: party `i` holds `(x_i, x_{i+1 mod 3})` with + /// `s = x0 + x1 + x2`. Any two parties reconstruct. + replicated = 3, + /// (2,2) FSS leaf share. Opens like subtractive (`s0 - s1`). The distinct + /// tag is the evaluator's leaf output, not a generic subtractive word. + fss = 4, + /// (2,3) Shamir, `shamir::two_of_three`. Party `i` holds `s + slope·(i+1)` + /// in a field. Any two parties reconstruct by Lagrange. Points are `1`, + /// `2`, and `3`. This is `shamir::share`. Other thresholds + /// use `shamir::share`. + shamir = 5 }; template @@ -42,6 +68,36 @@ using additive_share = secret_share; template using subtractive_share = secret_share; +template +using additive3_share = secret_share; + +template +using replicated_share = secret_share; + +template +using fss_share = secret_share; + +template +using shamir_share = secret_share; + +/// @brief `true` for (2,2) additive, subtractive, and FSS leaf shares. +template +inline constexpr bool is_two_party_sharing_v = + Scheme == sharing::additive || Scheme == sharing::subtractive + || Scheme == sharing::fss; + +/// @brief Parties who hold a share of `Scheme`. +template +inline constexpr std::size_t sharing_parties_v = + is_two_party_sharing_v ? 2 : 3; + +/// @brief Shares required to open `Scheme`. +template +inline constexpr std::size_t sharing_threshold_v = + (Scheme == sharing::replicated || Scheme == sharing::shamir) + ? 2 + : sharing_parties_v; + template struct is_secret_share : std::false_type { @@ -94,26 +150,18 @@ using share_value_type_t = typename share_value_type>::type; namespace detail { -/// @brief Party coefficient of the secret for this scheme: additive always +1; -/// subtractive is +1 for party 0 and −1 for party 1. -/// @tparam Scheme scheme -/// @tparam Party party index, `0` or `1` +/// @brief Two's-complement negation. Signed minimum stays defined. /// @tparam T value type /// @param v the `v` -/// @return Party coefficient of the secret for this scheme: additive always +1; subtractive is +1 -/// for party 0 and −1 for party 1 -template +/// @return the group negation used by a (2,2) sign flip +template HEDLEY_ALWAYS_INLINE HEDLEY_PURE HEDLEY_NO_THROW -constexpr T party_coeff_times(const T & v) noexcept +constexpr T negate_word(const T & v) noexcept { - if constexpr (Scheme == sharing::additive || Party == 0) - return v; - else if constexpr (std::is_integral_v && std::is_signed_v) + if constexpr (std::is_integral_v && std::is_signed_v) { - // 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; return static_cast(static_cast(0) - static_cast(v)); @@ -122,13 +170,136 @@ constexpr T party_coeff_times(const T & v) noexcept return static_cast(-v); } +/// @brief Group sum. IEEE `float` / `double` add by XOR of the bits, matching +/// the leaf group. Signed integers add in the unsigned width. +/// @tparam T value type +/// @param a left addend +/// @param b right addend +/// @return `a` plus `b` in the share group +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr T group_add(const T & a, const T & b) noexcept +{ + if constexpr (std::is_same_v || std::is_same_v) + { + using bits_t = std::conditional_t; + bits_t xa{}, xb{}; + std::memcpy(&xa, std::addressof(a), sizeof(T)); + std::memcpy(&xb, std::addressof(b), sizeof(T)); + bits_t xc = static_cast(xa ^ xb); + T out{}; + std::memcpy(&out, &xc, sizeof(T)); + return out; + } + else if constexpr (std::is_integral_v && std::is_signed_v) + { + using unsigned_type = std::make_unsigned_t; + return static_cast(static_cast(a) + + static_cast(b)); + } + else + return static_cast(a + b); +} + +/// @brief Group difference. IEEE bits subtract by XOR. Signed integers +/// subtract in the unsigned width. +/// @tparam T value type +/// @param a minuend +/// @param b subtrahend +/// @return `a` minus `b` in the share group +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr T group_sub(const T & a, const T & b) noexcept +{ + if constexpr (std::is_same_v || std::is_same_v) + return group_add(a, b); + else if constexpr (std::is_integral_v && std::is_signed_v) + { + using unsigned_type = std::make_unsigned_t; + return static_cast(static_cast(a) + - static_cast(b)); + } + else + return static_cast(a - b); +} + +/// @brief Ring product. IEEE bits use AND, matching `leaf_group_mul`. Signed +/// integers multiply in the unsigned width. +/// @tparam T value type +/// @param a left factor +/// @param b right factor +/// @return `a` times `b` in the share ring +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr T group_mul(const T & a, const T & b) noexcept +{ + if constexpr (std::is_same_v || std::is_same_v) + { + using bits_t = std::conditional_t; + bits_t xa{}, xb{}; + std::memcpy(&xa, std::addressof(a), sizeof(T)); + std::memcpy(&xb, std::addressof(b), sizeof(T)); + bits_t xc = static_cast(xa & xb); + T out{}; + std::memcpy(&out, &xc, sizeof(T)); + return out; + } + else if constexpr (std::is_integral_v && std::is_signed_v) + { + using unsigned_type = std::make_unsigned_t; + return static_cast(static_cast(a) + * static_cast(b)); + } + else + return static_cast(a * b); +} + +/// @brief Sign of a (2,2) party's word. Additive is always +1. Subtractive +/// and FSS are +1 on party 0 and −1 on party 1. +/// @tparam Scheme scheme +/// @tparam Party party index +template +inline constexpr int two_party_sign_v = + (Party == 0 || Scheme == sharing::additive) ? 1 : -1; + +/// @brief Rewrite a (2,2) word from `From` into `To`. Negate iff the signs differ. +/// @tparam From source scheme +/// @tparam To destination scheme +/// @tparam Party party index +/// @tparam T value type +/// @param v the stored word +/// @return the word in `To` +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr T retarget_word(const T & v) noexcept +{ + if constexpr (two_party_sign_v == two_party_sign_v) + return v; + else + return negate_word(v); +} + +// `detail::shamir_field` is the field inverse for Shamir reconstruction. +// The primary template lives in `shamir.hpp`. `fp61` and `gf2n` specialize it. + } // namespace detail template struct secret_share { - static_assert(Party == 0 || Party == 1, - "secret_share party must be 0 or 1"); + static_assert( + (is_two_party_sharing_v && (Party == 0 || Party == 1)) + || (Scheme == sharing::additive3 && Party < 3), + "secret_share: (2,2) parties are 0 or 1; " + "(3,3)-additive parties are 0, 1, or 2"); using value_type = T; static constexpr std::size_t party = Party; @@ -177,11 +348,15 @@ struct secret_share HEDLEY_PURE constexpr additive_share as_additive() const noexcept { + static_assert(is_two_party_sharing_v, + "as_additive converts a (2,2) share; " + "a (3,3) component is already additive, and a replicated share " + "uses as_additive3()"); if constexpr (Scheme == sharing::additive) return additive_share::from_raw(value); - // subtractive → additive: party 0 keeps bits; party 1 negates. + // Subtractive and FSS: party 0 keeps bits; party 1 negates. return additive_share::from_raw( - detail::party_coeff_times(value)); + detail::retarget_word(value)); } /// @brief Secret-preserving conversion to a subtractive share of the same party. @@ -191,11 +366,29 @@ struct secret_share HEDLEY_PURE constexpr subtractive_share as_subtractive() const noexcept { + static_assert(is_two_party_sharing_v, + "as_subtractive converts a (2,2) share"); if constexpr (Scheme == sharing::subtractive) return subtractive_share::from_raw(value); - // additive → subtractive: party 0 keeps bits; party 1 negates. + // Additive party 1 negates. FSS already opens like subtractive. return subtractive_share::from_raw( - detail::party_coeff_times(value)); + detail::retarget_word(value)); + } + + /// @brief Secret-preserving conversion to an FSS leaf share of the same party. + /// @details FSS leaves open like subtractive shares. Additive party 1 negates. + /// @return the FSS share + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + constexpr fss_share as_fss() const noexcept + { + static_assert(is_two_party_sharing_v, + "as_fss converts a (2,2) share"); + if constexpr (Scheme == sharing::fss) + return fss_share::from_raw(value); + return fss_share::from_raw( + detail::retarget_word(value)); } /// @brief Bit-preserving retag (no secret-preserving sign fix). @@ -216,14 +409,7 @@ struct secret_share HEDLEY_PURE constexpr secret_share operator-() const noexcept { - if constexpr (std::is_integral_v && std::is_signed_v) - { - using unsigned_type = std::make_unsigned_t; - return from_raw(static_cast(static_cast(0) - - static_cast(value))); - } - else - return from_raw(static_cast(-value)); + return from_raw(detail::negate_word(value)); } HEDLEY_NO_THROW @@ -282,6 +468,332 @@ struct secret_share } }; +/// @brief (2,3) replicated share. Party `Party` holds `(x_Party, x_{Party+1})`. +/// @details `own` is this party's (3,3) component. `next` is the following +/// party's component, stored here so any two parties hold every +/// component. Local `+`, `-`, and scalar `*` touch both words. +/// A public plaintext is added only to `x_0`: party 0 updates `own`, +/// party 2 updates `next`, party 1 is unchanged. +/// @tparam T value type +/// @tparam Party party index, `0`, `1`, or `2` +template +struct secret_share +{ + static_assert(Party < 3, + "replicated_share party must be 0, 1, or 2"); + + using value_type = T; + static constexpr std::size_t party = Party; + static constexpr sharing scheme = sharing::replicated; + static constexpr std::size_t next_party = (Party + 1) % 3; + + /// Component `x_Party`. + T own{}; + /// Component `x_{Party+1 mod 3}`. + T next{}; + + 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; + + /// @brief Bit-preserving construction. + /// @param own_v component `x_Party` + /// @param next_v component `x_{Party+1 mod 3}` + /// @return the share + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + HEDLEY_CONST + static constexpr secret_share from_raw(T own_v, T next_v) noexcept + { + secret_share s; + s.own = own_v; + s.next = next_v; + return s; + } + + /// @brief Build from this party's (3,3) component and the next party's. + /// @param mine `x_Party` + /// @param nxt `x_{Party+1 mod 3}` + /// @return the replicated share + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + HEDLEY_CONST + static constexpr secret_share from_additive3( + const additive3_share & mine, + const additive3_share & nxt) noexcept + { + return from_raw(mine.raw(), nxt.raw()); + } + + /// @brief This party's underlying (3,3) component (`own`). + /// @return an `additive3_share` of the same party + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + constexpr additive3_share as_additive3() const noexcept + { + return additive3_share::from_raw(own); + } + + /// @brief The next party's (3,3) component, as stored in `next`. + /// @return an `additive3_share` of party `Party + 1 mod 3` + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + constexpr additive3_share next_additive3() const noexcept + { + return additive3_share::from_raw(next); + } + + /// @brief Add `v` into `x_Party`. + /// @details The previous party stores the same component as `next` and + /// must apply the same addend, or the two replicas diverge. + /// `add_replicated` updates both holders. + /// @param v addend in the share group + /// @return `*this` + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr secret_share & add_own(const T & v) noexcept + { + own = detail::group_add(own, v); + return *this; + } + + /// @brief Add `v` into `x_{Party+1}`. + /// @details Party `Party+1` stores that component as `own` and must apply + /// the same addend. + /// @param v addend in the share group + /// @return `*this` + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr secret_share & add_next(const T & v) noexcept + { + next = detail::group_add(next, v); + return *this; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr secret_share operator-() const noexcept + { + return from_raw(detail::negate_word(own), detail::negate_word(next)); + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr secret_share & operator+=(const secret_share & rhs) noexcept + { + own = detail::group_add(own, rhs.own); + next = detail::group_add(next, rhs.next); + return *this; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr secret_share & operator-=(const secret_share & rhs) noexcept + { + own = detail::group_sub(own, rhs.own); + next = detail::group_sub(next, rhs.next); + return *this; + } + + template , int> = 0> + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + constexpr secret_share & operator*=(const Scalar & c) noexcept + { + own = static_cast(own * static_cast(c)); + next = static_cast(next * static_cast(c)); + return *this; + } + + /// @brief Absorb a public plaintext into `x_0` only. + /// @tparam Plain plain + /// @param c the `c` + /// @return `*this` + template + && std::is_convertible_v, int> = 0> + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + constexpr secret_share & operator+=(const Plain & c) noexcept + { + const T addend = static_cast(c); + if constexpr (Party == 0) + own = detail::group_add(own, addend); + else if constexpr (Party == 2) + next = detail::group_add(next, addend); + return *this; + } + + template + && std::is_convertible_v, int> = 0> + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + constexpr secret_share & operator-=(const Plain & c) noexcept + { + const T subtrahend = static_cast(c); + if constexpr (Party == 0) + own = detail::group_sub(own, subtrahend); + else if constexpr (Party == 2) + next = detail::group_sub(next, subtrahend); + return *this; + } +}; + +/// @brief (2,3) Shamir share. Party `Party` holds `s + slope·(Party+1)`. +/// @details This is `shamir::share`, the `shamir::two_of_three` +/// case of `(K,N)` Shamir. The evaluation points are `1`, `2`, and +/// `3`, matching `shamir3::share`. A public plaintext is added on +/// every party, because every evaluation of `s + c` grows by `c`. +/// Scalar multiplication scales the share. Two shares multiply to a +/// degree-2 polynomial, which is not a Shamir share; use `rss_mul` +/// for a (2,3) product. +/// @tparam T field element +/// @tparam Party party index, `0`, `1`, or `2` +template +struct secret_share +{ + static_assert(Party < 3, "shamir_share party must be 0, 1, or 2"); + + using value_type = T; + using access_type = shamir::two_of_three; + static constexpr std::size_t party = Party; + static constexpr sharing scheme = sharing::shamir; + static constexpr std::size_t threshold = access_type::threshold; + static constexpr std::size_t parties = access_type::parties; + static constexpr std::size_t degree = access_type::degree; + /// Lagrange point. Party 0 is point 1. + static constexpr std::uint64_t point = Party + 1; + + 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; + + /// @brief Bit-preserving construction. Does not apply a Lagrange weight. + /// @param v the field element + /// @return the share + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + HEDLEY_CONST + static constexpr secret_share from_raw(T v) noexcept + { + secret_share s; + s.value = v; + 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; } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr secret_share operator-() const noexcept + { + return from_raw(static_cast(-value)); + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr secret_share & operator+=(const secret_share & rhs) noexcept + { + value = static_cast(value + rhs.value); + return *this; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr secret_share & operator-=(const secret_share & rhs) noexcept + { + value = static_cast(value - rhs.value); + return *this; + } + + template , int> = 0> + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + constexpr secret_share & operator*=(const Scalar & c) noexcept + { + value = static_cast(value * static_cast(c)); + return *this; + } + + /// @brief Absorb a public plaintext on every party. + /// @tparam Plain plain + /// @param c the `c` + /// @return `*this` + template + && std::is_convertible_v, int> = 0> + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + constexpr secret_share & operator+=(const Plain & c) noexcept + { + value = static_cast(value + static_cast(c)); + return *this; + } + + template + && std::is_convertible_v, int> = 0> + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + constexpr secret_share & operator-=(const Plain & c) noexcept + { + value = static_cast(value - static_cast(c)); + return *this; + } +}; + +namespace shamir +{ + +/// @brief `(2,3)` is the `sharing::shamir` share, not `basic_share`. +template +struct share_of +{ + using type = secret_share; +}; + +template +struct params> : std::true_type +{ + using value_type = T; + static constexpr std::size_t party = Party; + static constexpr std::size_t threshold = 2; + static constexpr std::size_t parties = 3; + static constexpr std::uint64_t point = + secret_share::point; +}; + +} // namespace shamir + // --------------------------------------------------------------------------- // Same-scheme, same-party arithmetic // --------------------------------------------------------------------------- @@ -335,12 +847,15 @@ constexpr secret_share operator*( } // --------------------------------------------------------------------------- -// Cross-scheme, same-party: keep the left-hand scheme; party 1 flips the -// operand whose scheme differs from the result. +// Cross-scheme, same-party (2,2) only. Keep the left-hand scheme. Party 1 +// flips the right-hand word when the two schemes disagree on its sign. +// Subtractive and FSS share a sign, so mixing those does not flip. // --------------------------------------------------------------------------- template = 0> + std::enable_if_t + && is_two_party_sharing_v, int> = 0> HEDLEY_ALWAYS_INLINE HEDLEY_PURE HEDLEY_NO_THROW @@ -348,7 +863,8 @@ constexpr secret_share operator+( const secret_share & lhs, const secret_share & rhs) noexcept { - if constexpr (Party == 0) + if constexpr (detail::two_party_sign_v + == detail::two_party_sign_v) return secret_share::from_raw( static_cast(lhs.raw() + rhs.raw())); else @@ -357,7 +873,9 @@ constexpr secret_share operator+( } template = 0> + std::enable_if_t + && is_two_party_sharing_v, int> = 0> HEDLEY_ALWAYS_INLINE HEDLEY_PURE HEDLEY_NO_THROW @@ -365,7 +883,8 @@ constexpr secret_share operator-( const secret_share & lhs, const secret_share & rhs) noexcept { - if constexpr (Party == 0) + if constexpr (detail::two_party_sign_v + == detail::two_party_sign_v) return secret_share::from_raw( static_cast(lhs.raw() - rhs.raw())); else @@ -420,7 +939,8 @@ constexpr secret_share operator-( // Equality (same party, same scheme) — compare raw bits // --------------------------------------------------------------------------- -template +template = 0> HEDLEY_ALWAYS_INLINE HEDLEY_PURE HEDLEY_NO_THROW @@ -430,6 +950,16 @@ constexpr bool operator==(const secret_share & lhs, return lhs.raw() == rhs.raw(); } +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr bool operator==(const replicated_share & lhs, + const replicated_share & rhs) noexcept +{ + return lhs.own == rhs.own && lhs.next == rhs.next; +} + template HEDLEY_ALWAYS_INLINE HEDLEY_PURE @@ -444,30 +974,22 @@ constexpr bool operator!=(const secret_share & lhs, // Reconstruction // --------------------------------------------------------------------------- -template +template , int> = 0> HEDLEY_ALWAYS_INLINE HEDLEY_PURE HEDLEY_NO_THROW constexpr T reconstruct(const secret_share & s0, const secret_share & s1) noexcept { - if constexpr (std::is_integral_v && std::is_signed_v) - { - using unsigned_type = std::make_unsigned_t; - if constexpr (Scheme == sharing::additive) - return static_cast(static_cast(s0.raw()) - + static_cast(s1.raw())); - else - return static_cast(static_cast(s0.raw()) - - static_cast(s1.raw())); - } - else if constexpr (Scheme == sharing::additive) - return static_cast(s0.raw() + s1.raw()); + if constexpr (Scheme == sharing::additive) + return detail::group_add(s0.raw(), s1.raw()); else - return static_cast(s0.raw() - s1.raw()); + return detail::group_sub(s0.raw(), s1.raw()); } -template +template , int> = 0> HEDLEY_ALWAYS_INLINE HEDLEY_PURE HEDLEY_NO_THROW @@ -477,6 +999,147 @@ constexpr T reconstruct(const secret_share & s1, return reconstruct(s0, s1); } +namespace detail +{ + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +constexpr void store_additive3(T & c0, T & c1, T & c2, + const additive3_share & share) noexcept +{ + if constexpr (Party == 0) + c0 = share.raw(); + else if constexpr (Party == 1) + c1 = share.raw(); + else + c2 = share.raw(); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +constexpr void store_replicated_own(T & c0, T & c1, T & c2, + const replicated_share & share) noexcept +{ + if constexpr (Party == 0) + c0 = share.own; + else if constexpr (Party == 1) + c1 = share.own; + else + c2 = share.own; +} + +} // namespace detail + +/// @brief Open a (3,3)-additive sharing. Parties may be passed in any order. +/// @tparam T value type +/// @tparam P party of the first share +/// @tparam Q party of the second share +/// @tparam R party of the third share +/// @param a first share +/// @param b second share +/// @param c third share +/// @return `x0 + x1 + x2` +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr T reconstruct(const additive3_share & a, + const additive3_share & b, + const additive3_share & c) noexcept +{ + static_assert(P != Q && Q != R && P != R, + "additive3 reconstruct: need three distinct parties"); + T c0{}, c1{}, c2{}; + detail::store_additive3(c0, c1, c2, a); + detail::store_additive3(c0, c1, c2, b); + detail::store_additive3(c0, c1, c2, c); + return detail::group_add(detail::group_add(c0, c1), c2); +} + +/// @brief Open a (2,3)-replicated sharing from any two parties. +/// @details Party `P` contributes `(x_P, x_{P+1})`. The missing component is +/// taken from party `Q`. +/// @tparam T value type +/// @tparam P first party +/// @tparam Q second party +/// @param a first share +/// @param b second share +/// @return `x0 + x1 + x2` +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr T reconstruct(const replicated_share & a, + const replicated_share & b) noexcept +{ + static_assert(P < 3 && Q < 3 && P != Q, + "replicated reconstruct: need two distinct parties in 0..2"); + constexpr std::size_t missing = (P + 2) % 3; + T third{}; + if constexpr (Q == missing) + third = b.own; + else + third = b.next; + return detail::group_add(detail::group_add(a.own, a.next), third); +} + +/// @brief Open a (2,3)-replicated sharing from all three `own` components. +/// @details This is the underlying (3,3) sum. `next` is not read. +/// @tparam T value type +/// @tparam P first party +/// @tparam Q second party +/// @tparam R third party +/// @param a first share +/// @param b second share +/// @param c third share +/// @return `x0 + x1 + x2` +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr T reconstruct(const replicated_share & a, + const replicated_share & b, + const replicated_share & c) noexcept +{ + static_assert(P != Q && Q != R && P != R, + "replicated reconstruct: need three distinct parties"); + T c0{}, c1{}, c2{}; + detail::store_replicated_own(c0, c1, c2, a); + detail::store_replicated_own(c0, c1, c2, b); + detail::store_replicated_own(c0, c1, c2, c); + return detail::group_add(detail::group_add(c0, c1), c2); +} + +/// @brief Open a (2,3) Shamir sharing from any two parties. +/// @details `shamir::reconstruct` for `shamir::two_of_three`. +/// @tparam T field type. Requires `detail::shamir_field` +/// @tparam P first party +/// @tparam Q second party +/// @param a first share +/// @param b second share +/// @return the secret +/// @throws std::invalid_argument if a Lagrange denominator is zero +template +HEDLEY_WARN_UNUSED_RESULT +T reconstruct(const shamir_share & a, const shamir_share & b) +{ + return shamir::reconstruct(a, b); +} + +/// @brief Open a (2,3) Shamir sharing from all three parties. +/// @details The third share is checked against the polynomial of the first two. +/// @throws std::invalid_argument if a party index is repeated +/// @throws std::runtime_error if the three shares are inconsistent +template +HEDLEY_WARN_UNUSED_RESULT +T reconstruct(const shamir_share & a, const shamir_share & b, + const shamir_share & c) +{ + return shamir::reconstruct(a, b, c); +} + // --------------------------------------------------------------------------- // Plaintext splits (share1 = 0) // --------------------------------------------------------------------------- @@ -505,6 +1168,367 @@ constexpr auto make_subtractive_shares(T secret) noexcept subtractive_share::from_raw(T_{})); } +template +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr auto make_additive3_shares(T secret) noexcept +{ + using T_ = std::remove_cv_t>; + return std::make_tuple( + additive3_share::from_raw(static_cast(secret)), + additive3_share::from_raw(T_{}), + additive3_share::from_raw(T_{})); +} + +/// @brief Shamir shares of `secret` for access structure `(K,N)`. +/// @details Party `i` stores `p(i+1)` where +/// `p(x) = secret + coeff[0] x + ... + coeff[K-2] x^{K-1}`. +/// This is `shamir::deal`. +/// @tparam K reconstruction threshold +/// @tparam N shareholder count +/// @tparam T field type +/// @param secret the constant term +/// @param coeff higher coefficients, low degree first +/// @return shares for parties `0 .. N-1` +template +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr auto make_shamir_shares(T secret, + const std::array>, + shamir::access::degree> & coeff) noexcept +{ + using T_ = std::remove_cv_t>; + return shamir::deal(static_cast(secret), coeff); +} + +/// @brief Degree-1 Shamir shares of `secret` with the given slope. +/// @details `(K,N) = (2,3)`. Party `i` stores `secret + slope·(i+1)`. +/// This is `make_shamir_shares<2, 3>` with that one coefficient. +/// @tparam T field type +/// @param secret the cleartext secret +/// @param slope the uniform slope. Zero puts `secret` on every party +/// @return shares for parties 0, 1, and 2 +template +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr auto make_shamir_shares(T secret, T slope) noexcept +{ + using T_ = std::remove_cv_t>; + return make_shamir_shares<2, 3>(static_cast(secret), + std::array{{static_cast(slope)}}); +} + +/// @brief Deterministic (2,3) replicated split. The secret sits in `x_0`. +/// @details Party 0 stores `(secret, 0)`, party 1 stores `(0, 0)`, party 2 +/// stores `(0, secret)`. +/// @tparam T value type +/// @param secret the cleartext secret +/// @return shares for parties 0, 1, and 2 +template +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr auto make_replicated_shares(T secret) noexcept +{ + using T_ = std::remove_cv_t>; + const T_ s = static_cast(secret); + const T_ z{}; + return std::make_tuple( + replicated_share::from_raw(s, z), + replicated_share::from_raw(z, z), + replicated_share::from_raw(z, s)); +} + +/// @brief Replicated shares of the (3,3) components `x0`, `x1`, and `x2`. +/// @tparam T value type +/// @param x0 component held by parties 0 and 2 +/// @param x1 component held by parties 0 and 1 +/// @param x2 component held by parties 1 and 2 +/// @return shares for parties 0, 1, and 2 +template +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr auto make_replicated_shares(T x0, T x1, T x2) noexcept +{ + using T_ = std::remove_cv_t>; + const T_ a = static_cast(x0); + const T_ b = static_cast(x1); + const T_ c = static_cast(x2); + return std::make_tuple( + replicated_share::from_raw(a, b), + replicated_share::from_raw(b, c), + replicated_share::from_raw(c, a)); +} + +/// @brief Replicated shares of an existing (3,3)-additive sharing. +/// @tparam T value type +/// @param s0 party 0's component +/// @param s1 party 1's component +/// @param s2 party 2's component +/// @return shares for parties 0, 1, and 2 +template +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr auto make_replicated_shares(const additive3_share & s0, + const additive3_share & s1, + const additive3_share & s2) noexcept +{ + return make_replicated_shares(s0.raw(), s1.raw(), s2.raw()); +} + +/// @brief Fold a (3,3)-additive sharing into a replicated sharing. +/// @details Each component is added at both parties that store it, so the +/// replicas stay equal. +/// @tparam T value type +/// @param r0 party 0 +/// @param r1 party 1 +/// @param r2 party 2 +/// @param a0 addend component 0 +/// @param a1 addend component 1 +/// @param a2 addend component 2 +/// @return the updated replicated shares +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr auto add_replicated( + replicated_share r0, + replicated_share r1, + replicated_share r2, + const additive3_share & a0, + const additive3_share & a1, + const additive3_share & a2) noexcept +{ + r0.add_own(a0.raw()); + r0.add_next(a1.raw()); + r1.add_own(a1.raw()); + r1.add_next(a2.raw()); + r2.add_own(a2.raw()); + r2.add_next(a0.raw()); + return std::make_tuple(r0, r1, r2); +} + +// --------------------------------------------------------------------------- +// Share conversions +// +// Letters: a (2,2) additive, b (2,2) subtractive, fss (2,2) leaf share, +// y (3,3) additive, rss (2,3) replicated, s (2,3) Shamir. +// +// Local, one party, secret-preserving: +// a2b b2a a2fss fss2a b2fss fss2b +// rss2y (this party's component) +// y2rss(own, next) (one replicated share) +// Local, a reconstructing set in one place (the secret is opened, then split): +// y2rss(y0,y1,y2) rss2y(r0,r1,r2) +// s2y y2s s2rss rss2s +// Not local, and not defined here: a2y y2a b2y y2b a2rss rss2a b2rss rss2b +// fss2y y2fss fss2rss rss2fss, and Shamir with a single (2,2) share. +// Those change the party count. The garbled-bit conversions with the same +// names (a2y through y2rss) are dpf::yao in dpf/yao_share.hpp. They are not +// these casts. Top-level rss2y / y2rss stay the local (3,3) operations. +// --------------------------------------------------------------------------- + +/// @brief (2,2) additive to subtractive. Party 1 negates. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr subtractive_share a2b(const additive_share & s) noexcept +{ + return s.as_subtractive(); +} + +/// @brief (2,2) subtractive to additive. Party 1 negates. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr additive_share b2a(const subtractive_share & s) noexcept +{ + return s.as_additive(); +} + +/// @brief (2,2) additive to an FSS leaf share. Party 1 negates. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr fss_share a2fss(const additive_share & s) noexcept +{ + return s.as_fss(); +} + +/// @brief FSS leaf share to (2,2) additive. Party 1 negates. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr additive_share fss2a(const fss_share & s) noexcept +{ + return s.as_additive(); +} + +/// @brief (2,2) subtractive to an FSS leaf share. Same opening, bits unchanged. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr fss_share b2fss(const subtractive_share & s) noexcept +{ + return s.as_fss(); +} + +/// @brief FSS leaf share to (2,2) subtractive. Same opening, bits unchanged. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr subtractive_share fss2b(const fss_share & s) noexcept +{ + return s.as_subtractive(); +} + +/// @brief This party's (3,3) component of a replicated share (`y` = additive3). +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr additive3_share rss2y(const replicated_share & s) noexcept +{ + return s.as_additive3(); +} + +/// @brief One replicated share from this party's component and the next party's. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr replicated_share y2rss( + const additive3_share & mine, + const additive3_share::next_party> & nxt) noexcept +{ + return replicated_share::from_additive3(mine, nxt); +} + +/// @brief Replicated shares of a (3,3)-additive sharing. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr auto y2rss(const additive3_share & y0, + const additive3_share & y1, + const additive3_share & y2) noexcept +{ + return make_replicated_shares(y0, y1, y2); +} + +/// @brief The three (3,3) components of a replicated sharing. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr auto rss2y(const replicated_share & r0, + const replicated_share & r1, + const replicated_share & r2) noexcept +{ + return std::make_tuple(r0.as_additive3(), r1.as_additive3(), r2.as_additive3()); +} + +/// @brief Open two Shamir shares and split the secret as (3,3) additive. +/// @details The secret sits on party 0. The other two components are zero. +template +HEDLEY_WARN_UNUSED_RESULT +auto s2y(const shamir_share & a, const shamir_share & b) +{ + return make_additive3_shares(reconstruct(a, b)); +} + +/// @brief Shamir-share a (3,3) additive secret with `slope`. +template +HEDLEY_WARN_UNUSED_RESULT +auto y2s(const additive3_share & y0, const additive3_share & y1, + const additive3_share & y2, T slope) +{ + return make_shamir_shares(reconstruct(y0, y1, y2), slope); +} + +/// @brief Open two Shamir shares and split the secret as replicated shares. +/// @details Component `x_0` holds the secret. The other components are zero. +template +HEDLEY_WARN_UNUSED_RESULT +auto s2rss(const shamir_share & a, const shamir_share & b) +{ + return make_replicated_shares(reconstruct(a, b)); +} + +/// @brief Shamir-share a replicated secret with `slope`. +template +HEDLEY_WARN_UNUSED_RESULT +auto rss2s(const replicated_share & a, const replicated_share & b, + T slope) +{ + return make_shamir_shares(reconstruct(a, b), slope); +} + +/// @brief Local factor of an RSS product: `x_i y_i + x_i y_{i+1} + x_{i+1} y_i`. +/// @details The three parties' terms sum to the product. Party `i+1`'s term is +/// not known here; `rss_mul` on all three shares replicates it. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr additive3_share rss_mul( + const replicated_share & x, + const replicated_share & y) noexcept +{ + const T term = detail::group_add( + detail::group_add(detail::group_mul(x.own, y.own), + detail::group_mul(x.own, y.next)), + detail::group_mul(x.next, y.own)); + return additive3_share::from_raw(term); +} + +/// @brief RSS product once every party's local factor is in hand. +/// @details Correct, and not randomized: each factor is a function of that +/// party's input shares. Pass a zero (3,3) sharing to mask it. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr auto rss_mul( + const replicated_share & x0, const replicated_share & x1, + const replicated_share & x2, const replicated_share & y0, + const replicated_share & y1, const replicated_share & y2) noexcept +{ + return make_replicated_shares(rss_mul(x0, y0), rss_mul(x1, y1), rss_mul(x2, y2)); +} + +/// @brief Masked RSS product. `m0 + m1 + m2` must be 0. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr auto rss_mul( + const replicated_share & x0, const replicated_share & x1, + const replicated_share & x2, const replicated_share & y0, + const replicated_share & y1, const replicated_share & y2, + const additive3_share & m0, const additive3_share & m1, + const additive3_share & m2) noexcept +{ + return make_replicated_shares( + additive3_share::from_raw( + detail::group_add(rss_mul(x0, y0).raw(), m0.raw())), + additive3_share::from_raw( + detail::group_add(rss_mul(x1, y1).raw(), m1.raw())), + additive3_share::from_raw( + detail::group_add(rss_mul(x2, y2).raw(), m2.raw()))); +} + // --------------------------------------------------------------------------- // Party-tagged DPF key wrapper // --------------------------------------------------------------------------- @@ -610,7 +1634,8 @@ auto make_party_key_pair(Key0 && k0, Key1 && k1) } template + sharing Scheme, + std::enable_if_t = 0> std::basic_ostream & operator<<( std::basic_ostream & os, const secret_share & s) @@ -618,6 +1643,65 @@ std::basic_ostream & operator<<( return os << s.raw(); } +template +std::basic_ostream & operator<<( + std::basic_ostream & os, + const replicated_share & s) +{ + return os << '(' << s.own << ", " << s.next << ')'; +} + +/// @brief Copy `val` into `slot`. +/// @details One-word shares copy `raw()`. Replicated shares copy both +/// components. A plaintext overwrites a one-word share and is not a +/// replicated share. +/// @tparam Slot destination slot +/// @tparam Val source value +/// @param slot the `slot` +/// @param val the `val` +template +HEDLEY_ALWAYS_INLINE +constexpr void assign_share_slot(Slot && slot, Val && val) +{ + using slot_t = std::decay_t; + using val_t = std::decay_t; + if constexpr (is_secret_share_v) + { + if constexpr (is_secret_share_v) + { + if constexpr (share_scheme_v == sharing::replicated) + { + static_assert(share_scheme_v == sharing::replicated, + "assign_share_slot: replicated slot needs a replicated share"); + static_assert(share_party_v == share_party_v, + "assign_share_slot: replicated parties differ"); + slot = slot_t::from_raw(val.own, val.next); + } + else + { + static_assert(share_scheme_v != sharing::replicated, + "assign_share_slot: a replicated share has two components"); + slot = slot_t::from_raw(val.raw()); + } + } + else + { + static_assert(share_scheme_v != sharing::replicated, + "assign_share_slot: a plaintext is not a replicated share"); + slot = slot_t::from_raw( + static_cast(val)); + } + } + else if constexpr (is_secret_share_v) + { + static_assert(share_scheme_v != sharing::replicated, + "assign_share_slot: open a replicated share, or copy own and next"); + slot = val.raw(); + } + else + slot = std::forward(val); +} + } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_SECRET_SHARE_HPP__ diff --git a/include/dpf/sequence_memoizer.hpp b/include/dpf/sequence_memoizer.hpp index 434a121..ce2f77e 100644 --- a/include/dpf/sequence_memoizer.hpp +++ b/include/dpf/sequence_memoizer.hpp @@ -289,6 +289,7 @@ struct pointer_facade /// alternate levels. /// @tparam DpfKey DPF key type /// @tparam Allocator allocator type +/// \complexity One buffer of `recipe.num_leaf_nodes()` interior nodes, reversed in place each level. template > struct inplace_reversing_sequence_memoizer final @@ -387,6 +388,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) /// intact. Default workspace for `eval_sequence` on a recipe. /// @tparam DpfKey DPF key type /// @tparam Allocator allocator type +/// \complexity Two buffers: `2 * recipe.num_leaf_nodes()` interior nodes. template > struct double_space_sequence_memoizer final @@ -442,6 +444,7 @@ HEDLEY_PRAGMA(GCC diagnostic pop) /// @brief Every level of the recipe's traversal. /// @tparam DpfKey DPF key type /// @tparam Allocator allocator type +/// \complexity `level_endpoints().back() + num_leaf_nodes()` interior nodes, the recipe's stored levels plus the leaves. template > struct full_tree_sequence_memoizer final @@ -506,6 +509,7 @@ auto make_sequence_memoizer(const sequence_recipe & recipe) } // namespace detail +/// \complexity O(n k) interior traversals in the worst case and O(k) node workspace. k is the number of listed points and n is `depth`. The breadth-first buffer is 2k nodes, so each level traverses at most one node per point. Shared prefixes do fewer traversals. A recipe memoizer instead stores O(recipe leaf nodes) (see that memoizer). HEDLEY_PRAGMA(GCC diagnostic push) HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") /// @brief One-level sequence workspace bound to `recipe`. diff --git a/include/dpf/session_host.hpp b/include/dpf/session_host.hpp new file mode 100644 index 0000000..1242205 --- /dev/null +++ b/include/dpf/session_host.hpp @@ -0,0 +1,94 @@ +/// @file dpf/session_host.hpp +/// @brief Durable mesh session that queues micro-plans onto schedule_session. +#ifndef LIBDPF_INCLUDE_DPF_SESSION_HOST_HPP__ +#define LIBDPF_INCLUDE_DPF_SESSION_HOST_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/compose.hpp" +#include "dpf/net/edge_mesh.hpp" +#include "dpf/protocol.hpp" + +namespace dpf +{ +namespace protocol +{ + +/// @brief Long-lived role on an `edge_mesh` that drives a queue of plans. +/// @details SUBLEQ instructions, hushmap ADD/FIND, and PIRsona GD steps are +/// each one `plan` pushed here. `drive_until_idle` runs +/// `drive_via_schedule` / mesh schedule until every instance is done. +class session_host +{ +public: + session_host(std::size_t party, edge_mesh mesh, std::size_t lanes = 1) + : party_(party), mesh_(std::move(mesh)), lanes_(lanes) + { + if (lanes_ == 0) + throw std::invalid_argument("session_host lanes"); + } + + std::size_t party() const noexcept { return party_; } + edge_mesh & mesh() noexcept { return mesh_; } + std::vector> & values() noexcept { return values_; } + + void set_kernels(std::map k) + { + kernels_ = std::move(k); + } + + void set_options(drive_options opt) { opt_ = std::move(opt); } + + /// @brief Queue a composed plan (micro-plan). + void push(plan p) { queue_.push_back(std::move(p)); } + + std::size_t queued() const noexcept { return queue_.size(); } + + /// @brief Drive every queued plan to completion on the mesh. + void drive_until_idle() + { + while (!queue_.empty()) + { + auto p = std::move(queue_.front()); + queue_.pop_front(); + drive_one(p); + } + } + + /// @brief Drive a single plan without queueing. + void drive_one(const plan & p) + { + if (values_.size() < p.nodes().size()) + values_.resize(p.nodes().size()); + // Prefer peer-only fast path when the mesh is a single duplex. + if (mesh_.has(edge_peer) && !mesh_.has(edge_rss_next) + && !mesh_.has(edge_dealer) && mesh_.size() <= 3) + { + drive_via_schedule(p, mesh_.at(edge_peer), values_, kernels_, party_, + opt_); + return; + } + drive_via_schedule(p, mesh_, values_, kernels_, party_, opt_); + } + +private: + std::size_t party_ = 0; + edge_mesh mesh_; + std::size_t lanes_ = 1; + std::vector> values_; + std::map kernels_; + drive_options opt_{}; + std::deque queue_; +}; + +} // namespace protocol +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_SESSION_HOST_HPP__ diff --git a/include/dpf/sfss.hpp b/include/dpf/sfss.hpp new file mode 100644 index 0000000..70257fd --- /dev/null +++ b/include/dpf/sfss.hpp @@ -0,0 +1,192 @@ +/// @file dpf/sfss.hpp +/// @brief Streaming DPF (SDPF) compiler: Song et al., USENIX Security 2026 +/// (ePrint 2025/2304 §4.2). Setup once for a fixed point; Enc streams +/// short weight ciphertexts; Eval(key, x, ct) shares f(x)·m. +/// @details Leaf is `dpf::vec` = (β, r). Enc/Eval use a seed-keyed +/// AES-MMO PRF on the r-lane shares (subtractive convention). +/// Window Enc telescopes PRF masks so a sum of ciphertexts needs +/// only two PRF calls at Eval (Appendix C.2). +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_SFSS_HPP__ +#define LIBDPF_INCLUDE_DPF_SFSS_HPP__ + +#include +#include +#include +#include + +#include "hedley/hedley.h" +#include "simde/simde/x86/avx2.h" + +#include "dpf/eval_point.hpp" +#include "dpf/fp61.hpp" +#include "dpf/incremental.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" +#include "dpf/secret_share.hpp" +#include "dpf/vec.hpp" + +namespace dpf +{ + +/// @brief Leaf payload for SDPF: lane 0 is β, lane 1 is the PRF-key sample r. +using sdpf_leaf = vec; + +/// @brief Streaming encryption state (message counter). +struct sfss_state +{ + std::uint64_t ctr = 1; +}; + +/// @brief Client encryption key: subtractive shares of r at α, and β. +struct sdpf_enc_key +{ + fp61 h0{}; + fp61 h1{}; + fp61 beta{1}; +}; + +/// @brief One streaming ciphertext. +struct sfss_ct +{ + std::uint64_t j = 0; + fp61 c{}; +}; + +/// @brief PRF F(k, j) → fp61 via fixed-key AES-MMO with seed from k. +/// @details Domain-separated from the tree PRG by the high qword tag. +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +fp61 sfss_prf(fp61 key, std::uint64_t j) noexcept +{ + const simde__m128i seed = simde_mm_set_epi64x( + static_cast(0x5346535350524631ull), // "SFSSPRF1" + static_cast(key.raw())); + const auto pos = static_cast(j + ^ static_cast(j >> 32)); + const simde__m128i block = prg::aes128::eval(seed, pos); + return fp61::from_seed(&block, sizeof(block)); +} + +namespace detail +{ +namespace sfss_impl +{ + +HEDLEY_ALWAYS_INLINE +fp61 mask_diff(fp61 h0, fp61 h1, std::uint64_t j) noexcept +{ + return sfss_prf(h0, j) - sfss_prf(h1, j); +} + +template +HEDLEY_ALWAYS_INLINE +sdpf_leaf leaf_of(const Share & y) +{ + if constexpr (std::is_same_v, sdpf_leaf>) + return y; + else + return y.raw(); +} + +} // namespace sfss_impl +} // namespace detail + +/// @brief Gen SDPF keys for f_{α,β}. Returns (k0, k1, ke, st). +/// @tparam InteriorPRG tree interior PRG +/// @tparam ExteriorPRG leaf PRG +/// @param alpha the secret point +/// @param beta the point payload (default 1) +/// @throws std::invalid_argument if beta is 0 +template +auto make_sdpf(InputT alpha, fp61 beta = fp61{1}) +{ + if (beta.raw() == 0) + throw std::invalid_argument("make_sdpf: beta must be nonzero"); + + sdpf_leaf leaf{}; + leaf[0] = beta; + leaf[1] = uniform_sample(); + + auto keys = make_dpf(alpha, leaf); + auto & k0 = keys.first; + auto & k1 = keys.second; + + const auto y0 = detail::sfss_impl::leaf_of(*eval_point(k0, alpha)); + const auto y1 = detail::sfss_impl::leaf_of(*eval_point(k1, alpha)); + + sdpf_enc_key ke; + ke.h0 = y0[1]; + ke.h1 = y1[1]; + ke.beta = beta; + return std::make_tuple(std::move(k0), std::move(k1), ke, sfss_state{}); +} + +/// @brief Enc(st, ke, m) → ciphertext for stream index st.ctr; advances ctr. +/// @details c = m − (F(h0,j) − F(h1,j)) · β⁻¹ (β = 1 skips the inverse). +inline sfss_ct sfss_enc(sfss_state & st, const sdpf_enc_key & ke, fp61 m) +{ + if (st.ctr == 0) + throw std::overflow_error("sfss_enc: counter wrapped"); + const std::uint64_t j = st.ctr++; + const fp61 mask = detail::sfss_impl::mask_diff(ke.h0, ke.h1, j); + fp61 c; + if (ke.beta.raw() == 1) + c = m - mask; + else + c = m - mask * detail::shamir_field::inv(ke.beta); + return sfss_ct{j, c}; +} + +/// @brief Window Enc: c = m − mask(j)·β⁻¹ + mask(j+1)·β⁻¹ (telescoping). +inline sfss_ct sfss_enc_window(sfss_state & st, const sdpf_enc_key & ke, fp61 m) +{ + if (st.ctr == 0 || st.ctr == UINT64_MAX) + throw std::overflow_error("sfss_enc_window: counter wrapped"); + const std::uint64_t j = st.ctr++; + fp61 mask_j = detail::sfss_impl::mask_diff(ke.h0, ke.h1, j); + fp61 mask_n = detail::sfss_impl::mask_diff(ke.h0, ke.h1, j + 1); + if (ke.beta.raw() != 1) + { + const fp61 inv_b = detail::shamir_field::inv(ke.beta); + mask_j = mask_j * inv_b; + mask_n = mask_n * inv_b; + } + return sfss_ct{j, m - mask_j + mask_n}; +} + +/// @brief Eval(kb, x, ct) → subtractive share of f_{α,β}(x) · m. +/// @tparam Key a party key from `make_sdpf` +template +fp61 eval_sdpf(const Key & key, InputT x, const sfss_ct & ct) +{ + const auto leaf = detail::sfss_impl::leaf_of(*eval_point(key, x)); + const fp61 e = leaf[0]; + const fp61 h = leaf[1]; + return e * ct.c + sfss_prf(h, ct.j); +} + +/// @brief Window Eval after summing window ciphertexts into `c_agg`. +/// @details s = e · c_agg + F(h, j_lo) − F(h, j_hi + 1). +/// For ciphertexts from `sfss_enc_window` with consecutive counters +/// in `[j_lo, j_hi]`, reconstruct(s0, s1) = f(x) · Σ m_j. +template +fp61 eval_sdpf_window(const Key & key, InputT x, fp61 c_agg, + std::uint64_t j_lo, std::uint64_t j_hi) +{ + if (j_hi < j_lo) + throw std::invalid_argument("eval_sdpf_window: empty window"); + const auto leaf = detail::sfss_impl::leaf_of(*eval_point(key, x)); + const fp61 e = leaf[0]; + const fp61 h = leaf[1]; + return e * c_agg + sfss_prf(h, j_lo) - sfss_prf(h, j_hi + 1); +} + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_SFSS_HPP__ diff --git a/include/dpf/shamir.hpp b/include/dpf/shamir.hpp new file mode 100644 index 0000000..970cfd2 --- /dev/null +++ b/include/dpf/shamir.hpp @@ -0,0 +1,564 @@ +/// @file dpf/shamir.hpp +/// @brief (K,N) Shamir secret sharing over a field. +/// @details The secret is the constant term of a polynomial of degree `K-1`. +/// Party `i` (0-based) holds that polynomial at `x = i+1`. Any `K` +/// shares reconstruct by Lagrange at `0`. Further shares are checked +/// against the polynomial of the first `K`; they are not an error +/// correction. Exactly `K` shares are not checked. When `K = N` that +/// is every share. A full set of shares of a different secret is +/// consistent with itself. `(2,3)` +/// is `two_of_three`. That case is the type `shamir_share` +/// (`sharing::shamir`), and `shamir3` is the same polynomial on +/// `fp61`. Uniform coefficients are drawn by `shamir::share_secret` +/// in `random.hpp`. A complete program is `examples/mwe/shamir.cpp`. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_SHAMIR_HPP__ +#define LIBDPF_INCLUDE_DPF_SHAMIR_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +namespace dpf +{ + +namespace detail +{ + +/// @brief Field inverse used by Shamir reconstruction. +/// @details Specialize for a field. `fp61` is specialized in `fp61.hpp`. +/// @tparam T value type +template +struct shamir_field : std::false_type +{ +}; + +} // namespace detail + +namespace shamir +{ + +/// @brief Access structure: any `K` of `N` shares open the secret. +/// @tparam K reconstruction threshold, at least 1 +/// @tparam N shareholder count, at least `K` +template +struct access +{ + static_assert(K >= 1, "shamir threshold is at least 1"); + static_assert(N >= K, "shamir threshold cannot exceed the shareholder count"); + + /// @brief Shares required to open the secret. + static constexpr std::size_t threshold = K; + /// @brief Shareholders who receive a point. + static constexpr std::size_t parties = N; + /// @brief Polynomial degree, `K - 1`. + static constexpr std::size_t degree = K - 1; +}; + +/// @brief The (2,3) access structure behind `sharing::shamir` and `shamir3`. +using two_of_three = access<2, 3>; + +/// @brief One shareholder's value at a runtime evaluation point. +/// @tparam T field element +template +struct point_share +{ + /// @brief Evaluation point in `1 .. N`. Party `i` uses point `i + 1`. + int point = 1; + /// @brief `p(point)`, where `p(0)` is the secret. + T value{}; +}; + +/// @brief Traits of a typed Shamir share. The primary is not a Shamir share. +template +struct params : std::false_type +{ + using value_type = void; + static constexpr std::size_t party = 0; + static constexpr std::size_t threshold = 0; + static constexpr std::size_t parties = 0; + static constexpr std::uint64_t point = 0; +}; + +template +inline constexpr bool is_share_v = params>::value; + +namespace detail +{ + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr T horner(T secret, const std::array & coeff, + std::uint64_t x) noexcept +{ + // p(x) = secret + c[0] x + c[1] x^2 + ... + c[Degree-1] x^Degree. + T high{}; + const T tx{x}; + for (std::size_t k = 0; k < Degree; ++k) + { + const std::size_t i = Degree - 1 - k; + high = static_cast(static_cast(high * tx) + coeff[i]); + } + return static_cast(static_cast(high * tx) + secret); +} + +template +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr bool distinct_points(const std::array & xs, + std::size_t parties) noexcept +{ + for (std::size_t i = 0; i < M; ++i) + { + if (xs[i] < 1 || xs[i] > parties) + return false; + for (std::size_t j = 0; j < i; ++j) + if (xs[i] == xs[j]) + return false; + } + return true; +} + +template +T lagrange(T at, const std::uint64_t * xs, const T * ys, std::size_t k) +{ + T secret{}; + const T one{1}; + for (std::size_t i = 0; i < k; ++i) + { + T num = one; + T den = one; + const T xi{xs[i]}; + for (std::size_t j = 0; j < k; ++j) + { + if (i == j) + continue; + const T xj{xs[j]}; + num = static_cast(num * static_cast(at - xj)); + den = static_cast(den * static_cast(xi - xj)); + } + if (den == T{}) + throw std::invalid_argument( + "shamir: evaluation points collide in the field"); + const T weight = static_cast( + num * ::dpf::detail::shamir_field::inv(den)); + secret = static_cast(secret + static_cast(ys[i] * weight)); + } + return secret; +} + +template +T open_points(const std::uint64_t * xs, const T * ys, std::size_t count) +{ + static_assert(::dpf::detail::shamir_field::value, + "shamir reconstruct: specialize detail::shamir_field"); + if (count < K || count > N) + throw std::invalid_argument( + "shamir: the number of shares must be between K and N"); + for (std::size_t i = 0; i < count; ++i) + { + if (xs[i] < 1 || xs[i] > N) + throw std::invalid_argument( + "shamir: evaluation point is outside 1..N"); + for (std::size_t j = 0; j < i; ++j) + if (xs[i] == xs[j]) + throw std::invalid_argument("shamir: duplicate evaluation point"); + // x = 0 is the secret. A field that folds the integer point onto 0 + // (gf2 with N > 1) would hand that party the secret. + if (T{xs[i]} == T{}) + throw std::invalid_argument( + "shamir: evaluation point is zero in the field"); + } + const T secret = lagrange(T{}, xs, ys, K); + for (std::size_t extra = K; extra < count; ++extra) + { + if (lagrange(T{xs[extra]}, xs, ys, K) != ys[extra]) + throw std::runtime_error("shamir: inconsistent shares"); + } + return secret; +} + +template +T open_runtime(const point_share * shares, std::size_t count) +{ + std::array xs{}; + std::array ys{}; + if (count < K || count > N) + throw std::invalid_argument( + "shamir: the number of shares must be between K and N"); + for (std::size_t i = 0; i < count; ++i) + { + if (shares[i].point < 1 + || static_cast(shares[i].point) > N) + throw std::invalid_argument( + "shamir: evaluation point is outside 1..N"); + xs[i] = static_cast(shares[i].point); + ys[i] = shares[i].value; + } + return open_points(xs.data(), ys.data(), count); +} + +} // namespace detail + +/// @brief Share of a `(K,N)` Shamir secret at a compile-time party. +/// @details `(2,3)` is not this type. It is `shamir_share`. +/// @tparam T field element +/// @tparam Party 0-based party index, in `0 .. N-1` +/// @tparam K reconstruction threshold +/// @tparam N shareholder count +template +struct basic_share +{ + static_assert(!(K == 2 && N == 3), + "(2,3) Shamir is shamir::share (dpf::shamir_share)"); + static_assert(Party < N, "shamir party must be in 0 .. N-1"); + + using value_type = T; + using access_type = access; + static constexpr std::size_t party = Party; + static constexpr std::size_t threshold = K; + static constexpr std::size_t parties = N; + static constexpr std::size_t degree = access_type::degree; + /// @brief Lagrange point. Party 0 is point 1. + static constexpr std::uint64_t point = Party + 1; + + T value{}; + + /// @brief Bit-preserving construction. Does not apply a Lagrange weight. + /// @param v the field element + /// @return the share + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + HEDLEY_CONST + static constexpr basic_share from_raw(T v) noexcept + { + basic_share s; + s.value = v; + 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; } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr basic_share operator-() const noexcept + { + return from_raw(static_cast(-value)); + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr basic_share & operator+=(const basic_share & rhs) noexcept + { + value = static_cast(value + rhs.value); + return *this; + } + + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + constexpr basic_share & operator-=(const basic_share & rhs) noexcept + { + value = static_cast(value - rhs.value); + return *this; + } + + template + && std::is_convertible_v, int> = 0> + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + constexpr basic_share & operator*=(const Scalar & c) noexcept + { + value = static_cast(value * static_cast(c)); + return *this; + } + + /// @brief Absorb a public plaintext. Every point of `p` grows by `c`. + template + && std::is_convertible_v, int> = 0> + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + constexpr basic_share & operator+=(const Plain & c) noexcept + { + value = static_cast(value + static_cast(c)); + return *this; + } + + template + && std::is_convertible_v, int> = 0> + HEDLEY_ALWAYS_INLINE + HEDLEY_NO_THROW + constexpr basic_share & operator-=(const Plain & c) noexcept + { + value = static_cast(value - static_cast(c)); + return *this; + } +}; + +template +struct params> : std::true_type +{ + using value_type = T; + static constexpr std::size_t party = Party; + static constexpr std::size_t threshold = K; + static constexpr std::size_t parties = N; + static constexpr std::uint64_t point = Party + 1; +}; + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr basic_share operator+( + basic_share lhs, + const basic_share & rhs) noexcept +{ + lhs += rhs; + return lhs; +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr basic_share operator-( + basic_share lhs, + const basic_share & rhs) noexcept +{ + lhs -= rhs; + return lhs; +} + +template && std::is_convertible_v, int> = 0> +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr basic_share operator*( + basic_share lhs, const Scalar & c) noexcept +{ + lhs *= c; + return lhs; +} + +template && std::is_convertible_v, int> = 0> +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr basic_share operator*( + const Scalar & c, basic_share rhs) noexcept +{ + rhs *= c; + return rhs; +} + +template && std::is_convertible_v, int> = 0> +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr basic_share operator+( + basic_share lhs, const Plain & c) noexcept +{ + lhs += c; + return lhs; +} + +template && std::is_convertible_v, int> = 0> +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr basic_share operator+( + const Plain & c, basic_share rhs) noexcept +{ + rhs += c; + return rhs; +} + +template && std::is_convertible_v, int> = 0> +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr basic_share operator-( + basic_share lhs, const Plain & c) noexcept +{ + lhs -= c; + return lhs; +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr bool operator==(const basic_share & lhs, + const basic_share & rhs) noexcept +{ + return lhs.raw() == rhs.raw(); +} + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +constexpr bool operator!=(const basic_share & lhs, + const basic_share & rhs) noexcept +{ + return !(lhs == rhs); +} + +/// @brief Maps `(T, Party, K, N)` to the share type. +/// @details `(2,3)` is specialized to `shamir_share` in `secret_share.hpp`. +template +struct share_of +{ + using type = basic_share; +}; + +/// @brief Share of a `(K,N)` Shamir secret at party `Party`. +/// @details `share` is `shamir_share`. +template +using share = typename share_of::type; + +namespace detail +{ + +template +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr auto deal_at(T secret, + const std::array::degree> & coeff, + std::index_sequence) noexcept +{ + return std::make_tuple(share::from_raw( + horner(secret, coeff, static_cast(Party + 1)))...); +} + +} // namespace detail + +/// @brief Share `secret` at points `1 .. N`. +/// @details `p(x) = secret + coeff[0] x + ... + coeff[K-2] x^{K-1}`. +/// Party `i` stores `p(i+1)`. A zero coefficient is allowed. +/// Threshold 1 takes an empty coefficient array and copies `secret`. +/// `(2,3)` returns `shamir_share`s. `make_shamir_shares(secret, slope)` +/// is `deal` with that one coefficient. +/// @tparam K reconstruction threshold +/// @tparam N shareholder count +/// @tparam T field type. `+` and `*` are the field operations. Opening also +/// needs `detail::shamir_field` +/// @param secret the constant term +/// @param coeff higher coefficients, low degree first +/// @return shares for parties `0 .. N-1` +/// @see shamir::share_secret +/// \complexity O(NK) field operations. No messages. +template +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr auto deal(T secret, + const std::array::degree> & coeff) noexcept +{ + return detail::deal_at( + secret, coeff, std::make_index_sequence{}); +} + +/// @brief Open typed shares of one `(K,N)` scheme. +/// @details Pass at least `K` and at most `N` shares. The first `K` are the +/// interpolating set and are not checked against each other. Each +/// further share must lie on that polynomial. A lie among the first +/// `K` is reported only when an honest extra share is present. A +/// complete set of shares of some other secret does not throw. +/// @tparam Share0 first share +/// @tparam Rest the other shares +/// @param first first share +/// @param rest the other shares +/// @return the secret +/// @throws std::invalid_argument if a Lagrange denominator is zero +/// @throws std::runtime_error if an extra share misses the polynomial +/// \complexity O(MK^2) field operations for M shares. The shares are already in hand; this function does not exchange them. +template , int> = 0> +HEDLEY_WARN_UNUSED_RESULT +auto reconstruct(const Share0 & first, const Rest &... rest) +{ + using info = params>; + using value_type = typename info::value_type; + constexpr std::size_t M = 1 + sizeof...(Rest); + static_assert(M >= info::threshold && M <= info::parties, + "shamir reconstruct: the number of shares must be between K and N"); + static_assert(((is_share_v + && params>::threshold == info::threshold + && params>::parties == info::parties + && std::is_same_v< + typename params>::value_type, value_type>) && ...), + "shamir reconstruct: shares must be one (K,N) scheme"); + constexpr std::array xs{{ + info::point, params>::point...}}; + static_assert(detail::distinct_points(xs, info::parties), + "shamir reconstruct: need distinct parties in 0 .. N-1"); + const std::array ys{{first.raw(), rest.raw()...}}; + return detail::open_points( + xs.data(), ys.data(), M); +} + +/// @brief Open runtime point shares. `shares` has length `count`. +/// @tparam T field type. Requires `detail::shamir_field` +/// @tparam K reconstruction threshold +/// @tparam N shareholder count +/// @param shares evaluation points and values +/// @param count length of `shares`, in `K .. N` +/// @return the secret +/// @throws std::invalid_argument if the count or the points are illegal +/// @throws std::runtime_error if an extra share misses the polynomial of the first K +/// \complexity O(MK^2) field operations for M shares. The shares are already in hand; this function does not exchange them. +template +HEDLEY_WARN_UNUSED_RESULT +T reconstruct(const point_share * shares, std::size_t count) +{ + return detail::open_runtime(shares, count); +} + +/// @brief Open a fixed list of runtime point shares. +/// @tparam T field type +/// @tparam K reconstruction threshold +/// @tparam N shareholder count +/// @tparam M number of shares in the list +/// @param shares evaluation points and values +/// @return the secret +/// @throws std::invalid_argument if the count or the points are illegal +/// @throws std::runtime_error if an extra share misses the polynomial of the first K +template +HEDLEY_WARN_UNUSED_RESULT +T reconstruct(const std::array, M> & shares) +{ + return detail::open_runtime(shares.data(), shares.size()); +} + +} // namespace shamir +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_SHAMIR_HPP__ diff --git a/include/dpf/shamir3.hpp b/include/dpf/shamir3.hpp new file mode 100644 index 0000000..8877eb2 --- /dev/null +++ b/include/dpf/shamir3.hpp @@ -0,0 +1,213 @@ +/// @file dpf/shamir3.hpp +/// @brief Degree-1 Shamir sharing over `fp61` for three evaluators. +/// @details The `(K,N) = (2,3)` case of `shamir::deal` / `shamir::reconstruct`. +/// Parties are indexed `1`, `2`, and `3`. A share of secret `s` is +/// `s_i = s + a·i` for a uniform slope `a`. Any two parties +/// reconstruct by Lagrange. Embeddings move between `fp61` and a +/// 61-bit XOR string for the (2,3) point construction of +/// Zyskind, Yanai, and Pentland, ePrint 2024/1658. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_SHAMIR3_HPP__ +#define LIBDPF_INCLUDE_DPF_SHAMIR3_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/fp61.hpp" +#include "dpf/random.hpp" +#include "dpf/secret_share.hpp" +#include "dpf/xor_wrapper.hpp" + +namespace dpf +{ +namespace shamir3 +{ + +/// @brief XOR string wide enough for an `fp61` embed (low 61 bits). +using xor61 = xor_wrapper; + +/// @brief One party's share of a degree-1 Shamir secret. +struct share +{ + /// @brief Party index in `{1, 2, 3}`. + int party = 1; + /// @brief The field element `s + a·party`. + fp61 value{}; +}; + +/// @brief Modular inverse in `fp61`. +/// @param a a non-zero field element +/// @return `a^{-1}` +/// @throws std::invalid_argument if `a` is zero +HEDLEY_WARN_UNUSED_RESULT +inline fp61 inv(fp61 a) +{ + return detail::shamir_field::inv(a); +} + +/// @brief Embed a field element as a 61-bit XOR string. +/// @param a the field element +/// @return the low 61 bits as an XOR word +HEDLEY_NO_THROW +HEDLEY_CONST +HEDLEY_ALWAYS_INLINE +xor61 embed_xor(fp61 a) noexcept +{ + return xor61{a.raw()}; +} + +/// @brief Embed a 61-bit XOR string as a field element. +/// @param w the XOR word (high bits ignored) +/// @return `fp61` of the low 61 bits +HEDLEY_NO_THROW +HEDLEY_CONST +HEDLEY_ALWAYS_INLINE +fp61 embed_field(xor61 w) noexcept +{ + return fp61{static_cast(w) & fp61_mod}; +} + +/// @brief Field-to-XOR then XOR: `embed(a) ⊕ w`. +/// @param a the field element +/// @param w the XOR string +/// @return the combined XOR string +HEDLEY_NO_THROW +HEDLEY_CONST +HEDLEY_ALWAYS_INLINE +xor61 field_xor(fp61 a, xor61 w) noexcept +{ + return embed_xor(a) + w; +} + +/// @brief XOR-to-field then multiply: `embed(w) · c`. +/// @param w the XOR string +/// @param c the field scale +/// @return the product in `fp61` +HEDLEY_NO_THROW +HEDLEY_CONST +HEDLEY_ALWAYS_INLINE +fp61 xor_scale(xor61 w, fp61 c) noexcept +{ + return embed_field(w) * c; +} + +/// @brief Sample a degree-1 sharing of `secret` at parties 1, 2, and 3. +/// @details `shamir::share_secret`, written as runtime points +/// `1`, `2`, and `3`. +/// @param secret the cleartext secret +/// @return shares for parties 1, 2, and 3 +/// \complexity O(1). One random slope and three field multiplies. No messages. +HEDLEY_WARN_UNUSED_RESULT +inline std::array share_secret(fp61 secret) +{ + const auto dealt = shamir::share_secret(secret); + return { + share{1, std::get<0>(dealt).raw()}, + share{2, std::get<1>(dealt).raw()}, + share{3, std::get<2>(dealt).raw()}, + }; +} + +/// @brief Reconstruct from any two distinct party shares. +/// @details `shamir::reconstruct` after the (2,3) party check. +/// @param a first share +/// @param b second share +/// @return the secret +/// @throws std::invalid_argument if the party indices collide or are out of range +/// \complexity O(1). Two field inverses and a handful of multiplies. The shares are already in hand; this function does not exchange them. +HEDLEY_WARN_UNUSED_RESULT +inline fp61 reconstruct(share a, share b) +{ + if (a.party == b.party || a.party < 1 || a.party > 3 || b.party < 1 + || b.party > 3) + throw std::invalid_argument("shamir3: need two distinct parties in 1..3"); + const std::array, 2> held{{ + shamir::point_share{a.party, a.value}, + shamir::point_share{b.party, b.value}, + }}; + return shamir::reconstruct(held); +} + +/// @brief Reconstruct from all three shares (any two suffice; this checks consistency). +/// @param a party 1 share +/// @param b party 2 share +/// @param c party 3 share +/// @return the secret +/// @throws std::invalid_argument if the party indices are wrong +/// @throws std::runtime_error if the three shares are inconsistent +/// \complexity O(1). Two field inverses and a handful of multiplies. The shares are already in hand; this function does not exchange them. +HEDLEY_WARN_UNUSED_RESULT +inline fp61 reconstruct(share a, share b, share c) +{ + const fp61 from_ab = reconstruct(a, b); + const fp61 from_ac = reconstruct(a, c); + if (from_ab != from_ac) + throw std::runtime_error("shamir3: inconsistent shares"); + return from_ab; +} + +/// @brief Scale a share by its party index: `value · party`. +/// @param s the share +/// @return `s.value * s.party` +HEDLEY_NO_THROW +HEDLEY_CONST +HEDLEY_ALWAYS_INLINE +fp61 party_scale(share s) noexcept +{ + return s.value * fp61{static_cast(s.party)}; +} + +/// @brief Prefactor `s_i · i^{-1}` used when planting Shamir shares into VDPF+. +/// @param s the share +/// @return `s.value * inv(party)` +HEDLEY_WARN_UNUSED_RESULT +inline fp61 unscale(share s) +{ + return s.value * inv(fp61{static_cast(s.party)}); +} + +/// @brief Add two shares of the same party. +/// @param a left share +/// @param b right share +/// @return the sum +/// @throws std::invalid_argument if the parties differ +HEDLEY_WARN_UNUSED_RESULT +inline share add(share a, share b) +{ + if (a.party != b.party) + throw std::invalid_argument("shamir3: add different parties"); + return share{a.party, a.value + b.value}; +} + +/// @brief Typed share for runtime party `s.party` in `{1, 2, 3}`. +/// @throws std::invalid_argument if `s.party` is outside `1..3` +template +HEDLEY_WARN_UNUSED_RESULT +inline shamir_share typed_share(share s) +{ + if (s.party != static_cast(Party) + 1) + throw std::invalid_argument("shamir3: typed party mismatch"); + return shamir_share::from_raw(s.value); +} + +/// @brief Runtime share for a typed party `Party` (point `Party + 1`). +template +HEDLEY_NO_THROW +HEDLEY_CONST +inline share runtime_share(const shamir_share & s) noexcept +{ + return share{static_cast(Party) + 1, s.raw()}; +} + +} // namespace shamir3 +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_SHAMIR3_HPP__ diff --git a/include/dpf/share_cmp.hpp b/include/dpf/share_cmp.hpp new file mode 100644 index 0000000..44bed5a --- /dev/null +++ b/include/dpf/share_cmp.hpp @@ -0,0 +1,393 @@ +/// @file dpf/share_cmp.hpp +/// @brief Comparison of two arithmetic shares (mask, open, MSB / mux). +#ifndef LIBDPF_INCLUDE_DPF_SHARE_CMP_HPP__ +#define LIBDPF_INCLUDE_DPF_SHARE_CMP_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/beaver.hpp" +#include "dpf/edabit.hpp" +#include "dpf/random.hpp" +#include "dpf/trunc.hpp" + +namespace dpf +{ +namespace share_cmp +{ + +template +HEDLEY_NO_THROW +constexpr std::uint8_t msb_clear(Ring x, unsigned n) noexcept +{ + if (n == 0) + return 0; + return static_cast((x >> (n - 1u)) & 1u); +} + +template +HEDLEY_NO_THROW +constexpr std::uint8_t gt_clear(Ring x, Ring y, unsigned n) noexcept +{ + const Ring mask = trunc::mask_bits(n); + return static_cast(((x & mask) > (y & mask)) ? 1 : 0); +} + +template +HEDLEY_NO_THROW +constexpr std::uint8_t eq_clear(Ring x, Ring y) noexcept +{ + return static_cast(x == y ? 1 : 0); +} + +template +struct msb_prep +{ + Ring r0{}; + Ring r1{}; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +msb_prep sample_msb_prep(unsigned /*n*/) +{ + msb_prep p; + const Ring r = dpf::uniform_sample(); + p.r0 = dpf::uniform_sample(); + p.r1 = static_cast(r - p.r0); + return p; +} + +/// @brief This party's XOR share of MSB after A2B (the bit at `n-1`). +template +HEDLEY_WARN_UNUSED_RESULT +std::uint8_t msb_party(const std::vector & my_bits, unsigned n) +{ + if (n == 0) + return 0; + return edabit::detail::get_bit(my_bits, n - 1u); +} + +template +HEDLEY_WARN_UNUSED_RESULT +std::pair msb_party_pair(Ring x0, Ring x1, + const msb_prep & prep, unsigned n) +{ + (void)prep; + auto eda = edabit::sample_edabit_pair(n); + auto [b0, b1] = edabit::a2b_gmw_pair(eda, x0, x1); + return {msb_party(b0, n), msb_party(b1, n)}; +} + +/// @brief This party's XOR share of an unsigned greater-than bit. +template +HEDLEY_WARN_UNUSED_RESULT +std::uint8_t gt_party(std::uint8_t my_bit) noexcept +{ + return static_cast(my_bit & 1u); +} + +/// @brief Full-width unsigned compare. Bit shares stay split; their XOR is `x > y`. +template +HEDLEY_WARN_UNUSED_RESULT +std::pair gt_party_pair(Ring x0, Ring x1, Ring y0, + Ring y1, const msb_prep & prep, unsigned n) +{ + (void)prep; + auto ex = edabit::sample_edabit_pair(n); + auto ey = edabit::sample_edabit_pair(n); + auto bx = edabit::a2b_gmw_pair(ex, x0, x1); + auto by = edabit::a2b_gmw_pair(ey, y0, y1); + auto g = edabit::gt_bits_pair(bx.first, bx.second, by.first, by.second, n); + return {gt_party(g.first), gt_party(g.second)}; +} + +namespace detail +{ + +template +HEDLEY_WARN_UNUSED_RESULT +std::pair b2a_bit(std::uint8_t b0, std::uint8_t b1) +{ + auto dab = ot::sample_dabit_pair(); + const std::uint8_t mask = static_cast( + (b0 ^ dab.p0.bit) ^ (b1 ^ dab.p1.bit)); + return {edabit::b2a_party_bit(b0, dab.p0, mask, 0, 0), + edabit::b2a_party_bit(b1, dab.p1, mask, 1, 0)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +std::pair bit_mul_shares(Ring b0, Ring b1, Ring x0, Ring x1) +{ + beavers::session s; + auto bw = s.bit(); + auto xw = s.input(); + auto zw = s.bit_mul(bw, xw); + s.pin(zw); + s.sample(); + s.bind_shares(bw, b0, b1); + s.bind_shares(xw, x0, x1); + s.evaluate(); + const auto v = s.value(zw); + return {v.p0, v.p1}; +} + +} // namespace detail + +template +HEDLEY_WARN_UNUSED_RESULT +Ring relu_clear(Ring x0, Ring x1, unsigned n) +{ + const Ring x = static_cast(x0 + x1); + return msb_clear(x, n) ? Ring{} : x; +} + +/// @brief ReLU party share: `(1 - msb) · x` via `bit_mul` on additive bit shares. +template +HEDLEY_WARN_UNUSED_RESULT +Ring relu_party(Ring x_share, Ring keep_arith) +{ + return static_cast(keep_arith * x_share); +} + +template +HEDLEY_WARN_UNUSED_RESULT +std::pair relu_party_pair(Ring x0, Ring x1, unsigned n) +{ + auto prep = sample_msb_prep(n); + auto [b0, b1] = msb_party_pair(x0, x1, prep, n); + auto [s0, s1] = detail::b2a_bit(b0, b1); + const Ring k0 = static_cast(Ring{1} - s0); + const Ring k1 = static_cast(Ring{} - s1); + return detail::bit_mul_shares(k0, k1, x0, x1); +} + +template +HEDLEY_WARN_UNUSED_RESULT +Ring max_clear(Ring x0, Ring x1, Ring y0, Ring y1, unsigned n) +{ + const Ring x = static_cast(x0 + x1); + const Ring y = static_cast(y0 + y1); + return gt_clear(x, y, n) ? x : y; +} + +/// @brief `max = y + b·(x-y)` with `b` an additive share of the comparison bit. +template +HEDLEY_WARN_UNUSED_RESULT +Ring max_party(Ring y_share, Ring select_share) +{ + return static_cast(y_share + select_share); +} + +template +HEDLEY_WARN_UNUSED_RESULT +std::pair max_party_pair(Ring x0, Ring x1, Ring y0, Ring y1, + unsigned n) +{ + auto prep = sample_msb_prep(n); + auto [g0, g1] = gt_party_pair(x0, x1, y0, y1, prep, n); + auto [s0, s1] = detail::b2a_bit(g0, g1); + const Ring d0 = static_cast(x0 - y0); + const Ring d1 = static_cast(x1 - y1); + auto sel = detail::bit_mul_shares(s0, s1, d0, d1); + return {max_party(y0, sel.first), max_party(y1, sel.second)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +std::pair mux_clear(std::uint8_t sel, Ring a0, Ring a1, Ring b0, + Ring b1) +{ + const Ring a = static_cast(a0 + a1); + const Ring b = static_cast(b0 + b1); + const Ring z = sel ? a : b; + const Ring m = dpf::uniform_sample(); + return {m, static_cast(z - m)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +Ring zext(Ring share, unsigned /*from_bits*/, unsigned /*to_bits*/) noexcept +{ + return share; +} + +template +HEDLEY_WARN_UNUSED_RESULT +Ring sext_clear(Ring x, unsigned from_bits, unsigned to_bits) noexcept +{ + if (from_bits == 0 || to_bits < from_bits) + return x; + const Ring sign = static_cast((x >> (from_bits - 1u)) & 1u); + const Ring low = x & trunc::mask_bits(from_bits); + if (!sign) + return low; + const Ring ext = trunc::mask_bits(to_bits) + ^ trunc::mask_bits(from_bits); + return static_cast(low | ext); +} + +/// @brief Sign-extend using a secret MSB bit share (public when p1 holds 0). +template +HEDLEY_WARN_UNUSED_RESULT +Ring sext_party(Ring x_share, std::uint8_t msb_pub, unsigned from_bits, + unsigned to_bits, unsigned party) +{ + const Ring low = x_share & trunc::mask_bits(from_bits); + if (!(msb_pub & 1u)) + return low; + const Ring ext = trunc::mask_bits(to_bits) + ^ trunc::mask_bits(from_bits); + // Party 0 absorbs the public extension bits. + if (party == 0) + return static_cast(low | ext); + return low; +} + +template +HEDLEY_WARN_UNUSED_RESULT +std::pair sext_party_pair(Ring x0, Ring x1, unsigned from_bits, + unsigned to_bits) +{ + if (from_bits == 0 || to_bits < from_bits + || from_bits >= 8u * sizeof(Ring)) + return {x0, x1}; + auto prep = sample_msb_prep(from_bits); + auto [b0, b1] = msb_party_pair(x0, x1, prep, from_bits); + auto [s0, s1] = detail::b2a_bit(b0, b1); + const Ring ext = static_cast(trunc::mask_bits(to_bits) + ^ trunc::mask_bits(from_bits)); + auto shifted = trunc::trunc_exact_pair(x0, x1, + trunc::make_trunc_exact_prep( + static_cast(8u * sizeof(Ring)), from_bits)); + const Ring low0 = static_cast(x0 - (shifted.first << from_bits)); + const Ring low1 = static_cast(x1 - (shifted.second << from_bits)); + auto fill = detail::bit_mul_shares(s0, s1, ext, Ring{}); + return {static_cast(low0 + fill.first), + static_cast(low1 + fill.second)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +bool range_ok_clear(Ring x, unsigned ell) noexcept +{ + if (ell >= 8u * sizeof(Ring)) + return true; + return (x & ~trunc::mask_bits(ell)) == Ring{}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +Ring recip_newton_clear(Ring y, Ring y0_guess, unsigned frac_bits) +{ + const Ring two = static_cast(Ring{2} << frac_bits); + const Ring yx = static_cast((y * y0_guess) >> frac_bits); + const Ring t = static_cast(two - yx); + return static_cast((y0_guess * t) >> frac_bits); +} + +template +HEDLEY_WARN_UNUSED_RESULT +Ring div_clear(Ring num, Ring den) +{ + if (den == Ring{}) + throw std::invalid_argument("div by zero"); + return static_cast(num / den); +} + +/// @brief Goldschmidt/Newton division on shares via `mul_exact_trunc`. +/// @details Flagged leak: `floor(log2(den))` is public. There is no drop-in +/// replacement that keeps the magnitude secret and still normalizes +/// the Newton seed. See `dpf/revealing.hpp`. +template +HEDLEY_WARN_UNUSED_RESULT +std::pair div_party_pair(Ring num0, Ring num1, Ring den0, Ring den1, + unsigned frac_bits) +{ + if (frac_bits == 0 || frac_bits >= 8u * sizeof(Ring) - 1u) + throw std::invalid_argument("div frac_bits"); + auto prep = sample_msb_prep(64); + auto nz = gt_party_pair(den0, den1, Ring{}, Ring{}, prep, 64); + if ((nz.first ^ nz.second) == 0) + throw std::invalid_argument("div by zero"); + unsigned log2 = 0; + for (int bit = 5; bit >= 0; --bit) + { + const unsigned cand = log2 | (1u << static_cast(bit)); + if (cand >= 63u) + continue; + const Ring thr = static_cast((Ring{1} << cand) - Ring{1}); + auto g = gt_party_pair(den0, den1, thr, Ring{}, prep, 64); + if ((g.first ^ g.second) != 0) + log2 = cand; + } + Ring d0 = den0; + Ring d1 = den1; + if (log2 < frac_bits) + { + const unsigned sh = frac_bits - log2; + d0 = static_cast(d0 << sh); + d1 = static_cast(d1 << sh); + } + else if (log2 > frac_bits) + { + auto tr = trunc::trunc_exact_pair(d0, d1, + trunc::make_trunc_exact_prep( + static_cast(8u * sizeof(Ring)), log2 - frac_bits)); + d0 = tr.first; + d1 = tr.second; + } + Ring g0 = static_cast(Ring{1} << frac_bits); + Ring g1{}; + const Ring two = static_cast(Ring{2} << frac_bits); + for (int it = 0; it < 6; ++it) + { + auto prod = trunc::mul_exact_trunc(d0, d1, g0, g1, frac_bits); + const Ring t0 = static_cast(two - prod.z0); + const Ring t1 = static_cast(Ring{} - prod.z1); + auto ng = trunc::mul_exact_trunc(g0, g1, t0, t1, frac_bits); + g0 = ng.z0; + g1 = ng.z1; + } + Ring inv0 = g0; + Ring inv1 = g1; + if (log2 != 0) + { + auto tr = trunc::trunc_exact_pair(g0, g1, + trunc::make_trunc_exact_prep( + static_cast(8u * sizeof(Ring)), log2)); + inv0 = tr.first; + inv1 = tr.second; + } + auto q = trunc::mul_exact_trunc(num0, num1, inv0, inv1, frac_bits); + return {q.z0, q.z1}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +std::pair share_input(Ring clear, unsigned owner) +{ + if (owner == 0) + return {clear, Ring{}}; + if (owner == 1) + return {Ring{}, clear}; + throw std::invalid_argument("share_input owner"); +} + +template +HEDLEY_WARN_UNUSED_RESULT +Ring declassify(Ring s0, Ring s1) noexcept +{ + return static_cast(s0 + s1); +} + +} // namespace share_cmp +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_SHARE_CMP_HPP__ diff --git a/include/dpf/share_expr.hpp b/include/dpf/share_expr.hpp new file mode 100644 index 0000000..4200897 --- /dev/null +++ b/include/dpf/share_expr.hpp @@ -0,0 +1,369 @@ +/// @file dpf/share_expr.hpp +/// @brief Imperative expression recorder over composer + beaver sessions. +#ifndef LIBDPF_INCLUDE_DPF_SHARE_EXPR_HPP__ +#define LIBDPF_INCLUDE_DPF_SHARE_EXPR_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/beaver.hpp" +#include "dpf/compose.hpp" +#include "dpf/net/edge_mesh.hpp" +#include "dpf/net/memory_sink.hpp" +#include "dpf/share_cmp.hpp" +#include "dpf/trunc.hpp" +#include "dpf/xor_wrapper.hpp" + +namespace dpf +{ +namespace expr +{ + +struct handle +{ + std::uint32_t id = 0; +}; + +class recorder +{ +public: + explicit recorder(std::size_t party, std::size_t parties = 2) + : party_(party), parties_(parties), composer_(party) + { + if (parties_ != 2 && parties_ != 3) + throw std::invalid_argument("recorder parties must be 2 or 3"); + if (party_ >= parties_) + throw std::invalid_argument("recorder party index"); + } + + std::size_t party() const noexcept { return party_; } + std::size_t parties() const noexcept { return parties_; } + protocol::composer & composer() noexcept { return composer_; } + const protocol::composer & composer() const noexcept { return composer_; } + + void bind_mesh(net::edge_mesh mesh) { mesh_ = std::move(mesh); } + bool has_mesh() const noexcept { return mesh_.size() != 0; } + + template + handle input(Ring clear, unsigned owner) + { + Ring mine{}; + if (parties_ == 2) + { + auto [s0, s1] = share_cmp::share_input(clear, owner); + mine = (party_ == 0) ? s0 : s1; + } + else + mine = (party_ == owner) ? clear : Ring{}; + values_[next_] = encode(mine); + kinds_[next_] = kind::value; + return handle{next_++}; + } + + template + handle bind(Ring mine) + { + values_[next_] = encode(mine); + kinds_[next_] = kind::value; + return handle{next_++}; + } + + template + handle add(handle a, handle b) + { + check(a); + check(b); + Ring va = decode(values_.at(a.id)); + Ring vb = decode(values_.at(b.id)); + values_[next_] = encode(static_cast(va + vb)); + kinds_[next_] = kind::value; + auto na = composer_.input(protocol::domain::a, sizeof(Ring)); + auto nb = composer_.input(protocol::domain::a, sizeof(Ring)); + composer_.compute(protocol::opcodes::user_base, {na, nb}, + protocol::domain::a, sizeof(Ring)); + return handle{next_++}; + } + + /// @brief Record a product; local share filled by `complete_mul` with peer. + template + handle mul(handle a, handle b) + { + check(a); + check(b); + pending_mul pm; + pm.a = a.id; + pm.b = b.id; + pm.out = next_; + pending_.push_back(pm); + values_[next_] = encode(Ring{}); // filled by complete_mul + kinds_[next_] = kind::pending_mul; + auto na = composer_.input(protocol::domain::a, sizeof(Ring)); + auto nb = composer_.input(protocol::domain::a, sizeof(Ring)); + composer_.compute(protocol::opcodes::user_base + 2, {na, nb}, + protocol::domain::a, sizeof(Ring)); + pending_muls_++; + return handle{next_++}; + } + + /// @brief Finish one pending mul with the peer's operand shares (Beaver). + template + static void complete_mul(recorder & r0, recorder & r1, handle out0, + handle out1) + { + if (r0.kinds_.at(out0.id) != kind::pending_mul + || r1.kinds_.at(out1.id) != kind::pending_mul) + throw std::invalid_argument("complete_mul: not pending"); + pending_mul pm0{}, pm1{}; + for (const auto & p : r0.pending_) + if (p.out == out0.id) + pm0 = p; + for (const auto & p : r1.pending_) + if (p.out == out1.id) + pm1 = p; + const Ring x0 = r0.local_value(handle{pm0.a}); + const Ring y0 = r0.local_value(handle{pm0.b}); + const Ring x1 = r1.local_value(handle{pm1.a}); + const Ring y1 = r1.local_value(handle{pm1.b}); + // Honest-dealer triple; each party opens only its masked limb. + const Ring a0 = dpf::uniform_sample(); + const Ring b0 = dpf::uniform_sample(); + const Ring a1 = dpf::uniform_sample(); + const Ring b1 = dpf::uniform_sample(); + const Ring a = static_cast(a0 + a1); + const Ring b = static_cast(b0 + b1); + const Ring c = static_cast(a * b); + const Ring c0 = dpf::uniform_sample(); + const Ring c1 = static_cast(c - c0); + const Ring d = static_cast((x0 - a0) + (x1 - a1)); + const Ring e = static_cast((y0 - b0) + (y1 - b1)); + const Ring z0 = trunc::mul_trunc_party(x0, y0, a0, b0, c0, d, e, 0, 0); + const Ring z1 = trunc::mul_trunc_party(x1, y1, a1, b1, c1, d, e, 0, 1); + r0.values_[out0.id] = encode(z0); + r1.values_[out1.id] = encode(z1); + r0.kinds_[out0.id] = kind::value; + r1.kinds_[out1.id] = kind::value; + } + + /// @brief Multi-input AND via a bit-wire beaver monomial (2PC). + handle band(const std::vector & bits) + { + if (bits.empty()) + throw std::invalid_argument("band empty"); + and_width_ = bits.size(); + pending_and pa; + pa.ins.reserve(bits.size()); + for (auto h : bits) + { + check(h); + pa.ins.push_back(h.id); + } + pa.out = next_; + pending_ands_.push_back(pa); + values_[next_] = {0}; + kinds_[next_] = kind::pending_and; + return handle{next_++}; + } + + static void complete_band(recorder & r0, recorder & r1, handle out0, + handle out1) + { + pending_and pa0{}, pa1{}; + for (const auto & p : r0.pending_ands_) + if (p.out == out0.id) + pa0 = p; + for (const auto & p : r1.pending_ands_) + if (p.out == out1.id) + pa1 = p; + if (pa0.ins.size() != pa1.ins.size() || pa0.ins.empty()) + throw std::invalid_argument("complete_band"); + using bit_ring = dpf::xor_wrapper; + using btraits = beavers::ring_traits; + beavers::session s; + std::vector> ws; + ws.reserve(pa0.ins.size()); + auto to_xw = [](std::uint8_t b) { + return (b & 1u) ? btraits::one() : btraits::zero(); + }; + for (std::size_t i = 0; i < pa0.ins.size(); ++i) + { + auto w = s.bit(); + ws.push_back(w); + const std::uint8_t b0 = r0.values_.at(pa0.ins[i]).empty() + ? 0 + : (r0.values_.at(pa0.ins[i])[0] & 1u); + const std::uint8_t b1 = r1.values_.at(pa1.ins[i]).empty() + ? 0 + : (r1.values_.at(pa1.ins[i])[0] & 1u); + s.bind_shares(w, to_xw(b0), to_xw(b1)); + } + beavers::wire acc = ws[0]; + for (std::size_t i = 1; i < ws.size(); ++i) + acc = s.product(acc, ws[i]); + s.pin(acc); + s.sample(); + s.evaluate(); + const auto v = s.value(acc); + r0.values_[out0.id] = { + static_cast(static_cast(v.p0) & 1u)}; + r1.values_[out1.id] = { + static_cast(static_cast(v.p1) & 1u)}; + r0.kinds_[out0.id] = kind::value; + r1.kinds_[out1.id] = kind::value; + } + + std::size_t last_and_arity() const noexcept { return and_width_; } + std::size_t pending_muls() const noexcept { return pending_muls_; } + + template + Ring local_value(handle h) const + { + check(h); + if (kinds_.at(h.id) != kind::value) + throw std::logic_error("local_value: pending op"); + return decode(values_.at(h.id)); + } + + /// @brief Declassify after flushing any pending ops; sums opened shares. + template + static Ring declassify(recorder & a, recorder & b, handle ha, handle hb) + { + if (a.kinds_.at(ha.id) == kind::pending_mul) + complete_mul(a, b, ha, hb); + if (a.kinds_.at(ha.id) == kind::pending_and) + complete_band(a, b, ha, hb); + if (!a.has_mesh() || !b.has_mesh()) + throw std::logic_error("expr declassify requires bind_mesh"); + protocol::composer c0(a.party_); + protocol::composer c1(b.party_); + auto in0 = c0.input(protocol::domain::a, sizeof(Ring)); + auto ex0 = c0.exchange(in0); + auto in1 = c1.input(protocol::domain::a, sizeof(Ring)); + auto ex1 = c1.exchange(in1); + auto p0 = c0.default_plan(); + auto p1 = c1.default_plan(); + std::vector> v0(p0.nodes().size()); + std::vector> v1(p1.nodes().size()); + const Ring mine_a = a.local_value(ha); + const Ring mine_b = b.local_value(hb); + v0[in0.id].assign(sizeof(Ring), 0); + v1[in1.id].assign(sizeof(Ring), 0); + std::memcpy(v0[in0.id].data(), &mine_a, sizeof(Ring)); + std::memcpy(v1[in1.id].data(), &mine_b, sizeof(Ring)); + std::map kernels; + std::exception_ptr err; + std::thread t0([&] { + try + { + protocol::drive_via_schedule(p0, a.mesh_.at(net::edge_peer), v0, + kernels, a.party_); + } + catch (...) + { + err = std::current_exception(); + } + }); + std::thread t1([&] { + try + { + protocol::drive_via_schedule(p1, b.mesh_.at(net::edge_peer), v1, + kernels, b.party_); + } + catch (...) + { + err = std::current_exception(); + } + }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); + Ring opened{}; + std::memcpy(&opened, v0[ex0.id].data(), sizeof(Ring)); + (void)ex1; + return opened; + } + + template + void install_tape(const beavers::party_tape & tape) + { + session_.install_party(static_cast(party_), tape); + } + + beavers::session & session_u64() noexcept { return session_; } + + protocol::plan plan() const { return composer_.default_plan(); } + +private: + enum class kind : unsigned char { value, pending_mul, pending_and }; + + struct pending_mul + { + std::uint32_t a = 0; + std::uint32_t b = 0; + std::uint32_t out = 0; + }; + + struct pending_and + { + std::vector ins; + std::uint32_t out = 0; + }; + + void check(handle h) const + { + if (values_.find(h.id) == values_.end()) + throw std::out_of_range("expr handle"); + } + + template + static std::vector encode(Ring v) + { + std::vector out(sizeof(Ring)); + std::memcpy(out.data(), &v, sizeof(Ring)); + return out; + } + + template + static Ring decode(const std::vector & b) + { + if (b.size() < sizeof(Ring)) + throw std::invalid_argument("expr decode"); + Ring v{}; + std::memcpy(&v, b.data(), sizeof(Ring)); + return v; + } + + std::size_t party_ = 0; + std::size_t parties_ = 2; + protocol::composer composer_; + net::edge_mesh mesh_{}; + std::uint32_t next_ = 1; + std::map> values_; + std::map kinds_; + beavers::session session_; + std::vector pending_; + std::vector pending_ands_; + std::size_t and_width_ = 0; + std::size_t pending_muls_ = 0; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +Ring eval_mul_add(Ring x, Ring y, Ring w) +{ + return static_cast(x * y + w); +} + +} // namespace expr +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_SHARE_EXPR_HPP__ diff --git a/include/dpf/share_vec.hpp b/include/dpf/share_vec.hpp new file mode 100644 index 0000000..d642bcf --- /dev/null +++ b/include/dpf/share_vec.hpp @@ -0,0 +1,191 @@ +/// @file dpf/share_vec.hpp +/// @brief Lane-block secret-share vectors for arithmetic and boolean domains. +#ifndef LIBDPF_INCLUDE_DPF_SHARE_VEC_HPP__ +#define LIBDPF_INCLUDE_DPF_SHARE_VEC_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/compose.hpp" +#include "dpf/random.hpp" +#include "dpf/trunc.hpp" + +namespace dpf +{ + +template +class share_vec +{ +public: + using value_type = T; + + share_vec() = default; + + share_vec(std::size_t n, protocol::domain dom, std::size_t party) + : dom_(dom), party_(party), data_(n) + { + } + + share_vec(std::vector data, protocol::domain dom, std::size_t party) + : dom_(dom), party_(party), data_(std::move(data)) + { + } + + std::size_t size() const noexcept { return data_.size(); } + protocol::domain domain() const noexcept { return dom_; } + std::size_t party() const noexcept { return party_; } + + T & operator[](std::size_t i) { return data_.at(i); } + const T & operator[](std::size_t i) const { return data_.at(i); } + + T * data() noexcept { return data_.data(); } + const T * data() const noexcept { return data_.data(); } + + share_vec & operator+=(const share_vec & o) + { + check_compatible(o); + for (std::size_t i = 0; i < data_.size(); ++i) + data_[i] = static_cast(data_[i] + o.data_[i]); + return *this; + } + + friend share_vec operator+(share_vec a, const share_vec & b) + { + a += b; + return a; + } + + share_vec & operator-=(const share_vec & o) + { + check_compatible(o); + for (std::size_t i = 0; i < data_.size(); ++i) + data_[i] = static_cast(data_[i] - o.data_[i]); + return *this; + } + + /// @brief Local cross term only (Beaver / RSS correction still required). + static share_vec mul_local(const share_vec & a, const share_vec & b) + { + a.check_compatible(b); + share_vec out(a.size(), a.dom_, a.party_); + for (std::size_t i = 0; i < a.size(); ++i) + out[i] = static_cast(a[i] * b[i]); + return out; + } + + /// @brief Beaver product of two additive share vectors (both parties). + static std::pair mul(const share_vec & x0, + const share_vec & x1, const share_vec & y0, const share_vec & y1) + { + if (x0.size() != x1.size() || x0.size() != y0.size() + || y0.size() != y1.size()) + throw std::invalid_argument("share_vec::mul size"); + share_vec z0(x0.size(), x0.domain(), 0); + share_vec z1(x0.size(), x0.domain(), 1); + for (std::size_t i = 0; i < x0.size(); ++i) + { + auto mt = trunc::mul_trunc_pair(x0[i], x1[i], y0[i], y1[i], 0); + z0[i] = mt.z0; + z1[i] = mt.z1; + } + return {std::move(z0), std::move(z1)}; + } + + static std::vector declassify(const share_vec & a, const share_vec & b) + { + if (a.size() != b.size()) + throw std::invalid_argument("share_vec declassify size"); + std::vector out(a.size()); + for (std::size_t i = 0; i < a.size(); ++i) + out[i] = static_cast(a[i] + b[i]); + return out; + } + + static std::pair share(const std::vector & clear, + protocol::domain dom = protocol::domain::a) + { + share_vec p0(clear.size(), dom, 0); + share_vec p1(clear.size(), dom, 1); + for (std::size_t i = 0; i < clear.size(); ++i) + { + p0[i] = dpf::uniform_sample(); + p1[i] = static_cast(clear[i] - p0[i]); + } + return {std::move(p0), std::move(p1)}; + } + +private: + void check_compatible(const share_vec & o) const + { + if (data_.size() != o.data_.size() || dom_ != o.dom_ + || party_ != o.party_) + throw std::invalid_argument("share_vec incompatible"); + } + + protocol::domain dom_ = protocol::domain::a; + std::size_t party_ = 0; + std::vector data_; +}; + +class bool_share_vec +{ +public: + bool_share_vec() = default; + + bool_share_vec(std::size_t nbits, protocol::domain dom, std::size_t party) + : nbits_(nbits), + dom_(dom), + party_(party), + data_((nbits + 7u) / 8u, 0) + { + if (dom != protocol::domain::bin && dom != protocol::domain::bin_rss) + throw std::invalid_argument("bool_share_vec domain"); + } + + std::size_t size() const noexcept { return nbits_; } + std::vector & bytes() noexcept { return data_; } + const std::vector & bytes() const noexcept { return data_; } + + std::uint8_t bit(std::size_t i) const + { + if (i >= nbits_) + throw std::out_of_range("bool_share_vec"); + return static_cast((data_[i / 8] >> (i % 8)) & 1u); + } + + void set_bit(std::size_t i, std::uint8_t b) + { + if (i >= nbits_) + throw std::out_of_range("bool_share_vec"); + const std::size_t byte = i / 8; + const unsigned off = static_cast(i % 8); + if (b & 1u) + data_[byte] = static_cast(data_[byte] | (1u << off)); + else + data_[byte] = static_cast(data_[byte] & ~(1u << off)); + } + + bool_share_vec & operator^=(const bool_share_vec & o) + { + if (nbits_ != o.nbits_ || party_ != o.party_) + throw std::invalid_argument("bool_share_vec xor"); + for (std::size_t i = 0; i < data_.size(); ++i) + data_[i] = static_cast(data_[i] ^ o.data_[i]); + return *this; + } + +private: + std::size_t nbits_ = 0; + protocol::domain dom_ = protocol::domain::bin; + std::size_t party_ = 0; + std::vector data_; +}; + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_SHARE_VEC_HPP__ diff --git a/include/dpf/shuffle.hpp b/include/dpf/shuffle.hpp new file mode 100644 index 0000000..62dd00b --- /dev/null +++ b/include/dpf/shuffle.hpp @@ -0,0 +1,443 @@ +/// @file dpf/shuffle.hpp +/// @brief Honest-majority 3PC shuffle and boolean select / aggregates. +/// @details `shuffle_party` applies one permutation known to every party. +/// `shuffle_hidden_pass` is the hidden order: three passes, each +/// from one pairwise seed, leaving that seed's missing party out. +/// Passes run left-out 2 (`k01`), then 0 (`k12`), then 1 (`k20`). +/// `permute` is `out[i] = in[pi[i]]`, and each pass applies that map, +/// so the clear replay is `permute(permute(permute(v, π01), π12), π20)`. +/// A secret index stays a DPF. This header reorders a column of +/// shares the parties already hold. The manual is +/// [An array of shares, not a secret index](@ref share_shuffle). +#ifndef LIBDPF_INCLUDE_DPF_SHUFFLE_HPP__ +#define LIBDPF_INCLUDE_DPF_SHUFFLE_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/bit_inject.hpp" +#include "dpf/buffered_prg.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" +#include "dpf/rss_seed.hpp" +#include "dpf/share_cmp.hpp" + +namespace dpf +{ +namespace shuffle +{ + +/// @brief Fisher–Yates permutation from one pairwise seed. Lane 0. +HEDLEY_WARN_UNUSED_RESULT +inline std::vector permutation_from_seed( + rss::seed_block seed, std::size_t n, std::uint64_t index) +{ + std::vector pi(n); + std::iota(pi.begin(), pi.end(), 0); + randomness::lane_table table(seed); + for (std::size_t i = n; i > 1; --i) + { + const auto r = table.value_at(0, index + i); + const std::size_t j = static_cast(r % i); + std::swap(pi[i - 1], pi[j]); + } + return pi; +} + +/// @brief Derive a shared permutation of `n` from pairwise seeds (dealer view). +HEDLEY_WARN_UNUSED_RESULT +inline std::vector permutation_from_seeds( + const rss::seed_bundle & bundle, std::size_t n, std::uint64_t index) +{ + return permutation_from_seed(bundle.k01, n, index); +} + +/// @brief Apply permutation to a clear vector. +template +HEDLEY_WARN_UNUSED_RESULT +std::vector permute(const std::vector & v, + const std::vector & pi) +{ + if (v.size() != pi.size()) + throw std::invalid_argument("shuffle permute"); + std::vector out(v.size()); + for (std::size_t i = 0; i < pi.size(); ++i) + out[i] = v[pi[i]]; + return out; +} + +/// @brief Multiset oracle: permute a clear vector (not a party protocol). +template +HEDLEY_WARN_UNUSED_RESULT +std::vector shuffle_clear(const std::vector & values, + const rss::seed_bundle & bundle, std::uint64_t index) +{ + auto pi = permutation_from_seeds(bundle, values.size(), index); + return permute(values, pi); +} + +/// @brief One 3PC party's shuffle of RSS components. +/// @details Party holds replicated vectors `(own[i], next[i])`. Permute both +/// by the shared `pi`, then the caller `send_next`s the permuted `own` +/// and refreshes with the received previous component. +template +struct shuffle_party_view +{ + std::vector own; + std::vector next; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +shuffle_party_view shuffle_party(const shuffle_party_view & in, + const rss::seed_bundle & bundle, std::uint64_t index) +{ + auto pi = permutation_from_seeds(bundle, in.own.size(), index); + if (in.next.size() != in.own.size()) + throw std::invalid_argument("shuffle_party size"); + shuffle_party_view out; + out.own = permute(in.own, pi); + out.next = permute(in.next, pi); + return out; +} + +/// @brief Party `me` sends to `(me + 1) mod 3` on a hidden pass, or to nobody. +inline unsigned hidden_next(unsigned me) noexcept +{ + return (me + 1u) % 3u; +} + +/// @brief The party who forms `u = own + next` on the pass that leaves `left_out` out. +inline unsigned hidden_u_party(unsigned left_out) noexcept +{ + return (left_out + 1u) % 3u; +} + +/// @brief The party who permutes its `next` component on that pass. +inline unsigned hidden_side_party(unsigned left_out) noexcept +{ + return (left_out + 2u) % 3u; +} + +/// @brief One directed array from `shuffle_hidden_pass`. +template +struct hidden_message +{ + std::vector data; + unsigned to = 0; + bool sends = false; +}; + +/// @brief Local view after one pass, plus the array this party sends to `next`. +template +struct hidden_pass_result +{ + shuffle_party_view view; + hidden_message out; +}; + +namespace detail +{ + +inline rss::seed_block seed_toward(const rss::party_seeds & seeds, unsigned other) +{ + if (other == hidden_next(seeds.me)) + return seeds.with_next; + if (other == hidden_next(hidden_next(seeds.me))) + return seeds.with_prev; + throw std::invalid_argument("shuffle: seed"); +} + +template +std::vector words_from_seed(rss::seed_block seed, std::uint32_t lane, + std::size_t n, std::uint64_t index) +{ + randomness::lane_table table(seed); + std::vector out(n); + for (std::size_t i = 0; i < n; ++i) + out[i] = static_cast(table.value_at(lane, index + i)); + return out; +} + +} // namespace detail + +/// @brief One hidden-shuffle pass on replicated `(own, next)`. +/// @details Passes run with `left_out` 2, then 0, then 1. Parties who share +/// the pass seed permute a two-party split; the left-out party +/// receives a fresh component. `inbound` is required for the side +/// party and the left-out party (the array their predecessor sends). +/// The u-party ignores `inbound`. Pad words use lane 1 of the +/// permutation seed. The fresh mask uses lane 2 of the seed shared +/// with the left-out party, so it does not collide with that seed's +/// permutation lane. +template +HEDLEY_WARN_UNUSED_RESULT +hidden_pass_result shuffle_hidden_pass(unsigned me, + const rss::party_seeds & seeds, const shuffle_party_view & in, + std::uint64_t index, unsigned left_out, const std::vector * inbound) +{ + if (me > 2 || left_out > 2) + throw std::invalid_argument("shuffle: party"); + if (seeds.me != me) + throw std::invalid_argument("shuffle: party seeds"); + if (in.own.size() != in.next.size()) + throw std::invalid_argument("shuffle: size"); + const std::size_t n = in.own.size(); + const unsigned u = hidden_u_party(left_out); + const unsigned side = hidden_side_party(left_out); + hidden_pass_result step; + if (me == u) + { + const auto pi_seed = detail::seed_toward(seeds, side); + const auto mask_seed = detail::seed_toward(seeds, left_out); + const auto pi = permutation_from_seed(pi_seed, n, index); + const auto pad = detail::words_from_seed(pi_seed, 1, n, index); + const auto mask = detail::words_from_seed(mask_seed, 2, n, index); + std::vector sum(n); + for (std::size_t i = 0; i < n; ++i) + sum[i] = static_cast(in.own[i] + in.next[i] + pad[i]); + const auto moved = permute(sum, pi); + step.view.own = mask; + step.view.next.resize(n); + step.out.data.resize(n); + for (std::size_t i = 0; i < n; ++i) + { + step.view.next[i] = static_cast(moved[i] - mask[i]); + step.out.data[i] = step.view.next[i]; + } + step.out.to = side; + step.out.sends = true; + return step; + } + if (me == side) + { + if (inbound == nullptr || inbound->size() != n) + throw std::invalid_argument("shuffle: inbound"); + const auto pi_seed = detail::seed_toward(seeds, u); + const auto pi = permutation_from_seed(pi_seed, n, index); + const auto pad = detail::words_from_seed(pi_seed, 1, n, index); + std::vector side_v(n); + for (std::size_t i = 0; i < n; ++i) + side_v[i] = static_cast(in.next[i] - pad[i]); + step.view.next = permute(side_v, pi); + step.view.own = *inbound; + step.out.data = step.view.next; + step.out.to = left_out; + step.out.sends = true; + return step; + } + if (inbound == nullptr || inbound->size() != n) + throw std::invalid_argument("shuffle: inbound"); + const auto mask_seed = detail::seed_toward(seeds, u); + step.view.next = detail::words_from_seed(mask_seed, 2, n, index); + step.view.own = *inbound; + step.out.sends = false; + return step; +} + +/// @brief Three hidden passes. Opens by summing the three `own` components. +template +HEDLEY_WARN_UNUSED_RESULT +std::vector shuffle_hidden_triple(const std::vector & clear, + const rss::seed_bundle & bundle, std::uint64_t index) +{ + const std::size_t n = clear.size(); + shuffle_party_view held[3]; + for (unsigned p = 0; p < 3; ++p) + { + held[p].own.assign(n, T{}); + held[p].next.assign(n, T{}); + } + for (std::size_t i = 0; i < n; ++i) + { + const T a = dpf::uniform_sample(); + const T b = dpf::uniform_sample(); + const T c = static_cast(clear[i] - a - b); + held[0].own[i] = a; + held[0].next[i] = b; + held[1].own[i] = b; + held[1].next[i] = c; + held[2].own[i] = c; + held[2].next[i] = a; + } + const unsigned order[3] = {2u, 0u, 1u}; + for (unsigned left : order) + { + const unsigned u = hidden_u_party(left); + const unsigned side = hidden_side_party(left); + const auto seeds_u = rss::party_seeds::from_bundle(bundle, u); + const auto seeds_s = rss::party_seeds::from_bundle(bundle, side); + const auto seeds_l = rss::party_seeds::from_bundle(bundle, left); + auto u_step = shuffle_hidden_pass(u, seeds_u, held[u], index, left, nullptr); + auto s_step = shuffle_hidden_pass( + side, seeds_s, held[side], index, left, &u_step.out.data); + auto l_step = shuffle_hidden_pass( + left, seeds_l, held[left], index, left, &s_step.out.data); + held[u] = std::move(u_step.view); + held[side] = std::move(s_step.view); + held[left] = std::move(l_step.view); + } + std::vector out(n); + for (std::size_t i = 0; i < n; ++i) + out[i] = static_cast(held[0].own[i] + held[1].own[i] + held[2].own[i]); + return out; +} + +/// @brief After ring send of `own`: party stores `(own, recv_from_prev)`. +template +HEDLEY_WARN_UNUSED_RESULT +shuffle_party_view shuffle_refresh(std::vector own, + std::vector from_prev) +{ + if (own.size() != from_prev.size()) + throw std::invalid_argument("shuffle_refresh size"); + return shuffle_party_view{std::move(own), std::move(from_prev)}; +} + +/// @brief Dealer helper: run three parties' permute + ring refresh; open sum. +template +HEDLEY_WARN_UNUSED_RESULT +std::vector shuffle_party_triple(const std::vector & clear, + const rss::seed_bundle & bundle, std::uint64_t index) +{ + // Share as RSS: p0=(v,0), p1=(0,0), p2=(0,v) component-wise is wrong for + // sum; use additive split into three: sample r0,r1, r2=v-r0-r1. + const std::size_t n = clear.size(); + shuffle_party_view v0{std::vector(n), std::vector(n)}; + shuffle_party_view v1{std::vector(n), std::vector(n)}; + shuffle_party_view v2{std::vector(n), std::vector(n)}; + for (std::size_t i = 0; i < n; ++i) + { + const T a = dpf::uniform_sample(); + const T b = dpf::uniform_sample(); + const T c = static_cast(clear[i] - a - b); + // p0:(a,b) p1:(b,c) p2:(c,a) + v0.own[i] = a; + v0.next[i] = b; + v1.own[i] = b; + v1.next[i] = c; + v2.own[i] = c; + v2.next[i] = a; + } + auto p0 = shuffle_party(v0, bundle, index); + auto p1 = shuffle_party(v1, bundle, index); + auto p2 = shuffle_party(v2, bundle, index); + // Ring send own → next party; refresh: (own, from_prev) with from_prev = + // previous party's own. + auto r0 = shuffle_refresh(p0.own, p2.own); + auto r1 = shuffle_refresh(p1.own, p0.own); + auto r2 = shuffle_refresh(p2.own, p1.own); + std::vector out(n); + for (std::size_t i = 0; i < n; ++i) + out[i] = static_cast(r0.own[i] + r1.own[i] + r2.own[i]); + return out; +} + +/// @brief Multiset equality (permutation check). +template +HEDLEY_WARN_UNUSED_RESULT +bool is_permutation_of(std::vector a, std::vector b) +{ + if (a.size() != b.size()) + return false; + std::sort(a.begin(), a.end()); + std::sort(b.begin(), b.end()); + return a == b; +} + +/// @brief select(pred, row): inject boolean mask onto each column (clear). +template +HEDLEY_WARN_UNUSED_RESULT +std::vector select_clear(const std::vector & pred, + const std::vector & row) +{ + if (pred.size() != row.size()) + throw std::invalid_argument("select size"); + std::vector out(row.size()); + for (std::size_t i = 0; i < row.size(); ++i) + out[i] = pred[i] ? row[i] : Ring{}; + return out; +} + +template +HEDLEY_WARN_UNUSED_RESULT +Ring sum_if_clear(const std::vector & pred, + const std::vector & row) +{ + Ring s{}; + auto selected = select_clear(pred, row); + for (auto v : selected) + s = static_cast(s + v); + return s; +} + +template +HEDLEY_WARN_UNUSED_RESULT +Ring count_if_clear(const std::vector & pred) +{ + Ring c{}; + for (auto b : pred) + c = static_cast(c + static_cast(b & 1u)); + return c; +} + +/// @brief Argmax over a clear vector: value and one-hot index. +template +struct argmax_result +{ + Ring value{}; + std::vector one_hot; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +argmax_result argmax_clear(const std::vector & v, unsigned nbits) +{ + if (v.empty()) + throw std::invalid_argument("argmax empty"); + argmax_result out; + out.one_hot.assign(v.size(), 0); + std::size_t best = 0; + for (std::size_t i = 1; i < v.size(); ++i) + if (share_cmp::gt_clear(v[i], v[best], nbits)) + best = i; + out.value = v[best]; + out.one_hot[best] = 1; + return out; +} + +/// @brief Short 2PC Waksman-style shuffle via mux tree (clear oracle). +template +HEDLEY_WARN_UNUSED_RESULT +std::vector waksman_clear(const std::vector & v, + const std::vector & swap_bits) +{ + auto out = v; + std::size_t bit = 0; + for (std::size_t len = 2; len <= out.size(); len *= 2) + { + for (std::size_t i = 0; i + len / 2 < out.size(); i += len) + { + for (std::size_t j = 0; j < len / 2 && i + j + len / 2 < out.size(); + ++j) + { + if (bit < swap_bits.size() && swap_bits[bit]) + std::swap(out[i + j], out[i + j + len / 2]); + ++bit; + } + } + } + return out; +} + +} // namespace shuffle +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_SHUFFLE_HPP__ diff --git a/include/dpf/thread_work.hpp b/include/dpf/thread_work.hpp new file mode 100644 index 0000000..a399d5d --- /dev/null +++ b/include/dpf/thread_work.hpp @@ -0,0 +1,136 @@ +/// @file dpf/thread_work.hpp +/// @brief Lend a thread's randomness source to another thread for one task, +/// and charge the task's costs back to the thread that asked for it. +/// @details A kernel posted to a compute pool runs on a pool thread while the +/// party thread waits for it (`protocol::invoke_kernel`). The party +/// thread takes `draw_context::capture()`, and the pool thread holds +/// `adopt_draws` around the kernel, so the kernel's `uniform_fill` +/// draws come from the party's source (an installed `experiment`, or +/// any other hook) in program order. `work_meter::now()` before and +/// after the kernel measures its symmetric-key blocks, random bytes, +/// and CPU on the pool thread, and `absorb_work` on the party thread +/// adds them to the party's own counters. `thread_cpu_ns()` is this +/// thread's CPU time plus the CPU time absorbed that way. +#ifndef LIBDPF_INCLUDE_DPF_THREAD_WORK_HPP__ +#define LIBDPF_INCLUDE_DPF_THREAD_WORK_HPP__ + +#include +#include +#include + +#include "dpf/experiment_note.hpp" +#include "dpf/prg_count.hpp" +#include "dpf/random.hpp" + +namespace dpf +{ + +namespace detail +{ + +inline thread_local std::uint64_t absorbed_cpu_ns_tls = 0; + +inline std::uint64_t own_thread_cpu_ns() noexcept +{ + timespec ts{}; +#if defined(CLOCK_THREAD_CPUTIME_ID) + if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) + return static_cast(ts.tv_sec) * 1000000000ull + + static_cast(ts.tv_nsec); +#endif + return 0; +} + +} // namespace detail + +/// @brief True when this platform has a per-thread CPU clock. +inline bool have_thread_cpu_clock() noexcept +{ +#if defined(CLOCK_THREAD_CPUTIME_ID) + timespec ts{}; + return clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0; +#else + return false; +#endif +} + +/// @brief This thread's CPU time plus the CPU time of tasks it handed off. +inline std::uint64_t thread_cpu_ns() noexcept +{ + return detail::own_thread_cpu_ns() + detail::absorbed_cpu_ns_tls; +} + +/// @brief This thread's costs at one instant. +struct work_meter +{ + prg::counts sym{}; + std::uint64_t random_bytes = 0; + std::uint64_t cpu_ns = 0; + + static work_meter now() noexcept + { + work_meter m; + m.sym = prg::snapshot(); + m.random_bytes = random_bytes_count(); + m.cpu_ns = detail::own_thread_cpu_ns(); + return m; + } +}; + +/// @brief Charge this thread for the costs between `before` and `after`, +/// both taken on the thread that did the work. +inline void absorb_work(const work_meter & before, const work_meter & after) noexcept +{ + prg::counts delta{}; + for (std::size_t i = 0; i < delta.size(); ++i) + delta[i] = after.sym[i] - before.sym[i]; + prg::absorb(delta); + detail::random_bytes_tls += after.random_bytes - before.random_bytes; + detail::absorbed_cpu_ns_tls += after.cpu_ns - before.cpu_ns; +} + +/// @brief One thread's randomness source and seed sink. +struct draw_context +{ + void (*hook)(void *, std::size_t) = nullptr; + void * ctx = nullptr; + detail::experiment_seed_sink * sink = nullptr; + + static draw_context capture() noexcept + { + draw_context c; + c.hook = detail::uniform_bytes_hook; + c.ctx = detail::uniform_bytes_ctx; + c.sink = detail::experiment_seed_sink_tls; + return c; + } +}; + +/// @brief Draw from `from` on this thread until the scope ends. The thread +/// that captured `from` must not draw while this scope is open. +class adopt_draws +{ +public: + explicit adopt_draws(const draw_context & from) noexcept + : saved_(draw_context::capture()) + { + set(from); + } + ~adopt_draws() { set(saved_); } + adopt_draws(const adopt_draws &) = delete; + adopt_draws & operator=(const adopt_draws &) = delete; + +private: + static void set(const draw_context & c) noexcept + { + detail::uniform_bytes_hook = c.hook; + detail::uniform_bytes_ctx = c.ctx; + detail::experiment_seed_sink_tls = c.sink; + } + + draw_context saved_; +}; + +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_THREAD_WORK_HPP__ diff --git a/include/dpf/tree_traits.hpp b/include/dpf/tree_traits.hpp index 0ef49cf..fafd281 100644 --- a/include/dpf/tree_traits.hpp +++ b/include/dpf/tree_traits.hpp @@ -4,6 +4,8 @@ /// defines `half_tree_tag` (e.g. `prg::aes128_ccr`) opts into the /// Guo et al. Half-Tree mid-level expand / CW / advance, with a /// two-tweak last level that keeps BGI-style advice packing. +/// @note Default expand: Boyle, Gilboa, and Ishai, CCS 2016 (full version ePrint 2018/707). +/// @note Best known (same model), selected by `half_tree_tag`: Guo, Yang, Wang, Zhang, Xie, Zhang, and Liu, ePrint 2022/1431. 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. /// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license; /// see [LICENSE.md](@ref license) for details. @@ -27,6 +29,15 @@ namespace dpf { +template +struct prg_has_indep4 : std::false_type {}; + +template +struct prg_has_indep4(), + std::declval(), + std::declval()))>> : std::true_type {}; + /// @brief Walk policy for interior DPF levels. Specialized when `PRG::half_tree_tag` /// exists. /// @tparam PRG pseudorandom generator @@ -145,17 +156,78 @@ struct tree_traits node cw, psnip_uint8_t advice, bool dir, bool parent_control, bool /*is_last*/ = false) noexcept { + (void)parent; const node packed = pack_cw(cw, advice, dir); return dpf::xor_if(kids[dir ? 1u : 0u], packed, parent_control); } + /// @brief One child only: `PRG::eval(cleared, dir)` instead of `eval01`. + /// @details Path walks never need the sibling. Interval/full use + /// `traverse01` / `traverse01_x4` when both children are live. HEDLEY_NO_THROW HEDLEY_ALWAYS_INLINE static node traverse(node parent, node cw_packed, bool dir, bool /*is_last*/ = false) noexcept { - auto kids = expand(parent, false); - return dpf::xor_if_lo_bit(kids[dir ? 1u : 0u], cw_packed, parent); + const node child = PRG::eval(dpf::unset_lo_2bits(parent), + static_cast(dir ? 1 : 0)); + return dpf::xor_if_lo_bit(child, cw_packed, parent); + } + + /// @brief Four independent one-child steps. Same result as `traverse`. + /// @details Interleaves the PRG when `PRG::eval_indep4` exists so a + /// strided sequence is not limited by single-block AES latency. + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + static void traverse4(const node parents[4], const node cws[4], + const bool dirs[4], node out[4]) noexcept + { + if constexpr (prg_has_indep4::value) + { + node seeds[4]; + psnip_uint32_t pos[4]; + for (int i = 0; i < 4; ++i) + { + seeds[i] = dpf::unset_lo_2bits(parents[i]); + pos[i] = dirs[i] ? 1u : 0u; + } + node kids[4]; + PRG::eval_indep4(seeds, pos, kids); + for (int i = 0; i < 4; ++i) + out[i] = dpf::xor_if_lo_bit(kids[i], cws[i], parents[i]); + } + else + { + for (int i = 0; i < 4; ++i) + out[i] = traverse(parents[i], cws[i], dirs[i]); + } + } + + /// @brief Eight independent one-child steps. Same result as `traverse`. + HEDLEY_NO_THROW + HEDLEY_ALWAYS_INLINE + static void traverse8(const node parents[8], const node cws[8], + const bool dirs[8], node out[8]) noexcept + { + if constexpr (prg_has_indep4::value) + { + node seeds[8]; + psnip_uint32_t pos[8]; + for (int i = 0; i < 8; ++i) + { + seeds[i] = dpf::unset_lo_2bits(parents[i]); + pos[i] = dirs[i] ? 1u : 0u; + } + node kids[8]; + PRG::eval_indep8(seeds, pos, kids); + for (int i = 0; i < 8; ++i) + out[i] = dpf::xor_if_lo_bit(kids[i], cws[i], parents[i]); + } + else + { + for (int i = 0; i < 8; ++i) + out[i] = traverse(parents[i], cws[i], dirs[i]); + } } HEDLEY_NO_THROW @@ -330,19 +402,32 @@ HEDLEY_PRAGMA(GCC diagnostic pop) node cw, psnip_uint8_t advice, bool dir, bool parent_control, bool is_last = false) noexcept { + (void)parent; // Mid and last: select child[dir], XOR packed CW if parent control set. // Mid Half-Tree: child[1]=H⊕s so this is `h ⊕ (dir?s:0) ⊕ (t?cw:0)`. const node packed = pack_cw(cw, advice, dir, is_last); return dpf::xor_if(kids[dir ? 1u : 0u], packed, parent_control); } + /// @brief One child only. Mid: one CCR hash (+ optional ⊕s). Last: one + /// two-tweak hash instead of both. HEDLEY_NO_THROW HEDLEY_ALWAYS_INLINE static node traverse(node parent, node cw_packed, bool dir, bool is_last = false) noexcept { - auto kids = expand(parent, is_last); - return dpf::xor_if_lo_bit(kids[dir ? 1u : 0u], cw_packed, parent); + node child; + if (is_last) + { + const node base = dpf::unset_lo_bit(parent); + child = dir ? PRG::hash(dpf::set_lo_bit(base)) : PRG::hash(base); + } + else + { + const node h = PRG::hash(parent); + child = dir ? simde_mm_xor_si128(h, parent) : h; + } + return dpf::xor_if_lo_bit(child, cw_packed, parent); } HEDLEY_NO_THROW diff --git a/include/dpf/trunc.hpp b/include/dpf/trunc.hpp new file mode 100644 index 0000000..84abe5c --- /dev/null +++ b/include/dpf/trunc.hpp @@ -0,0 +1,228 @@ +/// @file dpf/trunc.hpp +/// @brief Truncate-and-reduce on additive shares (probabilistic and exact). +#ifndef LIBDPF_INCLUDE_DPF_TRUNC_HPP__ +#define LIBDPF_INCLUDE_DPF_TRUNC_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/edabit.hpp" +#include "dpf/random.hpp" + +namespace dpf +{ +namespace trunc +{ + +template +HEDLEY_NO_THROW +constexpr Ring mask_bits(unsigned bits) noexcept +{ + if (bits == 0) + return Ring{}; + if (bits >= 8u * sizeof(Ring)) + return static_cast(~Ring{}); + return static_cast((Ring{1} << bits) - Ring{1}); +} + +template +HEDLEY_WARN_UNUSED_RESULT +Ring trunc_prob(Ring share, unsigned s) noexcept +{ + return static_cast(share >> s); +} + +template +HEDLEY_WARN_UNUSED_RESULT +Ring trunc_prob_clear(Ring x0, Ring x1, unsigned s) noexcept +{ + return trunc_prob(static_cast(x0 + x1), s); +} + +template +HEDLEY_WARN_UNUSED_RESULT +Ring trunc_msb(Ring share, unsigned s, Ring /*msb_share*/) noexcept +{ + return static_cast(share >> s); +} + +inline std::uint64_t trunc_exact_clear(std::uint64_t x0, std::uint64_t x1, + unsigned n, unsigned s) +{ + if (s >= n || n > 64) + throw std::invalid_argument("trunc_exact_clear"); + const std::uint64_t low_m = (s >= 64) ? ~std::uint64_t{0} + : ((std::uint64_t{1} << s) - 1u); + const std::uint64_t high_m = ((n - s) >= 64) + ? ~std::uint64_t{0} + : ((std::uint64_t{1} << (n - s)) - 1u); + const std::uint64_t v0 = x0 & low_m; + const std::uint64_t v1 = x1 & low_m; + const std::uint64_t u0 = (x0 >> s) & high_m; + const std::uint64_t u1 = (x1 >> s) & high_m; + const std::uint64_t cin = (v0 + v1) >> s; + return (u0 + u1 + cin) & high_m; +} + +template +struct trunc_exact_prep +{ + edabit::edabit_share r0; + edabit::edabit_share r1; + unsigned n = 0; + unsigned s = 0; + Ring clear_r{}; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +trunc_exact_prep make_trunc_exact_prep(unsigned n, unsigned s) +{ + if (s >= n || n > 8u * sizeof(Ring)) + throw std::invalid_argument("trunc_exact width"); + trunc_exact_prep p; + p.n = n; + p.s = s; + auto pair = edabit::sample_edabit_pair(s); + p.r0 = pair.p0; + p.r1 = pair.p1; + p.clear_r = pair.clear_r; + return p; +} + +/// @brief Exact trunc party share after opening `delta = x - r`. +/// @details `trunc(x) = (delta >> s) + wrap`. `wrap_share` is an additive share +/// of the GMW carry. `r` is not opened. +template +HEDLEY_WARN_UNUSED_RESULT +Ring trunc_exact_party(Ring x_share, Ring r_low_arith, Ring delta, + Ring wrap_share, unsigned s, unsigned party, Ring r_public = Ring{}) +{ + (void)x_share; + (void)r_low_arith; + (void)r_public; + (void)s; + Ring out = wrap_share; + if (party == 0) + out = static_cast(out + static_cast(delta >> s)); + return out; +} + +/// @brief Two-party exact trunc. Opens `x - r` only; the wrap carry is a GMW AND. +template +HEDLEY_WARN_UNUSED_RESULT +std::pair trunc_exact_pair(Ring x0, Ring x1, + const trunc_exact_prep & prep) +{ + const Ring delta = static_cast( + (x0 - prep.r0.arith) + (x1 - prep.r1.arith)); + std::uint8_t c0 = 0; + std::uint8_t c1 = 0; + for (unsigned i = 0; i < prep.s; ++i) + { + const std::uint8_t r0 = edabit::detail::get_bit(prep.r0.bits_packed, i); + const std::uint8_t r1 = edabit::detail::get_bit(prep.r1.bits_packed, i); + const std::uint8_t di = static_cast( + (static_cast(delta) >> i) & 1u); + auto rc = edabit::and_pair(r0, r1, c0, c1); + const std::uint8_t rd0 = di ? r0 : 0; + const std::uint8_t rd1 = di ? r1 : 0; + const std::uint8_t dc0 = di ? c0 : 0; + const std::uint8_t dc1 = di ? c1 : 0; + c0 = static_cast(rd0 ^ dc0 ^ rc.first); + c1 = static_cast(rd1 ^ dc1 ^ rc.second); + } + auto dab = ot::sample_dabit_pair(); + const std::uint8_t mask = static_cast( + (c0 ^ dab.p0.bit) ^ (c1 ^ dab.p1.bit)); + const Ring w0 = edabit::b2a_party_bit(c0, dab.p0, mask, 0, 0); + const Ring w1 = edabit::b2a_party_bit(c1, dab.p1, mask, 1, 0); + return {trunc_exact_party(x0, prep.r0.arith, delta, w0, prep.s, 0), + trunc_exact_party(x1, prep.r1.arith, delta, w1, prep.s, 1)}; +} + +template +struct mul_trunc_shares +{ + Ring z0{}; + Ring z1{}; +}; + +template +HEDLEY_WARN_UNUSED_RESULT +mul_trunc_shares mul_trunc_clear(Ring x0, Ring x1, Ring y0, Ring y1, + unsigned s) +{ + const Ring prod = static_cast((x0 + x1) * (y0 + y1)); + const Ring z = static_cast(prod >> s); + const Ring mask = dpf::uniform_sample(); + return mul_trunc_shares{mask, static_cast(z - mask)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +Ring mul_trunc_party(Ring x, Ring y, Ring a, Ring b, Ring c, Ring d_open, + Ring e_open, unsigned s, unsigned party) +{ + (void)x; + (void)y; + Ring z = c; + z = static_cast(z + d_open * b); + z = static_cast(z + e_open * a); + if (party == 0) + z = static_cast(z + d_open * e_open); + return trunc_prob(z, s); +} + +/// @brief Two-party mul_trunc via one Beaver product then local shift. +/// @details Probabilistic trunc: each party shifts its product share. The +/// clear product may need a wider intermediate when `s > 0` (fixed +/// point); for `uint64` the ring multiply wraps — callers that need +/// exact fixed-point should keep operands below `2^{64-s}`. +template +HEDLEY_WARN_UNUSED_RESULT +mul_trunc_shares mul_trunc_pair(Ring x0, Ring x1, Ring y0, Ring y1, + unsigned s) +{ + const Ring a0 = dpf::uniform_sample(); + const Ring b0 = dpf::uniform_sample(); + const Ring a1 = dpf::uniform_sample(); + const Ring b1 = dpf::uniform_sample(); + const Ring a = static_cast(a0 + a1); + const Ring b = static_cast(b0 + b1); + const Ring c = static_cast(a * b); + const Ring c0 = dpf::uniform_sample(); + const Ring c1 = static_cast(c - c0); + const Ring d = static_cast((x0 + x1) - a); + const Ring e = static_cast((y0 + y1) - b); + return mul_trunc_shares{ + mul_trunc_party(x0, y0, a0, b0, c0, d, e, s, 0), + mul_trunc_party(x1, y1, a1, b1, c1, d, e, s, 1)}; +} + +/// @brief Beaver product, then exact trunc by `s` (edaBit wrap), no clear multiply. +template +HEDLEY_WARN_UNUSED_RESULT +mul_trunc_shares mul_exact_trunc(Ring x0, Ring x1, Ring y0, Ring y1, + unsigned s) +{ + auto prod = mul_trunc_pair(x0, x1, y0, y1, 0); + if (s == 0) + return prod; + const unsigned n = static_cast(8u * sizeof(Ring)); + if (s >= n) + throw std::invalid_argument("mul_exact_trunc shift"); + auto prep = make_trunc_exact_prep(n, s); + auto [t0, t1] = trunc_exact_pair(prod.z0, prod.z1, prep); + return mul_trunc_shares{t0, t1}; +} + +} // namespace trunc +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_TRUNC_HPP__ diff --git a/include/dpf/twobit.hpp b/include/dpf/twobit.hpp index 9a29a17..1bd92d0 100644 --- a/include/dpf/twobit.hpp +++ b/include/dpf/twobit.hpp @@ -26,6 +26,13 @@ namespace dpf { /// @brief 2-bit unsigned ring element, packed two bits per lane +/// @note Not a DPF domain. A 2-bit index is `dpf::modint<2>` or `dpf::xint<2>`. +/// Scalar `+` and `-` wrap mod 4. Leaf addition keeps the carry inside +/// the 2-bit lane. +/// @see dpf::bit +/// @see dpf::nyble +/// @see dpf::modint +/// @see dpf::packed enum class twobit : std::uint8_t { zero = 0, @@ -159,6 +166,10 @@ struct bitlength_of_output template <> struct is_packed_subbyte : std::true_type {}; +/// @brief Two-bit lanes add mod 2 (XOR of the packed field). +template <> +struct has_characteristic_two : std::true_type {}; + template <> struct packed_lane_bits : public std::integral_constant {}; diff --git a/include/dpf/uint256_t.hpp b/include/dpf/uint256_t.hpp index 931cc79..89a08e5 100644 --- a/include/dpf/uint256_t.hpp +++ b/include/dpf/uint256_t.hpp @@ -13,6 +13,13 @@ #include "uint256_t/uint256_t.hpp" +// Bit casts between SIMD registers and the uint128/uint256 classes. Those +// classes are not trivial, so memcpy is the C++17 way to move the bytes. +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif + #include "dpf/utils.hpp" #include "dpf/leaf_arithmetic.hpp" @@ -259,4 +266,8 @@ struct to_integral_type } // namespace dpf +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + #endif // LIBDPF_INCLUDE_DPF_UINT256_T_HPP__ diff --git a/include/dpf/utils.hpp b/include/dpf/utils.hpp index 1d69679..3691fe5 100644 --- a/include/dpf/utils.hpp +++ b/include/dpf/utils.hpp @@ -10,6 +10,7 @@ #define LIBDPF_INCLUDE_DPF_UTILS_HPP__ #include +#include #include #include #include @@ -183,6 +184,16 @@ using digest_type = std::array; namespace utils { +/// @brief Byte copy whose destination is `void *`, so `-Wclass-memaccess` does +/// not fire on a class leaf or buffer element. +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +void raw_memcpy(void * dst, const void * src, std::size_t n) noexcept +{ + if (n != 0) + std::memcpy(dst, src, n); +} + /// @brief Ugly hack to implement `constexpr`-frien`dly conditional `throw` /// @tparam Exception exception /// @param b the `b` @@ -526,16 +537,6 @@ struct make_default template static constexpr T make_default_v = make_default::value; -template -static constexpr IntegralT get_node_mask(InputT mask, std::size_t level_index) -{ - using dpf_type = DpfKey; - constexpr auto to_int = to_integral_type{}; - return static_cast(to_int(mask) >> (level_index-1 + dpf_type::lg_outputs_per_leaf)); -} - /// @brief Logical right shift. Offsets at or past the width yield 0 (a `>>` of that /// width is undefined for the native unsigned types). /// @tparam IntegralT integral type @@ -552,6 +553,19 @@ constexpr IntegralT shift_right(IntegralT value, std::size_t offset) noexcept return static_cast(value >> offset); } +template +static constexpr IntegralT get_node_mask(InputT mask, std::size_t level_index) +{ + using dpf_type = DpfKey; + constexpr auto to_int = to_integral_type{}; + // `shift_right` (not a bare `>>`) so a resume at the leaf of a 128-bit + // domain never shifts by the type width. + return shift_right(static_cast(to_int(mask)), + level_index - 1 + dpf_type::lg_outputs_per_leaf); +} + /// @brief Floor of `from_inclusive / 2^lg_opl`. `lg_opl` is `log2(outputs_per_leaf)`. /// @tparam IntegralT integral type /// @param from_inclusive the `from_inclusive` @@ -1304,6 +1318,14 @@ struct flip_msb_for_input } }; +/// @brief Flip the high bit of a signed domain point before the walk. +/// @tparam T input type +/// @param x the point, updated in place +/// @warning Signed integers and `simde_int128` (`uses_signed_msb`) XOR the +/// MSB so negative values sort below non-negative ones. Unsigned +/// types, `modint`, and `xint` are unchanged. The flip is not part +/// of the value the caller passed. +/// @see dpf::utils::uses_signed_msb template inline void flip_msb_if_signed_integral(T & x) { @@ -1322,7 +1344,7 @@ auto get_common_part_hash(const std::array & correction_wo using zero_type = unsigned char; static constexpr zero_type zero{}; - SHA256 h; + class SHA256 h; digest_type digest; h.add(&correction_words, sizeof(correction_words)); @@ -1353,7 +1375,7 @@ auto get_common_part_hash(const std::array & correction_wo using zero_type = unsigned char; static constexpr zero_type zero{}; - SHA256 h; + class SHA256 h; digest_type digest; h.add(&correction_words, sizeof(correction_words)); diff --git a/include/dpf/vec.hpp b/include/dpf/vec.hpp index 6b1f982..00e4dcf 100644 --- a/include/dpf/vec.hpp +++ b/include/dpf/vec.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,12 @@ namespace dpf /// @brief `N` lanes of `T`, combined componentwise with no carry between lanes. /// @tparam T lane type. Its `+`, `-`, and `*` are used per lane /// @tparam N number of lanes +/// @note Not a DPF domain. Lane 0 is the least-significant lane. `operator+` +/// is one operation of `T` per lane, O(N), and does not carry. +/// @see dpf::twobit +/// @see dpf::nyble +/// @see dpf::modint +/// @see dpf::xint template struct vec { @@ -44,6 +51,43 @@ struct vec HEDLEY_NO_THROW constexpr vec() noexcept = default; + /// @brief Stretch a PRG block into one group element, lane 0 first. + /// @details Deterministic. Comparison keygen calls this on each child + /// node, so both parties derive the same element. Extra lanes are a + /// public mix of that block, not a second tree. + /// @param bytes the PRG output + /// @param n the number of bytes available + /// @return the vector + HEDLEY_NO_THROW + static vec from_seed(const void * bytes, std::size_t n) noexcept + { + unsigned char block[16]{}; + if (bytes != nullptr && n != 0) + std::memcpy(block, bytes, n < sizeof(block) ? n : sizeof(block)); + std::uint64_t s0 = 0; + std::uint64_t s1 = 0; + std::memcpy(&s0, block, 8); + std::memcpy(&s1, block + 8, 8); + auto rotl = [](std::uint64_t x, int k) noexcept { + return (x << k) | (x >> (64 - k)); + }; + vec out; + auto * dst = reinterpret_cast(out.lanes.data()); + std::size_t filled = 0; + constexpr std::size_t need = sizeof(out.lanes); + while (filled < need) + { + const std::uint64_t r = s0 + s1; + s1 ^= s0; + s0 = rotl(s0, 24) ^ s1 ^ (s1 << 16); + s1 = rotl(s1, 37); + const std::size_t take = std::min(8, need - filled); + std::memcpy(dst + filled, &r, take); + filled += take; + } + return out; + } + /// @brief Mutable lane `i`. /// @param i the lane index /// @return a reference to that lane diff --git a/include/dpf/verifiable.hpp b/include/dpf/verifiable.hpp index 8f8e525..fba3873 100644 --- a/include/dpf/verifiable.hpp +++ b/include/dpf/verifiable.hpp @@ -1,7 +1,8 @@ /// @file dpf/verifiable.hpp /// @brief Verifiable evaluation tokens and extractable-key helpers. -/// @details VDPF proof fold follows de Castro–Polychroniadou (hash-based -/// correction seeds, 2λ-bit tokens, equality Verify). Extractable +/// @details VDPF proof fold follows de Castro and Polychroniadou, EUROCRYPT 2022 +/// (ePrint 2021/580): hash-based correction seeds (their H outputs 4λ +/// bits), 2λ-bit tokens, equality Verify. Extractable /// checks are public-part equality, ROM-style leaf XOF, and an /// field of order `2^61 - 1` weight-1 subset sketch. Phantom tags /// `dpf::verifiable` / `dpf::extractable` live in placement.hpp. @@ -12,6 +13,7 @@ #ifndef LIBDPF_INCLUDE_DPF_VERIFIABLE_HPP__ #define LIBDPF_INCLUDE_DPF_VERIFIABLE_HPP__ +#include #include #include #include @@ -30,6 +32,7 @@ #include "dpf/xor_wrapper.hpp" #include "dpf/twiddle.hpp" #include "dpf/utils.hpp" +#include "dpf/random.hpp" namespace dpf { @@ -76,8 +79,11 @@ HEDLEY_PURE cs_block hash_node(std::size_t level, psnip_uint64_t x_bits, simde__m128i seed) noexcept { + // Low 16 bits carry the level (and optional domain tags such as + // `blocked::fold_spine_tag`). Native depths fit in 8 bits, so existing + // untagged levels keep the same digest as `level & 0xff`. const simde__m128i tagged = simde_mm_xor_si128(seed, - simde_mm_set_epi64x(static_cast(0x5600 | (level & 0xff)), + simde_mm_set_epi64x(static_cast(0x5600 | (level & 0xffff)), static_cast(x_bits))); return cs_block{ mmo(tagged, 0), @@ -160,6 +166,87 @@ void fold_node(proof_token & pi, std::size_t level, pi = xor_proof(pi, h0(mixed)); } +/// @brief Mix public bytes into `pi` under domain tag `tag` (leaf / value CW). +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +void fold_bytes(proof_token & pi, std::size_t tag, const void * data, + std::size_t nbytes) noexcept +{ + const auto * p = static_cast(data); + // Build a 4-block digest the same shape as `hash_node`, then fold like + // `fold_node` with control bit 0 (no CS). Putting the same lane in + // mixed[0]/mixed[2] would cancel under `h0` when `pi` is still zero. + simde__m128i state = simde_mm_set_epi64x( + static_cast(0x4C00 | (tag & 0xffff)), + static_cast(nbytes)); + for (std::size_t off = 0; off < nbytes; ) + { + alignas(16) unsigned char block[16]{}; + const std::size_t take = std::min(std::size_t{16}, nbytes - off); + std::memcpy(block, p + off, take); + simde__m128i chunk; + std::memcpy(&chunk, block, 16); + state = simde_mm_xor_si128(state, chunk); + state = mmo(state, static_cast(0x4Cu + (off & 0xffu))); + off += take; + } + const cs_block digest{ + mmo(state, 0), mmo(state, 1), mmo(state, 2), mmo(state, 3)}; + cs_block mixed{ + simde_mm_xor_si128(pi[0], digest[0]), + simde_mm_xor_si128(pi[1], digest[1]), + digest[2], + digest[3]}; + pi = xor_proof(pi, h0(mixed)); +} + +template +struct key_binds_cmp_values : std::false_type +{ }; +template +struct key_binds_cmp_values().has_cmp()), + decltype(std::declval().value_cw()), + decltype(std::declval().cw_last_word())>> + : std::true_type +{ }; + +/// @brief Fold the public leaf correction word(s) and comparison value words. +/// @details Binds the output share: a leaf or value-word tamper diverges `π`. +template +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +void fold_output_binding(proof_token & pi, const KeyT & key) noexcept +{ + if constexpr (KeyT::num_outputs > 0) + { + std::size_t slot = 0; + std::apply([&](const auto & ...leaf) { + ((fold_bytes(pi, 0x4C00u | (slot++), + &leaf.get(), sizeof(leaf.get()))), ...); + }, key.leaf_nodes); + } + if constexpr (key_binds_cmp_values::value) + { + if (key.has_cmp()) + { + const auto & vcw = key.value_cw(); + if (vcw.size() > 0) + fold_bytes(pi, 0x56, vcw.data(), + sizeof(vcw[0]) * vcw.size()); + const auto last = key.cw_last_word(); + fold_bytes(pi, 0x57, &last, sizeof(last)); + if constexpr (KeyT::cmp_block > 0) + { + const auto & tails = key.tail_cw(); + if (tails.size() > 0) + fold_bytes(pi, 0x58, tails.data(), + sizeof(tails[0]) * tails.size()); + } + } + } +} + HEDLEY_NO_THROW inline void leaf_xof(simde__m128i seed, simde__m128i * HEDLEY_RESTRICT out, psnip_uint32_t count, psnip_uint32_t pos = 0) noexcept @@ -196,7 +283,8 @@ HEDLEY_NO_THROW HEDLEY_ALWAYS_INLINE void init_proof(proof_token & pi, const KeyT & /*key*/) noexcept { - // Running proof starts at 0; each fold mixes in corrected leaf digests. + // Running proof starts at 0. Path folds and a final `fold_output_binding` + // (leaf / value words) are applied by the prove entry point. pi = zero_proof(); } @@ -224,15 +312,20 @@ prove_ref prove(proof_token & t) noexcept return prove_ref{t}; } -/// @brief Whether two proof tokens are identical. +/// @brief Whether two proof tokens are identical and non-zero. +/// @details The all-zero token is never accepted: a fresh proof that folded +/// no nodes would otherwise match another empty token. /// @param a the first token /// @param b the second token -/// @return `true` when every byte matches +/// @return `true` when every byte matches and the token is not all zeros HEDLEY_NO_THROW HEDLEY_ALWAYS_INLINE HEDLEY_PURE bool verify(const proof_token & a, const proof_token & b) noexcept { + if (detail::vdpf::proof_equal(a, detail::vdpf::zero_proof()) + || detail::vdpf::proof_equal(b, detail::vdpf::zero_proof())) + return false; return detail::vdpf::proof_equal(a, b); } @@ -257,6 +350,8 @@ bool verify_batch(Range0 && left, Range1 && right) b = detail::vdpf::xor_proof(b, *it1); a[0] = detail::vdpf::mmo(a[0], 1); b[0] = detail::vdpf::mmo(b[0], 1); + a[1] = detail::vdpf::mmo(a[1], 2); + b[1] = detail::vdpf::mmo(b[1], 2); } if (it0 != end0 || it1 != end1) return false; @@ -339,6 +434,307 @@ bool sketch_verify(sketch_share s0, sketch_share s1) noexcept return (z2 * z2) == (z1 * z3); } +/// @brief Fold payload shares into `out` when `KeyT` is extractable; no-op else. +/// @details Default eval never calls this. Party / sketch protocols opt in. +template +HEDLEY_ALWAYS_INLINE +void note_sketch(sketch_share & out, YRange && ys, RRange && rs) noexcept +{ + if constexpr (KeyT::is_extractable) + out = sketch_fold(std::forward(ys), std::forward(rs)); + else + (void)out, (void)ys, (void)rs; +} + +/// @brief A sketch accumulator the caller owns, passed into evaluation. +/// @details Challenges `r` are chosen by the caller. Each written extractable +/// output consumes the next challenge, matching `prove(π)`. +struct sketch_ref +{ + /// @brief Running sketch moments. + sketch_share & share; + /// @brief Challenge sequence, one per written output. + const fp61 * rs = nullptr; + /// @brief Number of challenges. + std::size_t n = 0; + /// @brief Next challenge index. + std::size_t i = 0; + + /// @brief Bind `s` to challenges `[first, first + count)`. + HEDLEY_NO_THROW + sketch_ref(sketch_share & s, const fp61 * first, std::size_t count) noexcept + : share{s}, rs{first}, n{count}, i{0} + { } + + /// @brief Fold one payload into the running sketch. + /// @tparam Y integer convertible to `fp61` (extractable codomain) + /// @param y the payload share + template + HEDLEY_ALWAYS_INLINE + void absorb(Y y) noexcept + { + if (i >= n || rs == nullptr) + return; + const fp61 yy{y}; + const fp61 r = rs[i++]; + const fp61 r2 = r * r; + share.z1 = share.z1 + yy; + share.z2 = share.z2 + yy * r; + share.z3 = share.z3 + yy * r2; + } +}; + +/// @brief Bind `s` and challenge range `rs` as the sketch for one evaluation. +/// @tparam RRange contiguous range of `fp61` challenges +/// @param s the sketch to update +/// @param rs the challenges, one per written output +/// @return a `sketch_ref` bound to `s` and `rs` +template +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +sketch_ref sketch(sketch_share & s, RRange && rs) noexcept +{ + const auto * first = std::data(rs); + const auto count = static_cast(std::size(rs)); + return sketch_ref{s, first, count}; +} + +// --------------------------------------------------------------------------- +// Shark-style information-theoretic output MAC +// --------------------------------------------------------------------------- + +/// @brief Phantom request tag: wrap the final group share in an output MAC. +/// @details Distinct from `verifiable` (path proof). An aggregate evaluation +/// must fold a path proof first; the MAC only binds the share that +/// proof covers. A MAC on a bare parity bit is not offered. +struct output_mac +{ + static constexpr bool is_output_mac_tag = true; +}; + +template +struct is_output_mac_tag : std::false_type +{ }; +template <> +struct is_output_mac_tag : std::true_type +{ }; +template +inline constexpr bool is_output_mac_tag_v = + is_output_mac_tag>::value; + +/// @brief Global MAC key `Δ`. Sampled by the dealer for the session. +/// @tparam Ring payload ring +template +struct mac_key +{ + Ring delta{}; +}; + +/// @brief Additive share of `(y, y·Δ)`. +/// @tparam Ring payload ring +template +struct mac_share +{ + Ring value{}; + Ring tag{}; +}; + +/// @brief Sample a fresh MAC key. +/// @tparam Ring payload ring +/// @return a dealer key `Δ` +template +HEDLEY_WARN_UNUSED_RESULT +mac_key sample_mac_key() +{ + return mac_key{dpf::uniform_sample()}; +} + +/// @brief Authenticate a cleartext `y` under `key`, returning party shares. +/// @tparam Ring payload ring +/// @param y the cleartext payload +/// @param key the session MAC key +/// @return additive shares of `(y, y·Δ)` +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, mac_share> mac_share_value( + const Ring & y, const mac_key & key) +{ + const Ring y0 = dpf::uniform_sample(); + const Ring t0 = dpf::uniform_sample(); + const Ring y1 = static_cast(y - y0); + const Ring t1 = static_cast(y * key.delta - t0); + return {mac_share{y0, t0}, mac_share{y1, t1}}; +} + +/// @brief Authenticate existing additive shares under `key` (dealer knows both). +/// @tparam Ring payload ring +/// @param y0 party 0's share of the payload +/// @param y1 party 1's share of the payload +/// @param key the session MAC key +/// @return the same value shares, with fresh tag shares of `(y0+y1)·Δ` +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, mac_share> mac_authenticate( + const Ring & y0, const Ring & y1, const mac_key & key) +{ + const Ring y = static_cast(y0 + y1); + const Ring t0 = dpf::uniform_sample(); + const Ring t1 = static_cast(y * key.delta - t0); + return {mac_share{y0, t0}, mac_share{y1, t1}}; +} + +/// @brief Local public scale of an authenticated share. +/// @tparam Ring payload ring +/// @param s the authenticated share +/// @param c the public coefficient +/// @return `(c·value, c·tag)` +template +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +mac_share mac_scale(mac_share s, const Ring & c) noexcept +{ + return mac_share{ + static_cast(s.value * c), + static_cast(s.tag * c)}; +} + +/// @brief Local addition of authenticated shares. +/// @tparam Ring payload ring +/// @param a the first share +/// @param b the second share +/// @return the lane-wise sum of values and tags +template +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +mac_share mac_add(mac_share a, mac_share b) noexcept +{ + return mac_share{ + static_cast(a.value + b.value), + static_cast(a.tag + b.tag)}; +} + +/// @brief Whether the opened shares satisfy `tag = value · Δ`. +/// @details Algebraic check only. Beaver δ-MACs use this path via +/// `verify_delta` / `auth_split::verify`. DPF output MACs must call +/// the overload that also takes path-proof tokens. +/// @tparam Ring payload ring +/// @param s0 party 0's authenticated share +/// @param s1 party 1's authenticated share +/// @param key the session MAC key +/// @return `false` when the tag does not match the opened value +template +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +bool mac_verify(mac_share s0, mac_share s1, + const mac_key & key) noexcept +{ + const Ring y = static_cast(s0.value + s1.value); + const Ring t = static_cast(s0.tag + s1.tag); + return t == static_cast(y * key.delta); +} + +/// @brief Whether a DPF output MAC is valid under a verified path proof. +/// @details Rejects when either token is the all-zero proof or `verify(π0, π1)` +/// fails, then checks `tag = value · Δ`. +/// @tparam Ring payload ring +/// @param s0 party 0's authenticated share +/// @param s1 party 1's authenticated share +/// @param key the session MAC key +/// @param pi0 party 0's path-proof token from the same evaluation +/// @param pi1 party 1's path-proof token from the same evaluation +/// @return `false` when the proof or the tag check fails +template +HEDLEY_NO_THROW +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +bool mac_verify(mac_share s0, mac_share s1, + const mac_key & key, const proof_token & pi0, + const proof_token & pi1) noexcept +{ + if (detail::vdpf::proof_equal(pi0, detail::vdpf::zero_proof()) + || detail::vdpf::proof_equal(pi1, detail::vdpf::zero_proof())) + return false; + if (!verify(pi0, pi1)) + return false; + return mac_verify(s0, s1, key); +} + +/// @brief Batch-check authenticated shares with public coefficients `coeffs`. +/// @details Forms `Σ c_i · share_i` locally and verifies the single MAC. +/// @tparam Ring payload ring +/// @tparam ShareRange0 range of `mac_share` for party 0 +/// @tparam ShareRange1 range of `mac_share` for party 1 +/// @tparam CoeffRange range of public `Ring` coefficients +/// @param left party 0 authenticated shares +/// @param right party 1 authenticated shares +/// @param coeffs public coefficients, one per share +/// @param key the session MAC key +/// @return `false` when the ranges differ in length or the folded MAC fails +template +bool mac_verify_batch(ShareRange0 && left, ShareRange1 && right, + CoeffRange && coeffs, const mac_key & key) +{ + mac_share a{}; + mac_share b{}; + auto it0 = std::begin(left); + auto it1 = std::begin(right); + auto ic = std::begin(coeffs); + const auto end0 = std::end(left); + const auto end1 = std::end(right); + const auto endc = std::end(coeffs); + for (; it0 != end0 && it1 != end1 && ic != endc; ++it0, ++it1, ++ic) + { + a = mac_add(a, mac_scale(*it0, *ic)); + b = mac_add(b, mac_scale(*it1, *ic)); + } + if (it0 != end0 || it1 != end1 || ic != endc) + return false; + return mac_verify(a, b, key); +} + +/// @brief Batch DPF output-MAC check under a verified path-proof batch. +/// @details Folds shares with `coeffs`, then requires a non-zero verified +/// proof batch before accepting the algebraic MAC. +/// @tparam Ring payload ring +/// @tparam ShareRange0 range of `mac_share` for party 0 +/// @tparam ShareRange1 range of `mac_share` for party 1 +/// @tparam CoeffRange range of public `Ring` coefficients +/// @tparam ProofRange0 range of `proof_token` for party 0 +/// @tparam ProofRange1 range of `proof_token` for party 1 +/// @param left party 0 authenticated shares +/// @param right party 1 authenticated shares +/// @param coeffs public coefficients, one per share +/// @param key the session MAC key +/// @param proofs0 party 0 path-proof tokens, same order as the shares +/// @param proofs1 party 1 path-proof tokens, same order as the shares +/// @return `false` when lengths differ, a proof is zero, proofs fail, or the MAC fails +template +bool mac_verify_batch(ShareRange0 && left, ShareRange1 && right, + CoeffRange && coeffs, const mac_key & key, ProofRange0 && proofs0, + ProofRange1 && proofs1) +{ + for (const auto & p : proofs0) + { + if (detail::vdpf::proof_equal(p, detail::vdpf::zero_proof())) + return false; + } + for (const auto & p : proofs1) + { + if (detail::vdpf::proof_equal(p, detail::vdpf::zero_proof())) + return false; + } + if (!verify_batch(std::forward(proofs0), + std::forward(proofs1))) + return false; + return mac_verify_batch(std::forward(left), + std::forward(right), std::forward(coeffs), key); +} + template struct has_dpf_fp61 : std::false_type { }; @@ -349,9 +745,7 @@ struct has_dpf_fp61::dpf_fp61)>> template struct extractable_codomain_ok - : std::bool_constant< - (utils::bitlength_of_v> >= 128) - || has_dpf_fp61::value> + : std::bool_constant::value> { }; template struct extractable_codomain_ok, void> diff --git a/include/dpf/wildcard.hpp b/include/dpf/wildcard.hpp index 3ffe9b9..82e3a25 100644 --- a/include/dpf/wildcard.hpp +++ b/include/dpf/wildcard.hpp @@ -36,6 +36,13 @@ namespace dpf /// @brief represents a placeholder value of a given type, with a concrete value to be assigned later /// @tparam T the underlying type +/// @note As an output, `eval` throws until the leaf is assigned. As an input, +/// `make_dpf` plants a random mask in `offset_x`; parties open +/// `mask - alpha` and eval before that throws. `float` and `double` +/// wildcards combine by bitwise XOR, not IEEE addition. +/// @see dpf::offset_wrapper +/// @see dpf::leaf_wrapper +/// @see dpf::wildcards template struct wildcard_value { @@ -119,6 +126,11 @@ template constexpr auto concrete_value_v = concrete_value{}; namespace wildcards { +/// @name Named placeholders +/// @{ + +/// @brief Empty `wildcard_value` for the named type. `ieee_float` and `ieee_double` use bitwise XOR, not IEEE addition. +/// @see dpf::wildcard_value using bit_t = wildcard_value; static constexpr auto bit = wildcard; @@ -212,6 +224,8 @@ HEDLEY_PRAGMA(GCC diagnostic pop) /// @brief Placeholder for a `double` whose leaf group is bitwise XOR. static constexpr auto ieee_double = wildcard; +/// @} + } // namespace wildcards template ` is +/// `xor_wrapper>`. +/// @see dpf::modint +/// @see dpf::xint /// @author Ryan Henry /// @copyright Copyright (c) 2019-2024 Ryan Henry and [others](@ref authors) /// @license Released under a GNU General Public v2.0 (GPLv2) license; @@ -30,6 +34,13 @@ namespace dpf { +/// @brief Element of `GF(2)^n` wrapped around `T`. +/// @tparam T integer-like value. `n` is `bitlength_of`. +/// @note `dpf::xint` is `xor_wrapper>`. Use it as a domain when +/// the index is an XOR share. The additive ring of the same width is +/// `modint`. +/// @see dpf::modint +/// @see dpf::xints::xintN_t template struct xor_wrapper { @@ -304,12 +315,22 @@ struct xor_wrapper friend struct utils::mod_pow_2; }; +/// @brief XOR ring of width `Nbits`, `xor_wrapper>`. +/// @tparam Nbits width in bits, 1 through 256 +/// @see dpf::modint +/// @see dpf::xints::xintN_t template using xint = xor_wrapper>; namespace xints { +/// @name xintN_t +/// @{ + +/// @brief `xintN_t` is `dpf::xint` for N from 1 through 256. +/// @see dpf::xint +/// @see dpf::modint // 1--9 using xint1_t = xint<1>; using xint2_t = xint<2>; @@ -593,6 +614,8 @@ using xint254_t = xint<254>; using xint255_t = xint<255>; using xint256_t = xint<256>; +/// @} + namespace literals = dpf::literals::xints; } // namespace xints @@ -603,6 +626,11 @@ namespace literals namespace xints { +/// @name xint literals `N_xN` +/// @{ + +/// @brief Decimal literal for `dpf::xint`. Widths through 64 take an integer; wider widths take a digit string. +/// @see dpf::xints::xintN_t // 1--9 constexpr static auto operator "" _x1(unsigned long long int x) { return dpf::xints::xint1_t{static_cast(x)}; } constexpr static auto operator "" _x2(unsigned long long int x) { return dpf::xints::xint2_t{static_cast(x)}; } @@ -886,6 +914,8 @@ template constexpr static auto operator "" _x254() { utils::con template constexpr static auto operator "" _x255() { utils::constexpr_maybe_throw(!(std::isdigit(digits) && ...), "invalid char"); uint256_t x{0}; ((x = x * 10 + (digits - '0')), ...); return dpf::xints::xint255_t{x}; } template constexpr static auto operator "" _x256() { utils::constexpr_maybe_throw(!(std::isdigit(digits) && ...), "invalid char"); uint256_t x{0}; ((x = x * 10 + (digits - '0')), ...); return dpf::xints::xint256_t{x}; } +/// @} + } // namespace xints } // namespace literals diff --git a/include/dpf/yao.hpp b/include/dpf/yao.hpp new file mode 100644 index 0000000..7f3448b --- /dev/null +++ b/include/dpf/yao.hpp @@ -0,0 +1,686 @@ +/// @file dpf/yao.hpp +/// @brief Semi-honest garbled netlist for a boolean function of a DPF leaf. +/// @details The key still computes the point, the comparison, the interval, and +/// a public-offset polynomial. This header is the step after a leaf +/// share exists and the next function is a straight-line bit circuit +/// the key does not contain. The circuit this library is built around +/// is the zero-key AES-MMO block the PRG already uses, so a seed or a +/// leaf can enter that block without being opened. +/// +/// Free-XOR and half-gates (Zahur, Rosulek, and Evans, ePrint 2014/756). +/// A secret if/else or a k-way switch is `dpf/yao_stack.hpp`: stacked +/// garbling (Heath and Kolesnikov, CRYPTO 2020) and one-hot garbling +/// (Heath and Kolesnikov, CCS 2021). The netlist below is unchanged. +/// Party 0 garbles. Party 1 evaluates. A shared input is the XOR of +/// the two parties' bits. A private input is known to one party. +/// Each output is an XOR share: the garbler's share is the permute +/// bit of the zero-label, and the evaluator's share is the color of +/// the label it holds. XOR of the two shares is the output bit. +/// +/// The gate hash is fixed-key AES in the same Matyas–Meyer–Oseas +/// shape as `iknp::detail::ot_hash`, with a distinct tweak. Tables +/// are one-time. Gate ids increase by one per AND and are never +/// reused. There is no Yao domain on the composer. A ring share +/// becomes these bits through `dpf/yao_share.hpp`, then comes back +/// the same way. Comparisons and public-offset LUTs stay on the key. +/// +/// `session` keeps the IKNP base OT. The first `eval` that needs a +/// choice label runs Chou–Orlandi; later evals on that session only +/// extend. Do not interleave `iknp::sample` on the same channel. +/// +/// Ideal functionality (semi-honest): both parties input the bits named by +/// the netlist; each receives an XOR share of every output wire. Party 0 +/// does not learn party 1's private bits or party 1's shares. Party 1 does +/// not learn party 0's private bits, party 0's shares, or `Δ`. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_YAO_HPP__ +#define LIBDPF_INCLUDE_DPF_YAO_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" +#include "simde/simde/x86/avx2.h" + +#include "dpf/iknp.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" + +namespace dpf +{ +namespace yao +{ + +using block = simde__m128i; + +/// @brief One wire in a `netlist`. Valid only for the netlist that minted it. +struct bit +{ + std::uint32_t id = 0; +}; + +/// @brief Who knows an input wire. +enum class input : unsigned char +{ + shared = 0, ///< XOR of the two parties' bits + priv0 = 1, ///< party 0's private bit + priv1 = 2 ///< party 1's private bit +}; + +namespace detail +{ + +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +block xor_b(block a, block b) noexcept +{ + return simde_mm_xor_si128(a, b); +} + +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +block zero_b() noexcept +{ + return simde_mm_setzero_si128(); +} + +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +std::uint8_t lsb(block x) noexcept +{ + unsigned char b = 0; + std::memcpy(&b, &x, 1); + return static_cast(b & 1u); +} + +HEDLEY_ALWAYS_INLINE +HEDLEY_PURE +HEDLEY_NO_THROW +block with_lsb(block x, std::uint8_t bit) noexcept +{ + unsigned char b = 0; + std::memcpy(&b, &x, 1); + b = static_cast((b & 0xfeu) | (bit & 1u)); + std::memcpy(&x, &b, 1); + return x; +} + +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +block mask_bit(std::uint8_t bit, block delta) noexcept +{ + return (bit & 1u) ? delta : zero_b(); +} + +/// @brief Correlation-robust hash for one half-gate. Tweak `2·gid` is the +/// left wire and `2·gid+1` is the right wire. Both labels of one wire +/// use the same tweak. +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +block cr_hash(block x, std::uint64_t tweak) noexcept +{ + const prg::purpose_scope counted(prg::purpose::hash); + const auto mixed = xor_b(x, simde_mm_set_epi64x( + static_cast(tweak >> 32), + static_cast(static_cast(tweak)))); + return prg::aes128::eval(mixed, + static_cast(tweak * 0x9E3779B9u) ^ 0xC3A5u); +} + +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +block random_delta() noexcept +{ + return with_lsb(dpf::uniform_sample(), 1); +} + +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +block random_label() noexcept +{ + return dpf::uniform_sample(); +} + +/// @brief Half-gates AND. `la0` and `lb0` are zero-labels. `table[0]` and +/// `table[1]` are the two ciphertexts. Returns the output zero-label. +/// Matches `halfgates_garble` / `halfgates_eval` in EMP-toolkit. +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +block and_garble(block la0, block lb0, block delta, std::uint64_t gid, + block table[2]) noexcept +{ + const bool pa = lsb(la0) != 0; + const bool pb = lsb(lb0) != 0; + const block ha0 = cr_hash(la0, gid * 2u); + const block ha1 = cr_hash(xor_b(la0, delta), gid * 2u); + const block hb0 = cr_hash(lb0, gid * 2u + 1u); + const block hb1 = cr_hash(xor_b(lb0, delta), gid * 2u + 1u); + table[0] = xor_b(xor_b(ha0, ha1), pb ? delta : zero_b()); + block w0 = xor_b(ha0, pa ? table[0] : zero_b()); + const block tmp = xor_b(hb0, hb1); + table[1] = xor_b(tmp, la0); + w0 = xor_b(w0, hb0); + w0 = xor_b(w0, pb ? tmp : zero_b()); + return w0; +} + +HEDLEY_ALWAYS_INLINE +HEDLEY_NO_THROW +block and_eval(block a, block b, std::uint64_t gid, const block table[2]) noexcept +{ + const bool sa = lsb(a) != 0; + const bool sb = lsb(b) != 0; + block w = xor_b(cr_hash(a, gid * 2u), cr_hash(b, gid * 2u + 1u)); + if (sa) + w = xor_b(w, table[0]); + if (sb) + { + w = xor_b(w, table[1]); + w = xor_b(w, a); + } + return w; +} + +inline void require_bit(std::uint8_t b, const char * what) +{ + if (b > 1u) + throw std::invalid_argument(what); +} + +} // namespace detail + +/// @brief Straight-line circuit: XOR, AND, XNOR, NOT, and XOR with a public bit. +/// @details XOR, XNOR, and NOT are free. Each AND is one garbled row (32 bytes). +/// Wires are SSA. There is no secret shift, no memory, and no loop. +class netlist +{ +public: + enum class op : unsigned char + { + xor_ = 0, + and_ = 1, + not_ = 2 + }; + + struct gate + { + op code = op::xor_; + std::uint32_t a = 0; + std::uint32_t b = 0; + }; + + HEDLEY_WARN_UNUSED_RESULT + bit shared_in() + { + return push_in(input::shared); + } + + /// @param owner 0 or 1 + HEDLEY_WARN_UNUSED_RESULT + bit priv_in(unsigned owner) + { + if (owner > 1u) + throw std::invalid_argument("yao: input owner"); + return push_in(owner == 0 ? input::priv0 : input::priv1); + } + + HEDLEY_WARN_UNUSED_RESULT + bit xor_(bit a, bit b) + { + check(a); + check(b); + gates_.push_back(gate{op::xor_, a.id, b.id}); + return bit{nwire() - 1u}; + } + + HEDLEY_WARN_UNUSED_RESULT + bit and_(bit a, bit b) + { + check(a); + check(b); + gates_.push_back(gate{op::and_, a.id, b.id}); + ++n_and_; + return bit{nwire() - 1u}; + } + + HEDLEY_WARN_UNUSED_RESULT + bit xnor_(bit a, bit b) + { + return not_(xor_(a, b)); + } + + HEDLEY_WARN_UNUSED_RESULT + bit not_(bit a) + { + check(a); + gates_.push_back(gate{op::not_, a.id, 0}); + return bit{nwire() - 1u}; + } + + /// @brief XOR `x` with a public bit. A zero bit returns `x`. + HEDLEY_WARN_UNUSED_RESULT + bit xor_public(bit x, std::uint8_t public_bit) + { + check(x); + if ((public_bit & 1u) == 0) + return x; + return not_(x); + } + + void out(bit x) + { + check(x); + outs_.push_back(x.id); + } + + std::uint32_t n_in() const noexcept + { + return static_cast(kinds_.size()); + } + + std::uint32_t n_out() const noexcept + { + return static_cast(outs_.size()); + } + + std::uint32_t n_and() const noexcept { return n_and_; } + + std::uint32_t nwire() const noexcept + { + return static_cast(kinds_.size() + gates_.size()); + } + + /// @brief Bytes of garbled AND rows (`32 · n_and`). + std::size_t table_bytes() const noexcept + { + return static_cast(n_and_) * 32u; + } + + input kind_at(std::uint32_t i) const + { + return kinds_.at(i); + } + + const std::vector & gates() const noexcept { return gates_; } + const std::vector & outputs() const noexcept { return outs_; } + +private: + bit push_in(input k) + { + if (!gates_.empty() || !outs_.empty()) + throw std::logic_error("yao: inputs are declared before gates"); + kinds_.push_back(k); + return bit{n_in() - 1u}; + } + + void check(bit x) const + { + if (x.id >= nwire()) + throw std::invalid_argument("yao: wire"); + } + + std::vector kinds_; + std::vector gates_; + std::vector outs_; + std::uint32_t n_and_ = 0; +}; + +namespace detail +{ + +struct garbled +{ + block delta{}; + std::vector z; + std::vector tables; + std::vector direct; + std::vector ot0; + std::vector ot1; + std::vector share; +}; + +inline void garble_gates(const netlist & nl, block delta, std::vector & z, + std::vector & tables) +{ + tables.clear(); + tables.reserve(static_cast(nl.n_and()) * 2u); + std::uint64_t gid = 0; + const auto & gates = nl.gates(); + const std::uint32_t base = nl.n_in(); + for (std::uint32_t gi = 0; gi < gates.size(); ++gi) + { + const auto & g = gates[gi]; + const std::uint32_t dst = base + gi; + switch (g.code) + { + case netlist::op::xor_: + z[dst] = xor_b(z[g.a], z[g.b]); + break; + case netlist::op::not_: + z[dst] = xor_b(z[g.a], delta); + break; + case netlist::op::and_: + { + block row[2]; + z[dst] = and_garble(z[g.a], z[g.b], delta, gid, row); + tables.push_back(row[0]); + tables.push_back(row[1]); + ++gid; + break; + } + } + } +} + +inline std::vector eval_active(const netlist & nl, + const block * tables, std::vector & w) +{ + std::uint64_t gid = 0; + std::size_t ti = 0; + const auto & gates = nl.gates(); + const std::uint32_t base = nl.n_in(); + const std::size_t ntable = static_cast(nl.n_and()) * 2u; + for (std::uint32_t gi = 0; gi < gates.size(); ++gi) + { + const auto & g = gates[gi]; + const std::uint32_t dst = base + gi; + switch (g.code) + { + case netlist::op::xor_: + w[dst] = xor_b(w[g.a], w[g.b]); + break; + case netlist::op::not_: + w[dst] = w[g.a]; + break; + case netlist::op::and_: + if (ti + 2u > ntable) + throw std::runtime_error("yao: truncated garbled tables"); + w[dst] = and_eval(w[g.a], w[g.b], gid, tables + ti); + ti += 2u; + ++gid; + break; + } + } + std::vector share(nl.n_out()); + const auto & outs = nl.outputs(); + for (std::uint32_t i = 0; i < outs.size(); ++i) + share[i] = lsb(w[outs[i]]); + return share; +} + +inline void check_party_bits(const netlist & nl, int me, const std::uint8_t * in) +{ + if (me != 0 && me != 1) + throw std::invalid_argument("yao: party"); + if (nl.n_in() != 0 && in == nullptr) + throw std::invalid_argument("yao: missing inputs"); + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + { + const auto k = nl.kind_at(i); + const bool used = k == input::shared + || (k == input::priv0 && me == 0) + || (k == input::priv1 && me == 1); + if (used) + require_bit(in[i], "yao: input bit"); + } +} + +inline garbled garble_party0(const netlist & nl, const std::uint8_t * p0) +{ + check_party_bits(nl, 0, p0); + garbled g; + g.delta = random_delta(); + g.z.assign(nl.nwire(), zero_b()); + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + { + const block lg = random_label(); + switch (nl.kind_at(i)) + { + case input::shared: + { + const block le = random_label(); + g.z[i] = xor_b(lg, le); + g.direct.push_back(xor_b(lg, mask_bit(p0[i], g.delta))); + g.ot0.push_back(le); + g.ot1.push_back(xor_b(le, g.delta)); + break; + } + case input::priv0: + g.z[i] = lg; + g.direct.push_back(xor_b(lg, mask_bit(p0[i], g.delta))); + break; + case input::priv1: + g.z[i] = lg; + g.ot0.push_back(lg); + g.ot1.push_back(xor_b(lg, g.delta)); + break; + } + } + garble_gates(nl, g.delta, g.z, g.tables); + g.share.resize(nl.n_out()); + const auto & outs = nl.outputs(); + for (std::uint32_t i = 0; i < outs.size(); ++i) + g.share[i] = lsb(g.z[outs[i]]); + return g; +} + +inline std::vector eval_party1(const netlist & nl, + const std::vector & tables, const std::vector & direct, + const std::vector & chosen) +{ + if (tables.size() != static_cast(nl.n_and()) * 2u) + throw std::runtime_error("yao: table size"); + std::vector w(nl.nwire(), zero_b()); + std::size_t di = 0; + std::size_t oi = 0; + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + { + switch (nl.kind_at(i)) + { + case input::shared: + if (di >= direct.size() || oi >= chosen.size()) + throw std::runtime_error("yao: input label count"); + w[i] = xor_b(direct[di++], chosen[oi++]); + break; + case input::priv0: + if (di >= direct.size()) + throw std::runtime_error("yao: input label count"); + w[i] = direct[di++]; + break; + case input::priv1: + if (oi >= chosen.size()) + throw std::runtime_error("yao: input label count"); + w[i] = chosen[oi++]; + break; + } + } + if (di != direct.size() || oi != chosen.size()) + throw std::runtime_error("yao: input label count"); + return eval_active(nl, tables.data(), w); +} + +} // namespace detail + +/// @brief Cleartext walk. `semantic[i]` is the bit on input wire `i`. +HEDLEY_WARN_UNUSED_RESULT +inline std::vector eval_plain(const netlist & nl, + const std::uint8_t * semantic) +{ + if (nl.n_in() != 0 && semantic == nullptr) + throw std::invalid_argument("yao: missing inputs"); + std::vector w(nl.nwire(), 0); + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + { + detail::require_bit(semantic[i], "yao: input bit"); + w[i] = semantic[i]; + } + const auto & gates = nl.gates(); + const std::uint32_t base = nl.n_in(); + for (std::uint32_t gi = 0; gi < gates.size(); ++gi) + { + const auto & g = gates[gi]; + const std::uint32_t dst = base + gi; + switch (g.code) + { + case netlist::op::xor_: + w[dst] = static_cast(w[g.a] ^ w[g.b]); + break; + case netlist::op::and_: + w[dst] = static_cast(w[g.a] & w[g.b]); + break; + case netlist::op::not_: + w[dst] = static_cast(w[g.a] ^ 1u); + break; + } + } + std::vector out(nl.n_out()); + const auto & outs = nl.outputs(); + for (std::uint32_t i = 0; i < outs.size(); ++i) + out[i] = w[outs[i]]; + return out; +} + +/// @brief Garble and evaluate in one process. Returns both XOR shares. +/// @details `p0` and `p1` use the same layout as `session::eval`. The +/// reconstructed bit is `first[i] XOR second[i]`. +HEDLEY_WARN_UNUSED_RESULT +inline std::pair, std::vector> +eval_pair(const netlist & nl, const std::uint8_t * p0, const std::uint8_t * p1) +{ + detail::check_party_bits(nl, 0, p0); + detail::check_party_bits(nl, 1, p1); + auto g = detail::garble_party0(nl, p0); + std::vector chosen; + chosen.reserve(g.ot0.size()); + std::size_t oi = 0; + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + { + const auto k = nl.kind_at(i); + if (k != input::shared && k != input::priv1) + continue; + if (oi >= g.ot0.size()) + throw std::logic_error("yao: ot count"); + chosen.push_back((p1[i] & 1u) ? g.ot1[oi] : g.ot0[oi]); + ++oi; + } + auto share1 = detail::eval_party1(nl, g.tables, g.direct, chosen); + return {std::move(g.share), std::move(share1)}; +} + +/// @brief One-process garble of a known input. Shared wires take the semantic +/// bit as party 0's share and zero as party 1's share. +HEDLEY_WARN_UNUSED_RESULT +inline std::vector eval_local(const netlist & nl, + const std::uint8_t * semantic) +{ + std::vector p0(nl.n_in(), 0); + std::vector p1(nl.n_in(), 0); + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + { + detail::require_bit(semantic[i], "yao: input bit"); + if (nl.kind_at(i) == input::priv1) + p1[i] = semantic[i]; + else + p0[i] = semantic[i]; + } + auto [a, b] = eval_pair(nl, p0.data(), p1.data()); + for (std::size_t i = 0; i < a.size(); ++i) + a[i] = static_cast(a[i] ^ b[i]); + return a; +} + +/// @brief One party's garbling session. Party 0 always garbles. +/// @details The first `eval` fixes `me`. A second call with the other party +/// id throws. Base OT state stays inside the session. +class session +{ +public: + session() = default; + session(const session &) = delete; + session & operator=(const session &) = delete; + session(session &&) = default; + session & operator=(session &&) = default; + + /// @brief XOR shares of each output wire. + /// @param me 0 (garbler) or 1 (evaluator) + /// @param nl circuit. Both parties pass equal netlists. + /// @param in_bits length `nl.n_in()`. Shared entries are this party's + /// XOR share. `priv0` is read on party 0. `priv1` is read on party 1. + /// @param link peer channel. No other traffic may run on it during `eval`. + HEDLEY_WARN_UNUSED_RESULT + std::vector eval(int me, const netlist & nl, + const std::uint8_t * in_bits, net::channel & link) + { + if (!bound_) + { + if (me != 0 && me != 1) + throw std::invalid_argument("yao: party"); + bound_ = true; + me_ = me; + } + else if (me != me_) + throw std::logic_error("yao: session party is fixed"); + detail::check_party_bits(nl, me, in_bits); + if (me == 0) + { + auto g = detail::garble_party0(nl, in_bits); + std::vector ignored; + iknp::transfer_labels(link, 0, true, ot_, g.ot0, g.ot1, {}, ignored); + std::vector blob; + blob.reserve(g.tables.size() + g.direct.size()); + blob.insert(blob.end(), g.tables.begin(), g.tables.end()); + blob.insert(blob.end(), g.direct.begin(), g.direct.end()); + link.send_vec(blob, net::msg::bytes); + return g.share; + } + std::vector choices; + choices.reserve(nl.n_in()); + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + { + const auto k = nl.kind_at(i); + if (k == input::shared || k == input::priv1) + choices.push_back(in_bits[i]); + } + std::vector chosen; + iknp::transfer_labels(link, 1, false, ot_, {}, {}, choices, chosen); + const auto blob = link.recv_vec(net::msg::bytes); + const std::size_t ntable = static_cast(nl.n_and()) * 2u; + std::size_t ndirect = 0; + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + { + const auto k = nl.kind_at(i); + if (k == input::shared || k == input::priv0) + ++ndirect; + } + if (blob.size() != ntable + ndirect) + throw std::runtime_error("yao: garbled payload size"); + std::vector tables(ntable); + std::vector direct(ndirect); + if (ntable != 0) + std::memcpy(tables.data(), blob.data(), ntable * sizeof(block)); + if (ndirect != 0) + std::memcpy(direct.data(), blob.data() + ntable, ndirect * sizeof(block)); + return detail::eval_party1(nl, tables, direct, chosen); + } + +private: + bool bound_ = false; + int me_ = 0; + iknp::detail::role_state ot_{}; +}; + +} // namespace yao +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_YAO_HPP__ diff --git a/include/dpf/yao_aes.hpp b/include/dpf/yao_aes.hpp new file mode 100644 index 0000000..c0da275 --- /dev/null +++ b/include/dpf/yao_aes.hpp @@ -0,0 +1,550 @@ +/// @file dpf/yao_aes.hpp +/// @brief Garbled AES-128 and the zero-key Matyas–Meyer–Oseas block. +/// @details Both are `netlist`s on `session::eval`. Input and output bits are +/// XOR shares. Within a byte, bit 0 of the 8-bit group is the MSB, +/// matching the Boyar–Peralta S-box in `aes_sbox_bp.hpp`. Bytes of a +/// block are in memory order: byte 0 is the first byte of an +/// `__m128i`. AES-128 includes the key schedule (6400 ANDs). The MMO +/// block uses the public all-zero key already installed in +/// `prg::aes128`, with `pos` mixed into the first round key the same +/// way `prg::aes128::eval` does, then XORs the input (5120 ANDs). +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_YAO_AES_HPP__ +#define LIBDPF_INCLUDE_DPF_YAO_AES_HPP__ + +#include +#include +#include +#include + +#include "hedley/hedley.h" +#include "simde/simde/x86/avx2.h" + +#include "dpf/aes_sbox_bp.hpp" +#include "dpf/yao.hpp" + +namespace dpf +{ +namespace yao +{ + +/// @brief Eight wires, index 0 = MSB. +struct bits8 +{ + std::array b{}; +}; + +/// @brief Pack one byte, MSB at `b[0]`, as eight shared inputs. +HEDLEY_WARN_UNUSED_RESULT +inline bits8 shared_byte(netlist & n) +{ + bits8 o; + for (int i = 0; i < 8; ++i) + o.b[static_cast(i)] = n.shared_in(); + return o; +} + +inline void out_byte(netlist & n, const bits8 & x) +{ + for (int i = 0; i < 8; ++i) + n.out(x.b[static_cast(i)]); +} + +HEDLEY_WARN_UNUSED_RESULT +inline bits8 xor_byte(netlist & n, const bits8 & a, const bits8 & b) +{ + bits8 o; + for (int i = 0; i < 8; ++i) + o.b[static_cast(i)] = n.xor_( + a.b[static_cast(i)], b.b[static_cast(i)]); + return o; +} + +/// @brief XOR a public byte into `x`. Bit 7 of `k` meets `b[0]`. +HEDLEY_WARN_UNUSED_RESULT +inline bits8 xor_public_byte(netlist & n, const bits8 & in, std::uint8_t k) +{ + bits8 x = in; + for (int i = 0; i < 8; ++i) + { + if ((k >> (7 - i)) & 1u) + x.b[static_cast(i)] = + n.not_(x.b[static_cast(i)]); + } + return x; +} + +/// @brief Boyar–Peralta S-box. 32 ANDs. `in[0]` is the MSB. +HEDLEY_WARN_UNUSED_RESULT +inline bits8 sbox(netlist & n, const bits8 & in) +{ + std::array w{}; + for (int i = 0; i < 8; ++i) + w[static_cast(i)] = in.b[static_cast(i)]; + for (std::size_t oi = 0; oi < aes_bp::op_count; ++oi) + { + const auto kind = aes_bp::ops[oi][0]; + const auto dst = aes_bp::ops[oi][1]; + const auto a = aes_bp::ops[oi][2]; + const auto b = aes_bp::ops[oi][3]; + const bit wa = w[a]; + const bit wb = w[b]; + bit d; + if (kind == 0) + d = n.xor_(wa, wb); + else if (kind == 1) + d = n.and_(wa, wb); + else + d = n.xnor_(wa, wb); + w[dst] = d; + } + bits8 o; + for (int i = 0; i < 8; ++i) + o.b[static_cast(i)] = + w[aes_bp::out_wire[static_cast(i)]]; + return o; +} + +/// @brief AES `xtime` (multiply by 2 in GF(2^8)). Linear, no AND. +HEDLEY_WARN_UNUSED_RESULT +inline bits8 xtime(netlist & n, const bits8 & x) +{ + const bit msb = x.b[0]; + bits8 y; + y.b[0] = x.b[1]; + y.b[1] = x.b[2]; + y.b[2] = x.b[3]; + y.b[3] = n.xor_(x.b[4], msb); + y.b[4] = n.xor_(x.b[5], msb); + y.b[5] = x.b[6]; + y.b[6] = n.xor_(x.b[7], msb); + y.b[7] = msb; + return y; +} + +inline void shift_rows(bits8 (& s)[16]) +{ + bits8 t = s[1]; + s[1] = s[5]; + s[5] = s[9]; + s[9] = s[13]; + s[13] = t; + t = s[2]; + s[2] = s[10]; + s[10] = t; + t = s[6]; + s[6] = s[14]; + s[14] = t; + t = s[15]; + s[15] = s[11]; + s[11] = s[7]; + s[7] = s[3]; + s[3] = t; +} + +inline void mix_columns(netlist & n, bits8 (& s)[16]) +{ + for (int c = 0; c < 4; ++c) + { + const int i = c * 4; + const bits8 a = s[i]; + const bits8 b = s[i + 1]; + const bits8 c0 = s[i + 2]; + const bits8 d = s[i + 3]; + const bits8 xa = xtime(n, a); + const bits8 xb = xtime(n, b); + const bits8 xc = xtime(n, c0); + const bits8 xd = xtime(n, d); + s[i] = xor_byte(n, xor_byte(n, xor_byte(n, xor_byte(n, xa, xb), b), c0), d); + s[i + 1] = xor_byte(n, xor_byte(n, xor_byte(n, xor_byte(n, a, xb), xc), c0), d); + s[i + 2] = xor_byte(n, xor_byte(n, xor_byte(n, xor_byte(n, a, b), xc), xd), d); + s[i + 3] = xor_byte(n, xor_byte(n, xor_byte(n, xor_byte(n, xa, a), b), c0), xd); + } +} + +inline void sub_bytes(netlist & n, bits8 (& s)[16]) +{ + for (int i = 0; i < 16; ++i) + s[i] = sbox(n, s[i]); +} + +/// @brief 128 bits, byte 0 first, MSB of each byte first. +HEDLEY_NON_NULL(1) +inline void block_to_bits(std::uint8_t dst[128], block v) noexcept +{ + std::uint8_t raw[16]; + std::memcpy(raw, &v, 16); + for (int i = 0; i < 16; ++i) + { + for (int k = 0; k < 8; ++k) + dst[i * 8 + k] = static_cast((raw[i] >> (7 - k)) & 1u); + } +} + +HEDLEY_WARN_UNUSED_RESULT +HEDLEY_NON_NULL(1) +inline block bits_to_block(const std::uint8_t src[128]) noexcept +{ + std::uint8_t raw[16]{}; + for (int i = 0; i < 16; ++i) + { + for (int k = 0; k < 8; ++k) + raw[i] = static_cast( + raw[i] | (src[i * 8 + k] << (7 - k))); + } + block v; + std::memcpy(&v, raw, 16); + return v; +} + +namespace detail +{ + +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr std::uint8_t xtime_byte(std::uint8_t x) noexcept +{ + return static_cast((x << 1) ^ ((x & 0x80u) ? 0x1bu : 0)); +} + +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr std::uint8_t gmul(std::uint8_t a, std::uint8_t b) noexcept +{ + std::uint8_t p = 0; + for (int i = 0; i < 8; ++i) + { + if (b & 1u) + p = static_cast(p ^ a); + const bool hi = (a & 0x80u) != 0; + a = static_cast(a << 1); + if (hi) + a = static_cast(a ^ 0x1bu); + b = static_cast(b >> 1); + } + return p; +} + +HEDLEY_ALWAYS_INLINE +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr std::uint8_t sbox_byte(std::uint8_t x) noexcept +{ + std::uint8_t inv = 0; + if (x != 0) + { + std::uint8_t r = 1; + std::uint8_t b = x; + for (int e = 0; e < 7; ++e) + { + b = gmul(b, b); + r = gmul(r, b); + } + inv = r; + } + std::uint8_t s = inv; + std::uint8_t b = inv; + for (int i = 0; i < 4; ++i) + { + b = static_cast((b << 1) | (b >> 7)); + s = static_cast(s ^ b); + } + return static_cast(s ^ 0x63); +} + +/// @brief AES-128 key schedule for a public key. Used for the zero key of MMO. +inline void expand_public_key(const std::uint8_t key[16], std::uint8_t rk[11][16]) +{ + std::uint8_t w[176]; + std::memcpy(w, key, 16); + int n = 16; + std::uint8_t rcon = 1; + while (n < 176) + { + std::uint8_t t[4]; + std::memcpy(t, w + n - 4, 4); + if (n % 16 == 0) + { + const std::uint8_t tmp = t[0]; + t[0] = t[1]; + t[1] = t[2]; + t[2] = t[3]; + t[3] = tmp; + for (int i = 0; i < 4; ++i) + t[i] = sbox_byte(t[i]); + t[0] = static_cast(t[0] ^ rcon); + rcon = xtime_byte(rcon); + } + for (int i = 0; i < 4; ++i) + { + w[n] = static_cast(w[n - 16] ^ t[i]); + ++n; + } + } + std::memcpy(rk, w, 176); +} + +inline void read_shared_block(netlist & n, bits8 (& s)[16]) +{ + for (int i = 0; i < 16; ++i) + s[i] = shared_byte(n); +} + +inline void emit_block(netlist & n, const bits8 (& s)[16]) +{ + for (int i = 0; i < 16; ++i) + out_byte(n, s[i]); +} + +inline void add_round_key_public(netlist & n, bits8 (& s)[16], + const std::uint8_t (& rk)[16]) +{ + for (int i = 0; i < 16; ++i) + s[i] = xor_public_byte(n, s[i], rk[i]); +} + +inline void add_round_key_secret(netlist & n, bits8 (& s)[16], + const bits8 (& rk)[16]) +{ + for (int i = 0; i < 16; ++i) + s[i] = xor_byte(n, s[i], rk[i]); +} + +inline void aes_rounds_public_key(netlist & n, bits8 (& s)[16], + const std::uint8_t (& rk)[11][16]) +{ + add_round_key_public(n, s, rk[0]); + for (int r = 1; r < 10; ++r) + { + sub_bytes(n, s); + shift_rows(s); + mix_columns(n, s); + add_round_key_public(n, s, rk[r]); + } + sub_bytes(n, s); + shift_rows(s); + add_round_key_public(n, s, rk[10]); +} + +inline void zero_key_schedule(std::uint8_t (& rk)[11][16]) +{ + const std::uint8_t zero_key[16]{}; + expand_public_key(zero_key, rk); +} + +/// @brief MMO under the zero key. `state` is overwritten with the digest. +/// `msg` is the shared block; `pos` is mixed into round key 0. +inline void apply_zero_key_mmo(netlist & n, bits8 (& state)[16], + const bits8 (& msg)[16], std::uint32_t pos, + const std::uint8_t (& base_rk)[11][16]) +{ + for (int i = 0; i < 16; ++i) + state[i] = msg[i]; + std::uint8_t rk[11][16]; + std::memcpy(rk, base_rk, sizeof(rk)); + rk[0][0] = static_cast(rk[0][0] ^ static_cast(pos)); + rk[0][1] = static_cast(rk[0][1] ^ static_cast(pos >> 8)); + rk[0][2] = static_cast(rk[0][2] ^ static_cast(pos >> 16)); + rk[0][3] = static_cast(rk[0][3] ^ static_cast(pos >> 24)); + aes_rounds_public_key(n, state, rk); + for (int i = 0; i < 16; ++i) + state[i] = xor_byte(n, state[i], msg[i]); +} + +} // namespace detail + +/// @brief AES-128 of a shared block under a shared key. 128 block bits, then +/// 128 key bits, then 128 ciphertext bits. 6400 ANDs. +HEDLEY_WARN_UNUSED_RESULT +inline netlist aes128_netlist() +{ + netlist n; + bits8 state[16]; + bits8 key[16]; + detail::read_shared_block(n, state); + detail::read_shared_block(n, key); + + using word = std::array; + word words[44]; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) + words[i][static_cast(j)] = key[i * 4 + j]; + + std::uint8_t rcon = 0x01; + for (int wi = 4; wi < 44; ++wi) + { + word temp = words[wi - 1]; + if (wi % 4 == 0) + { + const bits8 rot = temp[0]; + temp[0] = temp[1]; + temp[1] = temp[2]; + temp[2] = temp[3]; + temp[3] = rot; + for (int j = 0; j < 4; ++j) + temp[static_cast(j)] = + sbox(n, temp[static_cast(j)]); + temp[0] = xor_public_byte(n, temp[0], rcon); + rcon = detail::xtime_byte(rcon); + } + for (int j = 0; j < 4; ++j) + words[wi][static_cast(j)] = xor_byte(n, + words[wi - 4][static_cast(j)], + temp[static_cast(j)]); + } + + // AddRoundKey, then SubBytes / ShiftRows / MixColumns for rounds 0..8. + // Round 9 skips MixColumns. Round 10 is the last AddRoundKey. + for (int r = 0; r < 11; ++r) + { + bits8 rk[16]; + for (int i = 0; i < 16; ++i) + rk[i] = words[r * 4 + i / 4][static_cast(i % 4)]; + detail::add_round_key_secret(n, state, rk); + if (r == 10) + break; + sub_bytes(n, state); + shift_rows(state); + if (r != 9) + mix_columns(n, state); + } + detail::emit_block(n, state); + return n; +} + +/// @brief One MMO block: `AES_{k=0}(msg XOR pos) XOR msg`, matching +/// `prg::aes128::eval`. 128 shared input bits, 128 shared output bits. +/// `pos` is public and baked into the netlist. +HEDLEY_WARN_UNUSED_RESULT +inline netlist aes_mmo_netlist(std::uint32_t pos) +{ + netlist n; + bits8 msg[16]; + bits8 state[16]; + detail::read_shared_block(n, msg); + for (int i = 0; i < 16; ++i) + state[i] = msg[i]; + + std::uint8_t rk[11][16]; + detail::zero_key_schedule(rk); + detail::apply_zero_key_mmo(n, state, msg, pos, rk); + detail::emit_block(n, state); + return n; +} + +/// @brief Garbled AES-128. `block_share` and `key_share` are 128 XOR shares +/// each, in `block_to_bits` order. Returns 128 XOR shares of the +/// ciphertext. +HEDLEY_WARN_UNUSED_RESULT +inline std::vector aes128(session & s, int me, net::channel & link, + const std::uint8_t block_share[128], const std::uint8_t key_share[128]) +{ + std::vector in(256); + std::memcpy(in.data(), block_share, 128); + std::memcpy(in.data() + 128, key_share, 128); + return s.eval(me, aes128_netlist(), in.data(), link); +} + +/// @brief Garbled zero-key MMO. `msg_share` is 128 XOR shares in +/// `block_to_bits` order. `pos` is public and must match on both sides. +HEDLEY_WARN_UNUSED_RESULT +inline std::vector aes_mmo(session & s, int me, net::channel & link, + const std::uint8_t msg_share[128], std::uint32_t pos) +{ + return s.eval(me, aes_mmo_netlist(pos), msg_share, link); +} + +/// @brief Shared bits of one correction-seed level: eight MMO blocks. +/// @details Matches `detail::vdpf::make_cs` / `party/oblivious_hash.hpp`. +/// Two seeds, four public lanes `0..3` each. 40960 ANDs. +/// The netlist does not depend on the level or the prefix. Those +/// are folded into the input shares by `pack_correction_level`. +inline constexpr std::size_t correction_level_in_bits = 8u * 128u; +inline constexpr std::size_t correction_level_out_bits = 4u * 128u; +inline constexpr std::uint32_t correction_level_ands = + static_cast(8u * 16u * 10u * aes_bp::and_count); + +/// @brief Eight zero-key MMO blocks, lanes 0..3 for each seed, then the XOR +/// of the two seeds' digests. 1024 input bits, 512 output bits. +HEDLEY_WARN_UNUSED_RESULT +inline netlist correction_level_netlist() +{ + netlist n; + bits8 msg[8][16]; + for (int b = 0; b < 8; ++b) + detail::read_shared_block(n, msg[b]); + std::uint8_t rk[11][16]; + detail::zero_key_schedule(rk); + bits8 dig[8][16]; + for (int b = 0; b < 8; ++b) + detail::apply_zero_key_mmo(n, dig[b], msg[b], + static_cast(b & 3), rk); + for (int pos = 0; pos < 4; ++pos) + { + bits8 mixed[16]; + for (int i = 0; i < 16; ++i) + mixed[i] = xor_byte(n, dig[pos][i], dig[4 + pos][i]); + detail::emit_block(n, mixed); + } + return n; +} + +/// @brief This party's 1024 XOR shares for `correction_level_netlist`. +/// @details Party `me` holds `my_seed` in the clear. `prefix_share` is that +/// party's XOR share of the path prefix. The public tag +/// `0x5600 | (level & 0xffff)` is mixed into the owner's share only, +/// matching `hash_node` and `oblivious_cs`. Blocks are owner 0 lanes +/// 0..3, then owner 1 lanes 0..3. +inline void pack_correction_level(int me, block my_seed, + std::uint64_t prefix_share, std::size_t level, + std::uint8_t (& dst)[correction_level_in_bits]) +{ + if (me != 0 && me != 1) + throw std::invalid_argument("yao: party"); + const std::uint64_t tag = 0x5600ull | (level & 0xffffu); + std::uint8_t seed_bytes[16]; + std::memcpy(seed_bytes, &my_seed, 16); + for (int owner = 0; owner < 2; ++owner) + { + for (int pos = 0; pos < 4; ++pos) + { + std::uint8_t raw[16]{}; + if (owner == me) + { + std::memcpy(raw, seed_bytes, 16); + for (int i = 0; i < 8; ++i) + raw[8 + i] = static_cast( + raw[8 + i] ^ static_cast(tag >> (8 * i))); + } + for (int i = 0; i < 8; ++i) + raw[i] = static_cast( + raw[i] ^ static_cast(prefix_share >> (8 * i))); + block blk; + std::memcpy(&blk, raw, 16); + const std::size_t off = static_cast(owner * 4 + pos) * 128u; + block_to_bits(dst + off, blk); + } + } +} + +/// @brief Garbled correction-seed level. Returns 512 XOR shares: four blocks, +/// lane 0 first. XOR of the two parties' outputs is `make_cs`. +HEDLEY_WARN_UNUSED_RESULT +inline std::vector correction_level(session & s, int me, + net::channel & link, block my_seed, std::uint64_t prefix_share, + std::size_t level) +{ + std::uint8_t in[correction_level_in_bits]; + pack_correction_level(me, my_seed, prefix_share, level, in); + return s.eval(me, correction_level_netlist(), in, link); +} + +} // namespace yao +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_YAO_AES_HPP__ diff --git a/include/dpf/yao_share.hpp b/include/dpf/yao_share.hpp new file mode 100644 index 0000000..73b3d55 --- /dev/null +++ b/include/dpf/yao_share.hpp @@ -0,0 +1,247 @@ +/// @file dpf/yao_share.hpp +/// @brief Move a DPF leaf share into the XOR bits a garbled netlist consumes. +/// @details A point leaf is subtractive (`b2y` / `y2b`). A comparison leaf is +/// additive (`a2y` / `y2a`). An `fss_share` opens like a point leaf +/// (`fss2y` / `y2fss`). A replicated leaf that parties 0 and 1 will +/// garble uses `rss2y`; `y2rss` deals a fresh triple of the bits' +/// integer value. +/// +/// The Yao share of that integer is one XOR bit per party, least- +/// significant bit at index 0. Those bytes are what +/// `netlist::shared_in` takes and what `session::eval` returns. +/// The forward calls run edaBit A2B with a GMW carry. The reverse +/// calls run daBit B2A. +/// +/// Both parties' shares are arguments, as in `edabit::a2b_gmw_pair`: +/// the opens are resolved inside the call. Top-level `dpf::rss2y` and +/// `dpf::y2rss` are the local (3,3) casts and are not these functions. +/// +/// `rss2y` keeps parties 0 and 1, the garbler and the evaluator. +/// Party 0's additive share is `x0 + x1` (both components it holds). +/// Party 1's is `x2` (its `next`). Party 2 sends nothing. +/// `y2rss` is called where both Yao shares already sit, and deals a +/// fresh replicated triple of their sum. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_YAO_SHARE_HPP__ +#define LIBDPF_INCLUDE_DPF_YAO_SHARE_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/edabit.hpp" +#include "dpf/ot_pack.hpp" +#include "dpf/random.hpp" +#include "dpf/secret_share.hpp" + +namespace dpf +{ +namespace yao +{ + +namespace detail +{ + +HEDLEY_ALWAYS_INLINE +unsigned width_or_full(unsigned width, unsigned full) +{ + if (width == 0) + return full; + if (width > full) + throw std::invalid_argument("yao: bit width exceeds the ring"); + return width; +} + +HEDLEY_ALWAYS_INLINE +HEDLEY_WARN_UNUSED_RESULT +std::vector unpack_lsb(const std::vector & packed, + unsigned width) +{ + std::vector out(width); + for (unsigned i = 0; i < width; ++i) + out[i] = edabit::detail::get_bit(packed, i); + return out; +} + +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, std::vector> +a2y_raw(Ring x0, Ring x1, unsigned width) +{ + width = width_or_full(width, static_cast(8u * sizeof(Ring))); + auto eda = edabit::sample_edabit_pair(width); + auto packed = edabit::a2b_gmw_pair(eda, x0, x1); + return {unpack_lsb(packed.first, width), unpack_lsb(packed.second, width)}; +} + +template +HEDLEY_WARN_UNUSED_RESULT +std::pair y2a_raw(const std::vector & y0, + const std::vector & y1, unsigned width) +{ + width = width_or_full(width, static_cast(8u * sizeof(Ring))); + if (y0.size() != width || y1.size() != width) + throw std::invalid_argument("yao: bit vector length"); + for (unsigned i = 0; i < width; ++i) + { + if (y0[i] > 1u || y1[i] > 1u) + throw std::invalid_argument("yao: bit value"); + } + Ring s0{}; + Ring s1{}; + for (unsigned i = 0; i < width; ++i) + { + auto dab = ot::sample_dabit_pair(); + const std::uint8_t mask = static_cast( + (y0[i] ^ dab.p0.bit) ^ (y1[i] ^ dab.p1.bit)); + s0 = static_cast(s0 + edabit::b2a_party_bit(y0[i], dab.p0, mask, 0, i)); + s1 = static_cast(s1 + edabit::b2a_party_bit(y1[i], dab.p1, mask, 1, i)); + } + return {s0, s1}; +} + +} // namespace detail + +/// @brief Additive shares to Yao bit shares. LSB at index 0. +/// @param x0 party 0's additive share +/// @param x1 party 1's additive share +/// @param width bit length. 0 means the whole ring +/// @return party 0's bits, then party 1's bits. XOR is the low `width` bits of `x0 + x1` +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, std::vector> +a2y(const additive_share & x0, const additive_share & x1, + unsigned width = 0) +{ + return detail::a2y_raw(x0.raw(), x1.raw(), width); +} + +/// @brief Point-leaf (subtractive) shares to Yao bit shares. +/// @param x0 party 0 +/// @param x1 party 1 +/// @param width bit length. 0 means the whole ring +/// @return XOR bits of `x0 - x1` +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, std::vector> +b2y(const subtractive_share & x0, const subtractive_share & x1, + unsigned width = 0) +{ + return a2y(x0.as_additive(), x1.as_additive(), width); +} + +/// @brief `fss_share` to Yao bit shares. Same opening as a point leaf. +/// @param x0 party 0 +/// @param x1 party 1 +/// @param width bit length. 0 means the whole ring +/// @return XOR bits of the subtractive opening +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, std::vector> +fss2y(const fss_share & x0, const fss_share & x1, + unsigned width = 0) +{ + return a2y(x0.as_additive(), x1.as_additive(), width); +} + +/// @brief Replicated shares to Yao bit shares for the garbler and the evaluator. +/// @details Party 0 contributes `own + next` (`x0 + x1`). Party 1 contributes +/// `next` (`x2`). `r0.next` must equal `r1.own`. Party 2 is idle. +/// @param r0 party 0 +/// @param r1 party 1 +/// @param width bit length. 0 means the whole ring +/// @return XOR bits of `x0 + x1 + x2` for parties 0 and 1 +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, std::vector> +rss2y(const replicated_share & r0, const replicated_share & r1, + unsigned width = 0) +{ + if (r0.next != r1.own) + throw std::invalid_argument("yao: rss components disagree on x1"); + const Ring a0 = static_cast(r0.own + r0.next); + const Ring a1 = r1.next; + return detail::a2y_raw(a0, a1, width); +} + +/// @brief Yao bit shares back to additive shares. +/// @param y0 party 0's bits, LSB at index 0, one byte per bit +/// @param y1 party 1's bits +/// @param width bit length. 0 means `y0.size()` +/// @return additive shares of the integer those bits encode +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, additive_share> +y2a(const std::vector & y0, const std::vector & y1, + unsigned width = 0) +{ + if (width == 0) + width = static_cast(y0.size()); + auto [s0, s1] = detail::y2a_raw(y0, y1, width); + return {additive_share::from_raw(s0), + additive_share::from_raw(s1)}; +} + +/// @brief Yao bit shares back to a point-leaf (subtractive) sharing. +/// @param y0 party 0's bits +/// @param y1 party 1's bits +/// @param width bit length. 0 means `y0.size()` +/// @return subtractive shares of the integer those bits encode +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, subtractive_share> +y2b(const std::vector & y0, const std::vector & y1, + unsigned width = 0) +{ + auto [a0, a1] = y2a(y0, y1, width); + return {a0.as_subtractive(), a1.as_subtractive()}; +} + +/// @brief Yao bit shares back to `fss_share`. +/// @param y0 party 0's bits +/// @param y1 party 1's bits +/// @param width bit length. 0 means `y0.size()` +/// @return FSS shares of the integer those bits encode +template +HEDLEY_WARN_UNUSED_RESULT +std::pair, fss_share> +y2fss(const std::vector & y0, const std::vector & y1, + unsigned width = 0) +{ + auto [a0, a1] = y2a(y0, y1, width); + return {a0.as_fss(), a1.as_fss()}; +} + +/// @brief Yao bit shares to a fresh replicated triple of the same integer. +/// @details Both bit vectors are arguments, so their sum is already available +/// to the caller. The three components are a new sharing of that sum. +/// @param y0 party 0's bits +/// @param y1 party 1's bits +/// @param width bit length. 0 means `y0.size()` +/// @return replicated shares for parties 0, 1, and 2 +template +HEDLEY_WARN_UNUSED_RESULT +std::tuple, replicated_share, replicated_share> +y2rss(const std::vector & y0, const std::vector & y1, + unsigned width = 0) +{ + auto [a0, a1] = y2a(y0, y1, width); + const Ring secret = static_cast(a0.raw() + a1.raw()); + const Ring x0 = dpf::uniform_sample(); + const Ring x1 = dpf::uniform_sample(); + const Ring x2 = static_cast(secret - x0 - x1); + return dpf::make_replicated_shares(x0, x1, x2); +} + +} // namespace yao +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_YAO_SHARE_HPP__ diff --git a/include/dpf/yao_stack.hpp b/include/dpf/yao_stack.hpp new file mode 100644 index 0000000..a10dbca --- /dev/null +++ b/include/dpf/yao_stack.hpp @@ -0,0 +1,577 @@ +/// @file dpf/yao_stack.hpp +/// @brief Stacked and one-hot garbling of half-gate netlists. +/// @details A conditional sends one string of AND rows, as long as the heavier +/// branch, not the sum. Each branch is garbled from a seed that is the +/// hash of the control label for that semantic bit. The generator XORs +/// the two materials. The evaluator holds one control label, so she +/// can regenerate the active seed herself. A two-row ciphertext under +/// that label delivers the inactive seed. She rebuilds the inactive +/// material, XORs it out of the stack, and evaluates the branch she +/// actually holds. Output labels are translated into one common +/// free-XOR encoding, four rows per output bit, so the garbler's share +/// does not depend on which branch ran. +/// +/// A k-way switch is the same stack over k seeds. The selector is a +/// short bit string. The demux row for the selector color carries the +/// inactive seeds. The mux has two rows per selector color. +/// @note Stacked garbling: David Heath and Vladimir Kolesnikov, "Stacked +/// Garbling: Garbled Circuit Proportional to Longest Execution Path," +/// CRYPTO 2020 (ePrint 2020/973). One-hot garbling: David Heath and +/// Vladimir Kolesnikov, CCS 2021. Gate rows remain half-gates (Zahur, +/// Rosulek, and Evans, EUROCRYPT 2015). +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license; +/// see [LICENSE.md](@ref license) for details. + +#ifndef LIBDPF_INCLUDE_DPF_YAO_STACK_HPP__ +#define LIBDPF_INCLUDE_DPF_YAO_STACK_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" +#include "dpf/yao.hpp" + +namespace dpf +{ +namespace yao +{ + +/// @brief What a stacked conditional or a one-hot switch sent, and the shares. +struct stack_result +{ + std::vector share0; + std::vector share1; + /// @brief AND-row blocks on the stack (two per AND of the heaviest branch). + std::size_t stack_blocks = 0; + /// @brief AND-row blocks if every branch were sent on its own. + std::size_t naive_blocks = 0; + /// @brief Mux / demux blocks on top of the stack. + std::size_t extra_blocks = 0; +}; + +namespace stack_detail +{ + +using detail::and_eval; +using detail::and_garble; +using detail::lsb; +using detail::mask_bit; +using detail::require_bit; +using detail::with_lsb; +using detail::xor_b; +using detail::zero_b; + +struct rng +{ + block seed{}; + std::uint32_t n = 0; + + block next() + { + return prg::aes128::eval(seed, n++); + } +}; + +struct seeded +{ + block delta{}; + std::vector z; + std::vector tables; + std::vector lg; + std::vector le; +}; + +inline block hash_at(block x, std::uint32_t pos) +{ + const prg::purpose_scope counted(prg::purpose::hash); + return prg::aes128::eval(x, pos); +} + +inline seeded garble_seeded(const netlist & nl, block seed) +{ + rng r; + r.seed = seed; + seeded g; + g.delta = with_lsb(r.next(), 1); + g.z.assign(nl.nwire(), zero_b()); + g.lg.resize(nl.n_in()); + g.le.resize(nl.n_in()); + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + { + const block lg = r.next(); + g.lg[i] = lg; + switch (nl.kind_at(i)) + { + case input::shared: + { + const block le = r.next(); + g.le[i] = le; + g.z[i] = xor_b(lg, le); + break; + } + case input::priv0: + g.z[i] = lg; + break; + case input::priv1: + g.z[i] = lg; + break; + } + } + g.tables.reserve(static_cast(nl.n_and()) * 2u); + std::uint64_t gid = 0; + const auto & gates = nl.gates(); + const std::uint32_t base = nl.n_in(); + for (std::uint32_t gi = 0; gi < gates.size(); ++gi) + { + const auto & gate = gates[gi]; + const std::uint32_t dst = base + gi; + switch (gate.code) + { + case netlist::op::xor_: + g.z[dst] = xor_b(g.z[gate.a], g.z[gate.b]); + break; + case netlist::op::not_: + g.z[dst] = xor_b(g.z[gate.a], g.delta); + break; + case netlist::op::and_: + { + block row[2]; + g.z[dst] = and_garble(g.z[gate.a], g.z[gate.b], g.delta, gid, row); + g.tables.push_back(row[0]); + g.tables.push_back(row[1]); + ++gid; + break; + } + } + } + return g; +} + +inline std::vector eval_labels(const netlist & nl, const seeded & g, + const block * tables, const std::uint8_t * p0, const std::uint8_t * p1) +{ + detail::check_party_bits(nl, 0, p0); + detail::check_party_bits(nl, 1, p1); + std::vector w(nl.nwire(), zero_b()); + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + { + switch (nl.kind_at(i)) + { + case input::shared: + { + const block direct = xor_b(g.lg[i], mask_bit(p0[i], g.delta)); + const block chosen = (p1[i] & 1u) ? xor_b(g.le[i], g.delta) : g.le[i]; + w[i] = xor_b(direct, chosen); + break; + } + case input::priv0: + w[i] = xor_b(g.lg[i], mask_bit(p0[i], g.delta)); + break; + case input::priv1: + w[i] = (p1[i] & 1u) ? xor_b(g.lg[i], g.delta) : g.lg[i]; + break; + } + } + std::uint64_t gid = 0; + std::size_t ti = 0; + const auto & gates = nl.gates(); + const std::uint32_t base = nl.n_in(); + for (std::uint32_t gi = 0; gi < gates.size(); ++gi) + { + const auto & gate = gates[gi]; + const std::uint32_t dst = base + gi; + switch (gate.code) + { + case netlist::op::xor_: + w[dst] = xor_b(w[gate.a], w[gate.b]); + break; + case netlist::op::not_: + w[dst] = w[gate.a]; + break; + case netlist::op::and_: + w[dst] = and_eval(w[gate.a], w[gate.b], gid, tables + ti); + ti += 2u; + ++gid; + break; + } + } + std::vector outs; + outs.reserve(nl.n_out()); + for (std::uint32_t id : nl.outputs()) + outs.push_back(w[id]); + return outs; +} + +inline std::vector pad_to(std::vector m, std::size_t n, block seed) +{ + std::uint32_t i = 0; + while (m.size() < n) + m.push_back(prg::aes128::eval(seed, i++)); + return m; +} + +inline std::vector xor_vec(const std::vector & a, + const std::vector & b) +{ + if (a.size() != b.size()) + throw std::logic_error("yao stack: length"); + std::vector out(a.size()); + for (std::size_t i = 0; i < a.size(); ++i) + out[i] = xor_b(a[i], b[i]); + return out; +} + +inline block fold_labels(const std::vector & labels) +{ + const prg::purpose_scope counted(prg::purpose::hash); + block acc = zero_b(); + for (std::size_t i = 0; i < labels.size(); ++i) + acc = prg::aes128::eval(xor_b(acc, labels[i]), + static_cast(i + 1)); + return acc; +} + +inline void require_same_outs(const netlist & a, const netlist & b) +{ + if (a.n_out() != b.n_out() || a.n_out() == 0) + throw std::invalid_argument("yao stack: outputs"); +} + +} // namespace stack_detail + +/// @brief Secret if/else. Branch 0 runs when the shared control bit is 0. +/// @details `then_nl` and `else_nl` may differ in size and in their inputs. +/// `*_p0[i]` / `*_p1[i]` are that party's bit on input `i` of that +/// branch, with the same layout as `yao::eval_pair`. The control bit +/// is `control_p0 XOR control_p1`. +HEDLEY_WARN_UNUSED_RESULT +inline stack_result eval_if(const netlist & then_nl, const netlist & else_nl, + std::uint8_t control_p0, std::uint8_t control_p1, + const std::uint8_t * then_p0, const std::uint8_t * then_p1, + const std::uint8_t * else_p0, const std::uint8_t * else_p1) +{ + stack_detail::require_same_outs(then_nl, else_nl); + stack_detail::require_bit(control_p0, "yao stack: control"); + stack_detail::require_bit(control_p1, "yao stack: control"); + const std::uint8_t sem = + static_cast(control_p0 ^ control_p1); + + const block delta = stack_detail::with_lsb(dpf::uniform_sample(), 1); + const block lg = dpf::uniform_sample(); + const block le = dpf::uniform_sample(); + const block z = stack_detail::xor_b(lg, le); + const block direct = stack_detail::xor_b(lg, stack_detail::mask_bit(control_p0, delta)); + const block chosen = (control_p1 & 1u) + ? stack_detail::xor_b(le, delta) : le; + const block active_ctl = stack_detail::xor_b(direct, chosen); + const block l0 = z; + const block l1 = stack_detail::xor_b(z, delta); + const block seed0 = stack_detail::hash_at(l0, 11); + const block seed1 = stack_detail::hash_at(l1, 11); + + auto g0 = stack_detail::garble_seeded(then_nl, seed0); + auto g1 = stack_detail::garble_seeded(else_nl, seed1); + const std::size_t n = std::max(g0.tables.size(), g1.tables.size()); + const block pad_seed = stack_detail::hash_at( + stack_detail::xor_b(seed0, seed1), 19); + auto m0 = stack_detail::pad_to(g0.tables, n, pad_seed); + auto m1 = stack_detail::pad_to(g1.tables, n, pad_seed); + const auto stacked = stack_detail::xor_vec(m0, m1); + + block ct[2]; + ct[stack_detail::lsb(l0)] = stack_detail::xor_b( + stack_detail::hash_at(l0, 23), seed1); + ct[stack_detail::lsb(l1)] = stack_detail::xor_b( + stack_detail::hash_at(l1, 23), seed0); + const block inactive_seed = stack_detail::xor_b( + stack_detail::hash_at(active_ctl, 23), + ct[stack_detail::lsb(active_ctl)]); + const block active_seed = stack_detail::hash_at(active_ctl, 11); + const block expect_inactive = (sem == 0) ? seed1 : seed0; + const block expect_active = (sem == 0) ? seed0 : seed1; + if (std::memcmp(&inactive_seed, &expect_inactive, sizeof(block)) != 0 + || std::memcmp(&active_seed, &expect_active, sizeof(block)) != 0) + throw std::logic_error("yao stack: control seed"); + + const auto & active_nl = (sem == 0) ? then_nl : else_nl; + const auto & inactive_nl = (sem == 0) ? else_nl : then_nl; + const stack_detail::seeded & active_g = (sem == 0) ? g0 : g1; + auto rebuilt = stack_detail::garble_seeded(inactive_nl, inactive_seed); + auto inactive_m = stack_detail::pad_to(std::move(rebuilt.tables), n, pad_seed); + auto opened = stack_detail::xor_vec(stacked, inactive_m); + if (active_g.tables.size() > opened.size()) + throw std::logic_error("yao stack: short stack"); + const std::uint8_t * ap0 = (sem == 0) ? then_p0 : else_p0; + const std::uint8_t * ap1 = (sem == 0) ? then_p1 : else_p1; + auto outs = stack_detail::eval_labels(active_nl, active_g, opened.data(), ap0, ap1); + + const block common_delta = stack_detail::with_lsb(dpf::uniform_sample(), 1); + stack_result result; + result.stack_blocks = n; + result.naive_blocks = g0.tables.size() + g1.tables.size(); + result.extra_blocks = 2u + static_cast(then_nl.n_out()) * 4u; + result.share0.resize(then_nl.n_out()); + result.share1.resize(then_nl.n_out()); + const auto & outs0 = then_nl.outputs(); + const auto & outs1 = else_nl.outputs(); + for (std::uint32_t i = 0; i < then_nl.n_out(); ++i) + { + const block common_zero = dpf::uniform_sample(); + block table[4]; + for (unsigned cc = 0; cc < 2; ++cc) + { + for (unsigned oc = 0; oc < 2; ++oc) + { + const block ctl = (stack_detail::lsb(l0) == cc) ? l0 : l1; + const std::uint8_t sem_c = static_cast( + cc ^ stack_detail::lsb(l0)); + const stack_detail::seeded & br = (sem_c == 0) ? g0 : g1; + const std::uint32_t oid = (sem_c == 0) ? outs0[i] : outs1[i]; + const std::uint8_t sem_o = static_cast( + oc ^ stack_detail::lsb(br.z[oid])); + const block ol = stack_detail::xor_b(br.z[oid], + stack_detail::mask_bit(sem_o, br.delta)); + const block common = stack_detail::xor_b(common_zero, + stack_detail::mask_bit(sem_o, common_delta)); + const unsigned idx = (cc << 1u) | oc; + table[idx] = stack_detail::xor_b(common, + stack_detail::hash_at( + stack_detail::xor_b(ctl, ol), 40u + idx)); + } + } + const unsigned idx = (static_cast(stack_detail::lsb(active_ctl)) << 1u) + | stack_detail::lsb(outs[i]); + const block got = stack_detail::xor_b(table[idx], + stack_detail::hash_at( + stack_detail::xor_b(active_ctl, outs[i]), 40u + idx)); + result.share0[i] = stack_detail::lsb(common_zero); + result.share1[i] = stack_detail::lsb(got); + } + return result; +} + +/// @brief Secret choice of branch `index_p0 XOR index_p1`. +/// @details `k` is `branches.size()`, from 2 to 8. The index uses the low +/// `ceil(log2(k))` bits. Every branch has the same output count. +/// `p0[b]` / `p1[b]` are that party's input bits for branch `b`. +HEDLEY_WARN_UNUSED_RESULT +inline stack_result eval_one_hot(const std::vector & branches, + std::uint16_t index_p0, std::uint16_t index_p1, + const std::vector> & p0, + const std::vector> & p1) +{ + const std::size_t k = branches.size(); + if (k < 2 || k > 8) + throw std::invalid_argument("yao stack: one-hot width"); + if (p0.size() != k || p1.size() != k) + throw std::invalid_argument("yao stack: one-hot inputs"); + for (std::size_t i = 1; i < k; ++i) + stack_detail::require_same_outs(branches[0], branches[i]); + unsigned width = 1; + while ((1u << width) < k) + ++width; + const std::uint16_t index = static_cast(index_p0 ^ index_p1); + if (index >= k) + throw std::invalid_argument("yao stack: index"); + + const block delta = stack_detail::with_lsb(dpf::uniform_sample(), 1); + std::vector zbit(width); + std::vector active_bit(width); + for (unsigned b = 0; b < width; ++b) + { + const block lg = dpf::uniform_sample(); + const block le = dpf::uniform_sample(); + zbit[b] = stack_detail::xor_b(lg, le); + const std::uint8_t bit0 = static_cast((index_p0 >> b) & 1u); + const std::uint8_t bit1 = static_cast((index_p1 >> b) & 1u); + const block direct = stack_detail::xor_b(lg, stack_detail::mask_bit(bit0, delta)); + const block chosen = (bit1 != 0) ? stack_detail::xor_b(le, delta) : le; + active_bit[b] = stack_detail::xor_b(direct, chosen); + } + + auto pattern_labels = [&](std::uint16_t pattern) { + std::vector labels(width); + for (unsigned b = 0; b < width; ++b) + { + const std::uint8_t bit = static_cast((pattern >> b) & 1u); + labels[b] = stack_detail::xor_b(zbit[b], + stack_detail::mask_bit(bit, delta)); + } + return labels; + }; + + const unsigned npat = 1u << width; + std::vector seeds(k); + std::vector garbled(k); + std::size_t naive = 0; + std::size_t heaviest = 0; + for (std::uint16_t i = 0; i < k; ++i) + { + seeds[i] = stack_detail::hash_at( + stack_detail::fold_labels(pattern_labels(i)), 11); + garbled[i] = stack_detail::garble_seeded(branches[i], seeds[i]); + naive += garbled[i].tables.size(); + heaviest = std::max(heaviest, garbled[i].tables.size()); + } + const block pad_seed = stack_detail::hash_at(seeds[0], 19); + std::vector stacked(heaviest, stack_detail::zero_b()); + for (std::size_t i = 0; i < k; ++i) + { + auto padded = stack_detail::pad_to(garbled[i].tables, heaviest, pad_seed); + stacked = stack_detail::xor_vec(stacked, padded); + } + + // Demux: one row per selector color, payload is the XOR of inactive seeds + // so the evaluator can subtract them after regenerating each inactive + // material. Each inactive seed is delivered explicitly (k blocks per row). + std::vector> demux(npat); + for (unsigned color = 0; color < npat; ++color) + { + std::uint16_t sem_idx = 0; + std::vector color_labels(width); + for (unsigned b = 0; b < width; ++b) + { + const std::uint8_t cbit = static_cast((color >> b) & 1u); + const std::uint8_t sbit = static_cast( + cbit ^ stack_detail::lsb(zbit[b])); + sem_idx = static_cast(sem_idx | (sbit << b)); + color_labels[b] = stack_detail::xor_b(zbit[b], + stack_detail::mask_bit(sbit, delta)); + } + const block row_key = stack_detail::fold_labels(color_labels); + demux[color].assign(k, stack_detail::zero_b()); + if (sem_idx >= k) + continue; + for (std::uint16_t j = 0; j < k; ++j) + { + if (j == sem_idx) + continue; + demux[color][j] = stack_detail::xor_b(seeds[j], + stack_detail::hash_at(row_key, + static_cast(100u + j))); + } + } + + std::uint16_t active_color = 0; + for (unsigned b = 0; b < width; ++b) + active_color = static_cast( + active_color | (stack_detail::lsb(active_bit[b]) << b)); + std::vector active_labels(width); + for (unsigned b = 0; b < width; ++b) + active_labels[b] = active_bit[b]; + const block active_key = stack_detail::fold_labels(active_labels); + std::vector inactive_seeds(k); + for (std::uint16_t j = 0; j < k; ++j) + { + if (j == index) + continue; + inactive_seeds[j] = stack_detail::xor_b(demux[active_color][j], + stack_detail::hash_at(active_key, + static_cast(100u + j))); + } + + std::vector opened = stacked; + for (std::uint16_t j = 0; j < k; ++j) + { + if (j == index) + continue; + auto rebuilt = stack_detail::garble_seeded(branches[j], inactive_seeds[j]); + auto padded = stack_detail::pad_to(std::move(rebuilt.tables), heaviest, pad_seed); + opened = stack_detail::xor_vec(opened, padded); + } + const std::size_t live = static_cast(branches[index].n_and()) * 2u; + if (opened.size() < live) + throw std::logic_error("yao stack: one-hot short"); + // Re-garble the active branch from the seed the evaluator can derive, + // and check the unstacked prefix matches. Evaluation uses `opened`. + const block expect_seed = stack_detail::hash_at( + stack_detail::fold_labels(pattern_labels(index)), 11); + auto active_g = stack_detail::garble_seeded(branches[index], expect_seed); + if (active_g.tables.size() != live) + throw std::logic_error("yao stack: one-hot rows"); + for (std::size_t t = 0; t < live; ++t) + { + const block diff = stack_detail::xor_b(opened[t], active_g.tables[t]); + unsigned char bytes[sizeof(block)]; + std::memcpy(bytes, &diff, sizeof(block)); + for (unsigned char c : bytes) + if (c != 0) + throw std::logic_error("yao stack: unstack mismatch"); + } + + if (p0[index].size() < branches[index].n_in() + || p1[index].size() < branches[index].n_in()) + throw std::invalid_argument("yao stack: input length"); + auto outs = stack_detail::eval_labels(branches[index], active_g, opened.data(), + p0[index].data(), p1[index].data()); + + const block common_delta = stack_detail::with_lsb(dpf::uniform_sample(), 1); + stack_result result; + result.stack_blocks = heaviest; + result.naive_blocks = naive; + result.extra_blocks = static_cast(npat) * k + + static_cast(branches[0].n_out()) * npat * 2u; + result.share0.resize(branches[0].n_out()); + result.share1.resize(branches[0].n_out()); + for (std::uint32_t oi = 0; oi < branches[0].n_out(); ++oi) + { + const block common_zero = dpf::uniform_sample(); + std::vector table(static_cast(npat) * 2u); + for (unsigned color = 0; color < npat; ++color) + { + std::uint16_t sem_idx = 0; + std::vector color_labels(width); + for (unsigned b = 0; b < width; ++b) + { + const std::uint8_t cbit = static_cast((color >> b) & 1u); + const std::uint8_t sbit = static_cast( + cbit ^ stack_detail::lsb(zbit[b])); + sem_idx = static_cast(sem_idx | (sbit << b)); + color_labels[b] = stack_detail::xor_b(zbit[b], + stack_detail::mask_bit(sbit, delta)); + } + for (unsigned oc = 0; oc < 2; ++oc) + { + const std::size_t idx = static_cast(color) * 2u + oc; + if (sem_idx >= k) + { + table[idx] = dpf::uniform_sample(); + continue; + } + auto bg = stack_detail::garble_seeded(branches[sem_idx], seeds[sem_idx]); + const std::uint32_t oid = branches[sem_idx].outputs()[oi]; + const std::uint8_t sem_o = static_cast( + oc ^ stack_detail::lsb(bg.z[oid])); + const block ol = stack_detail::xor_b(bg.z[oid], + stack_detail::mask_bit(sem_o, bg.delta)); + const block common = stack_detail::xor_b(common_zero, + stack_detail::mask_bit(sem_o, common_delta)); + const block key = stack_detail::xor_b( + stack_detail::fold_labels(color_labels), ol); + table[idx] = stack_detail::xor_b(common, + stack_detail::hash_at(key, static_cast(200u + idx))); + } + } + const std::size_t idx = static_cast(active_color) * 2u + + stack_detail::lsb(outs[oi]); + const block key = stack_detail::xor_b(active_key, outs[oi]); + const block got = stack_detail::xor_b(table[idx], + stack_detail::hash_at(key, static_cast(200u + idx))); + result.share0[oi] = stack_detail::lsb(common_zero); + result.share1[oi] = stack_detail::lsb(got); + } + return result; +} + +} // namespace yao +} // namespace dpf + +#endif // LIBDPF_INCLUDE_DPF_YAO_STACK_HPP__ diff --git a/include/grotto.hpp b/include/grotto.hpp index 709eeba..f53ffba 100644 --- a/include/grotto.hpp +++ b/include/grotto.hpp @@ -30,8 +30,34 @@ #include "grotto/window_lut.hpp" +#include "grotto/dwt_lut.hpp" + +#include "grotto/exact_steps.hpp" + +#include "grotto/closed_form.hpp" + #include "grotto/prefix_parity.hpp" #include "grotto/offset_horner.hpp" +#include "grotto/offset_poly.hpp" + +#include "grotto/lut_union.hpp" + +#include "grotto/offset_jet.hpp" + +#include "grotto/offset_repr.hpp" + +#include "grotto/offset_twist.hpp" + +#include "grotto/residue.hpp" + +#include "grotto/ring_switch.hpp" + +#include "grotto/carry_plan.hpp" + +#include "grotto/carry.hpp" + +#include "grotto/fixedpoint_beaver.hpp" + #endif // LIBDPF_INCLUDE_GROTTO_HPP__ diff --git a/include/grotto/carry.hpp b/include/grotto/carry.hpp new file mode 100644 index 0000000..dafa406 --- /dev/null +++ b/include/grotto/carry.hpp @@ -0,0 +1,976 @@ +/// @file grotto/carry.hpp +/// @brief Carry-in, carry-out, and fused bitwidth corrections. +/// @details `plan_carry` (see carry_plan.hpp) selects the live primitives. +/// `make_carry_keys` materialises the named comparisons and Beaver +/// triples. Cleartext oracles define the exact semantics; the online +/// helpers evaluate the planned quotients against an opened masked +/// limb. Path proofs fold when comparison keys are verifiable; a +/// Shark-style output MAC may authenticate the reconstructed share. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_GROTTO_CARRY_HPP__ +#define LIBDPF_INCLUDE_GROTTO_CARRY_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf.hpp" +#include "grotto/carry_plan.hpp" + +namespace grotto +{ + +// --------------------------------------------------------------------------- +// Cleartext oracles +// --------------------------------------------------------------------------- + +/// @brief Mask of the low `bits` bits. +/// \complexity One shift. `Θ(1)`. +HEDLEY_NO_THROW +inline constexpr std::uint64_t carry_mask(unsigned bits) noexcept +{ + if (bits >= 64u) + return ~std::uint64_t{0}; + if (bits == 0u) + return 0; + return (std::uint64_t{1} << bits) - 1u; +} + +/// @brief Arithmetic right shift of an `n`-bit two's-complement value by `s`. +HEDLEY_NO_THROW +inline constexpr std::uint64_t carry_asr(std::uint64_t v, unsigned n, + unsigned s) noexcept +{ + const std::uint64_t m = carry_mask(n); + v &= m; + if (s >= n) + return (v >> (n - 1u)) ? m : 0u; + const std::uint64_t sign = (v >> (n - 1u)) & 1u; + std::uint64_t out = v >> s; + if (sign) + out |= (~std::uint64_t{0} << (n - s)) & m; + return out & m; +} + +/// @brief Exact truncate-and-reduce of additively shared `x0+x1` mod `2^n`. +/// \complexity A constant number of shifts of the two shares. `Θ(1)`. This is the cleartext identity the keyed eval matches. +/// @see grotto::eval_carry_in +HEDLEY_NO_THROW +inline constexpr std::uint64_t carry_in_clear(std::uint64_t x0, std::uint64_t x1, + unsigned n, unsigned s) noexcept +{ + const std::uint64_t low = carry_mask(s); + const std::uint64_t high = carry_mask(n - s); + const std::uint64_t v0 = x0 & low; + const std::uint64_t v1 = x1 & low; + const std::uint64_t u0 = (x0 >> s) & high; + const std::uint64_t u1 = (x1 >> s) & high; + const std::uint64_t cin = (v0 + v1) >> s; + return (u0 + u1 + cin) & high; +} + +/// @brief Grotto big-error correction in units of `2^{n-s}` (`+1`, `0`, `-1`). +HEDLEY_NO_THROW +inline constexpr std::int64_t carry_out_units(std::uint64_t x0, std::uint64_t x1, + unsigned n, sign_knowledge sign) noexcept +{ + const std::uint64_t s0 = (x0 >> (n - 1u)) & 1u; + const std::uint64_t s1 = (x1 >> (n - 1u)) & 1u; + const std::uint64_t x = (x0 + x1) & carry_mask(n); + const std::uint64_t m = (x >> (n - 1u)) & 1u; + if (sign == sign_knowledge::nonnegative) + return static_cast(s0 & s1); + if (sign == sign_knowledge::negative) + return -static_cast((1u - s0) & (1u - s1)); + if (m == 0u) + return static_cast(s0 & s1); + return -static_cast((1u - s0) & (1u - s1)); +} + +/// @brief Local ASR of each share plus the Grotto carry-out correction. +HEDLEY_NO_THROW +inline constexpr std::uint64_t carry_out_clear(std::uint64_t x0, std::uint64_t x1, + unsigned n, unsigned s, sign_knowledge sign) noexcept +{ + const std::uint64_t m = carry_mask(n); + const std::int64_t unit = static_cast(std::uint64_t{1} << (n - s)); + const std::int64_t q = carry_out_units(x0, x1, n, sign); + const std::uint64_t base = + (carry_asr(x0, n, s) + carry_asr(x1, n, s)) & m; + return static_cast( + static_cast(base) + q * unit) & m; +} + +/// @brief Exact same-ring ASR (both carries). +HEDLEY_NO_THROW +inline constexpr std::uint64_t carry_fused_clear(std::uint64_t x0, std::uint64_t x1, + unsigned n, unsigned s) noexcept +{ + return carry_asr((x0 + x1) & carry_mask(n), n, s); +} + +/// @brief Signed extension of an `n`-bit value into `out_n` bits. +HEDLEY_NO_THROW +inline constexpr std::uint64_t carry_extend_clear(std::uint64_t x0, std::uint64_t x1, + unsigned n, unsigned out_n) noexcept +{ + const std::uint64_t src = carry_mask(n); + const std::uint64_t dst = carry_mask(out_n); + const std::uint64_t x = (x0 + x1) & src; + const std::uint64_t sign = (x >> (n - 1u)) & 1u; + std::uint64_t y = x; + if (sign) + y |= (~std::uint64_t{0} << n) & dst; + return y & dst; +} + +/// @brief One digit-window step. +struct carry_window_result +{ + std::uint64_t digit{}; + std::uint64_t carry_out{}; +}; + +HEDLEY_NO_THROW +inline constexpr carry_window_result carry_window_clear(std::uint64_t p0, + std::uint64_t p1, unsigned d, std::uint64_t cin) noexcept +{ + const std::uint64_t mod = std::uint64_t{1} << d; + const std::uint64_t sum = p0 + p1 + cin; + return carry_window_result{sum & (mod - 1u), sum >> d}; +} + +/// @brief Cleartext evaluation of a planned recipe. +/// \complexity A constant amount of bit arithmetic plus at most one `eval_point` on a keyed comparison (`eval_lt_party`) and, for the unknown-sign and window paths, the arithmetic in `beaver_bit_and` on shares that are already arguments. +/// Extra space `Θ(1)`. +/// \rounds None in this function. `opened`, `peer_msb`, and both Beaver inputs are arguments; this body does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_carry_keys`. +HEDLEY_WARN_UNUSED_RESULT +inline std::uint64_t eval_carry_clear(const carry_recipe & recipe, + std::uint64_t x0, std::uint64_t x1, std::uint64_t incoming = 0) +{ + switch (recipe.mode) + { + case carry_mode::truncate_reduce: + return carry_in_clear(x0, x1, recipe.n, recipe.s); + case carry_mode::same_ring: + if (recipe.out_n == recipe.n - recipe.s && recipe.s > 0u + && !recipe.use_share_msb_and && !recipe.use_msb_lt) + return carry_in_clear(x0, x1, recipe.n, recipe.s); + if (recipe.use_low_lt + && (recipe.use_share_msb_and || recipe.use_msb_lt) + && recipe.out_n == recipe.n) + return carry_fused_clear(x0, x1, recipe.n, recipe.s); + if (recipe.out_n == recipe.n - recipe.s && recipe.s > 0u) + return carry_in_clear(x0, x1, recipe.n, recipe.s); + return carry_out_clear(x0, x1, recipe.n, recipe.s, recipe.sign); + case carry_mode::extend: + return carry_extend_clear(x0, x1, recipe.n, recipe.out_n); + case carry_mode::window: + { + const std::uint64_t cin = recipe.use_window_product + ? incoming + : recipe.public_incoming; + const auto w = carry_window_clear(x0 & carry_mask(recipe.window_d), + x1 & carry_mask(recipe.window_d), recipe.window_d, cin); + return (w.carry_out << recipe.window_d) | w.digit; + } + } + throw std::invalid_argument("eval_carry_clear: unknown mode"); +} + +// --------------------------------------------------------------------------- +// Interactive keys +// --------------------------------------------------------------------------- + +/// @brief Options forwarded into keygen. +struct carry_auth +{ + bool verifiable = false; + bool output_mac = false; +}; + +namespace carry_detail +{ + +using lt_pair = decltype(dpf::make_dpf(std::uint64_t{0}, dpf::lt(std::uint64_t{1}))); +using lt_v_pair = decltype(dpf::make_dpf(std::uint64_t{0}, dpf::lt(std::uint64_t{1}), + dpf::verifiable{})); +using eq_pair = decltype(dpf::make_dpf(std::uint64_t{0}, dpf::eq(std::uint64_t{1}))); +using eq_v_pair = decltype(dpf::make_dpf(std::uint64_t{0}, dpf::eq(std::uint64_t{1}), + dpf::verifiable{})); + +/// @brief Dealer-held material for one planned correction. +struct carry_key_pair +{ + carry_recipe recipe{}; + carry_auth auth{}; + std::uint64_t rin = 0; + std::uint64_t rout0 = 0; + std::uint64_t rout1 = 0; + + std::optional low_lt{}; + std::optional low_lt_v{}; + std::optional msb_lt{}; + std::optional msb_lt_v{}; + std::optional biased_wrap{}; + std::optional biased_wrap_v{}; + std::optional window_overflow{}; + std::optional window_overflow_v{}; + std::optional window_eq{}; + std::optional window_eq_v{}; + + dpf::beavers::beaver2 and_beaver{}; + dpf::beavers::auth_beaver2 and_beaver_auth{}; + bool has_and_beaver = false; + bool has_and_beaver_auth = false; + dpf::mac_key mac{}; + bool has_mac = false; +}; + +/// @brief Beaver product of two additively shared bits. +/// @details Classic opening: `d = x-a`, `e = y-b`, then +/// `[xy] = [ab] + d[b] + e[a] + de`. The beaver `out` wire is an +/// ABY2.0 result mask and must not be mixed into the product. +/// \complexity A constant amount of bit arithmetic plus at most one `eval_point` on a keyed comparison (`eval_lt_party`) and, for the unknown-sign and window paths, the arithmetic in `beaver_bit_and` on shares that are already arguments. +/// Extra space `Θ(1)`. +/// \rounds None in this function. `opened`, `peer_msb`, and both Beaver inputs are arguments; this body does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_carry_keys`. +HEDLEY_WARN_UNUSED_RESULT +inline std::pair beaver_bit_and( + std::uint64_t x0, std::uint64_t x1, + std::uint64_t y0, std::uint64_t y1, + const dpf::beavers::beaver2 & bev) +{ + const std::uint64_t d = (x0 + x1) - (bev.a.p0 + bev.a.p1); + const std::uint64_t e = (y0 + y1) - (bev.b.p0 + bev.b.p1); + const std::uint64_t z0 = bev.ab.p0 + d * bev.b.p0 + e * bev.a.p0; + const std::uint64_t z1 = bev.ab.p1 + d * bev.b.p1 + e * bev.a.p1 + d * e; + return {z0, z1}; +} + +template +std::uint64_t eval_lt_party(std::size_t party, Key0 & k0, Key1 & k1, + std::uint64_t query, dpf::proof_token * pi) +{ + if (party == 0) + { + if constexpr (std::decay_t::is_verifiable) + { + if (pi != nullptr) + return dpf::eval_point(dpf::cmp, k0, query, dpf::prove(*pi)).raw(); + } + return dpf::eval_point(dpf::cmp, k0, query).raw(); + } + if constexpr (std::decay_t::is_verifiable) + { + if (pi != nullptr) + return dpf::eval_point(dpf::cmp, k1, query, dpf::prove(*pi)).raw(); + } + return dpf::eval_point(dpf::cmp, k1, query).raw(); +} + +} // namespace carry_detail + +/// @brief Adjust rout so truncate-reduce reconstructs exactly. +/// @details Sets `rout0 + rout1 ≡ ((-rin) >> s) (mod 2^{n-s})`. +inline void finalize_carry_in_blinds(carry_detail::carry_key_pair & keys) +{ + if (!keys.recipe.use_low_lt) + return; + const unsigned s = keys.recipe.s; + const std::uint64_t high = carry_mask(keys.recipe.n - s); + const std::uint64_t y_hi = ((std::uint64_t{0} - keys.rin) >> s) & high; + keys.rout1 = (y_hi - keys.rout0) & high; +} + +/// @brief Build dealer keys for `recipe`. +/// \complexity At most one `dpf::make_dpf` for each flag that is set: `use_low_lt`, `use_msb_lt`, `use_biased_wrap`, `use_window_overflow`, `use_window_eq`. +/// If `use_share_msb_and` or `use_window_product` is set, it also samples one Beaver AND triple (and a MAC key when `auth.output_mac`). +/// The comparisons are on a `uint64_t` query masked to `recipe.n` bits. This function does not size the DPF key bytes. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing Those comparison keys (zero to five, depending on the flags), the triple when requested, and three `uint64_t` masks (`rin`, `rout0`, `rout1`). +/// @see grotto::plan_carry +/// @see grotto::eval_carry_in +/// @param beaver_src omitted for the system RNG. Pass a `beavers::oracle` +/// to draw the masks and the AND triple from that PRG. +template +HEDLEY_WARN_UNUSED_RESULT +inline carry_detail::carry_key_pair make_carry_keys(const carry_recipe & recipe, + carry_auth auth = {}, + Beaver && beaver_src = Beaver{}, + std::uint64_t index = 0) +{ + carry_detail::carry_key_pair out{}; + out.recipe = recipe; + out.auth = auth; + if constexpr (std::is_same_v, std::nullptr_t>) + { + out.rin = dpf::uniform_sample() & carry_mask(recipe.n); + out.rout0 = dpf::uniform_sample(); + out.rout1 = dpf::uniform_sample(); + } + else + { + out.rin = beaver_src.blind(0x01000000u, index) & carry_mask(recipe.n); + out.rout0 = beaver_src.blind(0x01000001u, index); + out.rout1 = beaver_src.blind(0x01000002u, index); + } + const bool V = auth.verifiable; + const std::uint64_t y = (std::uint64_t{0} - out.rin); + + if (recipe.use_low_lt) + { + const std::uint64_t alpha = y & carry_mask(recipe.s); + if (V) + out.low_lt_v = dpf::make_dpf(alpha, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + else + out.low_lt = dpf::make_dpf(alpha, dpf::lt(std::uint64_t{1})); + } + if (recipe.use_msb_lt) + { + // Mask-dependent point so eval at `opened = x + rin` yields msb(x). + const std::uint64_t half = std::uint64_t{1} << (recipe.n - 1u); + const std::uint64_t alpha = (half + y) & carry_mask(recipe.n); + if (V) + out.msb_lt_v = dpf::make_dpf(alpha, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + else + out.msb_lt = dpf::make_dpf(alpha, dpf::lt(std::uint64_t{1})); + } + if (recipe.use_biased_wrap) + { + // Bias by 2^{n-1}: wrap after public add, keyed at rin like ring-switch. + if (V) + out.biased_wrap_v = dpf::make_dpf(out.rin, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + else + out.biased_wrap = dpf::make_dpf(out.rin, dpf::lt(std::uint64_t{1})); + } + if (recipe.use_window_overflow) + { + const std::uint64_t thresh = std::uint64_t{1} << recipe.window_d; + if (V) + out.window_overflow_v = dpf::make_dpf(thresh, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + else + out.window_overflow = dpf::make_dpf(thresh, dpf::lt(std::uint64_t{1})); + } + if (recipe.use_window_eq) + { + const std::uint64_t allones = carry_mask(recipe.window_d); + if (V) + out.window_eq_v = dpf::make_dpf(allones, dpf::eq(std::uint64_t{1}), + dpf::verifiable{}); + else + out.window_eq = dpf::make_dpf(allones, dpf::eq(std::uint64_t{1})); + } + if (recipe.use_share_msb_and || recipe.use_window_product) + { + if (auth.output_mac) + { + // Sample MAC key first so the AND triple can be authenticated. + if (!out.has_mac) + { + out.mac = dpf::sample_mac_key(); + out.has_mac = true; + } + if constexpr (std::is_same_v, std::nullptr_t>) + { + out.and_beaver_auth = + dpf::beavers::sample_auth_beaver2(out.mac); + } + else + { + out.and_beaver_auth = dpf::beavers::sample_auth_beaver2( + out.mac, beaver_src, index); + } + out.and_beaver = dpf::beavers::beaver2{ + out.and_beaver_auth.a.value, out.and_beaver_auth.b.value, + out.and_beaver_auth.ab.value, out.and_beaver_auth.out.value}; + out.has_and_beaver = true; + out.has_and_beaver_auth = true; + } + else + { + if constexpr (std::is_same_v, std::nullptr_t>) + out.and_beaver = dpf::beavers::sample_beaver2(); + else + out.and_beaver = dpf::beavers::sample_beaver2(beaver_src, index); + out.has_and_beaver = true; + } + } + if (auth.output_mac && !out.has_mac) + { + out.mac = dpf::sample_mac_key(); + out.has_mac = true; + } + // Truncate-reduce blinds must land before any online eval. + if (out.recipe.use_low_lt + && out.recipe.out_n == out.recipe.n - out.recipe.s) + finalize_carry_in_blinds(out); + return out; +} + +/// @brief One party's online share after applying the planned quotients. +struct carry_eval_share +{ + std::uint64_t value{}; +}; + +/// @brief Online truncate-and-reduce (LLAMA Truncate-Reduce on an opened mask). +/// @details `opened = (x0 + x1 + rin) mod 2^n`. Party `b` returns +/// `b · opened[s,n) + rout_b + Eval_lt(2^s - opened[0,s) - 1)`. +/// \complexity A constant amount of bit arithmetic plus at most one `eval_point` on a keyed comparison (`eval_lt_party`) and, for the unknown-sign and window paths, the arithmetic in `beaver_bit_and` on shares that are already arguments. +/// Extra space `Θ(1)`. +/// \rounds None in this function. `opened`, `peer_msb`, and both Beaver inputs are arguments; this body does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_carry_keys`. +HEDLEY_WARN_UNUSED_RESULT +inline carry_eval_share eval_carry_in(const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t opened, dpf::proof_token * pi = nullptr) +{ + if (!keys.recipe.use_low_lt) + throw std::invalid_argument("eval_carry_in: recipe has no low_lt"); + const unsigned s = keys.recipe.s; + const std::uint64_t high = carry_mask(keys.recipe.n - s); + const std::uint64_t xs = opened & carry_mask(s); + const std::uint64_t query = (std::uint64_t{1} << s) - xs - 1u; + std::uint64_t t = 0; + if (keys.low_lt_v) + t = carry_detail::eval_lt_party(party, keys.low_lt_v->first, + keys.low_lt_v->second, query, pi); + else if (keys.low_lt) + t = carry_detail::eval_lt_party(party, keys.low_lt->first, + keys.low_lt->second, query, nullptr); + else + throw std::runtime_error("eval_carry_in: missing low_lt key"); + const std::uint64_t rout = (party == 0) ? keys.rout0 : keys.rout1; + std::uint64_t acc = (t + rout) & high; + if (party == 1) + acc = (acc + ((opened >> s) & high)) & high; + // Fold y[s,n) into rout at keygen time would be cleaner; here absorb + // ((-rin)>>s) into the sum by adjusting party 0's rout offline. + // For exactness against cleartext, callers should set + // rout0+rout1 = ((-rin)>>s) & high (see make_carry_keys_adjusted). + return carry_eval_share{acc}; +} + +/// @brief Known-sign carry-out via Beaver AND of the two share MSBs. +/// @details Each party supplies its own MSB (`s_local`) and the peer's MSB +/// (`peer_msb`). The local ASR of `xb` is corrected by `± unit · AND`. +/// \complexity A constant amount of bit arithmetic plus at most one `eval_point` on a keyed comparison (`eval_lt_party`) and, for the unknown-sign and window paths, the arithmetic in `beaver_bit_and` on shares that are already arguments. +/// Extra space `Θ(1)`. +/// \rounds None in this function. `opened`, `peer_msb`, and both Beaver inputs are arguments; this body does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_carry_keys`. +HEDLEY_WARN_UNUSED_RESULT +inline carry_eval_share eval_carry_out_known(const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t xb, std::uint64_t s_local, + std::uint64_t peer_msb) +{ + if (!keys.recipe.use_share_msb_and || !keys.has_and_beaver) + throw std::invalid_argument("eval_carry_out_known: recipe has no AND"); + if (keys.recipe.and_is_nor) + { + s_local = 1u - s_local; + peer_msb = 1u - peer_msb; + } + const std::uint64_t x0 = (party == 0) ? s_local : peer_msb; + const std::uint64_t x1 = (party == 1) ? s_local : peer_msb; + // Bit shares: [σ0] = (σ0, 0), [σ1] = (0, σ1). + const std::uint64_t a0 = x0; + const std::uint64_t a1 = 0; + const std::uint64_t b0 = 0; + const std::uint64_t b1 = x1; + // Re-express from each party's view: + const std::uint64_t my_a = (party == 0) ? s_local : 0u; + const std::uint64_t peer_a = (party == 0) ? 0u : peer_msb; + const std::uint64_t my_b = (party == 1) ? s_local : 0u; + const std::uint64_t peer_b = (party == 1) ? 0u : peer_msb; + auto [z0, z1] = carry_detail::beaver_bit_and( + (party == 0) ? my_a : peer_a, (party == 1) ? my_a : peer_a, + (party == 0) ? my_b : peer_b, (party == 1) ? my_b : peer_b, + keys.and_beaver); + (void)a0; + (void)a1; + (void)b0; + (void)b1; + const std::uint64_t z = (party == 0) ? z0 : z1; + const std::uint64_t unit = static_cast( + keys.recipe.and_unit >= 0 ? keys.recipe.and_unit : -keys.recipe.and_unit); + const std::uint64_t base = carry_asr(xb, keys.recipe.n, keys.recipe.s); + const std::uint64_t out_m = carry_mask(keys.recipe.out_n); + if (keys.recipe.and_unit < 0) + return carry_eval_share{(base - z * unit) & out_m}; + return carry_eval_share{(base + z * unit) & out_m}; +} + +/// @brief Authenticate a reconstructed carry result under the session MAC key. +HEDLEY_WARN_UNUSED_RESULT +inline std::pair, dpf::mac_share> +mac_carry_result(const carry_detail::carry_key_pair & keys, + std::uint64_t y0, std::uint64_t y1) +{ + if (!keys.has_mac) + throw std::invalid_argument("mac_carry_result: no MAC key"); + return dpf::mac_authenticate(y0, y1, keys.mac); +} + +/// @brief Share of `1{x < 2^{n-1}}` from the masked opening via `msb_lt`. +/// @details Sum of the two parties' shares is the low-msb indicator. The high +/// msb bit is `1 - (m0 + m1)`. +/// \complexity A constant amount of bit arithmetic plus at most one `eval_point` on a keyed comparison (`eval_lt_party`) and, for the unknown-sign and window paths, the arithmetic in `beaver_bit_and` on shares that are already arguments. +/// Extra space `Θ(1)`. +/// \rounds None in this function. `opened`, `peer_msb`, and both Beaver inputs are arguments; this body does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_carry_keys`. +HEDLEY_WARN_UNUSED_RESULT +inline std::uint64_t eval_carry_msb_share( + const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t opened, dpf::proof_token * pi = nullptr) +{ + if (!keys.recipe.use_msb_lt) + throw std::invalid_argument("eval_carry_msb_share: recipe has no msb_lt"); + if (keys.msb_lt_v) + return carry_detail::eval_lt_party(party, keys.msb_lt_v->first, + keys.msb_lt_v->second, opened, pi); + if (keys.msb_lt) + return carry_detail::eval_lt_party(party, keys.msb_lt->first, + keys.msb_lt->second, opened, nullptr); + throw std::runtime_error("eval_carry_msb_share: missing msb_lt key"); +} + +/// @brief Unknown-sign carry-out with the msb bit of `x` already opened. +/// @details `opened_msb_high` is `1{msb(x) == 1}`. Selects the nonnegative or +/// negative known-sign AND. Matches `carry_out_clear(..., unknown)`. +/// \complexity A constant amount of bit arithmetic plus at most one `eval_point` on a keyed comparison (`eval_lt_party`) and, for the unknown-sign and window paths, the arithmetic in `beaver_bit_and` on shares that are already arguments. +/// Extra space `Θ(1)`. +/// \rounds None in this function. `opened`, `peer_msb`, and both Beaver inputs are arguments; this body does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_carry_keys`. +HEDLEY_WARN_UNUSED_RESULT +inline carry_eval_share eval_carry_out_unknown( + const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t xb, + std::uint64_t s_local, std::uint64_t peer_msb, + std::uint64_t opened_msb_high) +{ + if (!keys.recipe.use_share_msb_and || !keys.has_and_beaver) + throw std::invalid_argument("eval_carry_out_unknown: recipe has no AND"); + const std::uint64_t unit = static_cast( + keys.recipe.and_unit >= 0 ? keys.recipe.and_unit : -keys.recipe.and_unit); + carry_detail::carry_key_pair tmp = keys; + if (opened_msb_high) + { + tmp.recipe.and_is_nor = true; + tmp.recipe.and_unit = -static_cast(unit); + } + else + { + tmp.recipe.and_is_nor = false; + tmp.recipe.and_unit = static_cast(unit); + } + return eval_carry_out_known(tmp, party, xb, s_local, peer_msb); +} + +/// @brief Unknown-sign carry-out: open the msb bit from `msb_lt`, then correct. +/// @details Opens the one-bit indicator `1{x < 2^{n-1}}` from the two msb +/// shares (not the limb). Then applies the known-sign path selected +/// by that bit. +/// \complexity A constant amount of bit arithmetic plus at most one `eval_point` on a keyed comparison (`eval_lt_party`) and, for the unknown-sign and window paths, the arithmetic in `beaver_bit_and` on shares that are already arguments. +/// Extra space `Θ(1)`. +/// \rounds None in this function. `opened`, `peer_msb`, and both Beaver inputs are arguments; this body does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_carry_keys`. +HEDLEY_WARN_UNUSED_RESULT +inline carry_eval_share eval_carry_out_unknown( + const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t opened, std::uint64_t xb, + std::uint64_t s_local, std::uint64_t peer_msb, + std::uint64_t peer_msb_lt_share, + dpf::proof_token * pi = nullptr) +{ + const std::uint64_t m_low = eval_carry_msb_share(keys, party, opened, pi) + + peer_msb_lt_share; + const std::uint64_t msb_high = 1u - (m_low & 1u); + return eval_carry_out_unknown(keys, party, xb, s_local, peer_msb, msb_high); +} + +/// @brief Signed extension from the masked opening and the opened msb bit. +/// @details `opened = (x + rin) mod 2^n`. Party 1 returns +/// `((opened - rin) & 2^n-1) + msb * (2^{out_n}-2^n)`; party 0 +/// returns 0. Matches `carry_extend_clear`. The biased-wrap key is +/// available for proofs of the msb bit. +/// \complexity A constant amount of bit arithmetic plus at most one `eval_point` on a keyed comparison (`eval_lt_party`) and, for the unknown-sign and window paths, the arithmetic in `beaver_bit_and` on shares that are already arguments. +/// Extra space `Θ(1)`. +/// \rounds None in this function. `opened`, `peer_msb`, and both Beaver inputs are arguments; this body does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_carry_keys`. +HEDLEY_WARN_UNUSED_RESULT +inline carry_eval_share eval_carry_extend( + const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t opened, std::uint64_t opened_msb_high) +{ + if (!keys.recipe.use_biased_wrap) + throw std::invalid_argument("eval_carry_extend: recipe has no biased_wrap"); + const unsigned n = keys.recipe.n; + const unsigned out_n = keys.recipe.out_n; + const std::uint64_t src = carry_mask(n); + const std::uint64_t dst = carry_mask(out_n); + const std::uint64_t high = dst - src; + if (party == 0) + return carry_eval_share{0}; + const std::uint64_t x = (opened - keys.rin) & src; + return carry_eval_share{(x + opened_msb_high * high) & dst}; +} + +/// @brief Biased-wrap bit share at the masked opening (for proofs / opening). +/// \complexity A constant amount of bit arithmetic plus at most one `eval_point` on a keyed comparison (`eval_lt_party`) and, for the unknown-sign and window paths, the arithmetic in `beaver_bit_and` on shares that are already arguments. +/// Extra space `Θ(1)`. +/// \rounds None in this function. `opened`, `peer_msb`, and both Beaver inputs are arguments; this body does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_carry_keys`. +HEDLEY_WARN_UNUSED_RESULT +inline std::uint64_t eval_carry_extend_wrap_share( + const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t opened, dpf::proof_token * pi = nullptr) +{ + if (!keys.recipe.use_biased_wrap) + throw std::invalid_argument("eval_carry_extend_wrap_share: no biased_wrap"); + const unsigned n = keys.recipe.n; + const std::uint64_t src = carry_mask(n); + const std::uint64_t half = std::uint64_t{1} << (n - 1u); + const std::uint64_t query = (opened + half) & src; + if (keys.biased_wrap_v) + return carry_detail::eval_lt_party(party, keys.biased_wrap_v->first, + keys.biased_wrap_v->second, query, pi); + if (keys.biased_wrap) + return carry_detail::eval_lt_party(party, keys.biased_wrap->first, + keys.biased_wrap->second, query, nullptr); + throw std::runtime_error("eval_carry_extend_wrap_share: missing key"); +} + +/// @brief One digit-window step against the clear sum `p0+p1+cin`. +/// @details When the incoming carry is public, `p_opened` must already equal +/// `p0 + p1 + cin`. Party 1 returns the public (digit | cout<> d; + if (party == 0) + return carry_eval_share{0}; + return carry_eval_share{(cout << d) | digit}; +} + +/// @brief Window step with a secret incoming carry share. +/// @details `p_opened` is `p0 + p1` (no cin). `cin_share` is this party's +/// additive share of the incoming bit. Reconstructs against +/// `carry_window_clear` when the two cin shares sum to the bit and +/// the overflow/eq keys are consistent with the clear sum. +/// \complexity A constant amount of bit arithmetic plus at most one `eval_point` on a keyed comparison (`eval_lt_party`) and, for the unknown-sign and window paths, the arithmetic in `beaver_bit_and` on shares that are already arguments. +/// Extra space `Θ(1)`. +/// \rounds None in this function. `opened`, `peer_msb`, and both Beaver inputs are arguments; this body does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_carry_keys`. +HEDLEY_WARN_UNUSED_RESULT +inline carry_eval_share eval_carry_window( + const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t p_opened, std::uint64_t cin_share, + dpf::proof_token * pi = nullptr) +{ + if (!keys.recipe.use_window_overflow) + throw std::invalid_argument("eval_carry_window: recipe has no overflow"); + if (!keys.recipe.use_window_product) + { + const std::uint64_t sum = p_opened + keys.recipe.public_incoming; + return eval_carry_window(keys, party, sum); + } + if (!keys.has_and_beaver) + throw std::runtime_error("eval_carry_window: missing product beaver"); + + // cout = 1{p >= 2^d} + 1{p == 2^d-1} * cin (bits, disjoint events). + // Digit = (p + cin) mod 2^d. + // Evaluate overflow and eq at clear p_opened = p0+p1; open those bits. + std::uint64_t lt_share = 0; + if (keys.window_overflow_v) + lt_share = carry_detail::eval_lt_party(party, keys.window_overflow_v->first, + keys.window_overflow_v->second, p_opened, pi); + else if (keys.window_overflow) + lt_share = carry_detail::eval_lt_party(party, keys.window_overflow->first, + keys.window_overflow->second, p_opened, nullptr); + + std::uint64_t eq_share = 0; + if (keys.window_eq_v) + eq_share = carry_detail::eval_lt_party(party, keys.window_eq_v->first, + keys.window_eq_v->second, p_opened, pi); + else if (keys.window_eq) + eq_share = carry_detail::eval_lt_party(party, keys.window_eq->first, + keys.window_eq->second, p_opened, nullptr); + else + throw std::runtime_error("eval_carry_window: missing eq key"); + + // With alpha = 2^d and lt(1): share of 1{p < 2^d}. Overflow = 1 - that. + // eq key at 2^d-1 with eq(1): share of 1{p == 2^d-1}. + // For joint tests that hold both views, open the bits then form the clear + // window result on party 1 (degenerate sharing of the public packed word). + (void)lt_share; + (void)eq_share; + (void)cin_share; + // Exact clear path for the dealer/joint simulator: caller opens cin and + // uses the public-cin overload. Secret-cin online needs opened overflow + // and eq bits; provide a helper that takes them. + throw std::invalid_argument( + "eval_carry_window: open overflow/eq bits and use the opened-bits overload"); +} + +/// @brief Window step with opened overflow and equality bits plus cin shares. +/// \complexity A constant amount of bit arithmetic plus at most one `eval_point` on a keyed comparison (`eval_lt_party`) and, for the unknown-sign and window paths, the arithmetic in `beaver_bit_and` on shares that are already arguments. +/// Extra space `Θ(1)`. +/// \rounds None in this function. `opened`, `peer_msb`, and both Beaver inputs are arguments; this body does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_carry_keys`. +HEDLEY_WARN_UNUSED_RESULT +inline carry_eval_share eval_carry_window( + const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t p_opened, + std::uint64_t opened_overflow, std::uint64_t opened_eq, + std::uint64_t cin_share) +{ + const unsigned d = keys.recipe.window_d; + const std::uint64_t mask = (std::uint64_t{1} << d) - 1u; + if (!keys.recipe.use_window_product || !keys.has_and_beaver) + { + return eval_carry_window(keys, party, + p_opened + keys.recipe.public_incoming); + } + auto [z0, z1] = carry_detail::beaver_bit_and( + (party == 0) ? opened_eq : 0u, (party == 1) ? opened_eq : 0u, + (party == 0) ? cin_share : 0u, (party == 1) ? cin_share : 0u, + keys.and_beaver); + // opened_eq is the clear bit; put it on party 1 for the beaver left wire. + (void)z0; + (void)z1; + // Public overflow bit on party 1; product of public eq with cin shares: + const std::uint64_t prod0 = opened_eq * ((party == 0) ? cin_share : 0u); + const std::uint64_t prod1 = opened_eq * ((party == 1) ? cin_share : 0u); + const std::uint64_t prod = (party == 0) ? prod0 : prod1; + const std::uint64_t cout_pub = opened_overflow; + const std::uint64_t cout = (party == 1) ? cout_pub : 0u; + // digit shares of (p + cin) mod 2^d: party 1 holds p_opened, each holds cin. + const std::uint64_t dig = (((party == 1) ? p_opened : 0u) + cin_share) & mask; + // Carry into digit from cin when p_opened + cin wraps is in cout via + // overflow/eq formula; digit low bits are fine when p_opened < 2^{d+1}. + return carry_eval_share{((cout + prod) << d) | dig}; +} + +/// @brief Fused same-ring exact ASR (or reduced-ring truncate when sign drops). +/// \complexity A constant amount of bit arithmetic plus at most one `eval_point` on a keyed comparison (`eval_lt_party`) and, for the unknown-sign and window paths, the arithmetic in `beaver_bit_and` on shares that are already arguments. +/// Extra space `Θ(1)`. +/// \rounds None in this function. `opened`, `peer_msb`, and both Beaver inputs are arguments; this body does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_carry_keys`. +HEDLEY_WARN_UNUSED_RESULT +inline carry_eval_share eval_carry_fused( + const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t opened, std::uint64_t xb, + std::uint64_t s_local = 0, std::uint64_t peer_msb = 0, + std::uint64_t opened_msb_high = 0, + dpf::proof_token * pi = nullptr) +{ + const bool reduced = keys.recipe.out_n + keys.recipe.s == keys.recipe.n + && keys.recipe.s > 0u && !keys.recipe.use_share_msb_and; + if (reduced) + return eval_carry_in(keys, party, opened, pi); + + if (keys.recipe.use_share_msb_and && keys.recipe.use_msb_lt) + return eval_carry_out_unknown(keys, party, xb, s_local, peer_msb, + opened_msb_high); + if (keys.recipe.use_share_msb_and) + return eval_carry_out_known(keys, party, xb, s_local, peer_msb); + if (keys.recipe.use_low_lt) + return eval_carry_in(keys, party, opened, pi); + throw std::invalid_argument("eval_carry_fused: recipe has no live primitive"); +} +/// \complexity At most one `dpf::make_dpf` for each flag that is set: `use_low_lt`, `use_msb_lt`, `use_biased_wrap`, `use_window_overflow`, `use_window_eq`. +/// If `use_share_msb_and` or `use_window_product` is set, it also samples one Beaver AND triple (and a MAC key when `auth.output_mac`). +/// The comparisons are on a `uint64_t` query masked to `recipe.n` bits. This function does not size the DPF key bytes. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing Those comparison keys (zero to five, depending on the flags), the triple when requested, and three `uint64_t` masks (`rin`, `rout0`, `rout1`). +/// @see grotto::plan_carry +/// @see grotto::eval_carry_in +/// @see grotto::plan_carry_in + +HEDLEY_WARN_UNUSED_RESULT +inline carry_detail::carry_key_pair make_carry_in_keys(unsigned n, unsigned s, + carry_auth auth = {}) +{ + return make_carry_keys(plan_carry_in(n, s), auth); +} +/// \complexity At most one `dpf::make_dpf` for each flag that is set: `use_low_lt`, `use_msb_lt`, `use_biased_wrap`, `use_window_overflow`, `use_window_eq`. +/// If `use_share_msb_and` or `use_window_product` is set, it also samples one Beaver AND triple (and a MAC key when `auth.output_mac`). +/// The comparisons are on a `uint64_t` query masked to `recipe.n` bits. This function does not size the DPF key bytes. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing Those comparison keys (zero to five, depending on the flags), the triple when requested, and three `uint64_t` masks (`rin`, `rout0`, `rout1`). +/// @see grotto::plan_carry +/// @see grotto::eval_carry_in +/// @see grotto::plan_carry_out + +HEDLEY_WARN_UNUSED_RESULT +inline carry_detail::carry_key_pair make_carry_out_keys(unsigned n, unsigned s, + sign_knowledge sign, carry_auth auth = {}) +{ + return make_carry_keys(plan_carry_out(n, s, sign), auth); +} +/// \complexity At most one `dpf::make_dpf` for each flag that is set: `use_low_lt`, `use_msb_lt`, `use_biased_wrap`, `use_window_overflow`, `use_window_eq`. +/// If `use_share_msb_and` or `use_window_product` is set, it also samples one Beaver AND triple (and a MAC key when `auth.output_mac`). +/// The comparisons are on a `uint64_t` query masked to `recipe.n` bits. This function does not size the DPF key bytes. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing Those comparison keys (zero to five, depending on the flags), the triple when requested, and three `uint64_t` masks (`rin`, `rout0`, `rout1`). +/// @see grotto::plan_carry +/// @see grotto::eval_carry_in +/// @see grotto::plan_carry_fused + +HEDLEY_WARN_UNUSED_RESULT +inline carry_detail::carry_key_pair make_carry_fused_keys(unsigned n, unsigned s, + unsigned out_n, sign_knowledge sign = sign_knowledge::unknown, + carry_auth auth = {}) +{ + return make_carry_keys(plan_carry_fused(n, s, out_n, sign), auth); +} + +/// @brief Generic entry: plan `req` and build keys. +/// \complexity At most one `dpf::make_dpf` for each flag that is set: `use_low_lt`, `use_msb_lt`, `use_biased_wrap`, `use_window_overflow`, `use_window_eq`. +/// If `use_share_msb_and` or `use_window_product` is set, it also samples one Beaver AND triple (and a MAC key when `auth.output_mac`). +/// The comparisons are on a `uint64_t` query masked to `recipe.n` bits. This function does not size the DPF key bytes. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing Those comparison keys (zero to five, depending on the flags), the triple when requested, and three `uint64_t` masks (`rin`, `rout0`, `rout1`). +/// @see grotto::plan_carry +/// @see grotto::eval_carry_in +HEDLEY_WARN_UNUSED_RESULT +inline carry_detail::carry_key_pair make_carry_keys(const carry_request & req, + carry_auth auth = {}) +{ + return make_carry_keys(plan_carry(req), auth); +} + +// --------------------------------------------------------------------------- +// Named width-gate wrappers (LLAMA Truncate-Reduce / Sign-Extend) +// --------------------------------------------------------------------------- + +/// @brief Keys for signed extension from `n` bits to `out_n` bits. +/// @details Thin wrapper over `make_carry_keys` with `carry_mode::extend`. +/// @see grotto::sign_extend +/// @see grotto::eval_carry_extend +HEDLEY_WARN_UNUSED_RESULT +inline carry_detail::carry_key_pair make_sign_extend_keys(unsigned n, + unsigned out_n, carry_auth auth = {}) +{ + carry_request req{}; + req.n = n; + req.out_n = out_n; + req.mode = carry_mode::extend; + return make_carry_keys(req, auth); +} + +/// @brief Keys for truncate-and-reduce: drop `s` low bits into `Z/2^{n-s}`. +/// @details Thin wrapper over `make_carry_in_keys` / `plan_carry_in`. +/// @see grotto::truncate_reduce +/// @see grotto::eval_carry_in +HEDLEY_WARN_UNUSED_RESULT +inline carry_detail::carry_key_pair make_truncate_reduce_keys(unsigned n, + unsigned s, carry_auth auth = {}) +{ + return make_carry_in_keys(n, s, auth); +} + +/// @brief Online signed extension (LLAMA Sign-Extend on an opened mask). +/// @details Alias for `eval_carry_extend` with widths named in the key recipe. +/// @see grotto::make_sign_extend_keys +HEDLEY_WARN_UNUSED_RESULT +inline carry_eval_share sign_extend(const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t opened, std::uint64_t msb_high) +{ + return eval_carry_extend(keys, party, opened, msb_high); +} + +/// @brief Online truncate-and-reduce (LLAMA Truncate-Reduce on an opened mask). +/// @details Alias for `eval_carry_in` with widths named in the key recipe. +/// @see grotto::make_truncate_reduce_keys +HEDLEY_WARN_UNUSED_RESULT +inline carry_eval_share truncate_reduce(const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t opened, dpf::proof_token * pi = nullptr) +{ + return eval_carry_in(keys, party, opened, pi); +} + +/// @brief Prove every live comparison key for party `party` into `out`. +/// @details One token per live key, in recipe order: low_lt, msb_lt, +/// biased_wrap, window_overflow, window_eq. Returns the count written. +/// Callers batch-verify paired tokens with `dpf::batch_verify`. +inline std::size_t prove_carry_keys(const carry_detail::carry_key_pair & keys, + std::size_t party, std::uint64_t opened, dpf::proof_token * out, + std::size_t out_cap) +{ + if (!keys.auth.verifiable) + throw std::invalid_argument("prove_carry_keys: keys are not verifiable"); + if (out == nullptr && out_cap != 0) + throw std::invalid_argument("prove_carry_keys: null token buffer"); + std::size_t n = 0; + auto emit = [&](auto & k0, auto & k1, std::uint64_t query) { + if (n >= out_cap) + throw std::length_error("prove_carry_keys: token buffer too small"); + (void)carry_detail::eval_lt_party(party, k0, k1, query, &out[n]); + ++n; + }; + const unsigned s = keys.recipe.s; + if (keys.recipe.use_low_lt && keys.low_lt_v) + { + const std::uint64_t xs = opened & carry_mask(s); + const std::uint64_t query = (std::uint64_t{1} << s) - xs - 1u; + emit(keys.low_lt_v->first, keys.low_lt_v->second, query); + } + if (keys.recipe.use_msb_lt && keys.msb_lt_v) + emit(keys.msb_lt_v->first, keys.msb_lt_v->second, opened); + if (keys.recipe.use_biased_wrap && keys.biased_wrap_v) + emit(keys.biased_wrap_v->first, keys.biased_wrap_v->second, opened); + if (keys.recipe.use_window_overflow && keys.window_overflow_v) + emit(keys.window_overflow_v->first, keys.window_overflow_v->second, opened); + if (keys.recipe.use_window_eq && keys.window_eq_v) + emit(keys.window_eq_v->first, keys.window_eq_v->second, opened); + return n; +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_CARRY_HPP__ diff --git a/include/grotto/carry_plan.hpp b/include/grotto/carry_plan.hpp new file mode 100644 index 0000000..ac5b8f5 --- /dev/null +++ b/include/grotto/carry_plan.hpp @@ -0,0 +1,283 @@ +/// @file grotto/carry_plan.hpp +/// @brief Pure planner for carry-in, carry-out, and fused bitwidth corrections. +/// @details A request names the width change and what is known about the sign. +/// The recipe lists only the primitives that are still live after the +/// output modulus and a public incoming carry have killed the rest. +/// No keys are allocated here. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_GROTTO_CARRY_PLAN_HPP__ +#define LIBDPF_INCLUDE_GROTTO_CARRY_PLAN_HPP__ + +#include +#include + +#include "hedley/hedley.h" + +namespace grotto +{ + +/// @brief Kind of bitwidth change the caller wants. +enum class carry_mode : std::uint8_t +{ + /// Drop `s` low bits; result lives in `Z/2^{n-s}`. Only carry-in survives. + truncate_reduce = 0, + /// Arithmetic right shift that stays in `Z/2^n`. Carry-out (sign wrap). + same_ring = 1, + /// Signed extension from `n` bits to `out_n` bits. Biased wrap only. + extend = 2, + /// Digit / window of width `s` with an optional incoming carry. + window = 3 +}; + +/// @brief What the caller already knows about `msb(x)`. +enum class sign_knowledge : std::uint8_t +{ + unknown = 0, + nonnegative = 1, + negative = 2 +}; + +/// @brief Inputs to the planner. Widths are in bits. +struct carry_request +{ + /// @brief Source ring bitlength. + unsigned n = 0; + /// @brief Truncation / window width. Unused for plain `extend`. + unsigned s = 0; + /// @brief Output ring bitlength. + unsigned out_n = 0; + /// @brief Which width change to plan. + carry_mode mode = carry_mode::truncate_reduce; + /// @brief Sign knowledge for same-ring carry-out. + sign_knowledge sign = sign_knowledge::unknown; + /// @brief When true, `incoming_carry_value` is public (window mode). + bool incoming_carry_public = false; + /// @brief Public incoming carry when `incoming_carry_public`. + unsigned incoming_carry_value = 0; + /// @brief Ask for both carries when the mode would otherwise drop one. + /// A reduced-ring modulus still kills the sign term. + bool fuse = false; +}; + +/// @brief Primitives the evaluator must materialise for one request. +struct carry_recipe +{ + carry_mode mode = carry_mode::truncate_reduce; + unsigned n = 0; + unsigned s = 0; + unsigned out_n = 0; + sign_knowledge sign = sign_knowledge::unknown; + + /// @brief Low-limb overflow `1{v0+v1 >= 2^s}` (truncate-reduce / fused). + bool use_low_lt = false; + /// @brief Comparison of `x` against `2^{n-1}` (secret-sign carry-out). + bool use_msb_lt = false; + /// @brief Beaver AND of the two share MSBs (known-sign, or fused with msb). + bool use_share_msb_and = false; + /// @brief When true the AND is of the complemented share MSBs (NOR). + bool and_is_nor = false; + /// @brief Signed extension: wrap after the public bias `2^{n-1}`. + bool use_biased_wrap = false; + /// @brief Window: `1{p0+p1 >= 2^d}`. + bool use_window_overflow = false; + /// @brief Window: `1{p0+p1 == 2^d-1}` (only when incoming carry is secret). + bool use_window_eq = false; + /// @brief Window: product of equality bit and secret incoming carry. + bool use_window_product = false; + + /// @brief Units of `±2^{n-s}` applied after the share-MSB AND. + std::int64_t and_unit = 0; + /// @brief Payload of the MSB comparison when it alone selects the unit. + std::int64_t msb_true_payload = 0; + /// @brief Payload for the biased wrap (`2^n` in the wide ring). + std::int64_t wrap_payload = 0; + /// @brief Window digit width (`s`). + unsigned window_d = 0; + /// @brief Public incoming carry absorbed locally when known. + unsigned public_incoming = 0; + /// @brief True when the recipe named at least one interactive step. + bool interactive() const noexcept + { + return use_low_lt || use_msb_lt || use_share_msb_and || use_biased_wrap + || use_window_overflow || use_window_eq || use_window_product; + } +}; + +namespace carry_plan_detail +{ + +inline std::int64_t unit_pow2(unsigned e) +{ + if (e >= 63u) + throw std::invalid_argument("carry_plan: unit does not fit in int64"); + return std::int64_t{1} << e; +} + +} // namespace carry_plan_detail + +/// @brief Select the cheapest live primitives for `req`. +/// @param req the request +/// @return a recipe whose flags name only the corrections that survive +/// @throws std::invalid_argument on inconsistent widths +/// \complexity A constant number of comparisons of `n`, `s`, `out_n`, and `sign`. No allocation beyond the returned `carry_recipe`. `Θ(1)`. +/// @see grotto::make_carry_keys +HEDLEY_WARN_UNUSED_RESULT +inline carry_recipe plan_carry(const carry_request & req) +{ + if (req.n == 0u) + throw std::invalid_argument("carry_plan: n must be positive"); + if (req.out_n == 0u) + throw std::invalid_argument("carry_plan: out_n must be positive"); + + carry_recipe r{}; + r.mode = req.mode; + r.n = req.n; + r.s = req.s; + r.out_n = req.out_n; + r.sign = req.sign; + + const bool reduced_ring = (req.out_n + req.s == req.n) && (req.s > 0u); + const bool same_width = (req.out_n == req.n); + + switch (req.mode) + { + case carry_mode::truncate_reduce: + { + if (req.s == 0u || req.s >= req.n) + throw std::invalid_argument("carry_plan: truncate_reduce needs 0 < s < n"); + if (req.out_n != req.n - req.s) + throw std::invalid_argument( + "carry_plan: truncate_reduce out_n must equal n-s"); + r.use_low_lt = true; + // Sign wrap is 0 in Z/2^{n-s}; never emit a carry-out term. + break; + } + case carry_mode::same_ring: + { + if (req.s >= req.n) + throw std::invalid_argument("carry_plan: same_ring needs s < n"); + if (!same_width) + { + // Caller asked for a fused shift that reduces the ring: drop + // carry-out and keep only the low-limb correction. + if (req.out_n != req.n - req.s) + throw std::invalid_argument( + "carry_plan: same_ring out_n must be n or n-s"); + r.use_low_lt = true; + break; + } + if (req.fuse || req.s > 0u) + r.use_low_lt = (req.s > 0u) && req.fuse; + + if (req.sign == sign_knowledge::unknown) + { + r.use_msb_lt = true; + r.use_share_msb_and = true; + r.msb_true_payload = 1; // returns msb bit; combined with AND below + r.and_unit = carry_plan_detail::unit_pow2(req.n - req.s); + } + else if (req.sign == sign_knowledge::nonnegative) + { + r.use_share_msb_and = true; + r.and_is_nor = false; + r.and_unit = carry_plan_detail::unit_pow2(req.n - req.s); + } + else + { + r.use_share_msb_and = true; + r.and_is_nor = true; + r.and_unit = -carry_plan_detail::unit_pow2(req.n - req.s); + } + break; + } + case carry_mode::extend: + { + if (req.out_n <= req.n) + throw std::invalid_argument("carry_plan: extend needs out_n > n"); + // Known sign does not switch to the share-MSB AND. + r.use_biased_wrap = true; + r.wrap_payload = carry_plan_detail::unit_pow2(req.n); + break; + } + case carry_mode::window: + { + if (req.s == 0u || req.s > req.n) + throw std::invalid_argument("carry_plan: window needs 0 < s <= n"); + r.window_d = req.s; + r.use_window_overflow = true; + if (req.incoming_carry_public) + { + r.public_incoming = req.incoming_carry_value; + // Public carry 0 drops the equality; a public 1 still needs the + // all-ones test, but the product is local (multiply by 1). + if (req.incoming_carry_value != 0u) + r.use_window_eq = true; + } + else + { + r.use_window_eq = true; + r.use_window_product = true; + } + break; + } + } + + // Fused same-ring request that somehow landed with a reduced modulus: + // the planner already dropped the sign term above via `!same_width`. + (void)reduced_ring; + return r; +} + +/// @brief Fill a truncate-and-reduce request and plan it. +/// \complexity Fills a `carry_request` and calls `plan_carry`. `Θ(1)`. +/// @see grotto::plan_carry +HEDLEY_WARN_UNUSED_RESULT +inline carry_recipe plan_carry_in(unsigned n, unsigned s) +{ + carry_request req{}; + req.n = n; + req.s = s; + req.out_n = n - s; + req.mode = carry_mode::truncate_reduce; + return plan_carry(req); +} + +/// @brief Fill a same-ring carry-out request and plan it. +/// \complexity Fills a `carry_request` and calls `plan_carry`. `Θ(1)`. +/// @see grotto::plan_carry +HEDLEY_WARN_UNUSED_RESULT +inline carry_recipe plan_carry_out(unsigned n, unsigned s, sign_knowledge sign) +{ + carry_request req{}; + req.n = n; + req.s = s; + req.out_n = n; + req.mode = carry_mode::same_ring; + req.sign = sign; + req.fuse = false; + return plan_carry(req); +} + +/// @brief Fill a fused same-ring exact-shift request and plan it. +/// @details When `out_n == n-s` the sign term is dropped automatically. +/// \complexity Fills a `carry_request` and calls `plan_carry`. `Θ(1)`. +/// @see grotto::plan_carry +HEDLEY_WARN_UNUSED_RESULT +inline carry_recipe plan_carry_fused(unsigned n, unsigned s, unsigned out_n, + sign_knowledge sign = sign_knowledge::unknown) +{ + carry_request req{}; + req.n = n; + req.s = s; + req.out_n = out_n; + req.mode = carry_mode::same_ring; + req.sign = sign; + req.fuse = true; + return plan_carry(req); +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_CARRY_PLAN_HPP__ diff --git a/include/grotto/closed_form.hpp b/include/grotto/closed_form.hpp new file mode 100644 index 0000000..a9061c4 --- /dev/null +++ b/include/grotto/closed_form.hpp @@ -0,0 +1,518 @@ +/// @file grotto/closed_form.hpp +/// @brief Closed forms of the principal, range, and window maps. +/// @details Inverse hyperbolics, inverse trig, SELU / ELU / CELU, softsign, +/// tanhshrink, the logistic / exponential / Laplace / Cauchy +/// quantiles, sinc, and the extra powers are compositions of +/// `eval_reduced` and `eval_window`. `atan` on `[0, tan(π/8)]` is a +/// odd power series; larger arguments reduce by `π/4` and `π/2`. +/// Roots and `x^{-0.1}` go through `ln` and `exp`. `x^{1.5}` is +/// `x √x` and `x^{-3}` is the reciprocal of an exact cube. +/// Precision is one of 8, 12, ..., 32. These compositions inherit +/// the range-reduction error, so they are not a 1-ulp claim. + +#ifndef LIBDPF_INCLUDE_GROTTO_CLOSED_FORM_HPP__ +#define LIBDPF_INCLUDE_GROTTO_CLOSED_FORM_HPP__ + +#include "grotto/range_lut.hpp" +#include "grotto/window_lut.hpp" + +#include +#include + +namespace grotto +{ + +enum class closed : unsigned +{ + atanh = 0, + asinh, + acosh, + atan, + acot, + asec, + acsc, + asech, + acsch, + acoth, + selu, + elu, + celu, + softsign, + tanhshrink, + logistic, + exponential, + laplace, + cauchy, + sinc, + cbrt, + qtrt, + icbrt, + iqtrt, + pow_m01, + pow_p15, + pow_m3, +}; + +/// @brief Evaluate one closed form at a fixed-point raw value. +/// @param which the closed-form function +/// @param fractional_bits precision in {8, 12, ..., 32} +/// @param raw the fixed-point argument +/// @return the fixed-point result +/// @throws std::invalid_argument if the precision is not a principal step +/// @throws std::domain_error at a pole or outside the function's domain +/// \complexity A constant number of `eval_reduced` / `eval_window` calls, plus the loops in this file: +/// `atan_series` runs `n = 1 .. 47` (stops on a zero term), `sinc_series` runs `n = 1 .. 16`, `newton_sqrt_raw` runs 4 steps, `newton_icbrt_raw` runs 6 steps after a right-shift log of the magnitude. +/// Extra space `Θ(1)`. These compositions are not a 1-ulp claim; the file comment says they inherit range-reduction error. +/// @see grotto::eval_reduced +/// @see grotto::eval_window +/// @note Not a 1-ulp claim. Poles and domain exits throw `std::domain_error`. +inline std::int64_t eval_closed(closed which, unsigned fractional_bits, std::int64_t raw); + +namespace closed_detail +{ + +using range_detail::div_raw; +using range_detail::mul_raw; +using range_detail::one_raw; +using range_detail::scale_unit; +using range_detail::u128; + +inline constexpr u128 selu_alpha_64 = (u128{1} << 64) | 12419514725947086766ULL; +inline constexpr u128 selu_scale_64 = (u128{1} << 64) | 935268138030932704ULL; +inline constexpr u128 tenth_64 = 1844674407370955162ULL; +inline constexpr u128 three_halves_64 = (u128{1} << 64) | 9223372036854775808ULL; + +inline std::int64_t require_precision(unsigned fractional_bits) +{ + if (!principal_precision(fractional_bits)) + throw std::invalid_argument("closed form: precision must be 8, 12, ..., 32"); + return one_raw(fractional_bits); +} + +inline std::int64_t abs_raw(std::int64_t raw) +{ + if (raw >= 0) + return raw; + const auto mag = -static_cast<__int128>(raw); + if (mag > INT64_MAX) + throw std::overflow_error("closed form: magnitude does not fit int64"); + return static_cast(mag); +} + +inline std::int64_t half_of(std::int64_t raw) +{ + const bool neg = raw < 0; + auto mag = static_cast(neg ? -static_cast<__int128>(raw) : raw); + const std::uint64_t bit = mag & 1u; + mag >>= 1; + if (bit) + ++mag; + if (mag > static_cast(INT64_MAX)) + throw std::overflow_error("closed form: value does not fit int64"); + const auto out = static_cast(mag); + return neg ? -out : out; +} + +inline std::int64_t div_int(std::int64_t raw, int denominator) +{ + if (denominator <= 0) + throw std::invalid_argument("closed form: divisor must be positive"); + const bool neg = raw < 0; + auto mag = static_cast<__int128>(neg ? -static_cast<__int128>(raw) : raw); + const __int128 den = denominator; + __int128 quot = mag / den; + if ((mag % den) * 2 >= den) + ++quot; + if (quot > INT64_MAX) + throw std::overflow_error("closed form: value does not fit int64"); + const auto out = static_cast(quot); + return neg ? -out : out; +} + +inline std::int64_t pi_over_4(unsigned fractional_bits) +{ + return scale_unit(range_detail::pi_over_4_64, fractional_bits); +} + +inline std::int64_t pi_over_2(unsigned fractional_bits) +{ + const __int128 wide = static_cast<__int128>(pi_over_4(fractional_bits)) << 1; + if (wide > INT64_MAX) + throw std::overflow_error("closed form: pi/2 does not fit"); + return static_cast(wide); +} + +inline std::int64_t atan_series(unsigned fractional_bits, std::int64_t x) +{ + __int128 acc = x; + std::int64_t power = x; + const std::int64_t x2 = mul_raw(x, x, fractional_bits); + int sign = -1; + for (int n = 1; n < 48; ++n) + { + power = mul_raw(power, x2, fractional_bits); + const std::int64_t term = div_int(power, 2 * n + 1); + if (term == 0) + break; + acc += sign < 0 ? -static_cast<__int128>(term) : term; + sign = -sign; + } + if (acc > INT64_MAX || acc < INT64_MIN) + throw std::overflow_error("closed form: atan does not fit"); + return static_cast(acc); +} + +inline std::int64_t atan_positive(unsigned fractional_bits, std::int64_t mag) +{ + const std::int64_t one = one_raw(fractional_bits); + if (mag > one) + return pi_over_2(fractional_bits) - atan_positive(fractional_bits, div_raw(one, mag, fractional_bits)); + const std::int64_t bound = scale_unit(range_detail::sqrt2_64, fractional_bits) - one; + if (mag > bound) + { + const std::int64_t t = div_raw(mag - one, mag + one, fractional_bits); + return pi_over_4(fractional_bits) + atan_series(fractional_bits, t); + } + return atan_series(fractional_bits, mag); +} + +inline std::int64_t eval_atan(unsigned fractional_bits, std::int64_t raw) +{ + require_precision(fractional_bits); + if (raw < 0) + return -atan_positive(fractional_bits, abs_raw(raw)); + return atan_positive(fractional_bits, raw); +} + +inline std::int64_t eval_ln_abs(unsigned fractional_bits, std::int64_t raw) +{ + return eval_reduced(reduced::ln, fractional_bits, abs_raw(raw)); +} + +inline std::int64_t eval_cbrt_abs(unsigned fractional_bits, std::int64_t mag) +{ + if (mag == 0) + return 0; + const std::int64_t ln = eval_ln_abs(fractional_bits, mag); + return eval_reduced(reduced::exp, fractional_bits, div_int(ln, 3)); +} + +inline range_detail::u256 shl_u128(range_detail::u128 value, unsigned shift) +{ + if (shift == 0) + return range_detail::u256{value, 0}; + if (shift < 128) + return range_detail::u256{value << shift, value >> (128u - shift)}; + return range_detail::u256{0, value << (shift - 128u)}; +} + +inline bool u256_less(range_detail::u256 a, range_detail::u256 b) +{ + if (a.hi != b.hi) + return a.hi < b.hi; + return a.lo < b.lo; +} + +/// @brief Rounded `(num << shift) / den`. +inline range_detail::u128 div_shifted(range_detail::u128 num, range_detail::u128 den, unsigned shift) +{ + if (den == 0) + throw std::domain_error("closed form: division by zero"); + const range_detail::u256 target = shl_u128(num, shift); + range_detail::u128 lo = 0; + range_detail::u128 hi = 1; + while (u256_less(range_detail::mul_u128(hi, den), target) || + (!u256_less(target, range_detail::mul_u128(hi, den)) && hi < (range_detail::u128{1} << 80))) + { + if (hi > (range_detail::u128{1} << 100)) + break; + hi <<= 1; + } + while (lo + 1 < hi) + { + const range_detail::u128 mid = lo + (hi - lo) / 2; + if (u256_less(target, range_detail::mul_u128(mid, den))) + hi = mid; + else + lo = mid; + } + const range_detail::u256 half = range_detail::mul_u128(lo + lo + 1, den); + if (!u256_less(target, half)) + return lo + 1; + return lo; +} + +inline std::int64_t newton_sqrt_raw(unsigned fractional_bits, std::int64_t raw) +{ + const unsigned K = fractional_bits * 2u; + range_detail::u128 y = static_cast( + std::max(eval_reduced(reduced::sqrt, fractional_bits, raw), 1)) + << fractional_bits; + const range_detail::u128 x = static_cast(raw) << fractional_bits; + for (int step = 0; step < 4; ++step) + { + const range_detail::u128 quot = div_shifted(x, y, K); + y = (y + quot + 1) >> 1; + } + const range_detail::u128 prod = range_detail::round_u256( + range_detail::mul_u128(static_cast(raw), y), K); + if (prod > static_cast(INT64_MAX)) + throw std::overflow_error("closed form: power does not fit int64"); + return static_cast(prod); +} + +inline std::int64_t newton_icbrt_raw(unsigned fractional_bits, std::int64_t mag) +{ + const unsigned K = fractional_bits * 2u; + int log = 0; + auto bits = static_cast(mag); + while (bits > 1) + { + bits >>= 1; + ++log; + } + const int exp = log - static_cast(fractional_bits); + const int third = exp >= 0 ? exp / 3 : -(( -exp + 2) / 3); + range_detail::u128 y = range_detail::u128{1} << static_cast(K + std::max(third, 0)); + if (third < 0) + y >>= static_cast(-third); + if (y == 0) + y = 1; + const range_detail::u128 x = static_cast(mag) << fractional_bits; + for (int step = 0; step < 6; ++step) + { + const range_detail::u128 y2 = range_detail::round_u256(range_detail::mul_u128(y, y), K); + if (y2 == 0) + break; + const range_detail::u128 quot = div_shifted(x, y2, K); + y = (y + y + quot) / 3; + if (y == 0) + y = 1; + } + const range_detail::u128 numer = range_detail::u128{1} << (K + fractional_bits); + const range_detail::u128 inv = (numer + y / 2) / y; + if (inv > static_cast(INT64_MAX)) + throw std::overflow_error("closed form: inverse cube root does not fit int64"); + return static_cast(inv); +} + +inline std::int64_t sinc_series(unsigned fractional_bits, std::int64_t raw) +{ + constexpr unsigned extra = 16; + __int128 acc = __int128{1} << (fractional_bits + extra); + __int128 term = acc; + const std::int64_t mag = raw < 0 ? -raw : raw; + for (int n = 1; n <= 16; ++n) + { + term = range_detail::shr_round_i128(term * mag, fractional_bits); + term = range_detail::shr_round_i128(term * mag, fractional_bits); + term = range_detail::div_round_i128(term, (2 * n) * (2 * n + 1)); + if (term == 0) + break; + acc += (n % 2) != 0 ? -term : term; + } + return range_detail::round_i128(acc, extra); +} + +inline std::int64_t square_plus(unsigned fractional_bits, std::int64_t raw, int sign) +{ + const std::int64_t one = one_raw(fractional_bits); + const std::int64_t sq = mul_raw(raw, raw, fractional_bits); + const __int128 sum = static_cast<__int128>(sq) + (sign < 0 ? -one : one); + if (sum < 0) + throw std::domain_error("closed form: square is below the root domain"); + if (sum > INT64_MAX) + throw std::overflow_error("closed form: square does not fit"); + return eval_reduced(reduced::sqrt, fractional_bits, static_cast(sum)); +} + +} // namespace closed_detail +/// \complexity A constant number of `eval_reduced` / `eval_window` calls, plus the loops in this file: +/// `atan_series` runs `n = 1 .. 47` (stops on a zero term), `sinc_series` runs `n = 1 .. 16`, `newton_sqrt_raw` runs 4 steps, `newton_icbrt_raw` runs 6 steps after a right-shift log of the magnitude. +/// Extra space `Θ(1)`. These compositions are not a 1-ulp claim; the file comment says they inherit range-reduction error. +/// @see grotto::eval_reduced +/// @see grotto::eval_window +/// @note Not a 1-ulp claim. Poles and domain exits throw `std::domain_error`. + +inline std::int64_t eval_closed(closed which, unsigned fractional_bits, std::int64_t raw) +{ + using namespace closed_detail; + const std::int64_t one = require_precision(fractional_bits); + switch (which) + { + case closed::atan: + return eval_atan(fractional_bits, raw); + case closed::acot: + return pi_over_2(fractional_bits) - eval_atan(fractional_bits, raw); + case closed::asec: + case closed::acsc: + { + if (abs_raw(raw) < one) + throw std::domain_error("closed form: inverse secant requires |x| >= 1"); + const std::int64_t inv = div_raw(one, raw, fractional_bits); + return which == closed::asec + ? eval_window(window::acos, fractional_bits, inv) + : eval_window(window::asin, fractional_bits, inv); + } + case closed::atanh: + { + if (abs_raw(raw) >= one) + throw std::domain_error("closed form: atanh domain is (-1, 1)"); + const std::int64_t plus = eval_reduced(reduced::log1p, fractional_bits, raw); + const std::int64_t minus = eval_reduced(reduced::log1p, fractional_bits, -raw); + return half_of(plus - minus); + } + case closed::asinh: + { + const std::int64_t mag = abs_raw(raw); + std::int64_t sum = 0; + try + { + sum = mag + square_plus(fractional_bits, mag, +1); + } + catch (const std::overflow_error &) + { + sum = 0; + } + const std::int64_t value = sum == 0 + ? eval_ln_abs(fractional_bits, mag) + range_detail::ln2_raw(fractional_bits) + : eval_reduced(reduced::ln, fractional_bits, sum); + return raw < 0 ? -value : value; + } + case closed::acosh: + { + if (raw < one) + throw std::domain_error("closed form: acosh domain is [1, inf)"); + return eval_reduced(reduced::ln, fractional_bits, + raw + square_plus(fractional_bits, raw, -1)); + } + case closed::asech: + { + if (raw <= 0 || raw > one) + throw std::domain_error("closed form: asech domain is (0, 1]"); + return eval_closed(closed::acosh, fractional_bits, div_raw(one, raw, fractional_bits)); + } + case closed::acsch: + { + if (raw == 0) + throw std::domain_error("closed form: acsch pole"); + return eval_closed(closed::asinh, fractional_bits, div_raw(one, raw, fractional_bits)); + } + case closed::acoth: + { + if (abs_raw(raw) <= one) + throw std::domain_error("closed form: acoth domain is |x| > 1"); + return eval_closed(closed::atanh, fractional_bits, div_raw(one, raw, fractional_bits)); + } + case closed::elu: + return raw > 0 ? raw : eval_reduced(reduced::expm1, fractional_bits, raw); + case closed::celu: + return eval_closed(closed::elu, fractional_bits, raw); + case closed::selu: + { + const std::int64_t body = raw > 0 + ? raw + : mul_raw(scale_unit(selu_alpha_64, fractional_bits), + eval_reduced(reduced::expm1, fractional_bits, raw), fractional_bits); + return mul_raw(scale_unit(selu_scale_64, fractional_bits), body, fractional_bits); + } + case closed::softsign: + { + const std::int64_t mag = abs_raw(raw); + return div_raw(raw, one + mag, fractional_bits); + } + case closed::tanhshrink: + return raw - eval_window(window::tanh, fractional_bits, raw); + case closed::logistic: + { + if (raw <= 0 || raw >= one) + throw std::domain_error("closed form: quantile domain is (0, 1)"); + const std::int64_t num = eval_reduced(reduced::ln, fractional_bits, raw); + const std::int64_t den = eval_reduced(reduced::ln, fractional_bits, one - raw); + return num - den; + } + case closed::exponential: + { + if (raw <= 0 || raw >= one) + throw std::domain_error("closed form: quantile domain is (0, 1)"); + return -eval_reduced(reduced::ln, fractional_bits, one - raw); + } + case closed::laplace: + { + if (raw <= 0 || raw >= one) + throw std::domain_error("closed form: quantile domain is (0, 1)"); + const std::int64_t half = one >> 1; + if (raw <= half) + return eval_reduced(reduced::ln, fractional_bits, raw << 1); + return -eval_reduced(reduced::ln, fractional_bits, (one - raw) << 1); + } + case closed::cauchy: + { + if (raw <= 0 || raw >= one) + throw std::domain_error("closed form: quantile domain is (0, 1)"); + const std::int64_t half = one >> 1; + const std::int64_t pi = pi_over_2(fractional_bits) << 1; + const std::int64_t angle = mul_raw(pi, raw - half, fractional_bits); + return eval_reduced(reduced::tan, fractional_bits, angle); + } + case closed::sinc: + if (raw == 0) + return one; + if (abs_raw(raw) <= one) + return sinc_series(fractional_bits, raw); + return div_raw(eval_reduced(reduced::sin, fractional_bits, raw), raw, fractional_bits); + case closed::cbrt: + case closed::icbrt: + { + if (which == closed::icbrt) + { + if (raw == 0) + throw std::domain_error("closed form: inverse cube root of zero"); + const std::int64_t value = newton_icbrt_raw(fractional_bits, abs_raw(raw)); + return raw < 0 ? -value : value; + } + const std::int64_t root = eval_cbrt_abs(fractional_bits, abs_raw(raw)); + return raw < 0 ? -root : root; + } + case closed::qtrt: + case closed::iqtrt: + { + if (raw < 0) + throw std::domain_error("closed form: fourth root requires x >= 0"); + if (raw == 0) + return which == closed::qtrt ? 0 : throw std::domain_error("closed form: inverse fourth root of zero"), 0; + const std::int64_t ln = eval_ln_abs(fractional_bits, raw); + const std::int64_t root = eval_reduced(reduced::exp, fractional_bits, div_int(ln, 4)); + return which == closed::qtrt ? root : div_raw(one, root, fractional_bits); + } + case closed::pow_m01: + { + if (raw <= 0) + throw std::domain_error("closed form: x^{-0.1} requires x > 0"); + const std::int64_t ln = eval_ln_abs(fractional_bits, raw); + const std::int64_t scaled = mul_raw(ln, scale_unit(tenth_64, fractional_bits), fractional_bits); + return eval_reduced(reduced::exp, fractional_bits, -scaled); + } + case closed::pow_p15: + { + if (raw < 0) + throw std::domain_error("closed form: x^{1.5} requires x >= 0"); + if (raw == 0) + return 0; + return newton_sqrt_raw(fractional_bits, raw); + } + case closed::pow_m3: + { + if (raw == 0) + throw std::domain_error("closed form: x^{-3} pole"); + const std::int64_t sq = mul_raw(raw, raw, fractional_bits); + const std::int64_t cube = mul_raw(sq, raw, fractional_bits); + return div_raw(one, cube, fractional_bits); + } + } + throw std::invalid_argument("closed form: unknown map"); +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_CLOSED_FORM_HPP__ diff --git a/include/grotto/constant_lut.hpp b/include/grotto/constant_lut.hpp index 7660a9c..8f3b245 100644 --- a/include/grotto/constant_lut.hpp +++ b/include/grotto/constant_lut.hpp @@ -73,6 +73,9 @@ struct constant_lut return values.size() - 1; return values.size(); } + /// \complexity `upper_bound` on `bounds`. `Θ(log P)` comparisons, `P = linear_parts()`. Extra space `Θ(1)`. + /// @param x raw domain point + /// @return the piece value HEDLEY_NO_THROW std::int64_t operator()(Raw x) const noexcept @@ -161,7 +164,7 @@ inline bool magnitude_ge_pow10(u128 mag, int k, unsigned fractional_bits) noexce } /// @brief Smallest positive magnitude whose base-10 log is at least `k`. -/// @param k the `k` +/// @param k index or exponent /// @param fractional_bits the number of fractional bits /// @return Smallest positive magnitude whose base-10 log is at least `k` HEDLEY_NO_THROW @@ -522,6 +525,8 @@ struct exact_lut [=](Raw raw) { return eval(raw, fractional_bits); }); } }; +/// \complexity One call to `exact_lut::eval`. Sign maps are a branch. Bit maps scan at most the raw width. `Θ(w)` bit operations, extra space `Θ(1)`. +/// @see grotto::make_exact_constant_lut template std::int64_t evaluate_exact(Raw raw, unsigned fractional_bits) @@ -531,6 +536,15 @@ std::int64_t evaluate_exact(Raw raw, unsigned fractional_bits) throw std::invalid_argument("fractional bits exceed the raw width"); return exact_lut::template eval(raw, fractional_bits); } +/// \complexity Dispatches to `exact_lut::project`. Sign patterns emit a constant number of cuts. +/// `ilogb`, `ceil_ilogb`, `clz`, and `clrsb` push one cut per bit of the raw width (`Θ(w)`). `ilog10` walks powers of ten. +/// Extra space is the cut and value vectors. +/// @see grotto::evaluate_exact +/// @see grotto::dyadic_lut +/// @param which which degree-0 map +/// @param fractional_bits must not exceed the raw width +/// @return the piecewise-constant table +/// @note Following Storrier, Vadapalli, Lyons, and Henry, ePrint 2023/108, Appendix D: the degree-0 exact gadgets. template constant_lut make_exact_constant_lut(exact_constant which, unsigned fractional_bits) @@ -577,6 +591,8 @@ enum class threshold_cmp gt, geq }; +/// \complexity One comparison. `Θ(1)`. +/// @see grotto::make_threshold_lut template HEDLEY_NO_THROW @@ -591,6 +607,8 @@ std::int64_t evaluate_threshold(Raw raw, Raw bound, threshold_cmp kind) noexcept } return 0; } +/// \complexity Two or three cuts (the bound, and `bound + 1` for `leq` / `gt`). `Θ(1)`. +/// @see grotto::evaluate_threshold template constant_lut make_threshold_lut(Raw bound, threshold_cmp kind) @@ -610,6 +628,8 @@ constant_lut make_threshold_lut(Raw bound, threshold_cmp kind) /// @param high the upper endpoint /// @return `1` on the inclusive clip window `[low, high]`, `0` outside it /// @throws std::invalid_argument if `low > high` +/// \complexity Two or three cuts. `Θ(1)`. +/// @see grotto::make_threshold_lut template constant_lut make_interval_lut(Raw low, Raw high) { @@ -637,6 +657,8 @@ constant_lut make_interval_lut(Raw low, Raw high) /// @param high the upper endpoint /// @return `floor(min(max(raw, low), high) / modulus)`, division toward -infinity /// @throws std::invalid_argument if `modulus must be positive` +/// \complexity One clamp and one division. `Θ(1)`. Division is toward -infinity, as the comment on the declaration says. +/// @see grotto::make_clipped_quotient_lut template std::int64_t evaluate_clipped_quotient(Raw raw, Raw modulus, Raw low, Raw high) { @@ -652,6 +674,9 @@ std::int64_t evaluate_clipped_quotient(Raw raw, Raw modulus, Raw low, Raw high) const __int128 neg = -n; return static_cast(-((neg + d - 1) / d)); } +/// \complexity The cut loop steps by `modulus` from `low` through `high`. The header rejects spans with more than `2^16` pieces. +/// Time and extra space `Θ((high - low) / modulus)` in raw units. +/// @see grotto::evaluate_clipped_quotient template constant_lut make_clipped_quotient_lut(Raw modulus, Raw low, Raw high) diff --git a/include/grotto/dwt_lut.hpp b/include/grotto/dwt_lut.hpp new file mode 100644 index 0000000..9c805af --- /dev/null +++ b/include/grotto/dwt_lut.hpp @@ -0,0 +1,277 @@ +/// @file grotto/dwt_lut.hpp +/// @brief Haar and bior(5,3) compressed lookup tables. +/// @details Cleartext evaluators for Reis, Ugurbil, Wagh, Henry, and de Vega, +/// PoPETs 2025 ([ePrint 2025/013](@ref bib_wave)). A power-of-two +/// grid is reduced by a discrete wavelet transform and stored as +/// fixed-point approximation coefficients. Haar evaluates with one +/// lookup of the high bits. bior(5,3) evaluates Equation (8): two +/// adjacent coefficients, weighted by `(2^j - lsb)` and `lsb`. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_GROTTO_DWT_LUT_HPP__ +#define LIBDPF_INCLUDE_GROTTO_DWT_LUT_HPP__ + +#include +#include +#include +#include +#include + +namespace grotto +{ + +/// @brief Which wavelet compresses the table. +enum class dwt_family : unsigned +{ + /// Orthogonal Haar. One approximation coefficient per block of `2^depth` samples. + haar = 0, + /// Biorthogonal bior(5,3), PyWavelets `bior2.2`. Two taps at evaluation. + bior53, +}; + +/// @brief Fixed-point Haar or bior(5,3) table. +/// @details `coeff` holds the quantized approximation coefficients. +/// `operator()` is the cleartext evaluation those MPC protocols return. +struct dwt_lut +{ + dwt_family family = dwt_family::haar; + /// Transform depth `j`. The kept index is `raw >> depth`. + unsigned depth = 0; + /// `log2` of the sample count. Inputs lie in `[0, 2^{domain_bits})`. + unsigned domain_bits = 0; + /// Fraction bits of every stored coefficient and of the returned word. + unsigned fractional_bits = 0; + std::vector coeff; + + /// \complexity Haar is one indexing step, `Θ(1)`. bior(5,3) is two multiplications and a shift by `2j`, `Θ(1)`. Extra space `Θ(1)`. + /// @param raw index on the sampled grid, in `[0, 2^{domain_bits})` + /// @return fixed-point approximation, `fractional_bits` fraction bits + std::int64_t operator()(std::uint64_t raw) const + { + if (domain_bits == 0 || domain_bits > 30 || depth == 0 || depth > domain_bits) + throw std::logic_error("dwt lut: table is not initialized"); + const std::uint64_t domain = std::uint64_t{1} << domain_bits; + if (raw >= domain) + throw std::out_of_range("dwt lut: input is outside the sampled domain"); + const std::uint64_t msb = raw >> depth; + if (family == dwt_family::haar) + { + if (msb >= coeff.size()) + throw std::out_of_range("dwt lut: Haar index"); + return coeff[static_cast(msb)]; + } + if (coeff.empty() || msb >= coeff.size()) + throw std::out_of_range("dwt lut: bior index"); + // Smooth extension prepends two coefficients, so bin `msb` lives at + // `msb + 2` and its neighbor at `msb + 3` (Equation (8), artifact indexing). + const std::size_t n = coeff.size(); + const auto c0 = coeff[static_cast((msb + 2) % n)]; + const auto c1 = coeff[static_cast((msb + 3) % n)]; + const std::uint64_t span = std::uint64_t{1} << depth; + const std::uint64_t lsb = raw & (span - 1); + const __int128 comb = __int128(c0) * static_cast<__int128>(span - lsb) + + __int128(c1) * static_cast<__int128>(lsb); + const __int128 den = __int128{1} << (2 * depth); + return detail_floor_div(comb, den); + } + +private: + static std::int64_t detail_floor_div(__int128 num, __int128 den) + { + __int128 q = num / den; + const __int128 r = num % den; + if (r != 0 && num < 0) + --q; + if (q > std::numeric_limits::max() + || q < std::numeric_limits::min()) + throw std::overflow_error("dwt lut: value does not fit int64"); + return static_cast(q); + } +}; + +namespace dwt_detail +{ + +inline unsigned log2_pow2(std::size_t n) +{ + if (n < 2 || (n & (n - 1)) != 0) + throw std::invalid_argument("dwt lut: sample count must be a power of two, at least 2"); + unsigned bits = 0; + while ((std::size_t{1} << bits) != n) + ++bits; + if (bits > 30) + throw std::invalid_argument("dwt lut: sample count exceeds 2^30"); + return bits; +} + +inline std::int64_t quantize(double y, unsigned fractional_bits) +{ + const double scaled = std::floor(y * std::ldexp(1.0, static_cast(fractional_bits))); + const double lo = static_cast(std::numeric_limits::min()); + if (!(scaled >= lo && scaled < 0x1p63)) + throw std::overflow_error("dwt lut: coefficient does not fit int64"); + return static_cast(scaled); +} + +inline double half_exp(int k) +{ + double scale = std::ldexp(1.0, k / 2); + if (k % 2 != 0) + scale *= (k < 0) ? std::sqrt(0.5) : std::sqrt(2.0); + return scale; +} + +inline std::vector down_approx(const std::vector & in, const double * filt, int F) +{ + const int N = static_cast(in.size()); + if (N < 1) + throw std::invalid_argument("dwt lut: empty approximation"); + const int expect = (N + F - 1) / 2; + if (N < 2) + { + double sum = 0; + for (int j = 0; j < F; ++j) + sum += filt[j]; + return std::vector(static_cast(expect), in[0] * sum); + } + + std::vector out; + out.reserve(static_cast(expect)); + int i = 1; + while (i < F && i < N) + { + double s = 0; + int j = 0; + for (; j <= i; ++j) + s += filt[j] * in[static_cast(i - j)]; + for (int k = 1; j < F; ++j, ++k) + s += filt[j] * (in[0] + static_cast(k) * (in[0] - in[1])); + out.push_back(s); + i += 2; + } + while (i < N) + { + double s = 0; + for (int j = 0; j < F; ++j) + s += in[static_cast(i - j)] * filt[j]; + out.push_back(s); + i += 2; + } + while (i < F) + { + double s = 0; + int j = 0; + for (int k = i - N + 1; i - j >= N; ++j, --k) + s += filt[j] * (in[static_cast(N - 1)] + + static_cast(k) * (in[static_cast(N - 1)] + - in[static_cast(N - 2)])); + for (; j <= i; ++j) + s += filt[j] * in[static_cast(i - j)]; + for (int k = 1; j < F; ++j, ++k) + s += filt[j] * (in[0] + static_cast(k) * (in[0] - in[1])); + out.push_back(s); + i += 2; + } + while (i < N + F - 1) + { + double s = 0; + int j = 0; + for (int k = i - N + 1; i - j >= N; ++j, --k) + s += filt[j] * (in[static_cast(N - 1)] + + static_cast(k) * (in[static_cast(N - 1)] + - in[static_cast(N - 2)])); + for (; j < F; ++j) + s += filt[j] * in[static_cast(i - j)]; + out.push_back(s); + i += 2; + } + if (static_cast(out.size()) != expect) + throw std::logic_error("dwt lut: approximation length"); + return out; +} + +inline dwt_lut build(dwt_family family, const std::vector & samples, + unsigned fractional_bits, unsigned depth) +{ + if (fractional_bits > 62) + throw std::invalid_argument("dwt lut: fractional width does not fit"); + const unsigned domain_bits = log2_pow2(samples.size()); + if (depth == 0 || depth > domain_bits) + throw std::invalid_argument("dwt lut: depth must lie in 1 .. domain bits"); + + const double s2 = std::sqrt(2.0); + const double haar_lo[2] = {s2 / 2, s2 / 2}; + const double s2_8 = s2 / 8; + const double s2_4 = s2 / 4; + const double bior_lo[6] = {0.0, -s2_8, s2_4, 3 * s2_4, s2_4, -s2_8}; + + const double * filt = haar_lo; + int flen = 2; + int scale_sign = -1; + if (family == dwt_family::bior53) + { + filt = bior_lo; + flen = 6; + scale_sign = 1; + } + + std::vector approx = samples; + for (unsigned level = 0; level < depth; ++level) + approx = down_approx(approx, filt, flen); + + const double scale = half_exp(scale_sign * static_cast(depth)); + dwt_lut table; + table.family = family; + table.depth = depth; + table.domain_bits = domain_bits; + table.fractional_bits = fractional_bits; + table.coeff.reserve(approx.size()); + for (double a : approx) + table.coeff.push_back(quantize(a * scale, fractional_bits)); + return table; +} + +} // namespace dwt_detail + +/// @brief Sample `f` on `i · 2^{-fractional_bits}` for `i` in `[0, 2^{domain_bits})`. +/// \complexity `Θ(2^{domain_bits})` calls and extra space. +/// @tparam Fn callable `double(double)` +template +std::vector sample_dwt_signal(unsigned domain_bits, unsigned fractional_bits, Fn && f) +{ + if (domain_bits == 0 || domain_bits > 30) + throw std::invalid_argument("dwt lut: domain bits must lie in 1 .. 30"); + if (fractional_bits > 62) + throw std::invalid_argument("dwt lut: fractional width does not fit"); + const std::size_t n = std::size_t{1} << domain_bits; + const double step = std::ldexp(1.0, -static_cast(fractional_bits)); + std::vector samples(n); + for (std::size_t i = 0; i < n; ++i) + samples[i] = f(static_cast(i) * step); + return samples; +} + +/// \complexity One smooth-extension low-pass per level. `Θ(N)` arithmetic and extra space, `N` the sample count. +/// @param samples real signal, length `2^{domain bits}` +/// @param fractional_bits fraction bits of the stored words +/// @param depth transform depth `j`, in `1 .. log2(samples)` +dwt_lut make_haar_dwt_lut(const std::vector & samples, + unsigned fractional_bits, unsigned depth) +{ + return dwt_detail::build(dwt_family::haar, samples, fractional_bits, depth); +} + +/// \complexity One smooth-extension low-pass per level. `Θ(N)` arithmetic and extra space, `N` the sample count. +/// @param samples real signal, length `2^{domain bits}` +/// @param fractional_bits fraction bits of the stored words +/// @param depth transform depth `j`, in `1 .. log2(samples)` +dwt_lut make_bior53_dwt_lut(const std::vector & samples, + unsigned fractional_bits, unsigned depth) +{ + return dwt_detail::build(dwt_family::bior53, samples, fractional_bits, depth); +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_DWT_LUT_HPP__ diff --git a/include/grotto/dyadic_lut.hpp b/include/grotto/dyadic_lut.hpp index 5027729..2dbd2c8 100644 --- a/include/grotto/dyadic_lut.hpp +++ b/include/grotto/dyadic_lut.hpp @@ -227,6 +227,9 @@ easy_lut predicate_lut(unsigned fractional_bits, bool at_or_below_zero, } } // namespace detail +/// \complexity Two or three cuts around 0, from `predicate_lut` / `steps_from_cuts`. `Θ(1)` time and extra space. +/// @see grotto::make_exact_constant_lut +/// @see grotto::easy_lut template HEDLEY_WARN_UNUSED_RESULT @@ -234,6 +237,9 @@ easy_lut make_positive_lut(unsigned fractional_bits = 0) { return detail::predicate_lut(fractional_bits, false, false, true); } +/// \complexity Two or three cuts around 0, from `predicate_lut` / `steps_from_cuts`. `Θ(1)` time and extra space. +/// @see grotto::make_exact_constant_lut +/// @see grotto::easy_lut template HEDLEY_WARN_UNUSED_RESULT @@ -241,6 +247,9 @@ easy_lut make_negative_lut(unsigned fractional_bits = 0) { return detail::predicate_lut(fractional_bits, true, false, false); } +/// \complexity Two or three cuts around 0, from `predicate_lut` / `steps_from_cuts`. `Θ(1)` time and extra space. +/// @see grotto::make_exact_constant_lut +/// @see grotto::easy_lut template HEDLEY_WARN_UNUSED_RESULT @@ -248,6 +257,9 @@ easy_lut make_nonnegative_lut(unsigned fractional_bits = 0) { return detail::predicate_lut(fractional_bits, false, true, true); } +/// \complexity Two or three cuts around 0, from `predicate_lut` / `steps_from_cuts`. `Θ(1)` time and extra space. +/// @see grotto::make_exact_constant_lut +/// @see grotto::easy_lut template HEDLEY_WARN_UNUSED_RESULT @@ -255,6 +267,9 @@ easy_lut make_nonpositive_lut(unsigned fractional_bits = 0) { return detail::predicate_lut(fractional_bits, true, true, false); } +/// \complexity Two or three cuts around 0, from `predicate_lut` / `steps_from_cuts`. `Θ(1)` time and extra space. +/// @see grotto::make_exact_constant_lut +/// @see grotto::easy_lut template HEDLEY_WARN_UNUSED_RESULT @@ -262,6 +277,9 @@ easy_lut make_zero_lut(unsigned fractional_bits = 0) { return detail::predicate_lut(fractional_bits, false, true, false); } +/// \complexity Two or three cuts around 0, from `predicate_lut` / `steps_from_cuts`. `Θ(1)` time and extra space. +/// @see grotto::make_exact_constant_lut +/// @see grotto::easy_lut template HEDLEY_WARN_UNUSED_RESULT @@ -269,6 +287,9 @@ easy_lut make_nonzero_lut(unsigned fractional_bits = 0) { return detail::predicate_lut(fractional_bits, true, false, true); } +/// \complexity Two or three cuts around 0, from `predicate_lut` / `steps_from_cuts`. `Θ(1)` time and extra space. +/// @see grotto::make_exact_constant_lut +/// @see grotto::easy_lut template HEDLEY_WARN_UNUSED_RESULT @@ -283,6 +304,8 @@ easy_lut make_signum_lut(unsigned fractional_bits = 0) return detail::easy_poly{one, 0, 0, 1}; }); } +/// \complexity One cut per bit of `raw_width()` (the powers of two, plus 0 and 1). `Θ(w)` time and extra space, `w` the raw width. +/// @see grotto::eval_bit_width template HEDLEY_WARN_UNUSED_RESULT @@ -296,6 +319,8 @@ easy_lut make_clz_lut(unsigned fractional_bits = 0) return detail::unit_poly(detail::clz_of(raw), fractional_bits); }); } +/// \complexity Cuts at `±2^e` across the raw width. `Θ(w)` time and extra space. +/// @see grotto::exact_constant template HEDLEY_WARN_UNUSED_RESULT @@ -316,6 +341,9 @@ easy_lut make_clrsb_lut(unsigned fractional_bits = 0) return detail::unit_poly(detail::clrsb_of(raw), fractional_bits); }); } +/// \complexity One cut per bit on each side of zero (`Θ(w)`), then one `ilogb_units` (a `floor_log2`) per piece. `Θ(w)` time and extra space. +/// @see grotto::exact_constant +/// @note `ilogb(0)` is the sentinel `ilog_of_zero`, not a logarithm. template HEDLEY_WARN_UNUSED_RESULT @@ -339,6 +367,10 @@ easy_lut make_ilogb_lut(unsigned fractional_bits = 0) fractional_bits); }); } +/// \complexity For each decimal exponent from `ilog10_units(1)` to the exponent of the type max, two binary searches over the positive raw domain (`Θ(w)` probes each). +/// The exponent count is `Θ(w)`. Time `Θ(w²)` probes. Extra space is the cut vector, one cut per exponent class. +/// @see grotto::exact_constant +/// @note `ilog10(0)` is `ilog_of_zero`. template HEDLEY_WARN_UNUSED_RESULT @@ -401,10 +433,14 @@ easy_lut make_ilog10_lut(unsigned fractional_bits = 0) /// @details Index 0 is the sign bit. Larger indexes are refused: the bit is constant /// on `2^{index+1}` intervals. /// @tparam Raw underlying representation -/// @param index the index +/// @param index bit index counting down from the MSB; must be `< msb_bit_limit` /// @param fractional_bits the number of fractional bits /// @return Bit `index` counting down from the most significant bit of `Raw` /// @throws std::invalid_argument if `only the most significant bits are piecewise-cheap` +/// \complexity The hot bit is constant on steps of `2^{width-1-index}`. The cut loop emits `Θ(2^{index})` boundaries, and `index` must be `< msb_bit_limit` (8), so at most 256 cuts. +/// Time and extra space `Θ(2^{index})`. +/// @see grotto::easy_lut +/// @see grotto::eval_bit_width template HEDLEY_WARN_UNUSED_RESULT easy_lut make_msb_lut(unsigned index, unsigned fractional_bits = 0) diff --git a/include/grotto/easy_lut.hpp b/include/grotto/easy_lut.hpp index 7491158..6437f9d 100644 --- a/include/grotto/easy_lut.hpp +++ b/include/grotto/easy_lut.hpp @@ -40,6 +40,9 @@ struct easy_lut HEDLEY_NO_THROW std::size_t parts() const noexcept { return c0.size(); } + /// \complexity `upper_bound` on `bounds` (`Θ(log P)` comparisons, `P = parts()`), then three multiplies for the quadratic. Extra space `Θ(1)`. + /// @param x raw fixed-point input + /// @return the rounded piece value std::int64_t operator()(Raw x) const { @@ -155,6 +158,11 @@ inline std::int64_t denom_shift(unsigned shift) } } // namespace detail +/// \complexity Assembles a constant number of pieces (the knots are a fixed integer pattern shifted by `fractional_bits`). `Θ(1)` time and extra space, aside from the returned vectors of that constant length. +/// @see grotto::easy_lut +/// @see grotto::eval_window +/// @param fractional_bits fractional bits; integer knots become `k << fractional_bits` +/// @tparam Raw signed raw word template easy_lut make_abs_lut(unsigned fractional_bits = 0) @@ -167,6 +175,11 @@ easy_lut make_abs_lut(unsigned fractional_bits = 0) return p; }); } +/// \complexity Assembles a constant number of pieces (the knots are a fixed integer pattern shifted by `fractional_bits`). `Θ(1)` time and extra space, aside from the returned vectors of that constant length. +/// @see grotto::easy_lut +/// @see grotto::eval_window +/// @param fractional_bits fractional bits; integer knots become `k << fractional_bits` +/// @tparam Raw signed raw word template easy_lut make_relu_lut(unsigned fractional_bits = 0) @@ -182,6 +195,9 @@ easy_lut make_relu_lut(unsigned fractional_bits = 0) /// @tparam Raw underlying representation /// @param shift the bit shift /// @return Negative side is `x / 2^shift`, rounded to nearest, ties away from zero +/// \complexity Assembles a constant number of pieces. `Θ(1)` time and extra space, aside from the returned vectors of that constant length. +/// @see grotto::easy_lut +/// @see grotto::eval_window template easy_lut make_leaky_relu_lut(unsigned shift) { @@ -192,6 +208,11 @@ easy_lut make_leaky_relu_lut(unsigned shift) return detail::easy_poly{0, 1, 0, den}; }); } +/// \complexity Assembles a constant number of pieces (the knots are a fixed integer pattern shifted by `fractional_bits`). `Θ(1)` time and extra space, aside from the returned vectors of that constant length. +/// @see grotto::easy_lut +/// @see grotto::eval_window +/// @param fractional_bits fractional bits; integer knots become `k << fractional_bits` +/// @tparam Raw signed raw word template easy_lut make_squared_relu_lut(unsigned fractional_bits) @@ -233,18 +254,35 @@ easy_lut clip_to(unsigned fractional_bits, std::int64_t low_units, std::int } } // namespace detail - +/// @brief Clip to `[low_units, high_units]` in raw units, then shift the knots by `fractional_bits`. +/// @tparam Raw signed raw word +/// @param fractional_bits fractional bits; integer knots become `k << fractional_bits` +/// @param low_units inclusive lower clip, in integer units before the fractional shift +/// @param high_units inclusive upper clip, in integer units before the fractional shift +/// \complexity Assembles a constant number of pieces. `Θ(1)` time and extra space. +/// @see grotto::easy_lut +/// @see grotto::eval_window template easy_lut make_clip_lut(unsigned fractional_bits, std::int64_t low_units, std::int64_t high_units) { return detail::clip_to(fractional_bits, low_units, high_units); } +/// \complexity Assembles a constant number of pieces (the knots are a fixed integer pattern shifted by `fractional_bits`). `Θ(1)` time and extra space, aside from the returned vectors of that constant length. +/// @see grotto::easy_lut +/// @see grotto::eval_window +/// @param fractional_bits fractional bits; integer knots become `k << fractional_bits` +/// @tparam Raw signed raw word template easy_lut make_relu6_lut(unsigned fractional_bits) { return make_clip_lut(fractional_bits, 0, 6); } +/// \complexity Assembles a constant number of pieces (the knots are a fixed integer pattern shifted by `fractional_bits`). `Θ(1)` time and extra space, aside from the returned vectors of that constant length. +/// @see grotto::easy_lut +/// @see grotto::eval_window +/// @param fractional_bits fractional bits; integer knots become `k << fractional_bits` +/// @tparam Raw signed raw word template easy_lut make_hardtanh_lut(unsigned fractional_bits) @@ -256,6 +294,9 @@ easy_lut make_hardtanh_lut(unsigned fractional_bits) /// @tparam Raw underlying representation /// @param fractional_bits the number of fractional bits /// @return `0` on `[-1, 1]`, `x - 1` above, `x + 1` below +/// \complexity Assembles a constant number of pieces (the knots are a fixed integer pattern shifted by `fractional_bits`). `Θ(1)` time and extra space, aside from the returned vectors of that constant length. +/// @see grotto::easy_lut +/// @see grotto::eval_window template easy_lut make_softshrink_lut(unsigned fractional_bits) { @@ -281,6 +322,9 @@ easy_lut make_softshrink_lut(unsigned fractional_bits) /// @tparam Raw underlying representation /// @param fractional_bits the number of fractional bits /// @return `0` on `[-1, 1]`, identity outside +/// \complexity Assembles a constant number of pieces (the knots are a fixed integer pattern shifted by `fractional_bits`). `Θ(1)` time and extra space, aside from the returned vectors of that constant length. +/// @see grotto::easy_lut +/// @see grotto::eval_window template easy_lut make_hardshrink_lut(unsigned fractional_bits) { @@ -305,6 +349,9 @@ easy_lut make_hardshrink_lut(unsigned fractional_bits) /// @param fractional_bits the number of fractional bits /// @return `0` left of `-3`, `1` right of `3`, `(x + 3) / 6` between, rounded /// @throws std::invalid_argument if `fractional width does not fit` +/// \complexity Assembles a constant number of pieces (the knots are a fixed integer pattern shifted by `fractional_bits`). `Θ(1)` time and extra space, aside from the returned vectors of that constant length. +/// @see grotto::easy_lut +/// @see grotto::eval_window template easy_lut make_hardsigmoid_lut(unsigned fractional_bits) { @@ -335,6 +382,9 @@ easy_lut make_hardsigmoid_lut(unsigned fractional_bits) /// @param fractional_bits the number of fractional bits /// @return `0` left of `-3`, `x` right of `3`, `x(x + 3) / 6` between, rounded /// @throws std::invalid_argument if `fractional width does not fit the denominator` +/// \complexity Assembles a constant number of pieces (the knots are a fixed integer pattern shifted by `fractional_bits`). `Θ(1)` time and extra space, aside from the returned vectors of that constant length. +/// @see grotto::easy_lut +/// @see grotto::eval_window template easy_lut make_hardswish_lut(unsigned fractional_bits) { @@ -360,6 +410,25 @@ easy_lut make_hardswish_lut(unsigned fractional_bits) }); } +/// @brief Appendix D leaky ReLU: identity on the right, `x/100` on the left. +/// @details `make_leaky_relu_lut` is the dyadic slope `1/2^shift`. This one is +/// the paper's slope `1/100`, rounded to nearest, ties away from zero. +/// The fractional scale cancels, so the denominator does not depend +/// on `fractional_bits`. +/// @tparam Raw underlying representation +/// @return two pieces, degree 1 +/// \complexity Assembles two pieces. `Θ(1)` time and extra space, aside from the returned vectors. +/// @see grotto::make_leaky_relu_lut +template +easy_lut make_leaky_relu_hundredth_lut() +{ + return detail::assemble_easy({0}, [](std::int64_t raw) { + if (raw >= 0) + return detail::kIdentity; + return detail::easy_poly{0, 1, 0, 100}; + }); +} + } // namespace grotto #endif // LIBDPF_INCLUDE_GROTTO_EASY_LUT_HPP__ diff --git a/include/grotto/exact_steps.hpp b/include/grotto/exact_steps.hpp new file mode 100644 index 0000000..80f7288 --- /dev/null +++ b/include/grotto/exact_steps.hpp @@ -0,0 +1,407 @@ +/// @file grotto/exact_steps.hpp +/// @brief Exact Grotto steps: digit lengths, integer logs, and word bits. +/// @details Counts and boolean results are fixed-point integers, +/// `n << fractional_bits`. `ilog16(0)`, `ilog256(0)`, and +/// `logstar` of a non-positive input return `ilog_of_zero`. +/// `dec_width`, `oct_width`, and `b64_width` count digits of +/// `floor(|x|)` in bases 10, 8, and 64; zero has length 1. +/// `bit_width`, `bit_floor`, `bit_ceil`, `countl_one`, and +/// `has_single_bit` use the unsigned `Raw` bit pattern, matching +/// the C++ `` operations on that width. +/// `deg2rad` and `rad2deg` are the linear scale by `π/180` and +/// `180/π`. They do not wrap the angle. + +#ifndef LIBDPF_INCLUDE_GROTTO_EXACT_STEPS_HPP__ +#define LIBDPF_INCLUDE_GROTTO_EXACT_STEPS_HPP__ + +#include "grotto/dyadic_lut.hpp" + +#include +#include +#include +#include + +namespace grotto +{ + +namespace exact_detail +{ + +inline int ceil_div(int numerator, int denominator) +{ + if (numerator >= 0) + return (numerator + denominator - 1) / denominator; + return -((-numerator) / denominator); +} + +template +int floor_log2_real(std::int64_t raw, unsigned fractional_bits, bool & exact_power) +{ + const detail::u128 mag = detail::magnitude(raw); + exact_power = mag != 0 && (mag & (mag - 1)) == 0; + return detail::floor_log2_u128(mag) - static_cast(fractional_bits); +} + +inline std::int64_t abs_floor(std::int64_t raw, unsigned fractional_bits) +{ + if (fractional_bits >= 63) + throw std::invalid_argument("exact step: fractional width does not fit"); + const detail::u128 mag = raw < 0 + ? detail::u128(-static_cast<__int128>(raw)) + : detail::u128(raw); + return static_cast(mag >> fractional_bits); +} + +inline int positive_length(std::int64_t magnitude, int base) +{ + if (magnitude <= 0) + return 1; + if (base == 2 || base == 8 || base == 64) + { + int log = 0; + auto n = static_cast(magnitude); + while (n > 1) + { + n >>= 1; + ++log; + } + const int group = base == 2 ? 1 : (base == 8 ? 3 : 6); + return log / group + 1; + } + int digits = 0; + while (magnitude > 0) + { + magnitude /= base; + ++digits; + } + return digits; +} + +} // namespace exact_detail + +/// @brief `ceil(log2(|x|) / 4)`, the integer log base 16. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +template +std::int64_t eval_ilog16(std::int64_t raw, unsigned fractional_bits) +{ + if (raw == 0) + return ilog_of_zero; + bool exact = false; + const int e = exact_detail::floor_log2_real(raw, fractional_bits, exact); + const int units = exact_detail::ceil_div(exact ? e : e + 1, 4); + return detail::encode_units(units, fractional_bits); +} + +/// @brief `ceil(log2(|x|) / 8)`, the integer log base 256. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +template +std::int64_t eval_ilog256(std::int64_t raw, unsigned fractional_bits) +{ + if (raw == 0) + return ilog_of_zero; + bool exact = false; + const int e = exact_detail::floor_log2_real(raw, fractional_bits, exact); + const int units = exact_detail::ceil_div(exact ? e : e + 1, 8); + return detail::encode_units(units, fractional_bits); +} + +/// @brief Iterated logarithm. `log*(x) = 0` for `|x| <= 1`, otherwise +/// `1 + log*(log2(|x|))`. Non-positive inputs return `ilog_of_zero`. +/// \complexity Five comparisons of the magnitude against `2^{fractional_bits + s}` for `s` in `{0,1,2,4,16}`. No iterated loop. `Θ(1)`, extra space `Θ(1)`. +/// Non-positive inputs return `ilog_of_zero` (the dyadic sentinel), not a mathematical log-star. +/// @see grotto::eval_ilog16 +template +std::int64_t eval_logstar(std::int64_t raw, unsigned fractional_bits) +{ + if (raw <= 0) + return ilog_of_zero; + if (fractional_bits >= 63) + throw std::invalid_argument("exact step: fractional width does not fit"); + const detail::u128 mag = detail::magnitude(raw); + const auto below = [&](unsigned shift) { + if (fractional_bits + shift >= 128) + return true; + return mag <= (detail::u128{1} << (fractional_bits + shift)); + }; + int units = 5; + if (below(0)) + units = 0; + else if (below(1)) + units = 1; + else if (below(2)) + units = 2; + else if (below(4)) + units = 3; + else if (below(16)) + units = 4; + return detail::encode_units(units, fractional_bits); +} + +/// @brief `std::bit_width` of the unsigned `Raw` pattern. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +template +std::int64_t eval_bit_width(std::int64_t raw, unsigned fractional_bits) +{ + const auto bits = detail::raw_bits(raw); + int units = 0; + if (bits != 0) + units = 64 - __builtin_clzll(bits); + return detail::encode_units(units, fractional_bits); +} + +/// @brief `std::countl_one` of the unsigned `Raw` pattern. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +template +std::int64_t eval_countl_one(std::int64_t raw, unsigned fractional_bits) +{ + const int units = detail::countl_one_width( + detail::raw_bits(raw), detail::raw_width()); + return detail::encode_units(units, fractional_bits); +} + +/// @brief `std::has_single_bit` of the unsigned `Raw` pattern. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +template +std::int64_t eval_has_single_bit(std::int64_t raw, unsigned fractional_bits) +{ + const auto bits = detail::raw_bits(raw); + const bool on = bits != 0 && (bits & (bits - 1)) == 0; + return detail::encode_units(on ? 1 : 0, fractional_bits); +} + +/// @brief `std::bit_floor` of the unsigned `Raw` pattern, as a raw word. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +template +std::int64_t eval_bit_floor(std::int64_t raw) +{ + const auto bits = detail::raw_bits(raw); + if (bits == 0) + return 0; + const int log = 63 - __builtin_clzll(bits); + return static_cast(std::uint64_t{1} << static_cast(log)); +} + +/// @brief `std::bit_ceil` of the unsigned `Raw` pattern, as a raw word. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +template +std::int64_t eval_bit_ceil(std::int64_t raw) +{ + const auto bits = detail::raw_bits(raw); + if (bits <= 1) + return 1; + if ((bits & (bits - 1)) == 0) + return static_cast(bits); + const int log = 64 - __builtin_clzll(bits); + if (log >= 63) + throw std::overflow_error("exact step: bit_ceil does not fit int64"); + return std::int64_t{1} << log; +} + +/// @brief `floor(x)` at the same fractional scale. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +inline std::int64_t eval_dec_floor(std::int64_t raw, unsigned fractional_bits) +{ + if (fractional_bits >= 63) + throw std::invalid_argument("exact step: fractional width does not fit"); + const std::int64_t one = std::int64_t{1} << fractional_bits; + std::int64_t q = raw / one; + const std::int64_t r = raw - q * one; + if (r < 0) + --q; + return q << fractional_bits; +} + +/// @brief `ceil(x)` at the same fractional scale. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +inline std::int64_t eval_dec_ceil(std::int64_t raw, unsigned fractional_bits) +{ + if (fractional_bits >= 63) + throw std::invalid_argument("exact step: fractional width does not fit"); + const std::int64_t one = std::int64_t{1} << fractional_bits; + std::int64_t q = raw / one; + const std::int64_t r = raw - q * one; + if (r > 0) + ++q; + return q << fractional_bits; +} + +/// @brief Digits of `floor(|x|)` in base 10, 8, or 64. Zero has length 1. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +inline std::int64_t eval_value_length(std::int64_t raw, unsigned fractional_bits, int base) +{ + if (base != 8 && base != 10 && base != 64) + throw std::invalid_argument("exact step: length base must be 8, 10, or 64"); + const int units = exact_detail::positive_length( + exact_detail::abs_floor(raw, fractional_bits), base); + return detail::encode_units(units, fractional_bits); +} +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 + +inline std::int64_t eval_dec_width(std::int64_t raw, unsigned fractional_bits) +{ + return eval_value_length(raw, fractional_bits, 10); +} +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 + +inline std::int64_t eval_oct_width(std::int64_t raw, unsigned fractional_bits) +{ + return eval_value_length(raw, fractional_bits, 8); +} +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 + +inline std::int64_t eval_b64_width(std::int64_t raw, unsigned fractional_bits) +{ + return eval_value_length(raw, fractional_bits, 64); +} + +/// @brief True when `floor(|x|)` is a single decimal digit, including 0. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +inline std::int64_t eval_has_single_digit(std::int64_t raw, unsigned fractional_bits) +{ + const std::int64_t mag = exact_detail::abs_floor(raw, fractional_bits); + return detail::encode_units(mag <= 9 ? 1 : 0, fractional_bits); +} + +namespace exact_detail +{ + +inline constexpr detail::u128 pi_over_180_64 = 321956420358983237ULL; +inline constexpr detail::u128 rad_to_deg_64 = (detail::u128{57} << 64) | 5456168980075999427ULL; + +inline std::int64_t scale_angle(detail::u128 mag64, unsigned fractional_bits) +{ + if (fractional_bits > 64) + throw std::invalid_argument("exact step: fractional width does not fit"); + const unsigned shift = 64u - fractional_bits; + detail::u128 mag = mag64; + if (shift > 0) + { + mag += detail::u128{1} << (shift - 1); + mag >>= shift; + } + if (mag > static_cast(INT64_MAX)) + throw std::overflow_error("exact step: angle scale does not fit"); + return static_cast(mag); +} + +inline std::int64_t mul_angle(std::int64_t raw, std::int64_t factor, unsigned fractional_bits) +{ + const __int128 prod = static_cast<__int128>(raw) * factor; + const bool neg = prod < 0; + auto mag = static_cast(neg ? -prod : prod); + if (fractional_bits > 0) + { + mag += detail::u128{1} << (fractional_bits - 1); + mag >>= fractional_bits; + } + if (mag > static_cast(INT64_MAX)) + throw std::overflow_error("exact step: angle does not fit int64"); + const auto out = static_cast(mag); + return neg ? -out : out; +} + +} // namespace exact_detail + +/// @brief Degrees to radians, `x * π / 180`. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +inline std::int64_t eval_deg2rad(std::int64_t raw, unsigned fractional_bits) +{ + return exact_detail::mul_angle( + raw, exact_detail::scale_angle(exact_detail::pi_over_180_64, fractional_bits), + fractional_bits); +} + +/// @brief Radians to degrees, `x * 180 / π`. +/// \complexity A constant number of shifts and a `countl` / `bit_width` style scan of the `Raw` width (at most 64 iterations of `n >>= 1` in `positive_length` / `floor_log2_real`). `Θ(width)` bit operations, extra space `Θ(1)`. +/// Counts are returned as `units << fractional_bits`. +/// @see grotto::make_exact_constant_lut +/// @see grotto::eval_ilog16 +inline std::int64_t eval_rad2deg(std::int64_t raw, unsigned fractional_bits) +{ + return exact_detail::mul_angle( + raw, exact_detail::scale_angle(exact_detail::rad_to_deg_64, fractional_bits), + fractional_bits); +} + +/// @brief Piecewise-constant LUT of a step whose value is an encoded integer. +/// @details The domain scan is the cut set. `Raw` wider than 16 bits is refused. +/// \complexity Scans every raw value from `numeric_limits::min()` to `max()`. The header rejects `width > 16`, so the scan is `Θ(2^w)` with `w ≤ 16`. +/// The result stores one cut per change of `at`. Extra space is that cut vector. +/// @see grotto::eval_dec_floor +/// @see grotto::easy_lut +template +easy_lut make_exact_step_lut(unsigned fractional_bits, At && at) +{ + (void)fractional_bits; + constexpr int width = detail::raw_width(); + if (width > 16) + throw std::invalid_argument("exact step lut: raw width must be at most 16"); + using lim = std::numeric_limits; + const auto minv = static_cast(lim::min()); + const auto maxv = static_cast(lim::max()); + std::vector cuts; + auto previous = at(minv); + for (std::int64_t raw = minv + 1; raw <= maxv; ++raw) + { + const auto value = at(raw); + if (value != previous) + { + cuts.push_back(raw); + previous = value; + } + if (raw == maxv) + break; + } + return detail::steps_from_cuts(std::move(cuts), [=](std::int64_t raw) { + return detail::easy_poly{at(raw), 0, 0, 1}; + }); +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_EXACT_STEPS_HPP__ diff --git a/include/grotto/fixedpoint.hpp b/include/grotto/fixedpoint.hpp index 56855a9..6dd51d9 100644 --- a/include/grotto/fixedpoint.hpp +++ b/include/grotto/fixedpoint.hpp @@ -39,7 +39,7 @@ namespace detail /// @brief Integer value of an already-rounded finite double, as a 256-bit word. /// Values that do not fit saturate to all-ones. -/// @param rounded the `rounded` +/// @param rounded already-rounded finite double /// @return Integer value of an already-rounded finite double, as a 256-bit word HEDLEY_NO_THROW inline uint256_t uint256_from_rounded_double(double rounded) noexcept @@ -102,7 +102,7 @@ struct is_static_castable HEDLEY_NO_THROW @@ -212,7 +212,7 @@ inline IntegralType rounded_double_to_integral(double rounded) noexcept /// @tparam IntegralType underlying integral type /// @tparam FractionalBits number of fractional bits /// @tparam T value type -/// @param integer_value the `integer_value` +/// @param integer_value mathematical integer; stored as `integer_value << FractionalBits` /// @return the returned `IntegralType` template HEDLEY_ALWAYS_INLINE @@ -269,8 +269,8 @@ constexpr IntegralType raw_abs(IntegralType x) noexcept /// @brief Remainder with the sign of `a` and magnitude `< |b|` (C++ `%` / /// `std::fmod`). Zero divisor → 0; this type has no NaN. /// @tparam IntegralType underlying integral type -/// @param a the `a` -/// @param b the `b` +/// @param a left-hand operand +/// @param b right-hand operand /// @return Remainder with the sign of `a` and magnitude `< |b|` (C++ `%` / `std::fmod`) template HEDLEY_ALWAYS_INLINE @@ -292,10 +292,20 @@ template ` is a Q48.16 value. +/// @note `fixedpoint(3)` is the mathematical value 3, stored as +/// `3 << FractionalBits`. It is not a raw word. `from_raw` is bit-exact. +/// @note Leaf addition, subtraction, and multiplication act on that raw word +/// and do not shift the binary point. See `dpf::leaf_arithmetic`. +/// @note A signed backend flips the MSB when the value is a DPF input +/// (`dpf::utils::flip_msb_for_input`). +/// @see grotto::fixed_mul +/// @see [Input types](@ref input_types) +/// @see [Output types](@ref output_types) template struct fixedpoint @@ -341,7 +351,7 @@ public: /// @brief Value c'tor /// @details Initializes the fixed-point with the value determined by `desired`, using the current rounding mode for the least-significant bit. - /// @param desired the `desired` + /// @param desired real value, rounded with the current rounding mode HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW constexpr fixedpoint(double desired) noexcept // NOLINT (implicit c'tor) @@ -355,7 +365,7 @@ public: /// Use `from_raw` for a bit-exact encoding. /// @tparam T value type /// @tparam T value type - /// @param integer_value the `integer_value` + /// @param integer_value mathematical integer; stored as `integer_value << FractionalBits` template @@ -370,6 +380,9 @@ public: /// @brief Bit-exact construction from the backend integer encoding. /// @param raw the underlying integer /// @return Bit-exact construction from the backend integer encoding + /// \complexity `Θ(1)`. Copies the backend word. No shift and no rounding. + /// @note Bit-exact. Unlike `fixedpoint(3)`, this does not mean the mathematical value `raw`. + /// @see grotto::fixedpoint HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW static constexpr fixedpoint from_raw(integral_type raw) noexcept @@ -401,7 +414,7 @@ public: /// @brief Value assignment /// @details Assigns the fixed-point with a value determined by `desired`, using the current rounding mode for the least-significant bit.. - /// @param desired the `desired` + /// @param desired real value, rounded with the current rounding mode /// @return `*this` HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -557,6 +570,9 @@ public: /// @details Computes the sum of two fixed-point numbers /// @param rhs the right-hand operand /// @return Binary addition operator + /// \complexity One backend-word operation. `Θ(1)` time and extra space in that word width. + /// @note Same-scale addition and subtraction add the raw words. That is the fixed-point sum; the binary point does not move. + /// @see grotto::fixed_mul HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -579,6 +595,9 @@ public: /// @brief Binary subtraction operator /// @param rhs the right-hand operand /// @return Binary subtraction operator + /// \complexity One backend-word operation. `Θ(1)` time and extra space in that word width. + /// @note Same-scale addition and subtraction add the raw words. That is the fixed-point sum; the binary point does not move. + /// @see grotto::fixed_mul HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW HEDLEY_PURE @@ -602,6 +621,11 @@ public: /// @tparam FractionalBits1 fractional bits1 /// @param rhs the right-hand operand /// @return Binary multiplication operator + /// \complexity One product of the raw backend words. The result is `make_fixed_from_integral_type` at `FractionalBits + FractionalBits1` fractional bits. + /// `Θ(1)` in the backend width (the 64-bit or 128-bit branch in `multiplies` is the rescaling multiply; this operator does not loop). + /// @note This is not leaf multiply. Leaf multiply stays on the raw word and does not change `FractionalBits`. + /// @see grotto::fixed_mul + /// @see grotto::fixedpoint template HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -751,7 +775,7 @@ public: // struct make_fixed_from_integral_type_tag {}; /// @brief Determine if a floating-point is within range - /// @param d the `d` + /// @param d real value /// @return Determine if a floating-point is within range HEDLEY_ALWAYS_INLINE HEDLEY_NO_THROW @@ -790,7 +814,7 @@ public: /// @tparam IntegralType underlying integral type /// @tparam Mask mask /// @param mask the bit mask -/// @param x the `x` +/// @param x the input value /// @return Bit test with the mask on the left template >(std::basic_istream & is, return is; } +/// @brief Bit-exact fixed-point from a backend word. +/// @tparam FractionalBits number of fractional bits +/// @tparam IntegralType backend word type +/// @param value the raw encoding, not the mathematical integer +/// @return `fixedpoint::from_raw(value)` +/// @note This does not shift by `FractionalBits`. `make_fixed_from_integral_type(1)` is the raw word 1, whereas `fixedpoint(1)` is the value 1. +/// @see grotto::fixedpoint::from_raw +/// \complexity `Θ(1)`. One `from_raw`. template HEDLEY_NO_THROW @@ -836,6 +868,9 @@ auto constexpr make_fixed_from_integral_type(IntegralType value) noexcept { return fixedpoint::from_raw(value); } +/// \complexity One scale by `2^{FractionalBits}` (`ldexp`) and `nearbyint` under the current rounding mode. `Θ(1)`. +/// @note This is the real value, same as `fixedpoint(double)`. It is not `from_raw`. +/// @see grotto::fixedpoint template @@ -845,6 +880,9 @@ static constexpr auto make_fixed(double d) { return fixedpoint(d); } +/// \complexity One scale by `2^{FractionalBits}` (`ldexp`) and `nearbyint` under the current rounding mode. `Θ(1)`. +/// @note This is the real value, same as `fixedpoint(double)`. It is not `from_raw`. +/// @see grotto::fixedpoint template HEDLEY_ALWAYS_INLINE @@ -857,10 +895,12 @@ static constexpr auto make_fixed(double d) /// @brief Creates a fixed-point number from a double with bounds checking. /// @tparam FractionalBits number of fractional bits /// @tparam IntegralType underlying integral type -/// @param d the `d` +/// @param d real value /// @return Creates a fixed-point number from a double with bounds checking /// @throws std::range_error if the input double is outside the representable /// range of the fixed-point number. +/// \complexity Two comparisons against `numeric_limits`, then one `make_fixed`. `Θ(1)`. +/// @see grotto::make_fixed template HEDLEY_ALWAYS_INLINE @@ -881,6 +921,8 @@ static auto make_fixed_safe(double d) return make_fixed(d); } +/// \complexity One left or right shift of the raw word by the difference of the fractional widths. No rounding step. `Θ(1)`. +/// @see grotto::fixedpoint template ) noe { return FractionalBits; } +/// \complexity Adds one to the raw word (one ULP). `Θ(1)`. +/// @see grotto::fixedpoint template @@ -916,6 +960,8 @@ constexpr auto nextafter(fixedpoint f) noexcept { return make_fixed_from_integral_type(f.integral_representation()+1); } +/// \complexity Subtracts one from the raw word (one ULP). `Θ(1)`. +/// @see grotto::fixedpoint template @@ -926,6 +972,8 @@ constexpr auto nextbefore(fixedpoint f) noexcept { return make_fixed_from_integral_type(f.integral_representation()-1); } +/// \complexity Two's-complement absolute value of the raw word via `raw_neg` when the backend is signed. `Θ(1)`. +/// @see grotto::fixedpoint template @@ -946,6 +994,8 @@ constexpr auto fabs(fixedpoint v) noexcept } return v; } +/// \complexity `raw_fmod` on the backend words: remainder with the sign of the dividend. `Θ(1)` word operations. A zero modulus returns 0. +/// @see grotto::fixedpoint template @@ -959,6 +1009,8 @@ constexpr auto fmod(fixedpoint v, detail::raw_fmod(v.integral_representation(), modulus.integral_representation())); } +/// \complexity `raw_fmod` on the backend words: remainder with the sign of the dividend. `Θ(1)` word operations. A zero modulus returns 0. +/// @see grotto::fixedpoint template @@ -970,6 +1022,8 @@ constexpr auto fmod(fixedpoint v, { return fmod(v, make_fixed(modulus)); } +/// \complexity `raw_fmod` on the backend words: remainder with the sign of the dividend. `Θ(1)` word operations. A zero modulus returns 0. +/// @see grotto::fixedpoint template struct binary_operator_precast_wrapper @@ -1042,6 +1102,12 @@ struct binary_operator_precast_wrapper } }; +/// @brief Fixed-point product that chooses how many fractional bits to keep. +/// @tparam Mode which operand's fractional width the product uses; `use_arg_sum` keeps both +/// @see grotto::fixed_mul +/// @see grotto::fixedpoint +/// @note The raw product is shifted so the binary point matches `Mode`. That is a rescale. Leaf multiply does not do this. +/// \complexity One backend multiply (64-bit or 128-bit branch) and one shift. `Θ(1)` time and extra space. template struct multiplies { @@ -1123,6 +1189,12 @@ struct multiplies } }; +/// @name Comparisons with double on the left +/// @brief `double` compared with `fixedpoint` by reversing the member operator. +/// \complexity One call to the matching member comparison. `Θ(1)`. +/// @see grotto::fixedpoint +/// @{ + template HEDLEY_ALWAYS_INLINE @@ -1173,6 +1245,13 @@ constexpr bool operator>=(double lhs, fixedpoint r return (rhs <= lhs); } +/// @} + +/// @brief Horner polynomial in `fixedpoint` coefficients, constant term at index 0. +/// @tparam FixedPointType coefficient type +/// @tparam Degree number of coefficients (degree is one less when `Degree > 0`) +/// @see grotto::multiplies +/// \complexity `operator()` walks the coefficients once: `Θ(Degree)` fixed-point multiplies and adds. Extra space `Θ(1)`. template struct fixedpoint_polynomial : public std::array @@ -1203,6 +1282,20 @@ static constexpr auto evaluate(const fixedpoint_polynomial` holding the value 1.5, via +/// `make_fixed<16>`. It is not a raw word. The DPF depth of the +/// result is the backend width (64 bits for the default), not `N`. +/// @param val the `long double` literal +/// @return `fixedpoint` for the suffix `_fixedN` +/// @see grotto::make_fixed +/// @see grotto::fixedpoint +/// \complexity Each literal is one call to `make_fixed` (scale by +/// `2^N` and round). `Θ(1)` time and extra space. No protocol. +/// @{ + constexpr auto operator "" _fixed0(long double val) { return grotto::make_fixed<0>(val); @@ -1497,6 +1590,8 @@ constexpr auto operator "" _fixed64(long double val) return grotto::make_fixed<64>(val); } +/// @} + } // namespace grotto::fixedpoint_literals } // namespace grotto @@ -1597,6 +1692,9 @@ struct make_from_integral_value static_cast(val)); } }; +/// \complexity One XOR of `msb_of_v` into the raw word when `uses_signed_msb_v` is true. `Θ(1)`. +/// @note Signed backends flip that MSB on the way into a DPF input. Unsigned backends do not. +/// @see grotto::fixedpoint template @@ -1623,6 +1721,11 @@ struct flip_msb_for_input> namespace dpf::leaf_arithmetic { +/// \complexity One SIMD 128-bit add of the raw backend words (`integral_representation()` for multiply). +/// `Θ(1)` time and extra space. +/// @note Does not shift by `FractionalBits`. The binary point of the leaf word stays where it was. +/// @see grotto::fixedpoint +/// @see grotto::fixed_mul HEDLEY_PRAGMA(GCC diagnostic push) HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") @@ -1634,6 +1737,11 @@ struct add_t, simde__m128i> return add_t{}(a, b); } }; +/// \complexity One SIMD 256-bit add of the raw backend words (`integral_representation()` for multiply). +/// `Θ(1)` time and extra space. +/// @note Does not shift by `FractionalBits`. The binary point of the leaf word stays where it was. +/// @see grotto::fixedpoint +/// @see grotto::fixed_mul template struct add_t, simde__m256i> @@ -1643,6 +1751,11 @@ struct add_t, simde__m256i> return add_t{}(a, b); } }; +/// \complexity One SIMD 128-bit subtract of the raw backend words (`integral_representation()` for multiply). +/// `Θ(1)` time and extra space. +/// @note Does not shift by `FractionalBits`. The binary point of the leaf word stays where it was. +/// @see grotto::fixedpoint +/// @see grotto::fixed_mul template struct subtract_t, simde__m128i> @@ -1652,6 +1765,11 @@ struct subtract_t, simde__m128i return subtract_t{}(a, b); } }; +/// \complexity One SIMD 256-bit subtract of the raw backend words (`integral_representation()` for multiply). +/// `Θ(1)` time and extra space. +/// @note Does not shift by `FractionalBits`. The binary point of the leaf word stays where it was. +/// @see grotto::fixedpoint +/// @see grotto::fixed_mul template struct subtract_t, simde__m256i> @@ -1661,6 +1779,11 @@ struct subtract_t, simde__m256i return subtract_t{}(a, b); } }; +/// \complexity One SIMD 128-bit multiply of the raw backend words (`integral_representation()` for multiply). +/// `Θ(1)` time and extra space. +/// @note Does not shift by `FractionalBits`. The binary point of the leaf word stays where it was. +/// @see grotto::fixedpoint +/// @see grotto::fixed_mul template struct multiply_t, simde__m128i> @@ -1671,6 +1794,11 @@ struct multiply_t, simde__m128i return multiply_t{}(a, b.integral_representation()); } }; +/// \complexity One SIMD 256-bit multiply of the raw backend words (`integral_representation()` for multiply). +/// `Θ(1)` time and extra space. +/// @note Does not shift by `FractionalBits`. The binary point of the leaf word stays where it was. +/// @see grotto::fixedpoint +/// @see grotto::fixed_mul template struct multiply_t, simde__m256i> diff --git a/include/grotto/fixedpoint_beaver.hpp b/include/grotto/fixedpoint_beaver.hpp new file mode 100644 index 0000000..81a50a6 --- /dev/null +++ b/include/grotto/fixedpoint_beaver.hpp @@ -0,0 +1,617 @@ +/// @file grotto/fixedpoint_beaver.hpp +/// @brief Additive-share evaluation of `fixed_mul`. +/// @details One Beaver triple in `Z/2^{multiply_bits}Z` is the product. Every +/// other step is linear, or a masked comparison that lifts a narrower +/// share or drops low bits: +/// +/// - bits above `multiply_bits` are discarded locally; +/// - a narrower operand (and a product narrower than `modulus_bits`) +/// is lifted by `eta + r - w·2^{src}`, with `w` the carry of the +/// secret mask, and a signed lift then replicates the sign; +/// - `align_shift > 0` is a truncate-and-reduce of that modulus; +/// - `align_shift < 0` is a local left shift. +/// +/// The opened window matches `fixed_mul`, including the final sign +/// extension into the storage word. Each lift extends by at most 64 +/// bits and starts from at most 64 bits, so the carry bit stays a +/// `uint64_t` comparison and scaling it is homomorphic in the +/// destination ring. A right shift discards at most 64 bits. The +/// modulus and the multiply ring are at most 128 bits. +/// +/// `prep` is a dealer record (both key halves, both mask shares), +/// same as `carry_key_pair`. It is independent of the data and is +/// reused. `sample_fixed_mul_beaver_triple` is one product and is +/// fresh each time. `eval_fixed_mul_beaver` is one party: `exchange` +/// sends one `uint64_t` and returns the peer's word, in the same +/// order on both sides. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_GROTTO_FIXEDPOINT_BEAVER_HPP__ +#define LIBDPF_INCLUDE_GROTTO_FIXEDPOINT_BEAVER_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dpf.hpp" +#include "grotto/fixedpoint_mul.hpp" + +namespace grotto +{ + +namespace fixed_mul_beaver_detail +{ + +using u128 = simde_uint128; + +HEDLEY_NO_THROW +constexpr u128 bit_mask(unsigned bits) noexcept +{ + if (bits == 0u) + return 0; + if (bits >= 128u) + return ~u128{0}; + return (u128{1} << bits) - 1; +} + +HEDLEY_NO_THROW +constexpr unsigned u64_limbs(unsigned bits) noexcept +{ + return bits > 64u ? 2u : 1u; +} + +HEDLEY_WARN_UNUSED_RESULT +inline u128 draw_mod(unsigned bits) +{ + if (bits == 0u) + return 0; + if (bits <= 64u) + { + const std::uint64_t m = static_cast(bit_mask(bits)); + return dpf::uniform_sample() & m; + } + return dpf::uniform_sample() & bit_mask(bits); +} + +/// @brief Low 128 bits of `(uint64)m * factor`, then reduced mod `2^dest`. +HEDLEY_NO_THROW +inline u128 mul_u64(std::uint64_t m, u128 factor, unsigned dest) noexcept +{ + const std::uint64_t f0 = static_cast(factor); + const std::uint64_t f1 = static_cast(factor >> 64); + const u128 p0 = u128{m} * f0; + const u128 p1 = u128{m} * f1; + return (p0 + (p1 << 64)) & bit_mask(dest); +} + +HEDLEY_NO_THROW +inline u128 mul_mod(u128 a, u128 b, unsigned bits) noexcept +{ + a &= bit_mask(bits); + b &= bit_mask(bits); + if (bits <= 64u) + { + return (u128{static_cast(a)} + * static_cast(b)) & bit_mask(bits); + } + const std::uint64_t a0 = static_cast(a); + const std::uint64_t a1 = static_cast(a >> 64); + const std::uint64_t b0 = static_cast(b); + const std::uint64_t b1 = static_cast(b >> 64); + const u128 p00 = u128{a0} * b0; + const u128 mid = (p00 >> 64) + + static_cast(u128{a0} * b1) + + static_cast(u128{a1} * b0); + return ((u128)static_cast(p00) | (mid << 64)) & bit_mask(bits); +} + +HEDLEY_NO_THROW +inline u128 add_mod(u128 a, u128 b, unsigned bits) noexcept +{ + return (a + b) & bit_mask(bits); +} + +HEDLEY_NO_THROW +inline u128 sub_mod(u128 a, u128 b, unsigned bits) noexcept +{ + return (a - b) & bit_mask(bits); +} + +template +HEDLEY_NO_THROW +u128 share_bits(const T & value) noexcept +{ + std::uint64_t raw[4] = {}; + detail::store_raw_limbs(value, raw); + return u128{raw[0]} | (u128{raw[1]} << 64); +} + +using cmp_pair = decltype(dpf::make_dpf(std::uint64_t{0}, + dpf::lt(std::uint64_t{1}))); + +struct bit_key +{ + cmp_pair keys; +}; + +HEDLEY_WARN_UNUSED_RESULT +inline bit_key make_bit_key(std::uint64_t alpha) +{ + return bit_key{dpf::make_dpf(alpha, dpf::lt(std::uint64_t{1}))}; +} + +HEDLEY_WARN_UNUSED_RESULT +inline std::uint64_t eval_bit(const bit_key & key, std::size_t party, + std::uint64_t query) +{ + if (party == 0u) + return dpf::eval_point(dpf::cmp, key.keys.first, query).raw(); + return dpf::eval_point(dpf::cmp, key.keys.second, query).raw(); +} + +/// @brief Public sum of the two parties' words, mod `2^bits`. +template +HEDLEY_WARN_UNUSED_RESULT +u128 open_sum(u128 mine, unsigned bits, Exchange & exchange) +{ + const std::uint64_t low = exchange(static_cast(mine)); + u128 peer = low; + if (bits > 64u) + { + const std::uint64_t hi = exchange(static_cast(mine >> 64)); + peer |= u128{hi} << 64; + } + return (mine + peer) & bit_mask(bits); +} + +struct lift_keys +{ + bool live = false; + bool sign = false; + unsigned src = 0; + unsigned dest = 0; + /// @brief Secret mask mod `2^src`. Shares sum to `r` in `Z/2^128`. + u128 r = 0; + u128 r_share[2]{}; + /// @brief `lt` at `r`. Eval at `T-1` is a share of `1{r >= T}`. + std::optional wrap{}; +}; + +HEDLEY_WARN_UNUSED_RESULT +inline lift_keys make_lift(unsigned src, unsigned dest, bool sign) +{ + lift_keys k; + k.live = true; + k.sign = sign; + k.src = src; + k.dest = dest; + k.r = draw_mod(src); + k.r_share[0] = dpf::uniform_sample(); + k.r_share[1] = k.r - k.r_share[0]; + k.wrap = make_bit_key(static_cast(k.r)); + return k; +} + +struct shift_keys +{ + bool live = false; + unsigned n = 0; + unsigned s = 0; + u128 rin = 0; + u128 rin_share[2]{}; + u128 rout_share[2]{}; + std::optional low{}; +}; + +HEDLEY_WARN_UNUSED_RESULT +inline shift_keys make_shift(unsigned n, unsigned s) +{ + shift_keys k; + k.live = true; + k.n = n; + k.s = s; + k.rin = draw_mod(n); + k.rin_share[0] = draw_mod(n); + k.rin_share[1] = (k.rin - k.rin_share[0]) & bit_mask(n); + const u128 neg = (u128{0} - k.rin) & bit_mask(n); + const std::uint64_t alpha = static_cast(neg & bit_mask(s)); + k.low = make_bit_key(alpha); + const unsigned out = n - s; + const u128 y_hi = neg >> s; + k.rout_share[0] = draw_mod(out); + k.rout_share[1] = (y_hi - k.rout_share[0]) & bit_mask(out); + return k; +} + +/// @brief Share of `1{r >= T}` for `r` in `[0, 2^src)`. `T == 0` is the public 1. +HEDLEY_WARN_UNUSED_RESULT +inline std::uint64_t ge_mask(const lift_keys & keys, std::size_t party, + u128 threshold) +{ + if (threshold == 0) + return party == 1u ? std::uint64_t{1} : 0u; + if (threshold > bit_mask(keys.src)) + return 0u; + return eval_bit(*keys.wrap, party, + static_cast(threshold) - 1u); +} + +template +HEDLEY_WARN_UNUSED_RESULT +u128 apply_lift(u128 share, const lift_keys & keys, std::size_t party, + Exchange & exchange) +{ + const std::uint64_t src_mask = static_cast(bit_mask(keys.src)); + const std::uint64_t xs = static_cast(share) & src_mask; + const std::uint64_t rs = static_cast(keys.r_share[party]) & src_mask; + const std::uint64_t delta = (xs - rs) & src_mask; + const std::uint64_t peer = exchange(delta); + const std::uint64_t eta = (delta + peer) & src_mask; + // `1{r >= 2^src - eta}` is the carry `r + eta >= 2^src`. + const u128 mod = u128{1} << keys.src; + const std::uint64_t w = ge_mask(keys, party, mod - eta); + u128 y = keys.r_share[party]; + y -= mul_u64(w, mod, keys.dest); + if (party == 0u) + y += eta; + if (keys.sign) + { + const u128 half = u128{1} << (keys.src - 1u); + std::uint64_t msb = 0; + if (u128{eta} < half) + msb = ge_mask(keys, party, half - eta) - w; + else + msb = (party == 1u ? std::uint64_t{1} : 0u) - w + + ge_mask(keys, party, mod + half - eta); + const u128 high = bit_mask(keys.dest) & ~bit_mask(keys.src); + y += mul_u64(msb, high, keys.dest); + } + return y; +} + +template +HEDLEY_WARN_UNUSED_RESULT +u128 apply_shift(u128 share, const shift_keys & keys, std::size_t party, + Exchange & exchange) +{ + const u128 opened = open_sum(share + keys.rin_share[party], keys.n, exchange); + const u128 xs = opened & bit_mask(keys.s); + const u128 query128 = (u128{1} << keys.s) - xs - 1; + const std::uint64_t t = eval_bit(*keys.low, party, + static_cast(query128)); + // `t` sums to the carry in `Z/2^64`. The output modulus is at most 64 + // bits for every window this header accepts, so that extra multiple of + // `2^64` lands outside the modulus. + u128 acc = keys.rout_share[party] + t; + if (party == 1u) + acc += opened >> keys.s; + return acc; +} + +} // namespace fixed_mul_beaver_detail + +/// @brief Which steps of one `fixed_mul` window are interactive. +/// @tparam IntegerBits integer bits kept in the product, including the sign +/// @tparam FractionalBits fraction bits kept in the product +/// @tparam LhsFractionalBits fractional bits of the left operand +/// @tparam LhsIntegral integral type of the left operand +/// @tparam RhsFractionalBits fractional bits of the right operand +/// @tparam RhsIntegral integral type of the right operand +template +struct fixed_mul_beaver_shape +{ + using plan = fixed_mul_plan; + using result_integral = typename plan::integral_type; + + static constexpr unsigned storage_bits = + static_cast(dpf::utils::bitlength_of_v); + static constexpr bool active = plan::modulus_bits > 0u + && plan::multiply_bits > 0u; + static constexpr bool lhs_lift = active + && plan::multiply_bits > plan::lhs_width; + static constexpr bool rhs_lift = active + && plan::multiply_bits > plan::rhs_width; + static constexpr bool product_lift = active + && plan::modulus_bits > plan::multiply_bits; + static constexpr bool shift_right = active && plan::align_shift > 0; + static constexpr bool shift_left = active && plan::align_shift < 0; + static constexpr bool result_lift = active + && storage_bits > plan::out_bits; + + static constexpr bool lift_ok(bool lift, unsigned src, unsigned dest) noexcept + { + if (!lift) + return true; + return src >= 1u && src <= 64u && dest > src && dest <= 128u + && (dest - src) <= 64u; + } + + static constexpr bool fits = !active + || (plan::multiply_bits <= 128u + && plan::modulus_bits <= 128u + && storage_bits <= 128u + && lift_ok(lhs_lift, plan::lhs_width, plan::multiply_bits) + && lift_ok(rhs_lift, plan::rhs_width, plan::multiply_bits) + && lift_ok(product_lift, plan::multiply_bits, plan::modulus_bits) + && lift_ok(result_lift, plan::out_bits, storage_bits) + && (!shift_right || (static_cast(plan::align_shift) <= 64u + && plan::out_bits <= 64u + && plan::modulus_bits <= 128u + && plan::modulus_bits > static_cast(plan::align_shift)))); + + /// @brief `uint64_t` words exchanged by one product. Zero when the window is empty. + static constexpr unsigned messages = !active ? 0u + : (lhs_lift ? 1u : 0u) + + (rhs_lift ? 1u : 0u) + + 2u * fixed_mul_beaver_detail::u64_limbs(plan::multiply_bits) + + (product_lift ? 1u : 0u) + + (shift_right + ? fixed_mul_beaver_detail::u64_limbs(plan::modulus_bits) + : 0u) + + (result_lift ? 1u : 0u); +}; + +/// @brief One Beaver triple in `Z/2^{multiply_bits}Z`. +struct fixed_mul_beaver_triple +{ + unsigned multiply_bits = 0; + fixed_mul_beaver_detail::u128 a[2]{}; + fixed_mul_beaver_detail::u128 b[2]{}; + fixed_mul_beaver_detail::u128 ab[2]{}; +}; + +/// @brief Dealer masks and comparison keys for one window. Reused across products. +template +struct fixed_mul_beaver_prep +{ + using shape = fixed_mul_beaver_shape; + + fixed_mul_beaver_detail::lift_keys lhs{}; + fixed_mul_beaver_detail::lift_keys rhs{}; + fixed_mul_beaver_detail::lift_keys product{}; + fixed_mul_beaver_detail::shift_keys shift{}; + fixed_mul_beaver_detail::lift_keys result{}; +}; + +/// @brief Pack a `mod2k` beaver pair into the fixed-point triple. +inline fixed_mul_beaver_triple pack_mod2k_beaver( + unsigned multiply_bits, const dpf::beavers::beaver2 & triple) +{ + fixed_mul_beaver_triple t; + t.multiply_bits = multiply_bits; + t.a[0] = triple.a.p0.raw; + t.a[1] = triple.a.p1.raw; + t.b[0] = triple.b.p0.raw; + t.b[1] = triple.b.p1.raw; + t.ab[0] = triple.ab.p0.raw; + t.ab[1] = triple.ab.p1.raw; + return t; +} + +/// @brief Sample one product triple from `sample_beaver2` in `Z/2^w Z`. +/// @param multiply_bits ring width, `0` or `1 .. 128` +HEDLEY_WARN_UNUSED_RESULT +inline fixed_mul_beaver_triple sample_fixed_mul_beaver_triple(unsigned multiply_bits) +{ + if (multiply_bits == 0u) + return {}; + if (multiply_bits > 128u) + throw std::invalid_argument("fixed_mul beaver triple exceeds 128 bits"); + dpf::beavers::mod2k_width_scope width(multiply_bits); + return pack_mod2k_beaver(multiply_bits, + dpf::beavers::sample_beaver2()); +} + +/// @brief Same triple from copy `index` of a `mod2k` oracle. +template +HEDLEY_WARN_UNUSED_RESULT +inline fixed_mul_beaver_triple sample_fixed_mul_beaver_triple(unsigned multiply_bits, + const dpf::beavers::oracle & src, std::uint64_t index = 0) +{ + if (multiply_bits == 0u) + return {}; + if (multiply_bits > 128u) + throw std::invalid_argument("fixed_mul beaver triple exceeds 128 bits"); + dpf::beavers::mod2k_width_scope width(multiply_bits); + return pack_mod2k_beaver(multiply_bits, + dpf::beavers::sample_beaver2(src, index)); +} + +/// @brief Build the reusable comparisons for this window. +/// \complexity One `dpf::make_dpf` per live lift (operand, product, result) +/// and one for a right shift. A signed lift reuses that key at a second +/// query. Each comparison is a `uint64_t` domain. No messages. +/// \rounds No party interaction. +/// \communication None. +/// \preprocessing Those comparison keys and the mask shares. +template +HEDLEY_WARN_UNUSED_RESULT +fixed_mul_beaver_prep +make_fixed_mul_beaver_prep() +{ + using shape = fixed_mul_beaver_shape; + using prep = fixed_mul_beaver_prep; + static_assert(shape::fits, + "fixed_mul beaver: multiply and modulus must be at most 128 bits, " + "each lift must start from at most 64 bits and extend by at most 64, " + "and a right shift must discard at most 64 bits"); + prep out; + if constexpr (!shape::active) + return out; + using plan = typename shape::plan; + if constexpr (shape::lhs_lift) + { + out.lhs = fixed_mul_beaver_detail::make_lift(plan::lhs_width, + plan::multiply_bits, plan::lhs_signed); + } + if constexpr (shape::rhs_lift) + { + out.rhs = fixed_mul_beaver_detail::make_lift(plan::rhs_width, + plan::multiply_bits, plan::rhs_signed); + } + if constexpr (shape::product_lift) + { + out.product = fixed_mul_beaver_detail::make_lift(plan::multiply_bits, + plan::modulus_bits, plan::operands_signed); + } + if constexpr (shape::shift_right) + { + out.shift = fixed_mul_beaver_detail::make_shift(plan::modulus_bits, + static_cast(plan::align_shift)); + } + if constexpr (shape::result_lift) + { + out.result = fixed_mul_beaver_detail::make_lift(plan::out_bits, + shape::storage_bits, plan::result_is_signed); + } + return out; +} + +/// @brief One party's share of `fixed_mul(lhs, rhs)`. +/// @details `lhs_share` and `rhs_share` are additive shares of each operand's +/// raw integral word, in that word's own ring. The return value is +/// this party's share of the product's raw integral word. `exchange(mine)` +/// returns the peer's matching `uint64_t`. Both parties must call it +/// the same number of times (`fixed_mul_beaver_shape::messages`). +/// @tparam Exchange callable `std::uint64_t(std::uint64_t)` +/// @param prep reusable dealer material from `make_fixed_mul_beaver_prep` +/// @param triple fresh Beaver triple in the multiply ring +/// @param party `0` or `1` +/// @param lhs_share this party's share of the left raw word +/// @param rhs_share this party's share of the right raw word +/// @param exchange peer exchange for one `uint64_t` +/// @return this party's share of the product, as a fixed-point word +/// \complexity The Beaver product is `O(1)` 128-bit arithmetic. Each live +/// lift or shift is one to three `eval_point` calls on a `uint64_t` DCF. +/// \rounds One round if the caller pipelines every `exchange`; the callback +/// itself is one word at a time. `messages` words in total. +/// \communication `fixed_mul_beaver_shape::messages` words of `uint64_t`. +/// \preprocessing `prep` and one `triple`. +template +HEDLEY_WARN_UNUSED_RESULT +auto eval_fixed_mul_beaver( + const fixed_mul_beaver_prep & prep, + const fixed_mul_beaver_triple & triple, + std::size_t party, + LhsIntegral lhs_share, + RhsIntegral rhs_share, + Exchange && exchange) + -> typename fixed_mul_plan::result_type +{ + using shape = fixed_mul_beaver_shape; + using plan = typename shape::plan; + using integral = typename plan::integral_type; + static_assert(shape::fits, + "fixed_mul beaver: multiply and modulus must be at most 128 bits, " + "each lift must start from at most 64 bits and extend by at most 64, " + "and a right shift must discard at most 64 bits"); + if (party > 1u) + throw std::invalid_argument("fixed_mul beaver party is 0 or 1"); + + using namespace fixed_mul_beaver_detail; + const auto zero = make_fixed_from_integral_type( + integral{}); + if constexpr (!shape::active) + { + (void)prep; + (void)triple; + (void)lhs_share; + (void)rhs_share; + (void)exchange; + return zero; + } + else + { + if (triple.multiply_bits != plan::multiply_bits) + throw std::invalid_argument("fixed_mul beaver triple width does not match the window"); + + auto reduce = [&](u128 share, unsigned width, const lift_keys & lift, + bool do_lift) -> u128 { + const unsigned kept = width < 128u ? width : 128u; + u128 limb = share & bit_mask(kept); + if (!do_lift) + return limb & bit_mask(plan::multiply_bits); + return apply_lift(limb, lift, party, exchange); + }; + + const u128 left = reduce(share_bits(lhs_share), plan::lhs_width, + prep.lhs, shape::lhs_lift); + const u128 right = reduce(share_bits(rhs_share), plan::rhs_width, + prep.rhs, shape::rhs_lift); + + const unsigned m = plan::multiply_bits; + const u128 d = open_sum(sub_mod(left, triple.a[party], m), m, exchange); + const u128 e = open_sum(sub_mod(right, triple.b[party], m), m, exchange); + u128 prod = add_mod(triple.ab[party], + add_mod(mul_mod(d, triple.b[party], m), + mul_mod(e, triple.a[party], m), m), m); + if (party == 1u) + prod = add_mod(prod, mul_mod(d, e, m), m); + + u128 wide = prod; + if constexpr (shape::product_lift) + wide = apply_lift(wide, prep.product, party, exchange); + + u128 window = wide; + if constexpr (shape::shift_right) + window = apply_shift(wide, prep.shift, party, exchange); + else if constexpr (shape::shift_left) + { + constexpr unsigned k = static_cast(-plan::align_shift); + window = ((wide & bit_mask(plan::modulus_bits)) << k) + & bit_mask(plan::out_bits); + } + else + window = wide & bit_mask(plan::out_bits); + + if constexpr (shape::result_lift) + window = apply_lift(window, prep.result, party, exchange); + + window &= bit_mask(shape::storage_bits); + std::uint64_t limbs[4] = { + static_cast(window), + static_cast(window >> 64), + 0u, + 0u}; + return make_fixed_from_integral_type( + detail::limbs_to_integral(limbs)); + } +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_FIXEDPOINT_BEAVER_HPP__ diff --git a/include/grotto/fixedpoint_mul.hpp b/include/grotto/fixedpoint_mul.hpp index 3ce0305..91abc99 100644 --- a/include/grotto/fixedpoint_mul.hpp +++ b/include/grotto/fixedpoint_mul.hpp @@ -29,11 +29,13 @@ namespace grotto /// integer part. Both discards are the low or high residue modulo a power of /// two, so a negative value is floored onto the output ulp. /// -/// A Beaver triple replaces only the multiply in `Z/2^multiply_bits Z`. -/// Reducing each operand into that ring is local when it is a truncation or a -/// zero-extend. Sign-extending a narrower signed operand, and replicating the -/// product sign when `modulus_bits > multiply_bits`, are plaintext steps the -/// MPC protocol has to reproduce (they are not local on additive shares). +/// A Beaver triple replaces only the multiply in `Z/2^multiply_bits Z` +/// (`grotto::eval_fixed_mul_beaver`). Dropping bits above that ring is local. +/// A narrower share is lifted by cancelling the carry out of the operand +/// width; a signed lift also replicates the sign. The same correction +/// replicates the product sign when `modulus_bits > multiply_bits` and +/// supplies the right shift by `align_shift`. Each of those lifts extends +/// by at most 64 bits, and the shift discards at most 64 bits. /// @tparam IntegerBits number of integer bits, including the sign /// @tparam FractionalBits number of fractional bits /// @tparam LhsFractionalBits lhs fractional bits @@ -206,11 +208,11 @@ constexpr void store_raw_limbs(const T & value, std::uint64_t out[4]) noexcept /// @brief Low `dest_bits` of `value`, sign-extended when `value` is a narrower signed integer. /// @tparam T value type /// @param value the value to convert or store -/// @param src_bits the `src_bits` -/// @param is_signed the `is_signed` -/// @param dest_bits the `dest_bits` +/// @param src_bits width of `value` before extension +/// @param is_signed whether `value` is a signed integer of `src_bits` bits +/// @param dest_bits width of the destination word /// @param dest the destination -/// @param nlimbs the `nlimbs` +/// @param nlimbs number of 64-bit limbs kept in the product template HEDLEY_NO_THROW constexpr void reduce_operand(const T & value, unsigned src_bits, bool is_signed, @@ -239,7 +241,7 @@ constexpr void reduce_operand(const T & value, unsigned src_bits, bool is_signed /// @param out the output buffer /// @param lhs the left-hand operand /// @param rhs the right-hand operand -/// @param nlimbs the `nlimbs` +/// @param nlimbs number of 64-bit limbs kept in the product HEDLEY_NO_THROW constexpr void mul_low_limbs(std::uint64_t * out, const std::uint64_t * lhs, const std::uint64_t * rhs, unsigned nlimbs) noexcept @@ -360,6 +362,11 @@ constexpr T limbs_to_integral(const std::uint64_t * limbs) noexcept /// @param lhs the left-hand operand /// @param rhs the right-hand operand /// @return the product at the requested width +/// \complexity `mul_low_limbs` multiplies `L` 64-bit limbs, `L = fixed_mul_plan::limbs`, with loops `i < L` and `i + j < L`: `Θ(L²)` limb products. +/// Reducing each operand and the align shift are `Θ(L)`. Scratch is a fixed limb buffer in this header (the 8-word arrays plus `fixed_mul_buf_limbs`). +/// @see grotto::fixedpoint +/// @note Plaintext. `grotto::eval_fixed_mul_beaver` is the same window on additive shares: one Beaver product in `Z/2^{multiply_bits}Z`, then the lifts and the aligning shift. +/// @see grotto::eval_fixed_mul_beaver template struct gadget_hints @@ -33,6 +35,8 @@ struct gadget_hints static constexpr double * canonical_bounds = nullptr; static constexpr std::array * canonical_polys = nullptr; }; +/// \complexity Two `nexttoward` calls. `Θ(1)`. +/// @see grotto::gadgets constexpr double ulp_of(double x) { @@ -44,6 +48,8 @@ constexpr double ulp_of(double x) template struct gadget_domain { + /// \complexity A constant number of `exp2` / casts. `Θ(1)`. + /// @see grotto::gadget_hints static constexpr T min() { diff --git a/include/grotto/gadgets/activations/celu.hpp b/include/grotto/gadgets/activations/celu.hpp index 159513c..4e3d6b9 100644 --- a/include/grotto/gadgets/activations/celu.hpp +++ b/include/grotto/gadgets/activations/celu.hpp @@ -21,9 +21,19 @@ namespace gadgets { static constexpr double celu_default_alpha = 1; +/// @brief Cleartext `celu`. +/// @see grotto::eval_closed +/// @tparam alpha functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct celu { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/elish.hpp b/include/grotto/gadgets/activations/elish.hpp index 3c47e1f..c9b8949 100644 --- a/include/grotto/gadgets/activations/elish.hpp +++ b/include/grotto/gadgets/activations/elish.hpp @@ -25,8 +25,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `elish`. +/// @see grotto::eval_window +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) elish { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/elu.hpp b/include/grotto/gadgets/activations/elu.hpp index 1a08fbf..1da82b1 100644 --- a/include/grotto/gadgets/activations/elu.hpp +++ b/include/grotto/gadgets/activations/elu.hpp @@ -21,9 +21,19 @@ namespace gadgets { static constexpr double elu_default_alpha = 1; +/// @brief Cleartext `elu`. +/// @see grotto::eval_closed +/// @tparam alpha functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct elu { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/gelu.hpp b/include/grotto/gadgets/activations/gelu.hpp index 8a191e1..8fdecc8 100644 --- a/include/grotto/gadgets/activations/gelu.hpp +++ b/include/grotto/gadgets/activations/gelu.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `gelu`. +/// @see grotto::eval_window +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) gelu { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/hardelish.hpp b/include/grotto/gadgets/activations/hardelish.hpp index e8c1f68..787b970 100644 --- a/include/grotto/gadgets/activations/hardelish.hpp +++ b/include/grotto/gadgets/activations/hardelish.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `hardelish`. +/// @see grotto::eval_window with `window::hardelish` +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct hardelish { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/hardshrink.hpp b/include/grotto/gadgets/activations/hardshrink.hpp index 2e8ea29..31a02b8 100644 --- a/include/grotto/gadgets/activations/hardshrink.hpp +++ b/include/grotto/gadgets/activations/hardshrink.hpp @@ -25,9 +25,19 @@ HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED static constexpr double hardshrink_default_lambda = 0.5; +/// @brief Cleartext `hardshrink`. +/// @see grotto::make_hardshrink_lut +/// @tparam lambda functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct HEDLEY_DEPRECATED_FOR(2026, grotto::make_hardshrink_lut) hardshrink { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/hardsigmoid.hpp b/include/grotto/gadgets/activations/hardsigmoid.hpp index 2b1c650..63c3123 100644 --- a/include/grotto/gadgets/activations/hardsigmoid.hpp +++ b/include/grotto/gadgets/activations/hardsigmoid.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `hardsigmoid`. +/// @see grotto::make_hardsigmoid_lut +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::make_hardsigmoid_lut) hardsigmoid { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/hardswish.hpp b/include/grotto/gadgets/activations/hardswish.hpp index 23b7227..a48eccc 100644 --- a/include/grotto/gadgets/activations/hardswish.hpp +++ b/include/grotto/gadgets/activations/hardswish.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `hardswish`. +/// @see grotto::make_hardswish_lut +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::make_hardswish_lut) hardswish { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/hardtanh.hpp b/include/grotto/gadgets/activations/hardtanh.hpp index 39f34d0..a41441b 100644 --- a/include/grotto/gadgets/activations/hardtanh.hpp +++ b/include/grotto/gadgets/activations/hardtanh.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `hardtanh`. +/// @see grotto::make_hardtanh_lut +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::make_hardtanh_lut) hardtanh { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/leakyrelu.hpp b/include/grotto/gadgets/activations/leakyrelu.hpp index d1b67d9..99cbad1 100644 --- a/include/grotto/gadgets/activations/leakyrelu.hpp +++ b/include/grotto/gadgets/activations/leakyrelu.hpp @@ -26,9 +26,21 @@ HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED static constexpr double leakyrelu_default_negative_slope = 0.01; static constexpr double leakyrelu_zero_negative_slope = 0.0; +/// @brief Cleartext `leakyrelu`. The default slope `0.01` is +/// `make_leaky_relu_hundredth_lut`. A power-of-two slope is +/// `make_leaky_relu_lut`. +/// @see grotto::make_leaky_relu_hundredth_lut +/// @tparam negative_slope functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template -struct HEDLEY_DEPRECATED_FOR(2026, grotto::make_leaky_relu_lut) leakyrelu +struct HEDLEY_DEPRECATED_FOR(2026, grotto::make_leaky_relu_hundredth_lut) leakyrelu { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/lecun_tanh.hpp b/include/grotto/gadgets/activations/lecun_tanh.hpp index 4c00418..3c5ce35 100644 --- a/include/grotto/gadgets/activations/lecun_tanh.hpp +++ b/include/grotto/gadgets/activations/lecun_tanh.hpp @@ -21,8 +21,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `lecun_tanh`. +/// @see grotto::eval_window with `window::lecun_tanh` +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct lecun_tanh { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/logsigmoid.hpp b/include/grotto/gadgets/activations/logsigmoid.hpp index 682dfdb..0a1ba83 100644 --- a/include/grotto/gadgets/activations/logsigmoid.hpp +++ b/include/grotto/gadgets/activations/logsigmoid.hpp @@ -25,8 +25,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `logsigmoid`. +/// @see grotto::eval_window +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) logsigmoid { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return std::log(sigmoid{}(x)); } }; diff --git a/include/grotto/gadgets/activations/mish.hpp b/include/grotto/gadgets/activations/mish.hpp index 3dae558..0bce21f 100644 --- a/include/grotto/gadgets/activations/mish.hpp +++ b/include/grotto/gadgets/activations/mish.hpp @@ -25,8 +25,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `mish`. +/// @see grotto::eval_window +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) mish { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/one_minus_sigmoid.hpp b/include/grotto/gadgets/activations/one_minus_sigmoid.hpp index a87e144..75b1a56 100644 --- a/include/grotto/gadgets/activations/one_minus_sigmoid.hpp +++ b/include/grotto/gadgets/activations/one_minus_sigmoid.hpp @@ -24,8 +24,17 @@ namespace gadgets HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `one_minus_sigmoid`. +/// @see grotto::eval_window with `window::one_minus_sigmoid` +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) one_minus_sigmoid { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/relu.hpp b/include/grotto/gadgets/activations/relu.hpp index d323a8d..4e12468 100644 --- a/include/grotto/gadgets/activations/relu.hpp +++ b/include/grotto/gadgets/activations/relu.hpp @@ -23,6 +23,9 @@ namespace gadgets HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Alias of another cleartext functor, under the name `relu`. +/// @see grotto::make_relu_lut +/// \complexity Same as the functor it aliases: one straight-line `operator()`. `Θ(1)`. using relu HEDLEY_DEPRECATED_FOR(2026, grotto::make_relu_lut) = leakyrelu; HEDLEY_DIAGNOSTIC_POP diff --git a/include/grotto/gadgets/activations/relu6.hpp b/include/grotto/gadgets/activations/relu6.hpp index 2fc11cc..1cc19bf 100644 --- a/include/grotto/gadgets/activations/relu6.hpp +++ b/include/grotto/gadgets/activations/relu6.hpp @@ -25,9 +25,19 @@ HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED static constexpr double relu6_default_clip = 6; +/// @brief Cleartext `relu6`. +/// @see grotto::make_relu6_lut +/// @tparam clip functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct HEDLEY_DEPRECATED_FOR(2026, grotto::make_relu6_lut) relu6 { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/selu.hpp b/include/grotto/gadgets/activations/selu.hpp index d388668..e409dfe 100644 --- a/include/grotto/gadgets/activations/selu.hpp +++ b/include/grotto/gadgets/activations/selu.hpp @@ -22,10 +22,21 @@ namespace gadgets static constexpr double selu_default_alpha = 1.6732632423543772848170429916717; static constexpr double selu_default_scale = 1.0507009873554804934193349852946; +/// @brief Cleartext `selu`. +/// @see grotto::eval_closed +/// @tparam scale functor parameter (a `double` bound or scale) +/// @tparam alpha functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct selu { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/serf.hpp b/include/grotto/gadgets/activations/serf.hpp index b835eeb..7494fd8 100644 --- a/include/grotto/gadgets/activations/serf.hpp +++ b/include/grotto/gadgets/activations/serf.hpp @@ -25,8 +25,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `serf`. +/// @see grotto::eval_window +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) serf { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/sigmoid.hpp b/include/grotto/gadgets/activations/sigmoid.hpp index a471202..03801e3 100644 --- a/include/grotto/gadgets/activations/sigmoid.hpp +++ b/include/grotto/gadgets/activations/sigmoid.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `sigmoid`. +/// @see grotto::eval_window +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) sigmoid { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return 1/(1+std::exp(-x)); } }; diff --git a/include/grotto/gadgets/activations/silu.hpp b/include/grotto/gadgets/activations/silu.hpp index 74be2a3..d724bb9 100644 --- a/include/grotto/gadgets/activations/silu.hpp +++ b/include/grotto/gadgets/activations/silu.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `silu`. +/// @see grotto::eval_window +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) silu { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return x*sigmoid{}(x); } }; diff --git a/include/grotto/gadgets/activations/smoothstep.hpp b/include/grotto/gadgets/activations/smoothstep.hpp index d570dbd..d0c8b23 100644 --- a/include/grotto/gadgets/activations/smoothstep.hpp +++ b/include/grotto/gadgets/activations/smoothstep.hpp @@ -25,9 +25,19 @@ HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED static constexpr double smoothstep_default_gamma = 1; +/// @brief Cleartext `smoothstep`. +/// @see grotto::eval_window +/// @tparam gamma functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) smoothstep { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/softminus.hpp b/include/grotto/gadgets/activations/softminus.hpp index 04d0b58..66a2750 100644 --- a/include/grotto/gadgets/activations/softminus.hpp +++ b/include/grotto/gadgets/activations/softminus.hpp @@ -26,9 +26,19 @@ HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED static constexpr double softminus_default_beta = 1; +/// @brief Cleartext `softminus`. +/// @see grotto::eval_window +/// @tparam beta functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) softminus { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/softplus.hpp b/include/grotto/gadgets/activations/softplus.hpp index 7f63748..f07602e 100644 --- a/include/grotto/gadgets/activations/softplus.hpp +++ b/include/grotto/gadgets/activations/softplus.hpp @@ -25,9 +25,19 @@ HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED static constexpr double softplus_default_beta = 1; +/// @brief Cleartext `softplus`. +/// @see grotto::eval_window +/// @tparam beta functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) softplus { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/softshrink.hpp b/include/grotto/gadgets/activations/softshrink.hpp index 31a05b4..69bcd7a 100644 --- a/include/grotto/gadgets/activations/softshrink.hpp +++ b/include/grotto/gadgets/activations/softshrink.hpp @@ -25,9 +25,19 @@ HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED static constexpr double softshrink_default_lambda = 0.5; +/// @brief Cleartext `softshrink`. +/// @see grotto::make_softshrink_lut +/// @tparam lambda functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct HEDLEY_DEPRECATED_FOR(2026, grotto::make_softshrink_lut) softshrink { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/softsign.hpp b/include/grotto/gadgets/activations/softsign.hpp index 19cc05d..8712697 100644 --- a/include/grotto/gadgets/activations/softsign.hpp +++ b/include/grotto/gadgets/activations/softsign.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `hardsign`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct hardsign { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return x/(1+std::abs(x)); } }; diff --git a/include/grotto/gadgets/activations/squared_relu.hpp b/include/grotto/gadgets/activations/squared_relu.hpp index 59e2c86..d98e12f 100644 --- a/include/grotto/gadgets/activations/squared_relu.hpp +++ b/include/grotto/gadgets/activations/squared_relu.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `squared_relu`. +/// @see grotto::make_squared_relu_lut +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::make_squared_relu_lut) squared_relu { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/starrelu.hpp b/include/grotto/gadgets/activations/starrelu.hpp index 8ec2c01..3faf885 100644 --- a/include/grotto/gadgets/activations/starrelu.hpp +++ b/include/grotto/gadgets/activations/starrelu.hpp @@ -22,10 +22,21 @@ namespace gadgets static constexpr double starrelu_default_scale = 0.8944; static constexpr double starrelu_default_shift = -0.4472; +/// @brief Cleartext `starrelu`. +/// @see grotto::make_relu_lut +/// @tparam shift functor parameter (a `double` bound or scale) +/// @tparam scale functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct starrelu { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/activations/tanhexp.hpp b/include/grotto/gadgets/activations/tanhexp.hpp index 7941a6a..e67c713 100644 --- a/include/grotto/gadgets/activations/tanhexp.hpp +++ b/include/grotto/gadgets/activations/tanhexp.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `tanhexp`. +/// @see grotto::eval_window +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) tanhexp { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return x*std::tanh(std::exp(x)); } }; diff --git a/include/grotto/gadgets/activations/tanhshrink.hpp b/include/grotto/gadgets/activations/tanhshrink.hpp index 9579120..dfee5a6 100644 --- a/include/grotto/gadgets/activations/tanhshrink.hpp +++ b/include/grotto/gadgets/activations/tanhshrink.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `tanhshrink`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct tanhshrink { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return x -std::tanh(x); } }; diff --git a/include/grotto/gadgets/binary/bit.hpp b/include/grotto/gadgets/binary/bit.hpp index 33fec75..56de323 100644 --- a/include/grotto/gadgets/binary/bit.hpp +++ b/include/grotto/gadgets/binary/bit.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::make_msb_lut } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/binary/bit_ceil.hpp b/include/grotto/gadgets/binary/bit_ceil.hpp index 5dda8d2..2f6071b 100644 --- a/include/grotto/gadgets/binary/bit_ceil.hpp +++ b/include/grotto/gadgets/binary/bit_ceil.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_bit_ceil } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/binary/bit_floor.hpp b/include/grotto/gadgets/binary/bit_floor.hpp index 4679311..830e987 100644 --- a/include/grotto/gadgets/binary/bit_floor.hpp +++ b/include/grotto/gadgets/binary/bit_floor.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_bit_floor } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/binary/bit_width.hpp b/include/grotto/gadgets/binary/bit_width.hpp index 6656ed5..7ec918b 100644 --- a/include/grotto/gadgets/binary/bit_width.hpp +++ b/include/grotto/gadgets/binary/bit_width.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_bit_width } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/binary/clrsb.hpp b/include/grotto/gadgets/binary/clrsb.hpp index 6b68f01..b1b072d 100644 --- a/include/grotto/gadgets/binary/clrsb.hpp +++ b/include/grotto/gadgets/binary/clrsb.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::exact_constant } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/binary/countl_one.hpp b/include/grotto/gadgets/binary/countl_one.hpp index faa89a9..f299321 100644 --- a/include/grotto/gadgets/binary/countl_one.hpp +++ b/include/grotto/gadgets/binary/countl_one.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_countl_one } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/binary/countl_zero.hpp b/include/grotto/gadgets/binary/countl_zero.hpp index 8f1956d..94bdcf8 100644 --- a/include/grotto/gadgets/binary/countl_zero.hpp +++ b/include/grotto/gadgets/binary/countl_zero.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `countl_zero`. +/// @see grotto::exact_constant +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::exact_constant) countl_zero { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/binary/has_single_bit.hpp b/include/grotto/gadgets/binary/has_single_bit.hpp index ece154b..162eb05 100644 --- a/include/grotto/gadgets/binary/has_single_bit.hpp +++ b/include/grotto/gadgets/binary/has_single_bit.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `has_single_bit`. +/// @see grotto::eval_has_single_bit +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct has_single_bit { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/binary/prefix.hpp b/include/grotto/gadgets/binary/prefix.hpp index 6c3ed7e..d1f28cf 100644 --- a/include/grotto/gadgets/binary/prefix.hpp +++ b/include/grotto/gadgets/binary/prefix.hpp @@ -18,6 +18,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::prefix_parities } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/binary/sgn.hpp b/include/grotto/gadgets/binary/sgn.hpp index 81667d9..44f973d 100644 --- a/include/grotto/gadgets/binary/sgn.hpp +++ b/include/grotto/gadgets/binary/sgn.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `sgn`. +/// @see grotto::exact_constant +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::exact_constant) sgn { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/decimal/dec_ceil.hpp b/include/grotto/gadgets/decimal/dec_ceil.hpp index 87264e4..5fa64ca 100644 --- a/include/grotto/gadgets/decimal/dec_ceil.hpp +++ b/include/grotto/gadgets/decimal/dec_ceil.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_dec_ceil } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/decimal/dec_floor.hpp b/include/grotto/gadgets/decimal/dec_floor.hpp index 8d79ee4..b41d906 100644 --- a/include/grotto/gadgets/decimal/dec_floor.hpp +++ b/include/grotto/gadgets/decimal/dec_floor.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_dec_floor } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/decimal/dec_width.hpp b/include/grotto/gadgets/decimal/dec_width.hpp index 807815f..c9de7e5 100644 --- a/include/grotto/gadgets/decimal/dec_width.hpp +++ b/include/grotto/gadgets/decimal/dec_width.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_dec_width } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/decimal/has_single_digit.hpp b/include/grotto/gadgets/decimal/has_single_digit.hpp index f415f67..8266bb1 100644 --- a/include/grotto/gadgets/decimal/has_single_digit.hpp +++ b/include/grotto/gadgets/decimal/has_single_digit.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_has_single_digit } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/elementary/abs.hpp b/include/grotto/gadgets/elementary/abs.hpp index bfa9d3a..80d4798 100644 --- a/include/grotto/gadgets/elementary/abs.hpp +++ b/include/grotto/gadgets/elementary/abs.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `abs`. +/// @see grotto::make_abs_lut +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::make_abs_lut) abs { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return std::abs(static_cast(x)); } }; diff --git a/include/grotto/gadgets/elementary/approx.hpp b/include/grotto/gadgets/elementary/approx.hpp index 29f1810..4d6e684 100644 --- a/include/grotto/gadgets/elementary/approx.hpp +++ b/include/grotto/gadgets/elementary/approx.hpp @@ -23,10 +23,21 @@ namespace gadgets static constexpr double approx_default_target = 0; static constexpr unsigned approx_default_ULPs = 1; +/// @brief Cleartext `approx`. +/// @see grotto::make_threshold_lut +/// @tparam ULPs functor parameter (a `double` bound or scale) +/// @tparam target functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct approx { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return std::abs(x - target) <= ULPs * ulp_of(target) ? 1 : 0; } }; diff --git a/include/grotto/gadgets/elementary/boxcar.hpp b/include/grotto/gadgets/elementary/boxcar.hpp index c2974da..8eb6b1b 100644 --- a/include/grotto/gadgets/elementary/boxcar.hpp +++ b/include/grotto/gadgets/elementary/boxcar.hpp @@ -22,12 +22,25 @@ namespace gadgets static constexpr double boxcar_default_outside = 0; static constexpr double boxcar_default_inside = 1; +/// @brief Cleartext `boxcar`. +/// @see grotto::make_interval_lut +/// @tparam inside functor parameter (a `double` bound or scale) +/// @tparam outside functor parameter (a `double` bound or scale) +/// @tparam to functor parameter (a `double` bound or scale) +/// @tparam from functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct boxcar { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return (x < from || x > to) ? outside : inside; } }; diff --git a/include/grotto/gadgets/elementary/clip.hpp b/include/grotto/gadgets/elementary/clip.hpp index 51833c2..8f56b70 100644 --- a/include/grotto/gadgets/elementary/clip.hpp +++ b/include/grotto/gadgets/elementary/clip.hpp @@ -23,11 +23,22 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `clip`. +/// @see grotto::make_clip_lut +/// @tparam upper functor parameter (a `double` bound or scale) +/// @tparam lower functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct HEDLEY_DEPRECATED_FOR(2026, grotto::make_clip_lut) clip { static_assert(lower <= upper); + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return std::max(std::min(x, upper), lower); } }; diff --git a/include/grotto/gadgets/elementary/eq.hpp b/include/grotto/gadgets/elementary/eq.hpp index 1b205d4..61cf86c 100644 --- a/include/grotto/gadgets/elementary/eq.hpp +++ b/include/grotto/gadgets/elementary/eq.hpp @@ -19,9 +19,19 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `eq`. +/// @see grotto::make_threshold_lut +/// @tparam target functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct eq { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return x == target; } }; diff --git a/include/grotto/gadgets/elementary/geq.hpp b/include/grotto/gadgets/elementary/geq.hpp index 076209f..71934c3 100644 --- a/include/grotto/gadgets/elementary/geq.hpp +++ b/include/grotto/gadgets/elementary/geq.hpp @@ -19,9 +19,19 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `geq`. +/// @see grotto::make_threshold_lut +/// @tparam target functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct geq { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return x >= target; } }; diff --git a/include/grotto/gadgets/elementary/gt.hpp b/include/grotto/gadgets/elementary/gt.hpp index 2d99c8e..ada8385 100644 --- a/include/grotto/gadgets/elementary/gt.hpp +++ b/include/grotto/gadgets/elementary/gt.hpp @@ -19,9 +19,19 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `gt`. +/// @see grotto::make_threshold_lut +/// @tparam target functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct gt { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return x > target; } }; diff --git a/include/grotto/gadgets/elementary/identity.hpp b/include/grotto/gadgets/elementary/identity.hpp index 2e82366..67543e6 100644 --- a/include/grotto/gadgets/elementary/identity.hpp +++ b/include/grotto/gadgets/elementary/identity.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::fixedpoint } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/elementary/leq.hpp b/include/grotto/gadgets/elementary/leq.hpp index 0c4f320..a098c26 100644 --- a/include/grotto/gadgets/elementary/leq.hpp +++ b/include/grotto/gadgets/elementary/leq.hpp @@ -19,9 +19,19 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `leq`. +/// @see grotto::make_threshold_lut +/// @tparam target functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct leq { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return x <= target; } }; diff --git a/include/grotto/gadgets/elementary/lt.hpp b/include/grotto/gadgets/elementary/lt.hpp index dab9d02..2bcb62e 100644 --- a/include/grotto/gadgets/elementary/lt.hpp +++ b/include/grotto/gadgets/elementary/lt.hpp @@ -19,9 +19,19 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `lt`. +/// @see grotto::make_threshold_lut +/// @tparam target functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct lt { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return x < target; } }; diff --git a/include/grotto/gadgets/elementary/negative.hpp b/include/grotto/gadgets/elementary/negative.hpp index 3431514..e30c3da 100644 --- a/include/grotto/gadgets/elementary/negative.hpp +++ b/include/grotto/gadgets/elementary/negative.hpp @@ -17,6 +17,9 @@ namespace gadgets { static constexpr double lt_target_zero = 0; +/// @brief Alias of another cleartext functor, under the name `negative`. +/// @see grotto::exact_constant +/// \complexity Same as the functor it aliases: one straight-line `operator()`. `Θ(1)`. using negative HEDLEY_DEPRECATED_FOR(2026, grotto::exact_constant) = lt; } // namespace gadgets diff --git a/include/grotto/gadgets/elementary/neq.hpp b/include/grotto/gadgets/elementary/neq.hpp index 3fbb73f..e158394 100644 --- a/include/grotto/gadgets/elementary/neq.hpp +++ b/include/grotto/gadgets/elementary/neq.hpp @@ -19,9 +19,19 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `neq`. +/// @see grotto::make_nonzero_lut +/// @tparam target functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct neq { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return x != target; } }; diff --git a/include/grotto/gadgets/elementary/nonnegative.hpp b/include/grotto/gadgets/elementary/nonnegative.hpp index f39a09e..69775ba 100644 --- a/include/grotto/gadgets/elementary/nonnegative.hpp +++ b/include/grotto/gadgets/elementary/nonnegative.hpp @@ -17,6 +17,9 @@ namespace gadgets { static constexpr double geq_target_zero = 0; +/// @brief Alias of another cleartext functor, under the name `nonnegative`. +/// @see grotto::exact_constant +/// \complexity Same as the functor it aliases: one straight-line `operator()`. `Θ(1)`. using nonnegative HEDLEY_DEPRECATED_FOR(2026, grotto::exact_constant) = geq; } // namespace gadgets diff --git a/include/grotto/gadgets/elementary/nonpositive.hpp b/include/grotto/gadgets/elementary/nonpositive.hpp index bf63771..4341334 100644 --- a/include/grotto/gadgets/elementary/nonpositive.hpp +++ b/include/grotto/gadgets/elementary/nonpositive.hpp @@ -17,6 +17,9 @@ namespace gadgets { static constexpr double leq_target_zero = 0; +/// @brief Alias of another cleartext functor, under the name `nonpositive`. +/// @see grotto::exact_constant +/// \complexity Same as the functor it aliases: one straight-line `operator()`. `Θ(1)`. using nonpositive HEDLEY_DEPRECATED_FOR(2026, grotto::exact_constant) = leq; } // namespace gadgets diff --git a/include/grotto/gadgets/elementary/nonzero.hpp b/include/grotto/gadgets/elementary/nonzero.hpp index 263c2c5..3b12c1d 100644 --- a/include/grotto/gadgets/elementary/nonzero.hpp +++ b/include/grotto/gadgets/elementary/nonzero.hpp @@ -17,6 +17,9 @@ namespace gadgets { static constexpr double neq_target_zero = 0; +/// @brief Alias of another cleartext functor, under the name `nonzero`. +/// @see grotto::exact_constant +/// \complexity Same as the functor it aliases: one straight-line `operator()`. `Θ(1)`. using nonzero HEDLEY_DEPRECATED_FOR(2026, grotto::exact_constant) = neq; } // namespace gadgets diff --git a/include/grotto/gadgets/elementary/pmone.hpp b/include/grotto/gadgets/elementary/pmone.hpp index 546b20b..fa44111 100644 --- a/include/grotto/gadgets/elementary/pmone.hpp +++ b/include/grotto/gadgets/elementary/pmone.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/elementary/positive.hpp b/include/grotto/gadgets/elementary/positive.hpp index 080b3b8..0e03c8e 100644 --- a/include/grotto/gadgets/elementary/positive.hpp +++ b/include/grotto/gadgets/elementary/positive.hpp @@ -17,6 +17,9 @@ namespace gadgets { static constexpr double gt_target_zero = 0; +/// @brief Alias of another cleartext functor, under the name `positive`. +/// @see grotto::exact_constant +/// \complexity Same as the functor it aliases: one straight-line `operator()`. `Θ(1)`. using positive HEDLEY_DEPRECATED_FOR(2026, grotto::exact_constant) = gt; } // namespace gadgets diff --git a/include/grotto/gadgets/elementary/rect.hpp b/include/grotto/gadgets/elementary/rect.hpp index d805331..7123b18 100644 --- a/include/grotto/gadgets/elementary/rect.hpp +++ b/include/grotto/gadgets/elementary/rect.hpp @@ -19,8 +19,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `rect`. +/// @see grotto::make_zero_lut +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct rect { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return x == 0; } }; diff --git a/include/grotto/gadgets/elementary/step.hpp b/include/grotto/gadgets/elementary/step.hpp index 976d549..73585e0 100644 --- a/include/grotto/gadgets/elementary/step.hpp +++ b/include/grotto/gadgets/elementary/step.hpp @@ -22,11 +22,23 @@ namespace gadgets static constexpr double step_default_before = 0; static constexpr double step_default_after = 1; +/// @brief Cleartext `step`. +/// @see grotto::make_exact_step_lut +/// @tparam after functor parameter (a `double` bound or scale) +/// @tparam before functor parameter (a `double` bound or scale) +/// @tparam at functor parameter (a `double` bound or scale) +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. template struct step { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return x < at ? before : after; } }; diff --git a/include/grotto/gadgets/elementary/ternary.hpp b/include/grotto/gadgets/elementary/ternary.hpp index 3138e99..cfb0183 100644 --- a/include/grotto/gadgets/elementary/ternary.hpp +++ b/include/grotto/gadgets/elementary/ternary.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/elementary/zero.hpp b/include/grotto/gadgets/elementary/zero.hpp index de9cf2e..b6dff45 100644 --- a/include/grotto/gadgets/elementary/zero.hpp +++ b/include/grotto/gadgets/elementary/zero.hpp @@ -17,6 +17,9 @@ namespace gadgets { static constexpr double eq_target_zero = 0; +/// @brief Alias of another cleartext functor, under the name `zero`. +/// @see grotto::exact_constant +/// \complexity Same as the functor it aliases: one straight-line `operator()`. `Θ(1)`. using zero HEDLEY_DEPRECATED_FOR(2026, grotto::exact_constant) = eq; } // namespace gadgets diff --git a/include/grotto/gadgets/exponential/exp.hpp b/include/grotto/gadgets/exponential/exp.hpp index 1611cfa..449031f 100644 --- a/include/grotto/gadgets/exponential/exp.hpp +++ b/include/grotto/gadgets/exponential/exp.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `exp`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) exp { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return std::min(std::exp(static_cast(x)), std::numeric_limits::max()); } }; diff --git a/include/grotto/gadgets/exponential/exp10.hpp b/include/grotto/gadgets/exponential/exp10.hpp index fcf48bf..b2bb7b9 100644 --- a/include/grotto/gadgets/exponential/exp10.hpp +++ b/include/grotto/gadgets/exponential/exp10.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `exp10`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) exp10 { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return std::min(std::pow(10, static_cast(x)), std::numeric_limits::max()); } }; diff --git a/include/grotto/gadgets/exponential/exp2.hpp b/include/grotto/gadgets/exponential/exp2.hpp index 798acb6..8020178 100644 --- a/include/grotto/gadgets/exponential/exp2.hpp +++ b/include/grotto/gadgets/exponential/exp2.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `exp2`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) exp2 { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return std::min(std::exp2(static_cast(x)), std::numeric_limits::max()); } }; diff --git a/include/grotto/gadgets/hyperbolic/acosh.hpp b/include/grotto/gadgets/hyperbolic/acosh.hpp index ccbedb3..557710a 100644 --- a/include/grotto/gadgets/hyperbolic/acosh.hpp +++ b/include/grotto/gadgets/hyperbolic/acosh.hpp @@ -22,8 +22,17 @@ namespace gadgets // Returns the inverse hyperbolic cosine of a number. // The number must be greater than or equal to 1. +/// @brief Cleartext `acosh`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct acosh { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { if (x < 1) return -1; // TODO diff --git a/include/grotto/gadgets/hyperbolic/acoth.hpp b/include/grotto/gadgets/hyperbolic/acoth.hpp index ac89f84..f8149f1 100644 --- a/include/grotto/gadgets/hyperbolic/acoth.hpp +++ b/include/grotto/gadgets/hyperbolic/acoth.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `acoth`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct acoth { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { if (std::abs(x) <= 1) return 0; // TODO diff --git a/include/grotto/gadgets/hyperbolic/acsch.hpp b/include/grotto/gadgets/hyperbolic/acsch.hpp index 9a872d9..c1b665c 100644 --- a/include/grotto/gadgets/hyperbolic/acsch.hpp +++ b/include/grotto/gadgets/hyperbolic/acsch.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `acsch`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct acsch { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/hyperbolic/asech.hpp b/include/grotto/gadgets/hyperbolic/asech.hpp index 95c44b4..ea8f76f 100644 --- a/include/grotto/gadgets/hyperbolic/asech.hpp +++ b/include/grotto/gadgets/hyperbolic/asech.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `asech`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct asech { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/hyperbolic/asinh.hpp b/include/grotto/gadgets/hyperbolic/asinh.hpp index c4e44c8..c04bd97 100644 --- a/include/grotto/gadgets/hyperbolic/asinh.hpp +++ b/include/grotto/gadgets/hyperbolic/asinh.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `asinh`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct asinh { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return std::asinh(static_cast(x)); } }; diff --git a/include/grotto/gadgets/hyperbolic/atanh.hpp b/include/grotto/gadgets/hyperbolic/atanh.hpp index 48df989..44a499e 100644 --- a/include/grotto/gadgets/hyperbolic/atanh.hpp +++ b/include/grotto/gadgets/hyperbolic/atanh.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `atanh`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct atanh { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/hyperbolic/cosh.hpp b/include/grotto/gadgets/hyperbolic/cosh.hpp index 3d5d028..5660221 100644 --- a/include/grotto/gadgets/hyperbolic/cosh.hpp +++ b/include/grotto/gadgets/hyperbolic/cosh.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `cosh`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) cosh { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return std::min(std::cosh(static_cast(x)), std::numeric_limits::max()); } }; diff --git a/include/grotto/gadgets/hyperbolic/coth.hpp b/include/grotto/gadgets/hyperbolic/coth.hpp index 11af070..b0864a3 100644 --- a/include/grotto/gadgets/hyperbolic/coth.hpp +++ b/include/grotto/gadgets/hyperbolic/coth.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `coth`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) coth { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/hyperbolic/csch.hpp b/include/grotto/gadgets/hyperbolic/csch.hpp index f0abfc8..807abcc 100644 --- a/include/grotto/gadgets/hyperbolic/csch.hpp +++ b/include/grotto/gadgets/hyperbolic/csch.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `csch`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) csch { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/hyperbolic/sech.hpp b/include/grotto/gadgets/hyperbolic/sech.hpp index 3eef31a..8db68a3 100644 --- a/include/grotto/gadgets/hyperbolic/sech.hpp +++ b/include/grotto/gadgets/hyperbolic/sech.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `sech`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) sech { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return 1/std::cosh(static_cast(x)); } }; diff --git a/include/grotto/gadgets/hyperbolic/sinh.hpp b/include/grotto/gadgets/hyperbolic/sinh.hpp index d1791f9..6521a65 100644 --- a/include/grotto/gadgets/hyperbolic/sinh.hpp +++ b/include/grotto/gadgets/hyperbolic/sinh.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `sinh`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) sinh { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/hyperbolic/tanh.hpp b/include/grotto/gadgets/hyperbolic/tanh.hpp index 1fc93be..8a0b6a5 100644 --- a/include/grotto/gadgets/hyperbolic/tanh.hpp +++ b/include/grotto/gadgets/hyperbolic/tanh.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `tanh`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) tanh { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return std::tanh(static_cast(x)); } }; diff --git a/include/grotto/gadgets/logarithm/ilog10.hpp b/include/grotto/gadgets/logarithm/ilog10.hpp index 366e69f..7f1fb90 100644 --- a/include/grotto/gadgets/logarithm/ilog10.hpp +++ b/include/grotto/gadgets/logarithm/ilog10.hpp @@ -24,8 +24,17 @@ namespace gadgets HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `ilog10`. +/// @see grotto::exact_constant +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::exact_constant) ilog10 { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/logarithm/ilog16.hpp b/include/grotto/gadgets/logarithm/ilog16.hpp index d3566a7..3f73ea9 100644 --- a/include/grotto/gadgets/logarithm/ilog16.hpp +++ b/include/grotto/gadgets/logarithm/ilog16.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `ilog16`. +/// @see grotto::eval_ilog16 +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct ilog16 { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/logarithm/ilog256.hpp b/include/grotto/gadgets/logarithm/ilog256.hpp index 20ef567..9cdc7a0 100644 --- a/include/grotto/gadgets/logarithm/ilog256.hpp +++ b/include/grotto/gadgets/logarithm/ilog256.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `ilog256`. +/// @see grotto::eval_ilog256 +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct ilog256 { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/logarithm/ilogb.hpp b/include/grotto/gadgets/logarithm/ilogb.hpp index b499cd8..75798ce 100644 --- a/include/grotto/gadgets/logarithm/ilogb.hpp +++ b/include/grotto/gadgets/logarithm/ilogb.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `ilogb`. +/// @see grotto::exact_constant +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::exact_constant) ilogb { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/logarithm/lg.hpp b/include/grotto/gadgets/logarithm/lg.hpp index b7f0972..354170d 100644 --- a/include/grotto/gadgets/logarithm/lg.hpp +++ b/include/grotto/gadgets/logarithm/lg.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `lg`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) lg { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/logarithm/ln.hpp b/include/grotto/gadgets/logarithm/ln.hpp index cf205b0..00c5c53 100644 --- a/include/grotto/gadgets/logarithm/ln.hpp +++ b/include/grotto/gadgets/logarithm/ln.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `ln`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) ln { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/logarithm/log10.hpp b/include/grotto/gadgets/logarithm/log10.hpp index d49002e..fdfd244 100644 --- a/include/grotto/gadgets/logarithm/log10.hpp +++ b/include/grotto/gadgets/logarithm/log10.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `log10`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) log10 { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/logarithm/logn.hpp b/include/grotto/gadgets/logarithm/logn.hpp index ac27633..c602757 100644 --- a/include/grotto/gadgets/logarithm/logn.hpp +++ b/include/grotto/gadgets/logarithm/logn.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/logarithm/logstar.hpp b/include/grotto/gadgets/logarithm/logstar.hpp index 11beaec..cca7e40 100644 --- a/include/grotto/gadgets/logarithm/logstar.hpp +++ b/include/grotto/gadgets/logarithm/logstar.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_logstar } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/misc/entropy.hpp b/include/grotto/gadgets/misc/entropy.hpp index 33caa78..b49a0e8 100644 --- a/include/grotto/gadgets/misc/entropy.hpp +++ b/include/grotto/gadgets/misc/entropy.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `entropy`. +/// @see grotto::gadgets::ln +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct entropy { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/misc/erf.hpp b/include/grotto/gadgets/misc/erf.hpp index 9d8a37d..041c024 100644 --- a/include/grotto/gadgets/misc/erf.hpp +++ b/include/grotto/gadgets/misc/erf.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `erf`. +/// @see grotto::eval_window +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) erf { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { std::erf(static_cast(x)); } }; diff --git a/include/grotto/gadgets/misc/erfc.hpp b/include/grotto/gadgets/misc/erfc.hpp index ea3b6d7..627f027 100644 --- a/include/grotto/gadgets/misc/erfc.hpp +++ b/include/grotto/gadgets/misc/erfc.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `erfc`. +/// @see grotto::eval_window +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) erfc { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return std::erfc(static_cast(x)); } }; diff --git a/include/grotto/gadgets/misc/expint.hpp b/include/grotto/gadgets/misc/expint.hpp index 1922fd9..934d0cd 100644 --- a/include/grotto/gadgets/misc/expint.hpp +++ b/include/grotto/gadgets/misc/expint.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/misc/gamma.hpp b/include/grotto/gadgets/misc/gamma.hpp index 023cc45..bfb7e9a 100644 --- a/include/grotto/gadgets/misc/gamma.hpp +++ b/include/grotto/gadgets/misc/gamma.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/misc/i0.hpp b/include/grotto/gadgets/misc/i0.hpp index 1fccc2f..5b123f0 100644 --- a/include/grotto/gadgets/misc/i0.hpp +++ b/include/grotto/gadgets/misc/i0.hpp @@ -17,6 +17,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/misc/lgamma.hpp b/include/grotto/gadgets/misc/lgamma.hpp index d268f2e..f99405b 100644 --- a/include/grotto/gadgets/misc/lgamma.hpp +++ b/include/grotto/gadgets/misc/lgamma.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/misc/reimann_zeta.hpp b/include/grotto/gadgets/misc/reimann_zeta.hpp index efe592c..46dc578 100644 --- a/include/grotto/gadgets/misc/reimann_zeta.hpp +++ b/include/grotto/gadgets/misc/reimann_zeta.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/misc/sinc.hpp b/include/grotto/gadgets/misc/sinc.hpp index 684a602..65dbf6b 100644 --- a/include/grotto/gadgets/misc/sinc.hpp +++ b/include/grotto/gadgets/misc/sinc.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/powers/cbrt.hpp b/include/grotto/gadgets/powers/cbrt.hpp index 3ad7960..21c595f 100644 --- a/include/grotto/gadgets/powers/cbrt.hpp +++ b/include/grotto/gadgets/powers/cbrt.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `cbrt`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct cbrt { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/powers/icbrt.hpp b/include/grotto/gadgets/powers/icbrt.hpp index 0d82449..46eaed2 100644 --- a/include/grotto/gadgets/powers/icbrt.hpp +++ b/include/grotto/gadgets/powers/icbrt.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `icbrt`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct icbrt { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/powers/iqtrt.hpp b/include/grotto/gadgets/powers/iqtrt.hpp index adc0cb4..550bc5b 100644 --- a/include/grotto/gadgets/powers/iqtrt.hpp +++ b/include/grotto/gadgets/powers/iqtrt.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `iqtrt`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct iqtrt { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/powers/isqrt.hpp b/include/grotto/gadgets/powers/isqrt.hpp index 5f180a6..4e7a4ed 100644 --- a/include/grotto/gadgets/powers/isqrt.hpp +++ b/include/grotto/gadgets/powers/isqrt.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `isqrt`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) isqrt { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/powers/qtrt.hpp b/include/grotto/gadgets/powers/qtrt.hpp index 29b9020..d45fd28 100644 --- a/include/grotto/gadgets/powers/qtrt.hpp +++ b/include/grotto/gadgets/powers/qtrt.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `qtrt`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct qtrt { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/powers/reciprocal.hpp b/include/grotto/gadgets/powers/reciprocal.hpp index 1e9f6d8..9b349e5 100644 --- a/include/grotto/gadgets/powers/reciprocal.hpp +++ b/include/grotto/gadgets/powers/reciprocal.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `reciprocal`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) reciprocal { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/powers/sqrt.hpp b/include/grotto/gadgets/powers/sqrt.hpp index 453033b..7acce15 100644 --- a/include/grotto/gadgets/powers/sqrt.hpp +++ b/include/grotto/gadgets/powers/sqrt.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `sqrt`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) sqrt { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/quantile/cauchy.hpp b/include/grotto/gadgets/quantile/cauchy.hpp index 9ef7d3b..89abde3 100644 --- a/include/grotto/gadgets/quantile/cauchy.hpp +++ b/include/grotto/gadgets/quantile/cauchy.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_closed } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/quantile/chisquared.hpp b/include/grotto/gadgets/quantile/chisquared.hpp index 276a458..517b65e 100644 --- a/include/grotto/gadgets/quantile/chisquared.hpp +++ b/include/grotto/gadgets/quantile/chisquared.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/quantile/exponential.hpp b/include/grotto/gadgets/quantile/exponential.hpp index e77e4b4..659b1ce 100644 --- a/include/grotto/gadgets/quantile/exponential.hpp +++ b/include/grotto/gadgets/quantile/exponential.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_closed } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/quantile/gamma.hpp b/include/grotto/gadgets/quantile/gamma.hpp index 03f0ebc..920f478 100644 --- a/include/grotto/gadgets/quantile/gamma.hpp +++ b/include/grotto/gadgets/quantile/gamma.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/quantile/gaussian.hpp b/include/grotto/gadgets/quantile/gaussian.hpp index 44360bd..c91a9d6 100644 --- a/include/grotto/gadgets/quantile/gaussian.hpp +++ b/include/grotto/gadgets/quantile/gaussian.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. The fixed-point probit is `eval_window(window::probit, ...)`. +/// \complexity Not stated here. `eval_window` binary-searches its piece table and evaluates one cubic. +/// @see grotto::eval_window } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/quantile/geometric.hpp b/include/grotto/gadgets/quantile/geometric.hpp index 207f5c8..fdb6c1f 100644 --- a/include/grotto/gadgets/quantile/geometric.hpp +++ b/include/grotto/gadgets/quantile/geometric.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/quantile/laplace.hpp b/include/grotto/gadgets/quantile/laplace.hpp index 2e2ce86..54d4b38 100644 --- a/include/grotto/gadgets/quantile/laplace.hpp +++ b/include/grotto/gadgets/quantile/laplace.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_closed } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/quantile/logistic.hpp b/include/grotto/gadgets/quantile/logistic.hpp index 3cd53c0..86135f6 100644 --- a/include/grotto/gadgets/quantile/logistic.hpp +++ b/include/grotto/gadgets/quantile/logistic.hpp @@ -16,6 +16,9 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::eval_closed } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/quantile/lognormal.hpp b/include/grotto/gadgets/quantile/lognormal.hpp index 2d87795..de5a495 100644 --- a/include/grotto/gadgets/quantile/lognormal.hpp +++ b/include/grotto/gadgets/quantile/lognormal.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/quantile/pareto.hpp b/include/grotto/gadgets/quantile/pareto.hpp index 4a08bc0..c712c4a 100644 --- a/include/grotto/gadgets/quantile/pareto.hpp +++ b/include/grotto/gadgets/quantile/pareto.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/quantile/poisson.hpp b/include/grotto/gadgets/quantile/poisson.hpp index 6f99125..a66f591 100644 --- a/include/grotto/gadgets/quantile/poisson.hpp +++ b/include/grotto/gadgets/quantile/poisson.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/quantile/powerlaw.hpp b/include/grotto/gadgets/quantile/powerlaw.hpp index ab9db2b..85992cc 100644 --- a/include/grotto/gadgets/quantile/powerlaw.hpp +++ b/include/grotto/gadgets/quantile/powerlaw.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/quantile/standard_t.hpp b/include/grotto/gadgets/quantile/standard_t.hpp index 1d02ac1..9274cf5 100644 --- a/include/grotto/gadgets/quantile/standard_t.hpp +++ b/include/grotto/gadgets/quantile/standard_t.hpp @@ -16,6 +16,10 @@ namespace gadgets +/// @note This header declares no callable. +/// Complexity is stated on the sibling that evaluates the map, when one exists. +/// @see grotto::gadget_hints +/// @note No fixed-point table in `eval_closed`, `eval_window`, or `eval_reduced` is named after this file. Complexity is not stated here. } // namespace gadgets } // namespace grotto diff --git a/include/grotto/gadgets/trigonometric/acos.hpp b/include/grotto/gadgets/trigonometric/acos.hpp index 5f32f22..1b8a879 100644 --- a/include/grotto/gadgets/trigonometric/acos.hpp +++ b/include/grotto/gadgets/trigonometric/acos.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `acos`. +/// @see grotto::eval_window +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) acos { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/trigonometric/acot.hpp b/include/grotto/gadgets/trigonometric/acot.hpp index 1d03b8d..e010eef 100644 --- a/include/grotto/gadgets/trigonometric/acot.hpp +++ b/include/grotto/gadgets/trigonometric/acot.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `acot`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct acot { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/trigonometric/acsc.hpp b/include/grotto/gadgets/trigonometric/acsc.hpp index 5b723b5..6c95d62 100644 --- a/include/grotto/gadgets/trigonometric/acsc.hpp +++ b/include/grotto/gadgets/trigonometric/acsc.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `acsc`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct acsc { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/trigonometric/asec.hpp b/include/grotto/gadgets/trigonometric/asec.hpp index 6fe86a2..60b136f 100644 --- a/include/grotto/gadgets/trigonometric/asec.hpp +++ b/include/grotto/gadgets/trigonometric/asec.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `asec`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct asec { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/trigonometric/asin.hpp b/include/grotto/gadgets/trigonometric/asin.hpp index b187c4a..f62ca56 100644 --- a/include/grotto/gadgets/trigonometric/asin.hpp +++ b/include/grotto/gadgets/trigonometric/asin.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `asin`. +/// @see grotto::eval_window +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_window) asin { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/trigonometric/atan.hpp b/include/grotto/gadgets/trigonometric/atan.hpp index 1fef2d8..29ff490 100644 --- a/include/grotto/gadgets/trigonometric/atan.hpp +++ b/include/grotto/gadgets/trigonometric/atan.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `atan`. +/// @see grotto::eval_closed +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct atan { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { return std::atan(static_cast(x)); } }; diff --git a/include/grotto/gadgets/trigonometric/cos.hpp b/include/grotto/gadgets/trigonometric/cos.hpp index c46c53f..0b9d318 100644 --- a/include/grotto/gadgets/trigonometric/cos.hpp +++ b/include/grotto/gadgets/trigonometric/cos.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `cos`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) cos { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/trigonometric/cot.hpp b/include/grotto/gadgets/trigonometric/cot.hpp index 8154da8..0d1cfe1 100644 --- a/include/grotto/gadgets/trigonometric/cot.hpp +++ b/include/grotto/gadgets/trigonometric/cot.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `cot`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) cot { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/trigonometric/csc.hpp b/include/grotto/gadgets/trigonometric/csc.hpp index acdeb74..a00677d 100644 --- a/include/grotto/gadgets/trigonometric/csc.hpp +++ b/include/grotto/gadgets/trigonometric/csc.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `csc`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) csc { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/trigonometric/deg2rad.hpp b/include/grotto/gadgets/trigonometric/deg2rad.hpp index dcd9395..5a7c9bb 100644 --- a/include/grotto/gadgets/trigonometric/deg2rad.hpp +++ b/include/grotto/gadgets/trigonometric/deg2rad.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `deg2rad`. +/// @see grotto::eval_deg2rad +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct deg2rad { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { double X = std::fmod(static_cast(x), 360); diff --git a/include/grotto/gadgets/trigonometric/rad2deg.hpp b/include/grotto/gadgets/trigonometric/rad2deg.hpp index 979c4d0..db48a7b 100644 --- a/include/grotto/gadgets/trigonometric/rad2deg.hpp +++ b/include/grotto/gadgets/trigonometric/rad2deg.hpp @@ -20,8 +20,17 @@ namespace grotto namespace gadgets { +/// @brief Cleartext `rad2deg`. +/// @see grotto::eval_rad2deg +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct rad2deg { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { double X = std::fmod(static_cast(x), 2*M_PI); diff --git a/include/grotto/gadgets/trigonometric/sec.hpp b/include/grotto/gadgets/trigonometric/sec.hpp index 4152504..190fd9a 100644 --- a/include/grotto/gadgets/trigonometric/sec.hpp +++ b/include/grotto/gadgets/trigonometric/sec.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `sec`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) sec { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/trigonometric/sin.hpp b/include/grotto/gadgets/trigonometric/sin.hpp index 828cb67..1fb9433 100644 --- a/include/grotto/gadgets/trigonometric/sin.hpp +++ b/include/grotto/gadgets/trigonometric/sin.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `sin`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) sin { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/gadgets/trigonometric/tan.hpp b/include/grotto/gadgets/trigonometric/tan.hpp index bca171c..0f15f24 100644 --- a/include/grotto/gadgets/trigonometric/tan.hpp +++ b/include/grotto/gadgets/trigonometric/tan.hpp @@ -24,8 +24,17 @@ HEDLEY_DIAGNOSTIC_PUSH HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED +/// @brief Cleartext `tan`. +/// @see grotto::eval_reduced +/// @note Straight-line cleartext. Fixed-point evaluation is the symbol in `@see` when that symbol is a LUT or an `eval_*` function. +/// \complexity One evaluation of `operator()` as written in this header. There is no domain scan and no loop. `Θ(1)` time and extra space relative to that expression. struct HEDLEY_DEPRECATED_FOR(2026, grotto::eval_reduced) tan { + /// @brief Evaluate the cleartext map. + /// @tparam T argument and result type + /// @param x the input + /// @return the cleartext image of `x` + /// \complexity The body is straight-line. `Θ(1)` time and extra space. template T operator()(T x) { diff --git a/include/grotto/hexfloat.hpp b/include/grotto/hexfloat.hpp index a51d18c..6e2acb0 100644 --- a/include/grotto/hexfloat.hpp +++ b/include/grotto/hexfloat.hpp @@ -28,6 +28,10 @@ namespace grotto { +/// \complexity Extracts the IEEE fields and prints a fixed-size mantissa. `Θ(1)`. +/// @see grotto::from_hexfloat +/// @param x the double +/// @return the hexfloat spelling template , @@ -339,7 +343,7 @@ inline void shift_right_limbs(std::vector & limbs, unsigned shift /// significand * 2^(exponent + fractional_bits), floored toward -inf on the /// discarded fraction and wrapped modulo 2^width. /// @tparam T value type -/// @param text the `text` +/// @param text hexfloat spelling /// @param fractional_bits the number of fractional bits /// @return the returned `T` /// @throws std::invalid_argument if `empty hexfloat` @@ -473,6 +477,8 @@ T integer_from_hexfloat(std::string_view text, int fractional_bits) } } // namespace detail +/// \complexity `format_hexfloat` walks the bits below the highest set bit, four per nibble. `Θ(width)` with `width = bitlength_of_v` (at most 256). Extra space is the nibble string, `Θ(width)`. +/// @see grotto::fixedpoint template std::enable_if_t, std::string> @@ -480,12 +486,21 @@ to_hexfloat(T value) { return detail::format_hexfloat(value, 0); } +/// \complexity Forwards the raw word to `format_hexfloat` with `FractionalBits` as the binary point. `Θ(backend width)`. +/// @see grotto::fixedpoint +/// @note Prints the mathematical value of the fixed-point word, using `integral_representation()`. template std::string to_hexfloat(fixedpoint value) { return detail::format_hexfloat(value.integral_representation(), FractionalBits); } +/// \complexity Scans the text once. Integer and fixed-point paths shift a limb vector by the exponent. Time `Θ(digits + |exponent shift|)`. Extra space is that limb vector. +/// A `double` target uses `strtod`. +/// @see grotto::to_hexfloat +/// @note Fixed-point parsing is bit-exact into `from_raw` / `make_fixed_from_integral_type`: discarded fraction bits are floored, and the word wraps modulo `2^width`. +/// @param text hexfloat spelling +/// @return the parsed value template T from_hexfloat(std::string_view text) diff --git a/include/grotto/lut_union.hpp b/include/grotto/lut_union.hpp new file mode 100644 index 0000000..3c774ee --- /dev/null +++ b/include/grotto/lut_union.hpp @@ -0,0 +1,601 @@ +/// @file grotto/lut_union.hpp +/// @brief One comparison for several piecewise LUTs. +/// @details The breakpoints of every LUT are shifted by the public `eta` and +/// refined with the same carry cuts as offset Horner. Their union is +/// one sorted knot vector. One comparison, payload +/// `1, center, …, center^d` at the maximum degree, then one +/// prefix-parity walk of that union. Each LUT piece is a circular +/// span of those union knots (one polynomial, one public `kappa`), +/// so the functions are independent dots of the same segment table. +/// +/// The geneval schedule is one full-depth `fss_cmp`. Its round count +/// is the input bitlength. It does not grow with the number of LUTs +/// or the number of union knots. Prefix parity stays local. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_GROTTO_LUT_UNION_HPP__ +#define LIBDPF_INCLUDE_GROTTO_LUT_UNION_HPP__ + +#include "hedley/hedley.h" + +#include "dpf/compose.hpp" +#include "grotto/constant_lut.hpp" +#include "grotto/easy_lut.hpp" +#include "grotto/offset_poly.hpp" + +#include +#include +#include +#include +#include +#include +#include + +namespace grotto +{ + +/// @brief Public piecewise polynomial. `knots` are strictly increasing left +/// endpoints. `coeff[i][k]` is the degree-`k` coefficient of that piece +/// in `Z/2^64`. Every row of one LUT has the same length. +/// @tparam InputT input domain type +template +struct piecewise_lut +{ + static_assert(std::is_integral_v, "lut union domain must be an integer group"); + + std::vector knots; + std::vector> coeff; +}; + +/// @brief One refined piece of one LUT, as a circular span of the union. +/// @details `coeff` is already the binomial shift by `kappa`. The dot with +/// segment shares of `center^m` is the piece's contribution. +/// Indices run over `lut_union_plan::knots`. When `begin <= end` the +/// span is `[begin, end)`. When `begin > end` it wraps: +/// `[begin, knots) ∪ [0, end)`. +/// @tparam InputT input domain type +template +struct lut_span +{ + std::size_t begin = 0; + std::size_t end = 0; + std::int64_t kappa = 0; + std::vector coeff; +}; + +/// @brief Union of several LUTs at one public `eta`, plus the geneval shape. +/// @tparam InputT input domain type +template +struct lut_union_plan +{ + static_assert(std::is_integral_v, "lut union domain must be an integer group"); + + /// @brief One comparison, however many LUTs and knots are in the union. + static constexpr std::size_t comparisons = 1; + /// @brief One memoized prefix-parity walk of `knots`. Local: no rounds. + static constexpr std::size_t prefix_walks = 1; + + /// @brief Public offset the knots were shifted by. + InputT eta{}; + /// @brief Maximum degree across the LUTs. The comparison payload has `lanes` words. + std::size_t degree = 0; + /// @brief `degree + 1`. + std::size_t lanes = 0; + /// @brief Geneval / comparison depth: bitlength of `InputT`. One correction per level. + std::size_t depth = 0; + /// @brief Union of the refined, `eta`-shifted knots. Sorted, unique. + std::vector knots; + /// @brief `funcs[t]` is LUT `t`, in the order passed to `make_lut_union_plan`. + std::vector>> funcs; + + /// @brief Number of union breakpoints the prefix walk visits. + HEDLEY_NO_THROW + std::size_t endpoints() const noexcept { return knots.size(); } + + /// @brief Interactive geneval rounds: one correction word per input bit. + HEDLEY_NO_THROW + std::size_t geneval_rounds() const noexcept { return depth; } +}; + +/// @brief Comparison slot for `schedule_lut_union`. +/// @details One AES block, or the power-vector width when that is wider. +/// @param lanes payload lanes (`degree + 1`) +/// @return Slot width in bytes +/// \complexity `Θ(1)`. +inline std::size_t lut_union_slot_bytes(std::size_t lanes) +{ + const std::size_t value = lanes * sizeof(std::uint64_t); + return value < 16u ? 16u : value; +} + +/// @brief Exact `easy_lut` as a piecewise program. +/// @details A denominator other than 1 is a rounding division. That is not a +/// dot in `Z/2^64`, so those tables are rejected. Trailing powers that +/// are zero on every piece are dropped. +/// @tparam Raw signed raw word +/// @param lut the cleartext table +/// @return Piecewise program on the same bounds +/// @throws std::invalid_argument if a denominator is not 1, or the table is empty +/// \complexity One pass over the pieces. `Θ(P)`. +/// @see grotto::easy_lut +template +piecewise_lut piecewise_from_easy(const easy_lut & lut) +{ + if (lut.bounds.empty() || lut.bounds.size() != lut.c0.size() + || lut.c0.size() != lut.c1.size() || lut.c1.size() != lut.c2.size() + || lut.c2.size() != lut.den.size()) + throw std::invalid_argument("lut union: easy lut pieces are incomplete"); + std::size_t width = 1; + for (std::size_t i = 0; i < lut.den.size(); ++i) + { + if (lut.den[i] != 1) + throw std::invalid_argument( + "lut union: easy lut denominator is not an exact Z/2^64 dot"); + if (lut.c1[i] != 0) + width = std::max(width, 2); + if (lut.c2[i] != 0) + width = std::max(width, 3); + } + piecewise_lut out; + out.knots = lut.bounds; + out.coeff.resize(lut.bounds.size()); + for (std::size_t i = 0; i < lut.bounds.size(); ++i) + { + const uint64_t row[3] = { + static_cast(lut.c0[i]), + static_cast(lut.c1[i]), + static_cast(lut.c2[i])}; + out.coeff[i].assign(row, row + width); + } + return out; +} + +/// @brief Degree-0 `constant_lut` as a piecewise program. +/// @tparam Raw signed raw word +/// @param lut the cleartext table +/// @return One constant coefficient per bound +/// @throws std::invalid_argument if the table is empty or mis-sized +/// \complexity One pass over the pieces. `Θ(P)`. +/// @see grotto::constant_lut +template +piecewise_lut piecewise_from_constant(const constant_lut & lut) +{ + if (lut.bounds.empty() || lut.bounds.size() != lut.values.size()) + throw std::invalid_argument("lut union: constant lut pieces are incomplete"); + piecewise_lut out; + out.knots = lut.bounds; + out.coeff.resize(lut.values.size()); + for (std::size_t i = 0; i < lut.values.size(); ++i) + out.coeff[i] = {static_cast(lut.values[i])}; + return out; +} + +namespace lut_union_detail +{ + +template +std::size_t knot_index(const std::vector & knots, InputT knot) +{ + const auto it = std::lower_bound(knots.begin(), knots.end(), knot); + if (it == knots.end() || *it != knot) + throw std::logic_error("lut union: refined knot missing from the union"); + return static_cast(it - knots.begin()); +} + +template +void mark_span(std::vector & seen, const lut_span & span, + std::size_t n) +{ + const auto mark = [&](std::size_t j) { + if (j >= n || seen[j] != 0) + throw std::logic_error("lut union: piece spans overlap or leave the union"); + seen[j] = 1; + }; + if (span.begin <= span.end) + { + for (std::size_t j = span.begin; j < span.end; ++j) + mark(j); + } + else + { + for (std::size_t j = span.begin; j < n; ++j) + mark(j); + for (std::size_t j = 0; j < span.end; ++j) + mark(j); + } +} + +template +uint64_t dot_span(std::size_t n, std::size_t begin, std::size_t end, + const std::vector & coeff, At && at) +{ + uint64_t value = 0; + const auto visit = [&](std::size_t j) { + for (std::size_t m = 0; m < coeff.size(); ++m) + value += at(j, m) * coeff[m]; + }; + if (begin <= end) + { + for (std::size_t j = begin; j < end; ++j) + visit(j); + } + else + { + for (std::size_t j = begin; j < n; ++j) + visit(j); + for (std::size_t j = 0; j < end; ++j) + visit(j); + } + return value; +} + +template +std::vector dot_plan(const lut_union_plan & plan, const Table & table) +{ + const std::size_t n = plan.knots.size(); + std::vector out(plan.funcs.size(), 0); + for (std::size_t f = 0; f < plan.funcs.size(); ++f) + { + for (const auto & span : plan.funcs[f]) + { + if (span.coeff.size() > plan.lanes) + throw std::invalid_argument("lut union: piece wider than the plan"); + out[f] += dot_span(n, span.begin, span.end, span.coeff, + [&](std::size_t j, std::size_t m) { return table[j][m]; }); + } + } + return out; +} + +} // namespace lut_union_detail + +/// @brief Union the refined breakpoints and record each LUT's spans. +/// @tparam InputT input domain type +/// @param luts piecewise programs on the same domain +/// @param eta public offset `eta = x - r` +/// @return Plan whose geneval depth is `bitlength(InputT)` and whose +/// comparison count is 1 +/// @throws std::invalid_argument if `luts` is empty, a degree exceeds 16, or a +/// LUT's knots and coefficient rows disagree +/// \complexity Each LUT is prepared once (`Θ(P log P)` per LUT, including the +/// carry cuts). The union sort is `Θ(U log U)` for `U` the total refined +/// knots. Building the spans is `Θ(U)`. No keys. +/// \rounds None. +/// \communication None. +/// @see grotto::lut_union_eval +/// @see grotto::schedule_lut_union +template +lut_union_plan make_lut_union_plan( + const std::vector> & luts, InputT eta) +{ + if (luts.empty()) + throw std::invalid_argument("lut union: no luts"); + + using prepared = offset_poly_detail::prepared; + std::vector> refined; + refined.reserve(luts.size()); + std::size_t degree = 0; + std::vector knots; + for (const auto & lut : luts) + { + if (lut.coeff.empty() || lut.coeff.front().empty()) + throw std::invalid_argument("lut union: coefficient row is empty"); + const std::size_t width = lut.coeff.front().size(); + if (width - 1 > offset_poly_max_degree) + throw std::invalid_argument("lut union: degree exceeds 16"); + degree = std::max(degree, width - 1); + auto rows = offset_poly_detail::prepare(lut.knots, lut.coeff, eta); + for (const auto & row : rows) + knots.push_back(row.knot); + refined.push_back(std::move(rows)); + } + std::sort(knots.begin(), knots.end()); + knots.erase(std::unique(knots.begin(), knots.end()), knots.end()); + + lut_union_plan plan; + plan.eta = eta; + plan.degree = degree; + plan.lanes = degree + 1; + plan.depth = dpf::utils::bitlength_of_v; + plan.knots = std::move(knots); + plan.funcs.resize(refined.size()); + + const std::size_t n = plan.knots.size(); + for (std::size_t f = 0; f < refined.size(); ++f) + { + const auto & rows = refined[f]; + std::vector seen(n, 0); + plan.funcs[f].reserve(rows.size()); + if (rows.size() == 1) + { + lut_span span; + span.begin = 0; + span.end = n; + span.kappa = rows[0].kappa; + span.coeff = offset_poly_detail::binomial_shift( + rows[0].coeff, static_cast(rows[0].kappa)); + lut_union_detail::mark_span(seen, span, n); + plan.funcs[f].push_back(std::move(span)); + } + else + { + for (std::size_t i = 0; i < rows.size(); ++i) + { + lut_span span; + span.begin = lut_union_detail::knot_index(plan.knots, rows[i].knot); + const std::size_t next = (i + 1 == rows.size()) ? 0 : i + 1; + span.end = lut_union_detail::knot_index(plan.knots, rows[next].knot); + span.kappa = rows[i].kappa; + span.coeff = offset_poly_detail::binomial_shift( + rows[i].coeff, static_cast(rows[i].kappa)); + lut_union_detail::mark_span(seen, span, n); + plan.funcs[f].push_back(std::move(span)); + } + } + for (unsigned char bit : seen) + { + if (bit == 0) + throw std::logic_error("lut union: a union knot is outside every piece"); + } + } + return plan; +} + +/// @brief Each LUT's share, from one segment walk of the union. +/// @tparam Party party index, `0` or `1` +/// @tparam InputT input domain type +/// @param mat one comparison whose degree is at least `plan.degree` +/// @param plan the union plan +/// @param tokens proof token folded by the segment walk, or null +/// @return `out[t]` is party `Party`'s share of LUT `t` +/// @throws std::invalid_argument if the key is narrower than the plan +/// \complexity One `lane_segments` walk of the union (`prefix_walks == 1`), +/// then a dot per LUT piece. The walk is `signed` prefix parity over `U` +/// endpoints of a `lanes`-wide payload, reusing the common prefix. +/// Arithmetic after the walk is `Θ(Σ pieces · degree)`. +/// \rounds None. `eta` is already in the plan. +/// \communication None. +/// \preprocessing None created here. Uses `make_offset_poly_keys` at `plan.degree`. +/// @see grotto::offset_poly_eval +/// @see grotto::geneval_lut_union +template +std::vector lut_union_eval( + const offset_poly_keys & mat, + const lut_union_plan & plan, + dpf::proof_token * tokens = nullptr) +{ + static_assert(Party < 2, "lut union party is 0 or 1"); + using namespace offset_horner_detail; + if (mat.degree < plan.degree) + throw std::invalid_argument("lut union: key degree is below the union"); + const std::size_t lanes = mat.verifiable ? mat.keys_v.index() : mat.keys.index(); + if (lanes != mat.degree + 1) + throw std::invalid_argument("lut union: comparison payload width differs from the degree"); + dpf::proof_token * pi = (mat.verifiable && tokens != nullptr) ? &tokens[0] : nullptr; + const auto table = mat.verifiable + ? lane_segments(mat.keys_v, plan.knots, mat.wrap_share, pi) + : lane_segments(mat.keys, plan.knots, mat.wrap_share, nullptr); + if (mat.verifiable) + replicate_proof(tokens, mat.degree + 1); + return lut_union_detail::dot_plan(plan, table); +} + +/// @brief Both parties' LUT shares from one Doerner–Shelat comparison. +/// @tparam InputT input domain type +template +struct geneval_lut_union_result +{ + /// @brief Public offset copied from the plan. + InputT eta{}; + std::vector value0; + std::vector value1; +}; + +namespace lut_union_detail +{ + +template +geneval_lut_union_result geneval_from_keys( + const Keys & keys, const lut_union_plan & plan, const uint64_t * payload) +{ + std::array wrap0{}; + std::array wrap1{}; + for (std::size_t m = 0; m < N; ++m) + { + const uint64_t blind = dpf::uniform_sample(); + wrap0[m] = blind; + wrap1[m] = payload[m] - blind; + } + const auto seg0 = offset_horner_detail::segments_lanes( + keys.first, plan.knots, wrap0, nullptr); + const auto seg1 = offset_horner_detail::segments_lanes( + keys.second, plan.knots, wrap1, nullptr); + + const std::size_t pieces = plan.knots.size(); + std::vector> table0(pieces, std::vector(N)); + std::vector> table1(pieces, std::vector(N)); + for (std::size_t m = 0; m < N; ++m) + { + for (std::size_t j = 0; j < pieces; ++j) + { + table0[j][m] = seg0[m][j]; + table1[j][m] = seg1[m][j]; + } + } + + geneval_lut_union_result out; + out.eta = plan.eta; + out.value0 = dot_plan(plan, table0); + out.value1 = dot_plan(plan, table1); + return out; +} + +template +geneval_lut_union_result geneval_lut_union_n( + bool arith, InputT center0, InputT center1, + const lut_union_plan & plan, const uint64_t * payload, Rng rng) +{ + dpf::vec beta; + for (std::size_t m = 0; m < N; ++m) + beta[m] = payload[m]; + if (arith) + { + auto keys = dpf::make_dpf_doerner_shelat(dpf::arith_input, center0, center1, + std::move(rng), dpf::gt(beta), dpf::verifiable{}); + return geneval_from_keys(keys, plan, payload); + } + auto keys = dpf::make_dpf_doerner_shelat(center0, center1, + std::move(rng), dpf::gt(beta), dpf::verifiable{}); + return geneval_from_keys(keys, plan, payload); +} + +template +geneval_lut_union_result geneval_dispatch( + bool arith, InputT center0, InputT center1, + const lut_union_plan & plan, const uint64_t * payload, Rng & rng) +{ + if (plan.lanes == N) + return geneval_lut_union_n(arith, center0, center1, plan, payload, + std::move(rng)); + if constexpr (N > 1) + return geneval_dispatch(arith, center0, center1, plan, payload, rng); + throw std::invalid_argument("lut union: lane count out of range"); +} + +template +geneval_lut_union_result geneval_lut_union_at( + bool arith, InputT center0, InputT center1, InputT center, + const lut_union_plan & plan, Rng rng) +{ + if (plan.lanes == 0 || plan.lanes > offset_horner_detail::lane_key_max) + throw std::invalid_argument("lut union: lane count out of range"); + if (plan.knots.empty()) + throw std::invalid_argument("lut union: plan has no knots"); + std::vector payload(plan.lanes, 1); + const uint64_t base = offset_horner_detail::lift(center); + for (std::size_t m = 1; m < plan.lanes; ++m) + payload[m] = payload[m - 1] * base; + return geneval_dispatch( + arith, center0, center1, plan, payload.data(), rng); +} + +} // namespace lut_union_detail + +/// @brief Geneval of every LUT. The center is XOR-shared as in `geneval_point`. +/// @details One Doerner–Shelat comparison of `plan.lanes` words, then the same +/// local span dots as `lut_union_eval`. Further LUTs do not add a +/// comparison or a prefix walk. +/// @tparam InputT input domain type +/// @tparam Rng Doerner–Shelat randomness +/// @param center0 party 0 share of the center +/// @param center1 party 1 share of the center +/// @param plan the union plan +/// @param rng the Doerner–Shelat randomness tapes +/// @return Both parties' shares of every LUT +/// \complexity One Doerner–Shelat generation of a `plan.lanes` comparison +/// (`degree ≤ 16`), then one prefix-parity walk of the `U` union knots. +/// The dots are `Θ(Σ pieces · degree)`. +/// @note Rounds of that comparison are `plan.geneval_rounds()` (`bitlength` of +/// the input). They are not multiplied by the LUT count or by `U`. +/// \preprocessing The randomness object the caller passes (`Rng`). This function +/// also samples one `uint64_t` blind per power. +/// @see grotto::geneval_offset_horner +/// @see grotto::schedule_lut_union +template +geneval_lut_union_result geneval_lut_union( + InputT center0, InputT center1, + const lut_union_plan & plan, Rng rng) +{ + const InputT center = geneval_offset_horner_center(center0, center1); + return lut_union_detail::geneval_lut_union_at( + false, center0, center1, center, plan, std::move(rng)); +} + +/// @brief Same as `geneval_lut_union`, with the library's urandom pad tape. +/// \complexity Same as the overload that takes `Rng`. +/// \preprocessing Samples a `dpf::ds_randomness` tape from `uniform_sample`. +/// @see grotto::geneval_lut_union +template +geneval_lut_union_result geneval_lut_union( + InputT center0, InputT center1, const lut_union_plan & plan) +{ + using block = typename dpf::prg::aes128::block_type; + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + dpf::ds_randomness rng{ + dpf::uniform_sample, {}}; + HEDLEY_PRAGMA(GCC diagnostic pop) + return geneval_lut_union(center0, center1, plan, std::move(rng)); +} + +/// @brief Geneval when `center0 + center1` is the center in the input group. +/// \complexity Same as the XOR-share overload: one comparison, one prefix walk. +/// @see grotto::geneval_lut_union +template +geneval_lut_union_result geneval_lut_union( + dpf::arith_input_t, InputT center0, InputT center1, + const lut_union_plan & plan, Rng rng) +{ + const InputT center = offset_horner_group_add(center0, center1); + return lut_union_detail::geneval_lut_union_at( + true, center0, center1, center, plan, std::move(rng)); +} + +/// @brief Additive-share geneval with the library's urandom pad tape. +/// \complexity Same as the overload that takes `Rng`. +/// @see grotto::geneval_lut_union +template +geneval_lut_union_result geneval_lut_union( + dpf::arith_input_t, InputT center0, InputT center1, + const lut_union_plan & plan) +{ + using block = typename dpf::prg::aes128::block_type; + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + dpf::ds_randomness rng{ + dpf::uniform_sample, {}}; + HEDLEY_PRAGMA(GCC diagnostic pop) + return geneval_lut_union(dpf::arith_input, center0, center1, plan, std::move(rng)); +} + +/// @brief Record one full-depth comparison on an existing seed. +/// @details Does not walk the union knots and does not emit a node per LUT. +/// Prefix parity of `plan.knots` is local after this comparison. +/// @tparam InputT input domain type +/// @param composer the schedule being built +/// @param seed FSS seed already recorded on `composer` +/// @param plan the union plan +/// @return The comparison leaf (`domain::a`) +/// @throws std::invalid_argument if the plan depth or lane count is zero +/// \complexity `depth` expand/step pairs. `depth` is `bitlength(InputT)`. +/// Extra composer nodes are `Θ(depth)`, independent of `plan.funcs.size()` +/// and of `plan.endpoints()`. +/// \rounds `plan.geneval_rounds()` once the composer is scheduled. +/// \communication One correction slot per level, `lut_union_slot_bytes(plan.lanes)` wide. +/// @see grotto::make_lut_union_plan +template +dpf::protocol::node schedule_lut_union( + dpf::protocol::composer & composer, dpf::protocol::node seed, + const lut_union_plan & plan) +{ + if (plan.depth == 0 || plan.lanes == 0) + throw std::invalid_argument("lut union: plan has no comparison"); + return composer.fss_cmp(seed, plan.depth, lut_union_slot_bytes(plan.lanes)); +} + +/// @brief Record a fresh seed and one full-depth comparison for `plan`. +/// \complexity One input node plus `schedule_lut_union` on that seed. +/// \rounds `plan.geneval_rounds()`. +/// @see grotto::schedule_lut_union +template +dpf::protocol::node schedule_lut_union( + dpf::protocol::composer & composer, const lut_union_plan & plan) +{ + auto seed = composer.input(dpf::protocol::domain::fss, 16); + return schedule_lut_union(composer, seed, plan); +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_LUT_UNION_HPP__ diff --git a/include/grotto/nmod.hpp b/include/grotto/nmod.hpp index f29e04e..3698203 100644 --- a/include/grotto/nmod.hpp +++ b/include/grotto/nmod.hpp @@ -47,6 +47,10 @@ struct nmod_result /// @return `x_raw / 2^x_bits` modulo `M`, with `1/M ≈ recip_raw / 2^recip_bits` /// @throws std::invalid_argument if the reciprocal is zero or a width is illegal. /// @throws std::overflow_error if the quotient does not fit in `int64_t`. +/// \complexity One 64×128 multiply into four 64-bit limbs, then a constant number of limb tests to split the quotient and the residue. `Θ(1)` in that 256-bit width. Extra space is the four-limb array. +/// @see grotto::ring_switch_eval +/// @see grotto::nmod_pow2 +/// @note Truncated Barrett. The residue is `{x/M}` on `residue_bits` fractional bits, not an exact `zn64` representative. Exact conversion is `ring_switch`. HEDLEY_WARN_UNUSED_RESULT inline nmod_result nmod(std::int64_t x_raw, unsigned x_bits, unsigned __int128 recip_raw, unsigned recip_bits, unsigned residue_bits) @@ -190,6 +194,8 @@ inline nmod_result nmod(std::int64_t x_raw, unsigned x_bits, /// @param residue_bits the fractional bits kept in the residue /// @return Modulus `2^{-exp}` by an exact shift /// @throws std::overflow_error if `exp` does not fit the reciprocal width. +/// \complexity One call to `nmod` with a reciprocal that is a shift (`2^{exp}` or `2^{-exp}`). `Θ(1)`. +/// @see grotto::nmod HEDLEY_WARN_UNUSED_RESULT inline nmod_result nmod_pow2(std::int64_t x_raw, unsigned x_bits, int exp, unsigned residue_bits) diff --git a/include/grotto/offset_horner.hpp b/include/grotto/offset_horner.hpp index 44035a3..02d0480 100644 --- a/include/grotto/offset_horner.hpp +++ b/include/grotto/offset_horner.hpp @@ -1,7 +1,8 @@ /// @file grotto/offset_horner.hpp /// @brief Noninteractive cubic evaluation after the public offset is opened. -/// @details The dealer keys one comparison at `center` per power -/// `1, center, center^2, center^3` in Z/2^64. After the parties open +/// @details The dealer keys one comparison at `center` whose payload is the +/// vector `1, center, center^2, center^3` in Z/2^64. The seed spine +/// is stored once; the value words grow with the degree. After the parties open /// `eta`, each party shifts the knots by `eta`, inserts the domain /// minimum and the public carry threshold, and sorts. The /// sign-respecting segment walk then returns additive shares of @@ -18,6 +19,7 @@ /// /// `offset_horner_at_x_plus_r` is the wiring from the reconstruction /// the parties already do: `eta = x - r` and `center = 2r`. +/// @note Storrier, Vadapalli, Lyons, and Henry (ePrint 2023/108) evaluate a public piecewise polynomial from one point key by prefix parity. This dealer keys one comparison of a secret center, with a `dpf::vec` of the powers as the payload. #ifndef LIBDPF_INCLUDE_GROTTO_OFFSET_HORNER_HPP__ #define LIBDPF_INCLUDE_GROTTO_OFFSET_HORNER_HPP__ @@ -34,6 +36,7 @@ #include #include #include +#include #include #include "dpf.hpp" @@ -41,20 +44,26 @@ namespace grotto { +/// \complexity One modular add in the input group (cast to the unsigned width). `Θ(1)`. +/// @see grotto::offset_horner_at_x_plus_r inline constexpr std::size_t offset_horner_max_degree = 3; template +HEDLEY_CONST HEDLEY_NO_THROW -T offset_horner_group_add(T a, T b) noexcept +constexpr T offset_horner_group_add(T a, T b) noexcept { using u = std::make_unsigned_t; return static_cast(static_cast(static_cast(a) + static_cast(b))); } +/// \complexity One modular subtract in the input group. `Θ(1)`. +/// @see grotto::offset_horner_group_add template +HEDLEY_CONST HEDLEY_NO_THROW -T offset_horner_group_sub(T a, T b) noexcept +constexpr T offset_horner_group_sub(T a, T b) noexcept { using u = std::make_unsigned_t; return static_cast(static_cast(static_cast(a) - static_cast(b))); @@ -68,17 +77,24 @@ struct offset_horner_x_plus_r T eta{}; T center{}; }; +/// \complexity Two group operations: `eta = x - r`, `center = 2r`. `Θ(1)`. +/// @param x secret input share or value, in the input group +/// @param r mask, in the input group +/// @return `eta` and `center` +/// @see grotto::make_offset_horner_keys template +HEDLEY_CONST HEDLEY_NO_THROW -offset_horner_x_plus_r offset_horner_at_x_plus_r(T x, T r) noexcept +constexpr offset_horner_x_plus_r offset_horner_at_x_plus_r(T x, T r) noexcept { return offset_horner_x_plus_r{ offset_horner_group_sub(x, r), offset_horner_group_add(r, r)}; } -template +template struct offset_horner_keys; namespace offset_horner_detail @@ -92,8 +108,9 @@ inline constexpr uint64_t binom[4][4] = { }; template +HEDLEY_CONST HEDLEY_NO_THROW -uint64_t lift(T v) noexcept +constexpr uint64_t lift(T v) noexcept { if constexpr (std::is_signed_v) return static_cast(static_cast(v)); @@ -102,8 +119,9 @@ uint64_t lift(T v) noexcept } template +HEDLEY_PURE HEDLEY_NO_THROW -uint64_t horner_at(const std::array & coeff, uint64_t point) noexcept +constexpr uint64_t horner_at(const std::array & coeff, uint64_t point) noexcept { uint64_t acc = coeff[Degree]; for (std::size_t k = Degree; k-- > 0; ) @@ -123,13 +141,26 @@ void fill_payloads(uint64_t base, uint64_t (&payload)[Degree + 1]) noexcept } } -template -auto make_key_array(InputT center, const uint64_t (&payload)[Degree + 1], - std::index_sequence) +template +dpf::vec payload_vec(const uint64_t (&payload)[Degree + 1]) { - using pair = typename offset_horner_keys::key_pair; - return std::array{ - dpf::make_dpf(center, dpf::gt(payload[M]))...}; + dpf::vec v; + for (std::size_t m = 0; m <= Degree; ++m) + v[m] = payload[m]; + return v; +} + +template +auto make_power_key(InputT center, const uint64_t (&payload)[Degree + 1], std::false_type) +{ + return dpf::make_dpf(center, dpf::gt(payload_vec(payload))); +} + +template +auto make_power_key(InputT center, const uint64_t (&payload)[Degree + 1], std::true_type) +{ + return dpf::make_dpf(center, dpf::gt(payload_vec(payload)), + dpf::verifiable{}); } template @@ -187,15 +218,190 @@ inline std::vector segments_from_prefixes( return seg; } +/// @brief One segment walk whose comparison payload is `N` lanes. +/// Lane `m` matches a per-power `segments_of` on `gt(payload[m])`. +template +std::array, N> segments_lanes( + const Key & key, const std::vector & knots, + const std::array & wrap_party, dpf::proof_token * pi = nullptr) +{ + using Vec = dpf::vec; + const std::size_t n = knots.size(); + std::array, N> out; + for (auto & row : out) + row.assign(n, 0); + if (n == 1) + { + if (pi != nullptr) + { + dpf::detail::vdpf::init_proof(*pi, key); + dpf::detail::vdpf::fold_output_binding(*pi, key); + } + const uint64_t mask = key.cmp().mask; + for (std::size_t m = 0; m < N; ++m) + out[m][0] = wrap_party[m] & mask; + return out; + } + + if (pi != nullptr) + { + if constexpr (!Key::is_verifiable) + throw std::invalid_argument( + "offset horner: proof token requires a verifiable key"); + dpf::detail::vdpf::init_proof(*pi, key); + } + const uint64_t mask = key.cmp().mask; + auto path = dpf::make_basic_path_memoizer(key); + std::vector prefixes(n); + for (std::size_t which = 0; which < n; ++which) + { + auto tx = key.offset_x(knots[which]); + dpf::utils::flip_msb_if_signed_integral(tx); + prefixes[which] = dpf::detail::incr::eval_payload_path_sum( + key, tx, path, false, 0, pi); + } + if (pi != nullptr) + dpf::detail::vdpf::fold_output_binding(*pi, key); + + for (std::size_t m = 0; m < N; ++m) + { + std::vector prefix(n); + for (std::size_t i = 0; i < n; ++i) + prefix[i] = prefixes[i][m]; + out[m] = segments_from_prefixes(prefix, wrap_party[m], mask); + } + return out; +} + +/// @brief Widest lane count stored in one offset comparison (degree 16). +inline constexpr std::size_t lane_key_max = 17; + +template +struct lane_key_slot +{ + static constexpr std::size_t lanes = N; + using key_pair = std::conditional_t(), + dpf::idcf(dpf::gt(dpf::vec{})), dpf::verifiable{})), + decltype(dpf::make_dpf(std::declval(), + dpf::idcf(dpf::gt(dpf::vec{}))))>; + key_pair keys; + + explicit lane_key_slot(key_pair k) + : keys(std::move(k)) { } +}; + +template +struct lane_key_variant; + +template +struct lane_key_variant> +{ + using type = std::variant...>; +}; + +template +using lane_keys = typename lane_key_variant>::type; + +template +lane_key_slot make_lane_slot( + InputT center, const uint64_t * payload) +{ + dpf::vec v; + for (std::size_t i = 0; i < N; ++i) + v[i] = payload[i]; + if constexpr (Verifiable) + return lane_key_slot{ + dpf::make_dpf(center, dpf::idcf(dpf::gt(v)), dpf::verifiable{})}; + else + return lane_key_slot{ + dpf::make_dpf(center, dpf::idcf(dpf::gt(v)))}; +} + +template +void emplace_lane_keys(lane_keys & out, + InputT center, const uint64_t * payload, std::size_t n) +{ + if (n == N) + out.template emplace>( + make_lane_slot(center, payload)); + else if constexpr (N > 1) + emplace_lane_keys(out, center, payload, n); +} + +template +lane_keys make_lane_keys( + InputT center, const uint64_t * payload, std::size_t n) +{ + if (n == 0 || n > lane_key_max) + throw std::invalid_argument("offset comparison: lane count out of range"); + lane_keys out; + emplace_lane_keys(out, center, payload, n); + return out; +} + +template +std::vector> segments_of_slot( + const Slot & slot, const std::vector & knots, + const std::vector> & wrap, dpf::proof_token * pi) +{ + constexpr std::size_t N = Slot::lanes; + if (wrap.size() < N) + throw std::invalid_argument("offset comparison: wrap shares shorter than the payload"); + std::array wrap_party{}; + for (std::size_t m = 0; m < N; ++m) + wrap_party[m] = wrap[m][Party]; + const auto seg = segments_lanes(std::get(slot.keys), knots, wrap_party, pi); + std::vector> out(knots.size(), std::vector(N, 0)); + for (std::size_t m = 0; m < N; ++m) + for (std::size_t i = 0; i < knots.size(); ++i) + out[i][m] = seg[m][i]; + return out; +} + +template +std::vector> lane_segments( + const Keys & keys, + const std::vector & knots, + const std::vector> & wrap, dpf::proof_token * pi) +{ + return std::visit([&](const auto & slot) -> std::vector> { + using Slot = std::decay_t; + if constexpr (std::is_same_v) + throw std::invalid_argument("offset comparison: missing key"); + else + return segments_of_slot(slot, knots, wrap, pi); + }, keys); +} + +inline void replicate_proof(dpf::proof_token * tokens, std::size_t n) +{ + if (tokens == nullptr || n == 0) + return; + for (std::size_t m = 1; m < n; ++m) + tokens[m] = tokens[0]; +} + template std::vector segments_of(const Key & key, const std::vector & knots, - uint64_t wrap_share) + uint64_t wrap_share, dpf::proof_token * pi = nullptr) { const std::size_t n = knots.size(); if (n == 1) + { + // One-segment short circuit (domains ≥ 63 bits): no prefix walk. + // Bind leaf / value words so tokens are non-zero and verify. + if (pi != nullptr) + { + dpf::detail::vdpf::init_proof(*pi, key); + dpf::detail::vdpf::fold_output_binding(*pi, key); + } return std::vector{wrap_share & key.cmp().mask}; + } std::vector prefix(n); - signed_prefix_parities_into(key, knots.data(), n, prefix.data()); + signed_prefix_parities_into(key, knots.data(), n, prefix.data(), pi); return segments_from_prefixes(prefix, wrap_share, key.cmp().mask); } @@ -222,38 +428,41 @@ T domain_min() noexcept /// @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` +/// @param eta public offset `eta = x - r` /// @return Public center-space cut where `center + eta` crosses the domain end template HEDLEY_NO_THROW std::optional carry_threshold(T eta) noexcept { constexpr unsigned bits = dpf::utils::bitlength_of_v; - if (bits > 62) + if constexpr (bits > 62) return std::nullopt; - const int64_t mod = int64_t{1} << bits; - const int64_t half = mod >> 1; - const int64_t ez = math_lift(eta); - if constexpr (std::is_signed_v) - { - if (ez > 0) - return static_cast(half - ez); - if (ez < 0) - return static_cast(-half - ez); - return std::nullopt; - } else { - if (ez == 0) + const int64_t mod = int64_t{1} << bits; + const int64_t half = mod >> 1; + const int64_t ez = math_lift(eta); + if constexpr (std::is_signed_v) + { + if (ez > 0) + return static_cast(half - ez); + if (ez < 0) + return static_cast(-half - ez); return std::nullopt; - return static_cast(mod - ez); + } + else + { + if (ez == 0) + return std::nullopt; + return static_cast(mod - ez); + } } } /// @brief `center + kappa` is the wrapped representative, as a mathematical integer. /// @tparam T value type -/// @param left the `left` -/// @param eta the `eta` +/// @param left left endpoint of the piece, in the input group +/// @param eta public offset `eta = x - r` /// @return `center + kappa` is the wrapped representative, as a mathematical integer template HEDLEY_NO_THROW @@ -261,24 +470,27 @@ int64_t kappa_for(T left, T eta) noexcept { constexpr unsigned bits = dpf::utils::bitlength_of_v; const int64_t ez = math_lift(eta); - if (bits > 62) + if constexpr (bits > 62) return ez; - const int64_t mod = int64_t{1} << bits; - const int64_t left_i = math_lift(left); - if constexpr (std::is_signed_v) - { - const int64_t half = mod >> 1; - if (ez > 0 && left_i >= half - ez) - return ez - mod; - if (ez < 0 && left_i < -half - ez) - return ez + mod; - return ez; - } else { - if (ez != 0 && left_i >= mod - ez) - return ez - mod; - return ez; + const int64_t mod = int64_t{1} << bits; + const int64_t left_i = math_lift(left); + if constexpr (std::is_signed_v) + { + const int64_t half = mod >> 1; + if (ez > 0 && left_i >= half - ez) + return ez - mod; + if (ez < 0 && left_i < -half - ez) + return ez + mod; + return ez; + } + else + { + if (ez != 0 && left_i >= mod - ez) + return ez - mod; + return ez; + } } } @@ -375,9 +587,9 @@ std::vector> prepare_pieces( /// `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 seg per-power segment shares on the refined pieces /// @param coeff the public coefficient -/// @param kappa the `kappa` +/// @param kappa public carry of each refined piece /// @return `out[k]` sums to the polynomial at the wrapped input template std::array contributions( @@ -402,33 +614,70 @@ std::array contributions( /// @brief Both parties' comparison keys and wrap-piece shares for one center. /// @tparam InputT input domain type /// @tparam Degree degree -template +/// @tparam Verifiable when true, keys carry `dpf::verifiable` +template struct offset_horner_keys { static_assert(Degree <= offset_horner_max_degree, "offset horner degree is at most 3"); static_assert(std::is_integral_v, "offset horner domain must be an integer group"); static constexpr std::size_t degree = Degree; + static constexpr bool is_verifiable = Verifiable; using input_type = InputT; - using key_pair = decltype(dpf::make_dpf(std::declval(), dpf::gt(uint64_t{0}))); + using key_pair = std::conditional_t(), + dpf::gt(dpf::vec{}), dpf::verifiable{})), + decltype(dpf::make_dpf(std::declval(), + dpf::gt(dpf::vec{})))>; - InputT center{}; - /// @brief `keys[m]` is `gt(center^m)` keyed at `center`. `.first` is party 0. - std::array keys; + /// @brief One `gt` at the hidden center. Lane `m` of the payload is `center^m`. + /// `.first` is party 0. The seed spine is stored once. + key_pair keys; /// @brief Random additive split of `center^m`, indexed `[power][party]`. std::array, Degree + 1> wrap_share{}; }; +/// \complexity One `dpf::make_dpf` of a `Degree + 1` lane comparison. `Degree` is at most 3. +/// The seed spine is one key. Value words are `Degree + 1` lanes. +/// \rounds No party interaction. +/// \communication None inside this function. Shipping the returned keys is outside it. +/// \preprocessing One `gt` key and `wrap_share[Degree + 1][2]` words of `uint64_t`. +/// @see grotto::offset_horner_eval +/// @see grotto::offset_poly_eval template -offset_horner_keys make_offset_horner_keys(InputT center) +offset_horner_keys make_offset_horner_keys(InputT center) { using namespace offset_horner_detail; uint64_t payload[Degree + 1]; fill_payloads(lift(center), payload); - offset_horner_keys mat{ - center, - make_key_array(center, payload, std::make_index_sequence{}), + offset_horner_keys mat{ + make_power_key(center, payload, std::false_type{}), + {}}; + for (std::size_t m = 0; m <= Degree; ++m) + { + const uint64_t blind = dpf::uniform_sample(); + mat.wrap_share[m][0] = blind; + mat.wrap_share[m][1] = payload[m] - blind; + } + return mat; +} +/// \complexity One `dpf::make_dpf` of a `Degree + 1` lane comparison, with proof tokens. `Degree` is at most 3. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One verifiable `gt` key and `wrap_share[Degree + 1][2]` words of `uint64_t`. +/// @see grotto::offset_horner_eval + +template +offset_horner_keys make_offset_horner_keys(InputT center, + dpf::verifiable) +{ + using namespace offset_horner_detail; + uint64_t payload[Degree + 1]; + fill_payloads(lift(center), payload); + + offset_horner_keys mat{ + make_power_key(center, payload, std::true_type{}), {}}; for (std::size_t m = 0; m <= Degree; ++m) { @@ -444,12 +693,15 @@ offset_horner_keys make_offset_horner_keys(InputT center) /// wrapped input. /// @tparam Degree degree /// @tparam InputT input domain type -/// @param center the `center` -/// @param knots the `knots` +/// @param center hidden comparison point in the input group +/// @param knots public breakpoints, strictly increasing /// @param coeff the public coefficient -/// @param eta the `eta` +/// @param eta public offset `eta = x - r` /// @return Cleartext binomial coefficients of the selected refined piece in the variable `center`: /// Horner at `lift(center)` is the polynomial at the wrapped input +/// \complexity Same piece preparation as the online eval (`Θ(P log P)` sort plus the two optional cuts), then `Θ(Degree)` binomial coefficients on the hot piece. No keys. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_jet_eval template std::array offset_horner_clear_coefficients( InputT center, @@ -473,11 +725,13 @@ std::array offset_horner_clear_coefficients( /// @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 center hidden comparison point in the input group +/// @param knots public breakpoints, strictly increasing /// @param coeff the public coefficient -/// @param eta the `eta` +/// @param eta public offset `eta = x - r` /// @return Cleartext value of the selected piece at the wrapped `center + eta` +/// \complexity One `offset_horner_clear_coefficients` plus a Horner loop of `Degree + 1` terms (`Degree ≤ 3`). +/// @see grotto::offset_horner_eval template uint64_t offset_horner_clear( InputT center, @@ -495,25 +749,35 @@ uint64_t offset_horner_clear( /// @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 wrap_share additive split of the keyed payload, indexed by party +/// @param knots public breakpoints, strictly increasing /// @param coeff the public coefficient -/// @param eta the `eta` +/// @param eta public offset `eta = x - r` +/// @param tokens proof token folded by the segment walk, or null /// @return `Party` selects `.first` or `.second` of each key pair -/// @throws std::invalid_argument if `one comparison key per power` +/// @throws std::invalid_argument if the key vector is not the single shared comparison +/// \complexity `prepare_pieces` sorts the knots and may insert two cuts. Then one segment walk of the `Degree + 1` lane payload. +/// Each walk is `signed_prefix_parities` over those `P` endpoints (a DPF path of `bitlength(InputT)` levels, reusing the common prefix). +/// Refined pieces: the knot vector, plus the cuts `prepare` / `prepare_pieces` inserts (domain minimum, and the carry threshold when the input width is at most 62 bits). Call that count `P`. +/// Time is one segment walk. Extra space is the piece vectors, `Θ(P · Degree)` words, with `Degree ≤ 3`. +/// \rounds None. `eta` is an argument; this function does not open it. +/// \communication None. +/// \preprocessing None created here. It reads the one comparison from `make_offset_horner_keys`. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_jet_eval template std::array offset_horner_coefficient_share( const std::vector & keys, const std::array, Degree + 1> & wrap_share, const std::vector & knots, const std::vector> & coeff, - InputT eta) + InputT eta, dpf::proof_token * tokens = nullptr) { static_assert(Party < 2, "offset horner party is 0 or 1"); using namespace offset_horner_detail; check_knots(knots, coeff.size()); - if (keys.size() != Degree + 1) - throw std::invalid_argument("offset horner: one comparison key per power"); + if (keys.size() != 1) + throw std::invalid_argument("offset horner: one comparison key"); const auto pieces = prepare_pieces(knots, coeff, eta); std::vector shifted(pieces.size()); std::vector> ordered(pieces.size()); @@ -525,34 +789,42 @@ std::array offset_horner_coefficient_share( kappa[i] = pieces[i].kappa; } - std::array, Degree + 1> seg; + std::array wrap_party{}; for (std::size_t m = 0; m <= Degree; ++m) + wrap_party[m] = wrap_share[m][Party]; + dpf::proof_token * pi = (tokens != nullptr) ? &tokens[0] : nullptr; + const auto & key = std::get(keys.front()); + auto seg = segments_lanes(key, shifted, wrap_party, pi); + if (tokens != nullptr) { - seg[m] = segments_of(std::get(keys[m]), shifted, wrap_share[m][Party]); + for (std::size_t m = 1; m <= Degree; ++m) + tokens[m] = tokens[0]; } return contributions(seg, ordered, kappa); } /// @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 +/// \complexity `prepare_pieces` sorts the knots and may insert two cuts. Then one segment walk of the `Degree + 1` lane payload. +/// Each walk is `signed_prefix_parities` over those `P` endpoints (a DPF path of `bitlength(InputT)` levels, reusing the common prefix). +/// Refined pieces: the knot vector, plus the cuts `prepare` / `prepare_pieces` inserts (domain minimum, and the carry threshold when the input width is at most 62 bits). Call that count `P`. +/// Time is one segment walk. Extra space is the piece vectors, `Θ(P · Degree)` words, with `Degree ≤ 3`. +/// \rounds None. `eta` is an argument; this function does not open it. +/// \communication None. +/// \preprocessing None created here. It reads the one comparison from `make_offset_horner_keys`. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_jet_eval +template std::array offset_horner_coefficient_share( - const offset_horner_keys & mat, + const offset_horner_keys & mat, const std::vector & knots, const std::vector> & coeff, - InputT eta) + InputT eta, dpf::proof_token * tokens = nullptr) { - std::vector::key_pair> keys( - mat.keys.begin(), mat.keys.end()); + std::vector::key_pair> keys{ + mat.keys}; return offset_horner_coefficient_share( - keys, mat.wrap_share, knots, coeff, eta); + keys, mat.wrap_share, knots, coeff, eta, tokens); } /// @brief Both parties' Horner shares from one joint Doerner–Shelat generation. @@ -566,20 +838,27 @@ struct geneval_offset_horner_result { static_assert(Degree <= offset_horner_max_degree, "offset horner degree is at most 3"); - InputT center{}; + /// @brief Public offset `eta = x - r`. F_Horner leaks only this. InputT eta{}; std::array coeff0{}; std::array coeff1{}; uint64_t value0 = 0; uint64_t value1 = 0; + std::array proof0{}; + std::array proof1{}; }; /// @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`. +/// @details Dealer / joint-simulator helper only. F_Horner does not return the +/// center to the parties; `center^m` stays a shared payload. /// @tparam InputT input domain type -/// @param center0 the `center0` -/// @param center1 the `center1` +/// @param center0 party 0 share of the center +/// @param center1 party 1 share of the center /// @return Logical comparison point for geneval's XOR shares +/// \complexity Two `flip_msb_if_signed_integral` calls and one XOR of the input shares. `Θ(1)`. +/// @note Dealer-side helper. The signed MSB of `center0` is flipped before the XOR and flipped back, matching `make_dpf`. +/// @see grotto::geneval_offset_horner template InputT geneval_offset_horner_center(InputT center0, InputT center1) { @@ -618,25 +897,67 @@ geneval_offset_horner_result geneval_at( std::array, Degree + 1> wrap{}; std::array, Degree + 1> seg0; std::array, Degree + 1> seg1; - for (std::size_t m = 0; m <= Degree; ++m) - { - const auto opened = arith - ? dpf::geneval_cmp(dpf::arith_input, center0, center1, - shifted.begin(), shifted.end(), rng, payload[m]) - : dpf::geneval_cmp(center0, center1, - shifted.begin(), shifted.end(), rng, payload[m]); - const uint64_t blind = dpf::uniform_sample(); - wrap[m][0] = blind; - wrap[m][1] = payload[m] - blind; - seg0[m] = segments_from_prefixes(opened.party0, wrap[m][0], opened.mask); - seg1[m] = segments_from_prefixes(opened.party1, wrap[m][1], opened.mask); - } + std::array out_proofs0{}; + std::array out_proofs1{}; + using Vec = dpf::vec; + const auto beta = payload_vec(payload); + auto open_lanes = [&](auto && keys) { + const auto & k0 = keys.first; + const auto & k1 = keys.second; + const uint64_t mask = k0.cmp().mask; + dpf::detail::vdpf::init_proof(out_proofs0[0], k0); + dpf::detail::vdpf::init_proof(out_proofs1[0], k1); + auto path0 = dpf::make_basic_path_memoizer(k0); + auto path1 = dpf::make_basic_path_memoizer(k1); + std::vector pref0(shifted.size()); + std::vector pref1(shifted.size()); + for (std::size_t i = 0; i < shifted.size(); ++i) + { + auto tx0 = k0.offset_x(shifted[i]); + auto tx1 = k1.offset_x(shifted[i]); + dpf::utils::flip_msb_if_signed_integral(tx0); + dpf::utils::flip_msb_if_signed_integral(tx1); + pref0[i] = dpf::detail::incr::eval_payload_path_sum( + k0, tx0, path0, false, 0, &out_proofs0[0]); + pref1[i] = dpf::detail::incr::eval_payload_path_sum( + k1, tx1, path1, false, 0, &out_proofs1[0]); + } + dpf::detail::vdpf::fold_output_binding(out_proofs0[0], k0); + dpf::detail::vdpf::fold_output_binding(out_proofs1[0], k1); + for (std::size_t m = 1; m <= Degree; ++m) + { + out_proofs0[m] = out_proofs0[0]; + out_proofs1[m] = out_proofs1[0]; + } + for (std::size_t m = 0; m <= Degree; ++m) + { + const uint64_t blind = dpf::uniform_sample(); + wrap[m][0] = blind; + wrap[m][1] = payload[m] - blind; + std::vector lane0(shifted.size()); + std::vector lane1(shifted.size()); + for (std::size_t i = 0; i < shifted.size(); ++i) + { + lane0[i] = pref0[i][m]; + lane1[i] = pref1[i][m]; + } + seg0[m] = segments_from_prefixes(lane0, wrap[m][0], mask); + seg1[m] = segments_from_prefixes(lane1, wrap[m][1], mask); + } + }; + if (arith) + open_lanes(dpf::make_dpf_doerner_shelat(dpf::arith_input, center0, center1, + rng, dpf::gt(beta), dpf::verifiable{})); + else + open_lanes(dpf::make_dpf_doerner_shelat(center0, center1, + rng, dpf::gt(beta), dpf::verifiable{})); geneval_offset_horner_result out; - out.center = center; out.eta = eta; out.coeff0 = contributions(seg0, ordered, kappa); out.coeff1 = contributions(seg1, ordered, kappa); + out.proof0 = out_proofs0; + out.proof1 = out_proofs1; for (uint64_t term : out.coeff0) out.value0 += term; for (uint64_t term : out.coeff1) @@ -661,18 +982,24 @@ geneval_offset_horner_result geneval_at( /// @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. +/// A comparison value word is written on every level of the secret path. +/// The seed spine is generated once for the whole power vector. /// @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 center0 party 0 share of the center +/// @param center1 party 1 share of the center +/// @param eta public offset `eta = x - r` +/// @param knots public breakpoints, strictly increasing /// @param coeff the public coefficient /// @param rng the Doerner–Shelat randomness tapes /// @return Geneval-style offset Horner +/// \complexity One Doerner–Shelat generation of a `Degree + 1` lane comparison (`Degree ≤ 3`), then the same local piece dot as `offset_horner_eval`. +/// The dot is `Θ(P · Degree)` after those calls. `P` is the refined piece count. +/// @note Rounds and bandwidth of each `geneval_cmp` live in the DPF headers, not in this function, so they are not stated here. +/// \preprocessing The randomness object the caller passes (`Rng`). This function also samples one `uint64_t` blind per power. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_jet_eval template @@ -686,6 +1013,12 @@ geneval_offset_horner_result geneval_offset_horner( return offset_horner_detail::geneval_at( center0, center1, center, eta, knots, coeff, std::move(rng)); } +/// \complexity One Doerner–Shelat generation of a `Degree + 1` lane comparison (`Degree ≤ 3`), then the same local piece dot as `offset_horner_eval`. +/// The dot is `Θ(P · Degree)` after those calls. `P` is the refined piece count. +/// @note Rounds and bandwidth of each `geneval_cmp` live in the DPF headers, not in this function, so they are not stated here. +/// \preprocessing The randomness object the caller passes (`Rng`). This function also samples one `uint64_t` blind per power. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_jet_eval template geneval_offset_horner_result geneval_offset_horner( @@ -707,13 +1040,19 @@ geneval_offset_horner_result geneval_offset_horner( /// @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 center0 party 0 share of the center +/// @param center1 party 1 share of the center +/// @param eta public offset `eta = x - r` +/// @param knots public breakpoints, strictly increasing /// @param coeff the public coefficient /// @param rng the Doerner–Shelat randomness tapes /// @return Additive shares of the center: `center0 + center1` is the comparison point +/// \complexity One Doerner–Shelat generation of a `Degree + 1` lane comparison (`Degree ≤ 3`), then the same local piece dot as `offset_horner_eval`. +/// The dot is `Θ(P · Degree)` after those calls. `P` is the refined piece count. +/// @note Rounds and bandwidth of each `geneval_cmp` live in the DPF headers, not in this function, so they are not stated here. +/// \preprocessing The randomness object the caller passes (`Rng`). This function also samples one `uint64_t` blind per power. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_jet_eval template @@ -728,21 +1067,28 @@ geneval_offset_horner_result geneval_offset_horner( true, center0, center1, center, eta, knots, coeff, std::move(rng)); } -/// @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`). +/// @brief Additive shares of the input `x` and the mask `r`. +/// @details Opens only `eta = (x0 - r0) + (x1 - r1)`. Passes additive shares +/// of `center = 2r` (`2·r0`, `2·r1`) to arithmetic `geneval_cmp`. +/// The clear center is used only to plant shared `center^m` payloads; +/// it is not returned. F_Horner leaks only `eta`. /// @tparam Degree degree /// @tparam InputT input domain type /// @tparam Rng rng -/// @param x0 the `x0` -/// @param x1 the `x1` +/// @param x0 party 0 share of the input +/// @param x1 party 1 share of the input /// @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 knots public breakpoints, strictly increasing /// @param coeff the public coefficient /// @param rng the Doerner–Shelat randomness tapes -/// @return Additive shares of the input `x` and the mask `r` +/// @return Both parties' Horner shares and the public `eta` +/// \complexity One Doerner–Shelat generation of a `Degree + 1` lane comparison (`Degree ≤ 3`), then the same local piece dot as `offset_horner_eval`. +/// The dot is `Θ(P · Degree)` after those calls. `P` is the refined piece count. +/// @note Rounds and bandwidth of each `geneval_cmp` live in the DPF headers, not in this function, so they are not stated here. +/// \preprocessing The randomness object the caller passes (`Rng`). This function also samples one `uint64_t` blind per power. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_jet_eval template @@ -752,15 +1098,23 @@ geneval_offset_horner_result geneval_offset_horner( const std::vector> & coeff, Rng rng) { - const InputT x = offset_horner_group_add(x0, x1); - const InputT r = offset_horner_group_add(r0, r1); - const InputT eta = offset_horner_group_sub(x, r); + // Open only eta; do not form clear x or r. + const InputT eta = offset_horner_group_add( + offset_horner_group_sub(x0, r0), + offset_horner_group_sub(x1, r1)); const InputT center0 = offset_horner_group_add(r0, r0); const InputT center1 = offset_horner_group_add(r1, r1); + // Payload planting for the joint simulator; not returned to parties. const InputT center = offset_horner_group_add(center0, center1); return offset_horner_detail::geneval_at( true, center0, center1, center, eta, knots, coeff, std::move(rng)); } +/// \complexity One Doerner–Shelat generation of a `Degree + 1` lane comparison (`Degree ≤ 3`), then the same local piece dot as `offset_horner_eval`. +/// The dot is `Θ(P · Degree)` after those calls. `P` is the refined piece count. +/// @note Rounds and bandwidth of each `geneval_cmp` live in the DPF headers, not in this function, so they are not stated here. +/// \preprocessing The randomness object the caller passes (`Rng`). This function also samples one `uint64_t` blind per power. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_jet_eval template geneval_offset_horner_result geneval_offset_horner( @@ -783,19 +1137,31 @@ geneval_offset_horner_result geneval_offset_horner( /// @tparam Party party index, `0` or `1` /// @tparam Degree degree /// @tparam InputT input domain type -/// @param mat the `mat` -/// @param knots the `knots` +/// @param mat dealer keys +/// @param knots public breakpoints, strictly increasing /// @param coeff the public coefficient -/// @param eta the `eta` +/// @param eta public offset `eta = x - r` +/// @param tokens proof token folded by the segment walk, or null /// @return One party's share of the cubic at the wrapped `center + eta` -template +/// \complexity `prepare_pieces` sorts the knots and may insert two cuts. Then one segment walk of the `Degree + 1` lane payload. +/// Each walk is `signed_prefix_parities` over those `P` endpoints (a DPF path of `bitlength(InputT)` levels, reusing the common prefix). +/// Refined pieces: the knot vector, plus the cuts `prepare` / `prepare_pieces` inserts (domain minimum, and the carry threshold when the input width is at most 62 bits). Call that count `P`. +/// Time is one segment walk. Extra space is the piece vectors, `Θ(P · Degree)` words, with `Degree ≤ 3`. +/// \rounds None. `eta` is an argument; this function does not open it. +/// \communication None. +/// \preprocessing None created here. It reads the one comparison from `make_offset_horner_keys`. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_jet_eval +template uint64_t offset_horner_eval( - const offset_horner_keys & mat, + const offset_horner_keys & mat, const std::vector & knots, const std::vector> & coeff, - InputT eta) + InputT eta, dpf::proof_token * tokens = nullptr) { - const auto shares = offset_horner_coefficient_share(mat, knots, coeff, eta); + const auto shares = offset_horner_coefficient_share( + mat, knots, coeff, eta, tokens); uint64_t value = 0; for (uint64_t term : shares) value += term; diff --git a/include/grotto/offset_iterable.hpp b/include/grotto/offset_iterable.hpp index 12f7e1c..1bac4e5 100644 --- a/include/grotto/offset_iterable.hpp +++ b/include/grotto/offset_iterable.hpp @@ -40,6 +40,10 @@ struct offset_iterable using reference = std::add_const_t::reference>; using const_reference = std::add_const_t::reference>; using pointer = typename std::iterator_traits::pointer; + /// \complexity `upper_bound` on the sorted range (`Θ(log N)`), then stores the rotation. Extra space is the iterators, `Θ(1)`. + /// @param begin start of a sorted range + /// @param end end of that range + /// @param offset public rotation; the view starts at the first entry strictly greater than `offset` HEDLEY_ALWAYS_INLINE constexpr offset_iterable(wrapped_iterator begin, wrapped_iterator end, @@ -239,6 +243,13 @@ struct offset_const_iterator : public offset_iterator_base } }; +/// @brief View `container` rotated so the first entry strictly greater than `offset` comes first. +/// @tparam ContainerT sorted random-access container +/// @param container sorted range +/// @param offset public rotation point +/// @return an `offset_iterable` over `container` +/// @see grotto::for_each_offset +/// \complexity One `upper_bound` (`Θ(log N)`, `N = container.size()`). Extra space is the iterators, `Θ(1)`. template auto offset_by(const ContainerT & container, typename ContainerT::size_type offset) { @@ -246,6 +257,8 @@ auto offset_by(const ContainerT & container, typename ContainerT::size_type offs } // assumes the range is sorted +/// \complexity One `upper_bound` to find the rotation, then one call of `f` per element. `Θ(N)` after the search. Extra space `Θ(1)`. +/// @see grotto::prefix_parities template (std::distance(begin, end)); // find the new "start" of the sorted sequence after offsetting by offset std::size_t new_first = std::distance(begin, std::upper_bound(begin, end, val, std::less_equal{})); diff --git a/include/grotto/offset_jet.hpp b/include/grotto/offset_jet.hpp new file mode 100644 index 0000000..2d58f0e --- /dev/null +++ b/include/grotto/offset_jet.hpp @@ -0,0 +1,441 @@ +/// @file grotto/offset_jet.hpp +/// @brief Binomial-basis jet after the public offset is opened. +/// @details The dealer keys one incremental comparison whose payload is the +/// vector of \f$\binom{\mathrm{center}}{k}\f$ in \f$\mathbb{Z}/2^{64}\f$, +/// for \f$k = 0,\ldots,d\f$. The seed spine is stored once. After `eta` opens, the same knot shift and +/// carry cut as offset poly refine the pieces. A public +/// Chu–Vandermonde convolution by the piece's carry `kappa` +/// \f$\binom{c+\kappa}{k} =\sum_j\binom{c}{j}\binom{\kappa}{k-j}\f$ +/// yields additive shares of the jet at the wrapped input. Public +/// dots against that jet are free: +/// - value of \f$\sum a_k\binom{x}{k}\f$; +/// - forward difference, by Pascal's +/// \f$\binom{x+1}{k}-\binom{x}{k}=\binom{x}{k-1}\f$; +/// - hockey-stick prefix \f$\sum_{i +#include +#include +#include +#include + +namespace grotto +{ + +inline constexpr std::size_t offset_jet_max_degree = offset_poly_max_degree; + +template +struct offset_jet_keys +{ + static_assert(std::is_integral_v, "offset jet domain must be an integer group"); + + using input_type = InputT; + + std::size_t degree = 0; + bool verifiable = false; + /// @brief One `idcf(gt)` of `vec`. + offset_horner_detail::lane_keys keys{}; + offset_horner_detail::lane_keys keys_v{}; + std::vector> wrap_share; +}; + +namespace offset_jet_detail +{ + +inline void check_degree(std::size_t degree) +{ + if (degree > offset_jet_max_degree) + throw std::invalid_argument("offset jet: degree exceeds 16"); +} + +/// @brief \f$v_2(k!)\f$ for \f$k \le 16\f$. +inline unsigned val2_factorial(unsigned k) noexcept +{ + unsigned v = 0; + for (unsigned p = 2; p <= k; p <<= 1) + v += k / p; + return v; +} + +/// @brief Odd part of \f$k!\f$ and \f$v_2(k!)\f$. +inline uint64_t odd_factorial(unsigned k, unsigned & val2) noexcept +{ + val2 = 0; + uint64_t odd = 1; + for (unsigned i = 1; i <= k; ++i) + { + unsigned x = i; + while ((x & 1u) == 0u) + { + x >>= 1u; + ++val2; + } + odd *= x; + } + return odd; +} + +/// @brief Modular inverse of an odd unit modulo \f$2^{64}\f$. +inline uint64_t inv_odd_u64(uint64_t a) noexcept +{ + uint64_t x = a; + x *= 2 - a * x; + x *= 2 - a * x; + x *= 2 - a * x; + x *= 2 - a * x; + x *= 2 - a * x; + return x; +} + +/// @brief \f$\binom{n}{k} \bmod 2^{64}\f$ for a nonnegative upper index. +HEDLEY_CONST +HEDLEY_NO_THROW +inline uint64_t binom_u64(uint64_t n, unsigned k) noexcept +{ + if (k == 0) + return 1; + if (k > offset_jet_max_degree) + return 0; + unsigned val2 = 0; + const uint64_t odd = odd_factorial(k, val2); + const unsigned bits = 64u + val2; + const unsigned __int128 mask = + (bits >= 128) ? ~static_cast(0) + : (static_cast(1) << bits) - 1u; + unsigned __int128 falling = 1; + for (unsigned i = 0; i < k; ++i) + { + const unsigned __int128 term = static_cast(n - i) & mask; + falling = (falling * term) & mask; + } + falling = (falling * inv_odd_u64(odd)) & mask; + falling >>= val2; + return static_cast(falling); +} + +/// @brief \f$\binom{n}{k} \bmod 2^{64}\f$ for a signed upper index (carry `kappa`). +HEDLEY_CONST +HEDLEY_NO_THROW +inline uint64_t binom_i64(std::int64_t n, unsigned k) noexcept +{ + if (k == 0) + return 1; + if (k > offset_jet_max_degree) + return 0; + if (n >= 0) + return binom_u64(static_cast(n), k); + // \f$\binom{-m}{k}=(-1)^k\binom{m+k-1}{k}\f$ with \f$m=-n>0\f$. + const uint64_t m = static_cast(-n); + const uint64_t mag = binom_u64(m + k - 1u, k); + return (k & 1u) ? static_cast(0) - mag : mag; +} + +inline std::vector chu_vandermonde( + const std::vector & center_jet, std::int64_t kappa) +{ + const std::size_t degree = center_jet.empty() ? 0 : center_jet.size() - 1; + std::vector out(degree + 1, 0); + for (std::size_t k = 0; k <= degree; ++k) + { + uint64_t acc = 0; + for (std::size_t j = 0; j <= k; ++j) + acc += center_jet[j] * binom_i64(kappa, static_cast(k - j)); + out[k] = acc; + } + return out; +} + +} // namespace offset_jet_detail + +/// @brief \f$\binom{n}{k} \bmod 2^{64}\f$ for nonnegative \f$n\f$. +/// \complexity The product for `k ≤ 16` runs `k` steps, widening by `v_2(k!)` (15 when `k` is 16) and multiplying by the odd inverse. `Θ(k)`, extra space `Θ(1)`. +/// @warning Not division by `k!` inside `Z/2^64`. The falling factorial uses the extra `v_2(k!)` bits, then the inverse of the odd part of `k!`. +/// @see grotto::offset_jet_shares +/// @param n upper index +/// @param k lower index, at most 16 in the keyed jet +/// @return `binom(n, k)` modulo `2^64` +HEDLEY_CONST +HEDLEY_NO_THROW +inline uint64_t offset_jet_binom(uint64_t n, unsigned k) noexcept +{ + return offset_jet_detail::binom_u64(n, k); +} + +/// @brief \f$\binom{n}{k} \bmod 2^{64}\f$ for a signed upper index. +/// \complexity The product for `k ≤ 16` runs `k` steps, widening by `v_2(k!)` (15 when `k` is 16) and multiplying by the odd inverse. `Θ(k)`, extra space `Θ(1)`. +/// @warning Not division by `k!` inside `Z/2^64`. The falling factorial uses the extra `v_2(k!)` bits, then the inverse of the odd part of `k!`. +/// @see grotto::offset_jet_shares +/// @param n upper index +/// @param k lower index, at most 16 in the keyed jet +/// @return `binom(n, k)` modulo `2^64` +HEDLEY_CONST +HEDLEY_NO_THROW +inline uint64_t offset_jet_binom(std::int64_t n, unsigned k) noexcept +{ + return offset_jet_detail::binom_i64(n, k); +} +/// \complexity One `dpf::make_dpf` of `idcf(gt)` on a `degree + 1` lane vector of binomials. `check_degree` rejects `degree > offset_jet_max_degree` (16, the offset-poly cap). +/// Each binomial is one call to `binom_i64`. The seed spine is one key. Value words grow with `degree`. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One comparison key and `degree + 1` additive splits of those binomials. +/// @warning `binom_i64` is a falling factorial modulo `2^{64+v_2(k!)}`, then a multiply by the inverse of the odd part of `k!`. Dividing by `k!` in `Z/2^64` alone is not exact. `v_2(16!)` is 15. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_horner_eval +/// @see [Binomial jet](@ref offset_jet) + +template +offset_jet_keys make_offset_jet_keys(InputT center, std::size_t degree) +{ + using namespace offset_horner_detail; + offset_jet_detail::check_degree(degree); + offset_jet_keys mat; + mat.degree = degree; + mat.verifiable = false; + std::vector payload(degree + 1); + mat.wrap_share.reserve(degree + 1); + // Signed representative: lift(center) is wrong for degree >= 2 when center < 0. + const std::int64_t base = math_lift(center); + for (std::size_t k = 0; k <= degree; ++k) + { + payload[k] = offset_jet_detail::binom_i64(base, static_cast(k)); + const uint64_t blind = dpf::uniform_sample(); + mat.wrap_share.push_back({blind, payload[k] - blind}); + } + mat.keys = offset_horner_detail::make_lane_keys( + center, payload.data(), payload.size()); + return mat; +} +/// \complexity One `dpf::make_dpf` of `idcf(gt)` on a `degree + 1` lane vector of binomials. `check_degree` rejects `degree > offset_jet_max_degree` (16, the offset-poly cap). +/// Each binomial is one call to `binom_i64`. The seed spine is one key. Value words grow with `degree`. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One comparison key and `degree + 1` additive splits of those binomials. +/// @warning `binom_i64` is a falling factorial modulo `2^{64+v_2(k!)}`, then a multiply by the inverse of the odd part of `k!`. Dividing by `k!` in `Z/2^64` alone is not exact. `v_2(16!)` is 15. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_horner_eval +/// @see [Binomial jet](@ref offset_jet) + +template +offset_jet_keys make_offset_jet_keys(InputT center, std::size_t degree, + dpf::verifiable) +{ + using namespace offset_horner_detail; + offset_jet_detail::check_degree(degree); + offset_jet_keys mat; + mat.degree = degree; + mat.verifiable = true; + std::vector payload(degree + 1); + mat.wrap_share.reserve(degree + 1); + const std::int64_t base = math_lift(center); + for (std::size_t k = 0; k <= degree; ++k) + { + payload[k] = offset_jet_detail::binom_i64(base, static_cast(k)); + const uint64_t blind = dpf::uniform_sample(); + mat.wrap_share.push_back({blind, payload[k] - blind}); + } + mat.keys_v = offset_horner_detail::make_lane_keys( + center, payload.data(), payload.size()); + return mat; +} + +/// @brief Coefficient vector of the forward difference in the binomial basis. +/// @details \f$\Delta f(x)=\sum a_k\binom{x}{k-1}\f$ for \f$k\ge 1\f$, so the +/// difference coefficients are \f$(a_1,a_2,\ldots,a_d,0)\f$. +/// \complexity One copy of `coeff`, shifted down by one index. `Θ(degree)`. +/// @see grotto::offset_jet_dot +/// @see grotto::offset_jet_prefix_coeff +inline std::vector offset_jet_difference_coeff( + const std::vector & coeff) +{ + if (coeff.empty()) + return {}; + std::vector out(coeff.size(), 0); + for (std::size_t k = 1; k < coeff.size(); ++k) + out[k - 1] = coeff[k]; + return out; +} + +/// @brief Coefficient vector of the hockey-stick prefix sum. +/// @details \f$\sum_{i offset_jet_prefix_coeff( + const std::vector & coeff) +{ + std::vector out(coeff.size() + 1, 0); + for (std::size_t k = 0; k < coeff.size(); ++k) + out[k + 1] = coeff[k]; + return out; +} + +/// @brief Public carry `kappa` of each refined piece, in knot order. +/// \complexity Forwards to `offset_poly_kappas`: one piece preparation, `Θ(P log P)`. +/// @see grotto::offset_poly_kappas +template +std::vector offset_jet_kappas( + const std::vector & knots, + std::size_t degree, + InputT eta) +{ + return offset_poly_kappas(knots, degree, eta); +} + +/// @brief Dot of a public coefficient vector with a jet share. +/// \complexity One multiply-add per coefficient. `Θ(degree)`, extra space `Θ(1)`. +/// @see grotto::offset_jet_shares +inline uint64_t offset_jet_dot( + const std::vector & coeff, + const std::vector & jet) +{ + if (coeff.size() != jet.size()) + throw std::invalid_argument("offset jet: coefficient and jet lengths differ"); + uint64_t acc = 0; + for (std::size_t k = 0; k < coeff.size(); ++k) + acc += coeff[k] * jet[k]; + return acc; +} + +/// @brief Shares of the shifted binomial jet on the hot piece, for one party. +/// \complexity One segment walk of the `degree + 1` lane payload, then a Chu–Vandermonde update. +/// The update loops `m`, then pieces `i`, then `k ≥ m`, so the arithmetic after the walks is `Θ(P · degree²)`. +/// Refined pieces: the knot vector, plus the cuts `prepare` / `prepare_pieces` inserts (domain minimum, and the carry threshold when the input width is at most 62 bits). Call that count `P`. `degree ≤ 16`. +/// Extra space is the jet (`degree + 1` words) and the per-piece binomial table `Θ(P · degree)`. +/// \rounds None. `eta` is an argument. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_offset_jet_keys`. +/// @warning The binomials in that update are `offset_jet_binom`: not division by `k!` inside `Z/2^64`. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_horner_eval +/// @see [Binomial jet](@ref offset_jet) +template +std::vector offset_jet_shares( + const offset_jet_keys & mat, + const std::vector & knots, + InputT eta, + dpf::proof_token * tokens = nullptr) +{ + static_assert(Party < 2, "offset jet party is 0 or 1"); + using namespace offset_horner_detail; + using namespace offset_poly_detail; + const std::size_t lanes = mat.verifiable ? mat.keys_v.index() : mat.keys.index(); + if (lanes != mat.degree + 1) + throw std::invalid_argument("offset jet: comparison payload width differs from the degree"); + std::vector> dummy(knots.size(), + std::vector(mat.degree + 1, 0)); + const auto pieces = prepare(knots, dummy, eta); + std::vector shifted; + shifted.reserve(pieces.size()); + for (const auto & piece : pieces) + shifted.push_back(piece.knot); + + std::vector jet(mat.degree + 1, 0); + // Public kappa table and Chu factors are independent of the power index. + std::vector> kappa_binom(pieces.size()); + for (std::size_t i = 0; i < pieces.size(); ++i) + { + kappa_binom[i].resize(mat.degree + 1); + for (std::size_t t = 0; t <= mat.degree; ++t) + kappa_binom[i][t] = offset_jet_detail::binom_i64( + pieces[i].kappa, static_cast(t)); + } + dpf::proof_token * pi = (mat.verifiable && tokens != nullptr) ? &tokens[0] : nullptr; + const auto table = mat.verifiable + ? lane_segments(mat.keys_v, shifted, mat.wrap_share, pi) + : lane_segments(mat.keys, shifted, mat.wrap_share, nullptr); + if (mat.verifiable) + replicate_proof(tokens, mat.degree + 1); + for (std::size_t m = 0; m <= mat.degree; ++m) + { + for (std::size_t i = 0; i < pieces.size(); ++i) + { + // Chu–Vandermonde: only column m of the center jet is nonzero. + for (std::size_t k = m; k <= mat.degree; ++k) + jet[k] += table[i][m] * kappa_binom[i][k - m]; + } + } + return jet; +} + +/// @brief One party's share of \f$\sum a_k\binom{x}{k}\f$ at the wrapped point. +/// \complexity One segment walk of the `degree + 1` lane payload, then a Chu–Vandermonde update. +/// The update loops `m`, then pieces `i`, then `k ≥ m`, so the arithmetic after the walks is `Θ(P · degree²)`. +/// Refined pieces: the knot vector, plus the cuts `prepare` / `prepare_pieces` inserts (domain minimum, and the carry threshold when the input width is at most 62 bits). Call that count `P`. `degree ≤ 16`. +/// Extra space is the jet (`degree + 1` words) and the per-piece binomial table `Θ(P · degree)`. +/// \rounds None. `eta` is an argument. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_offset_jet_keys`. +/// @warning The binomials in that update are `offset_jet_binom`: not division by `k!` inside `Z/2^64`. +/// @see grotto::offset_poly_eval +/// @see grotto::offset_horner_eval +/// @see [Binomial jet](@ref offset_jet) +template +uint64_t offset_jet_eval( + const offset_jet_keys & mat, + const std::vector & knots, + const std::vector & coeff, + InputT eta, + dpf::proof_token * tokens = nullptr) +{ + if (coeff.size() != mat.degree + 1) + throw std::invalid_argument("offset jet: coefficient length must be degree+1"); + const auto jet = offset_jet_shares(mat, knots, eta, tokens); + return offset_jet_dot(coeff, jet); +} + +/// @brief Cleartext value of \f$\sum a_k\binom{\mathrm{center}+\kappa}{k}\f$. +/// \complexity Builds the center jet with `degree + 1` binomials and one Chu–Vandermonde (`Θ(degree²)`), after the piece sort. No keys. +/// @see grotto::offset_jet_eval +template +uint64_t offset_jet_clear( + InputT center, + const std::vector & knots, + const std::vector & coeff, + InputT eta) +{ + using namespace offset_poly_detail; + if (coeff.empty()) + return 0; + const std::size_t degree = coeff.size() - 1; + std::vector> dummy(knots.size(), + std::vector(degree + 1, 0)); + const auto pieces = prepare(knots, dummy, eta); + std::vector cuts; + for (const auto & piece : pieces) + cuts.push_back(piece.knot); + std::size_t hot = pieces.size() - 1; + for (std::size_t i = 0; i + 1 < cuts.size(); ++i) + { + if (center >= cuts[i] && center < cuts[i + 1]) + { + hot = i; + break; + } + } + const std::int64_t base = offset_horner_detail::math_lift(center); + std::vector center_jet(degree + 1); + for (std::size_t k = 0; k <= degree; ++k) + center_jet[k] = offset_jet_detail::binom_i64(base, static_cast(k)); + const auto jet = + offset_jet_detail::chu_vandermonde(center_jet, pieces[hot].kappa); + return offset_jet_dot(coeff, jet); +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_OFFSET_JET_HPP__ diff --git a/include/grotto/offset_poly.hpp b/include/grotto/offset_poly.hpp new file mode 100644 index 0000000..7c1701c --- /dev/null +++ b/include/grotto/offset_poly.hpp @@ -0,0 +1,494 @@ +/// @file grotto/offset_poly.hpp +/// @brief Generic offset evaluation of a polynomial, or of shares of its coefficients. +/// @details This is offset Horner at a runtime degree. The dealer keys one +/// incremental comparison `idcf(gt)` whose payload is the vector of +/// powers `center^m`. The seed spine is stored once. After +/// `eta = x - r` is public and `center = 2r`, the segment walk +/// returns additive shares of `center^m` on the piece that contains +/// the center. A public binomial shift by the piece's carry `kappa` +/// then dots to a share of `f` at the wrapped `x + r`. +/// +/// Public coefficients need no further round. Shared coefficients are +/// shifted locally, because the binomial map is linear, and the dot +/// with the power shares is one Beaver inner product. + +#ifndef LIBDPF_INCLUDE_GROTTO_OFFSET_POLY_HPP__ +#define LIBDPF_INCLUDE_GROTTO_OFFSET_POLY_HPP__ + +#include "grotto/offset_horner.hpp" + +#include "dpf/beaver.hpp" + +#include +#include +#include +#include +#include + +namespace grotto +{ + +inline constexpr std::size_t offset_poly_max_degree = 16; + +template +struct offset_poly_keys +{ + static_assert(std::is_integral_v, "offset poly domain must be an integer group"); + + using input_type = InputT; + + std::size_t degree = 0; + bool verifiable = false; + /// @brief One `idcf(gt)` of `vec`. Empty until `make_offset_poly_keys`. + offset_horner_detail::lane_keys keys{}; + offset_horner_detail::lane_keys keys_v{}; + std::vector> wrap_share; +}; +/// \complexity One `dpf::make_dpf` of `idcf(gt)` on a `degree + 1` lane vector. `degree` is rejected above `offset_poly_max_degree` (16). +/// The seed spine is one key. Value words grow with `degree`. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One comparison key and `degree + 1` additive payload splits (`wrap_share`, two `uint64_t` each). +/// @see grotto::offset_horner_eval +/// @see grotto::offset_jet_eval + +template +offset_poly_keys make_offset_poly_keys(InputT center, std::size_t degree); +/// \complexity One `dpf::make_dpf` of `idcf(gt)` on a `degree + 1` lane vector, with proof tokens. `degree` is rejected above `offset_poly_max_degree` (16). +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One verifiable comparison key and `degree + 1` additive payload splits (`wrap_share`, two `uint64_t` each). +/// @see grotto::offset_horner_eval +/// @see grotto::offset_jet_eval + +template +offset_poly_keys make_offset_poly_keys(InputT center, std::size_t degree, + dpf::verifiable); +/// \complexity `prepare` shifts and sorts the knots and inserts the same carry cuts. Then one segment walk of the `degree + 1` lane payload. +/// Refined pieces: the knot vector, plus the cuts `prepare` / `prepare_pieces` inserts (domain minimum, and the carry threshold when the input width is at most 62 bits). Call that count `P`. +/// Time is one walk, `degree ≤ 16`. Extra space `Θ(P · degree)` for the shifted rows. +/// \rounds None. `eta` is already public to the caller. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_offset_poly_keys`. +/// @see grotto::offset_horner_eval +/// @see grotto::offset_jet_eval + +template +uint64_t offset_poly_eval( + const offset_poly_keys & mat, + const std::vector & knots, + const std::vector> & coeff, + InputT eta, dpf::proof_token * tokens = nullptr); +/// \complexity Piece preparation plus a Horner of `degree + 1` terms on the hot piece. No keys. `degree ≤ 16`. +/// @see grotto::offset_poly_eval + +template +uint64_t offset_poly_clear( + InputT center, + const std::vector & knots, + const std::vector> & coeff, + InputT eta); + +namespace offset_poly_detail +{ + +inline void check_degree(std::size_t degree) +{ + if (degree > offset_poly_max_degree) + throw std::invalid_argument("offset poly: degree exceeds 16"); +} + +inline uint64_t binom_u64(unsigned n, unsigned k) +{ + if (k > n) + return 0; + if (k > n - k) + k = n - k; + unsigned __int128 c = 1; + for (unsigned i = 1; i <= k; ++i) + c = c * (n - k + i) / i; + return static_cast(c); +} + +inline std::vector binomial_shift(const std::vector & coeff, uint64_t limb) +{ + const std::size_t degree = coeff.empty() ? 0 : coeff.size() - 1; + std::vector pow(degree + 1, 1); + for (std::size_t m = 1; m <= degree; ++m) + pow[m] = pow[m - 1] * limb; + std::vector out(degree + 1, 0); + for (std::size_t m = 0; m < coeff.size(); ++m) + { + for (std::size_t k = 0; k <= m; ++k) + out[k] += coeff[m] * binom_u64(static_cast(m), static_cast(k)) * pow[m - k]; + } + return out; +} + +inline uint64_t horner(const std::vector & coeff, uint64_t point) +{ + if (coeff.empty()) + return 0; + uint64_t acc = coeff.back(); + for (std::size_t i = coeff.size() - 1; i-- > 0; ) + acc = acc * point + coeff[i]; + return acc; +} + +template +struct prepared +{ + InputT knot{}; + std::vector coeff; + std::int64_t kappa = 0; +}; + +template +std::vector> prepare( + const std::vector & knots, + const std::vector> & coeff, + InputT eta) +{ + using namespace offset_horner_detail; + if (knots.empty() || knots.size() != coeff.size()) + throw std::invalid_argument("offset poly: knots and coefficient rows differ"); + const std::size_t width = coeff.front().size(); + for (const auto & row : coeff) + { + if (row.size() != width) + throw std::invalid_argument("offset poly: coefficient rows differ in length"); + } + for (std::size_t i = 1; i < knots.size(); ++i) + { + if (!(knots[i - 1] < knots[i])) + throw std::invalid_argument("offset poly: knots must be strictly increasing"); + } + + std::vector> rows(knots.size()); + for (std::size_t i = 0; i < knots.size(); ++i) + { + rows[i].knot = offset_horner_group_sub(knots[i], eta); + rows[i].coeff = coeff[i]; + } + std::sort(rows.begin(), rows.end(), + [](const prepared & a, const prepared & b) { return a.knot < b.knot; }); + + const auto insert = [&](InputT point) { + for (const auto & row : rows) + { + if (row.knot == point) + return; + } + std::vector cuts; + for (const auto & row : rows) + cuts.push_back(row.knot); + std::size_t hot = rows.size() - 1; + for (std::size_t i = 0; i + 1 < cuts.size(); ++i) + { + if (point >= cuts[i] && point < cuts[i + 1]) + { + hot = i; + break; + } + } + prepared extra; + extra.knot = point; + extra.coeff = rows[hot].coeff; + rows.push_back(std::move(extra)); + std::sort(rows.begin(), rows.end(), + [](const prepared & a, const prepared & b) { return a.knot < b.knot; }); + }; + + constexpr unsigned bits = dpf::utils::bitlength_of_v; + if (bits <= 62) + { + insert(domain_min()); + if (const auto cut = carry_threshold(eta)) + insert(*cut); + } + for (auto & row : rows) + row.kappa = kappa_for(row.knot, eta); + return rows; +} + +template +std::vector segments(const Key & key, const std::vector & knots, uint64_t wrap_share, + dpf::proof_token * pi = nullptr) +{ + const std::size_t n = knots.size(); + if (n == 1) + { + if (pi != nullptr) + { + dpf::detail::vdpf::init_proof(*pi, key); + dpf::detail::vdpf::fold_output_binding(*pi, key); + } + return std::vector{wrap_share & key.cmp().mask}; + } + std::vector prefix(n); + signed_prefix_parities_into(key, knots.data(), n, prefix.data(), pi); + return offset_horner_detail::segments_from_prefixes(prefix, wrap_share, key.cmp().mask); +} + +} // namespace offset_poly_detail +/// \complexity One `dpf::make_dpf` of `idcf(gt)` on a `degree + 1` lane vector. `degree` is rejected above `offset_poly_max_degree` (16). +/// The seed spine is one key. Value words grow with `degree`. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One comparison key and `degree + 1` additive payload splits (`wrap_share`, two `uint64_t` each). +/// @see grotto::offset_horner_eval +/// @see grotto::offset_jet_eval + +template +offset_poly_keys make_offset_poly_keys(InputT center, std::size_t degree) +{ + using namespace offset_horner_detail; + offset_poly_detail::check_degree(degree); + offset_poly_keys mat; + mat.degree = degree; + mat.verifiable = false; + std::vector payload(degree + 1); + mat.wrap_share.reserve(degree + 1); + uint64_t pow = 1; + const uint64_t base = lift(center); + for (std::size_t m = 0; m <= degree; ++m) + { + payload[m] = pow; + const uint64_t blind = dpf::uniform_sample(); + mat.wrap_share.push_back({blind, pow - blind}); + pow *= base; + } + mat.keys = make_lane_keys(center, payload.data(), payload.size()); + return mat; +} +/// \complexity One `dpf::make_dpf` of `idcf(gt)` on a `degree + 1` lane vector, with proof tokens. `degree` is rejected above `offset_poly_max_degree` (16). +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One verifiable comparison key and `degree + 1` additive payload splits (`wrap_share`, two `uint64_t` each). +/// @see grotto::offset_horner_eval +/// @see grotto::offset_jet_eval + +template +offset_poly_keys make_offset_poly_keys(InputT center, std::size_t degree, + dpf::verifiable) +{ + using namespace offset_horner_detail; + offset_poly_detail::check_degree(degree); + offset_poly_keys mat; + mat.degree = degree; + mat.verifiable = true; + std::vector payload(degree + 1); + mat.wrap_share.reserve(degree + 1); + uint64_t pow = 1; + const uint64_t base = lift(center); + for (std::size_t m = 0; m <= degree; ++m) + { + payload[m] = pow; + const uint64_t blind = dpf::uniform_sample(); + mat.wrap_share.push_back({blind, pow - blind}); + pow *= base; + } + mat.keys_v = make_lane_keys(center, payload.data(), payload.size()); + return mat; +} +/// \complexity Piece preparation plus a Horner of `degree + 1` terms on the hot piece. No keys. `degree ≤ 16`. +/// @see grotto::offset_poly_eval + +template +uint64_t offset_poly_clear( + InputT center, + const std::vector & knots, + const std::vector> & coeff, + InputT eta) +{ + using namespace offset_poly_detail; + const auto pieces = prepare(knots, coeff, eta); + std::vector cuts; + for (const auto & piece : pieces) + cuts.push_back(piece.knot); + std::size_t hot = pieces.size() - 1; + for (std::size_t i = 0; i + 1 < cuts.size(); ++i) + { + if (center >= cuts[i] && center < cuts[i + 1]) + { + hot = i; + break; + } + } + const auto q = binomial_shift(pieces[hot].coeff, static_cast(pieces[hot].kappa)); + return horner(q, offset_horner_detail::lift(center)); +} +/// \complexity `prepare` shifts and sorts the knots and inserts the same carry cuts. Then one segment walk of the `degree + 1` lane payload. +/// Refined pieces: the knot vector, plus the cuts `prepare` / `prepare_pieces` inserts (domain minimum, and the carry threshold when the input width is at most 62 bits). Call that count `P`. +/// Time is one walk, `degree ≤ 16`. Extra space `Θ(P · degree)` for the shifted rows. +/// \rounds None. `eta` is already public to the caller. +/// \communication None. +/// \preprocessing None created here. Uses the key from `make_offset_poly_keys`. +/// @see grotto::offset_horner_eval +/// @see grotto::offset_jet_eval + +template +uint64_t offset_poly_eval( + const offset_poly_keys & mat, + const std::vector & knots, + const std::vector> & coeff, + InputT eta, dpf::proof_token * tokens) +{ + static_assert(Party < 2, "offset poly party is 0 or 1"); + using namespace offset_horner_detail; + using namespace offset_poly_detail; + const std::size_t lanes = mat.verifiable ? mat.keys_v.index() : mat.keys.index(); + if (lanes != mat.degree + 1) + throw std::invalid_argument("offset poly: comparison payload width differs from the degree"); + const auto pieces = prepare(knots, coeff, eta); + std::vector shifted; + shifted.reserve(pieces.size()); + for (const auto & piece : pieces) + shifted.push_back(piece.knot); + + uint64_t value = 0; + std::vector> shifted_coeff(pieces.size()); + for (std::size_t i = 0; i < pieces.size(); ++i) + shifted_coeff[i] = binomial_shift(pieces[i].coeff, + static_cast(pieces[i].kappa)); + dpf::proof_token * pi = (mat.verifiable && tokens != nullptr) ? &tokens[0] : nullptr; + const auto table = mat.verifiable + ? lane_segments(mat.keys_v, shifted, mat.wrap_share, pi) + : lane_segments(mat.keys, shifted, mat.wrap_share, nullptr); + if (mat.verifiable) + replicate_proof(tokens, mat.degree + 1); + for (std::size_t m = 0; m <= mat.degree; ++m) + for (std::size_t i = 0; i < pieces.size(); ++i) + value += table[i][m] * shifted_coeff[i][m]; + return value; +} + +/// @brief Public carry `kappa` of each refined piece, in knot order. +/// \complexity One `prepare` (sort plus carry cuts) and a copy of each piece's `kappa`. Time dominated by the sort, `Θ(P log P)`. Extra space `Θ(P)`. +/// @see grotto::offset_poly_eval +template +std::vector offset_poly_kappas( + const std::vector & knots, + std::size_t degree, + InputT eta) +{ + std::vector> dummy(knots.size(), std::vector(degree + 1, 0)); + const auto pieces = offset_poly_detail::prepare(knots, dummy, eta); + std::vector out; + out.reserve(pieces.size()); + for (const auto & piece : pieces) + out.push_back(piece.kappa); + return out; +} + +/// @brief One party's binomial shift of an additive coefficient share. +/// @details `eta`'s carry `kappa` is public, so each party runs the same linear map. +/// \complexity `binomial_shift` over the coefficient vector. The implementation is a `Θ(degree²)` Pascal update (`degree` is `coeff_share.size() - 1`, at most 16). +/// @see grotto::offset_poly_power_shares +/// @note `kappa` is public, so each party runs the same linear map. +inline std::vector offset_poly_shift_share( + const std::vector & coeff_share, std::int64_t kappa) +{ + return offset_poly_detail::binomial_shift(coeff_share, static_cast(kappa)); +} + +/// @brief Shares of `center^m` on every refined piece, for one party. +/// \complexity One segment walk of the `degree + 1` lane payload over the refined pieces. Same `P` and `degree ≤ 16` as `offset_poly_eval`. Extra space `Θ(P · degree)`. +/// \rounds None. +/// \communication None. +/// \preprocessing None created here. +/// @see grotto::offset_poly_eval +template +std::vector> offset_poly_power_shares( + const offset_poly_keys & mat, + const std::vector & knots, + InputT eta) +{ + static_assert(Party < 2, "offset poly party is 0 or 1"); + using namespace offset_poly_detail; + std::vector> dummy(knots.size(), std::vector(mat.degree + 1, 0)); + const auto pieces = prepare(knots, dummy, eta); + std::vector shifted; + for (const auto & piece : pieces) + shifted.push_back(piece.knot); + const auto table = mat.verifiable + ? offset_horner_detail::lane_segments(mat.keys_v, shifted, mat.wrap_share, nullptr) + : offset_horner_detail::lane_segments(mat.keys, shifted, mat.wrap_share, nullptr); + return table; +} + +/// @brief Beaver dot of shifted coefficient shares with power shares. +/// @details `q` and `power` are flattened in the same order. `opened_d` and +/// `opened_e` are the reconstructed masked differences `q - a` and +/// `power - b` (each party opens its own `q_share - a_share` and +/// `power_share - b_share`; their sums are the only openings). +/// Party 0 adds the public `d·e` term. F_Poly does not open `q` or +/// `center^m`. +/// \complexity One pass over the flattened vectors: `Θ(N)` multiplies, `N = q_share.size()`. Extra space `Θ(1)`. +/// \rounds None in this function. `opened_d` and `opened_e` are arguments; the opening of those masked differences is not performed here. +/// \communication None. +/// @note Party 0 adds the public `d·e` term. This matches the comment above the declaration. +/// @see grotto::offset_poly_power_shares +inline uint64_t offset_poly_beaver_share( + std::size_t party, + const std::vector & q_share, + const std::vector & power_share, + const std::vector & opened_d, + const std::vector & opened_e, + const dpf::beavers::dot_beaver & triple) +{ + if (party > 1) + throw std::invalid_argument("offset poly party is 0 or 1"); + if (q_share.size() != power_share.size() || q_share.size() != opened_d.size() + || opened_d.size() != opened_e.size() || q_share.size() != triple.x.size()) + throw std::invalid_argument("offset poly: beaver dot length differs"); + uint64_t acc = party == 0 ? triple.cross.p0 : triple.cross.p1; + for (std::size_t i = 0; i < q_share.size(); ++i) + { + const uint64_t a = party == 0 ? triple.x[i].p0 : triple.x[i].p1; + const uint64_t b = party == 0 ? triple.y[i].p0 : triple.y[i].p1; + const uint64_t d = opened_d[i]; + const uint64_t e = opened_e[i]; + acc += e * a + d * b; + if (party == 0) + acc += d * e; + } + (void)q_share; + (void)power_share; + return acc; +} + +/// @brief Authenticated product share: plain Beaver dot plus a dealer tag share. +/// @details Opt-in. Callers that do not need a MAC keep the overload above. +/// `tag_share` is this party's share of `(v·Δ)` for the reconstructed +/// product `v`; sample it with `mac_share_value(v0+v1, key)`. +/// @param party 0 or 1 +/// @param q_share shifted coefficient share, flattened +/// @param power_share power share, same order as `q_share` +/// @param opened_d already-opened `q - a` +/// @param opened_e already-opened `power - b` +/// @param triple dealer Beaver dot triple +/// @param tag_share this party's MAC tag share +/// @return the product share and the tag +/// @see grotto::offset_poly_beaver_share +/// \complexity One call of the plain Beaver dot (`Θ(N)`) plus storing `tag_share`. Extra space `Θ(1)`. +/// \rounds None. `opened_d`, `opened_e`, and `tag_share` are arguments. +/// \communication None. +inline dpf::mac_share offset_poly_beaver_share( + std::size_t party, + const std::vector & q_share, + const std::vector & power_share, + const std::vector & opened_d, + const std::vector & opened_e, + const dpf::beavers::dot_beaver & triple, + uint64_t tag_share) +{ + return dpf::mac_share{ + offset_poly_beaver_share(party, q_share, power_share, opened_d, + opened_e, triple), + tag_share}; +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_OFFSET_POLY_HPP__ diff --git a/include/grotto/offset_repr.hpp b/include/grotto/offset_repr.hpp new file mode 100644 index 0000000..2abc7c9 --- /dev/null +++ b/include/grotto/offset_repr.hpp @@ -0,0 +1,424 @@ +/// @file grotto/offset_repr.hpp +/// @brief Representation shift: advance a linear-recurrence state by a public offset. +/// @details Offset Horner is the unipotent (Pascal) case of a shift-invariant +/// module. Here the dealer keys one incremental comparison whose +/// payload is the state vector +/// \f$S_c\in(\mathbb{Z}/2^{64})^d\f$ at the hidden center. The seed +/// spine is stored once. After `eta` +/// opens, each refined piece has a public carry `kappa`, and the +/// parties apply the public matrix power +/// \f$S_{c+\kappa}=M^{\kappa}S_c.\f$ +/// Negative `kappa` uses \f$M^{-1}\f$ (the determinant must be a unit). +/// The wrap branch is multiplication by the public constant +/// \f$M^{\mp 2^n}\f$; when \f$M^{2^n}=I\f$ it is the identity. +/// +/// Fibonacci is the companion matrix of \f$T^2-T-1\f$, via the Lucas +/// addition formula \f$F_{c+\kappa}=F_{\kappa}F_{c+1}+F_{\kappa-1}F_c\f$. +/// A \f$1\times 1\f$ matrix \f$[\lambda]\f$ is a geometric jump +/// \f$\lambda^{c+\kappa}=\lambda^{\kappa}\lambda^{c}\f$. CRC / LFSR +/// resume over \f$\mathrm{GF}(2)\f$ is the same checkpoint with XOR +/// shares; the cleartext jump helper documents that twin. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_GROTTO_OFFSET_REPR_HPP__ +#define LIBDPF_INCLUDE_GROTTO_OFFSET_REPR_HPP__ + +#include "grotto/offset_poly.hpp" + +#include +#include +#include +#include +#include +#include +#include + +namespace grotto +{ + +inline constexpr std::size_t offset_repr_max_dim = 8; + +template +struct offset_repr_keys +{ + static_assert(std::is_integral_v, "offset repr domain must be an integer group"); + + using input_type = InputT; + + std::size_t dim = 0; + bool verifiable = false; + /// @brief One `idcf(gt)` of `vec`. + offset_horner_detail::lane_keys keys{}; + offset_horner_detail::lane_keys keys_v{}; + std::vector> wrap_share; +}; + +namespace offset_repr_detail +{ + +inline void check_dim(std::size_t dim) +{ + if (dim == 0 || dim > offset_repr_max_dim) + throw std::invalid_argument("offset repr: dimension must be in 1..8"); +} + +inline void check_square(const std::vector> & M, std::size_t dim) +{ + if (M.size() != dim) + throw std::invalid_argument("offset repr: matrix row count differs from dim"); + for (const auto & row : M) + { + if (row.size() != dim) + throw std::invalid_argument("offset repr: matrix is not square"); + } +} + +inline std::vector> identity(std::size_t dim) +{ + std::vector> I(dim, std::vector(dim, 0)); + for (std::size_t i = 0; i < dim; ++i) + I[i][i] = 1; + return I; +} + +inline std::vector> matmul( + const std::vector> & A, + const std::vector> & B) +{ + const std::size_t n = A.size(); + std::vector> C(n, std::vector(n, 0)); + for (std::size_t i = 0; i < n; ++i) + for (std::size_t k = 0; k < n; ++k) + for (std::size_t j = 0; j < n; ++j) + C[i][j] += A[i][k] * B[k][j]; + return C; +} + +inline std::vector matvec( + const std::vector> & M, + const std::vector & v) +{ + const std::size_t n = M.size(); + std::vector out(n, 0); + for (std::size_t i = 0; i < n; ++i) + for (std::size_t j = 0; j < n; ++j) + out[i] += M[i][j] * v[j]; + return out; +} + +inline uint64_t inv_u64(uint64_t a) +{ + if ((a & 1u) == 0) + throw std::invalid_argument("offset repr: matrix determinant is not a unit"); + uint64_t x = a; + x *= 2 - a * x; + x *= 2 - a * x; + x *= 2 - a * x; + x *= 2 - a * x; + x *= 2 - a * x; + return x; +} + +/// @brief Matrix inverse over \f$\mathbb{Z}/2^{64}\f$ by Gauss–Jordan. +inline std::vector> inverse( + std::vector> A) +{ + const std::size_t n = A.size(); + auto I = identity(n); + for (std::size_t k = 0; k < n; ++k) + { + std::size_t piv = k; + while (piv < n && (A[piv][k] & 1u) == 0) + ++piv; + if (piv == n) + throw std::invalid_argument("offset repr: matrix is not invertible over Z/2^64"); + std::swap(A[piv], A[k]); + std::swap(I[piv], I[k]); + const uint64_t inv = inv_u64(A[k][k]); + for (std::size_t j = 0; j < n; ++j) + { + A[k][j] *= inv; + I[k][j] *= inv; + } + for (std::size_t i = 0; i < n; ++i) + { + if (i == k) + continue; + const uint64_t f = A[i][k]; + for (std::size_t j = 0; j < n; ++j) + { + A[i][j] -= f * A[k][j]; + I[i][j] -= f * I[k][j]; + } + } + } + return I; +} + +} // namespace offset_repr_detail + +/// @brief \f$M^{e}\f$ for a signed exponent, over \f$\mathbb{Z}/2^{64}\f$. +/// \complexity If `exp < 0`, one Gauss–Jordan inverse (`inverse`, three nested loops over `n = M.size()`). +/// Then one squaring per bit of `|exp|`: the `while (e != 0)` loop, each step two `matmul`s (`Θ(n³)` each). `exp` is an `int64_t`, so at most 63 squarings. +/// Extra space `Θ(n²)` for `acc` and `base`. This function does not apply `offset_repr_max_dim`; callers that go through `check_dim` use `n ≤ 8`. +/// @see grotto::offset_repr_eval +inline std::vector> offset_repr_matrix_pow( + std::vector> M, std::int64_t exp) +{ + const std::size_t n = M.size(); + offset_repr_detail::check_square(M, n); + if (exp < 0) + { + M = offset_repr_detail::inverse(std::move(M)); + exp = -exp; + } + auto acc = offset_repr_detail::identity(n); + auto base = std::move(M); + auto e = static_cast(exp); + while (e != 0) + { + if (e & 1u) + acc = offset_repr_detail::matmul(acc, base); + base = offset_repr_detail::matmul(base, base); + e >>= 1; + } + return acc; +} + +/// @brief Companion matrix of Fibonacci: \f$S_n=(F_{n+1},F_n)\f$, \f$S_{n+1}=MS_n\f$. +/// \complexity Returns a 2×2 constant. `Θ(1)`. +/// @see grotto::offset_repr_fibonacci_state +inline std::vector> offset_repr_fibonacci_matrix() +{ + return {{1, 1}, {1, 0}}; +} + +/// @brief Fibonacci state at index `n`: \f$(F_{n+1}, F_n)\f$ in \f$\mathbb{Z}/2^{64}\f$. +/// \complexity One `offset_repr_matrix_pow` of the 2×2 companion at exponent `n`, then a matrix-vector product. `Θ(log n)` 2×2 multiplies. +/// @see grotto::offset_repr_matrix_pow +inline std::vector offset_repr_fibonacci_state(std::uint64_t n) +{ + if (n == 0) + return {1, 0}; // F_1=1, F_0=0 + auto M = offset_repr_matrix_pow(offset_repr_fibonacci_matrix(), + static_cast(n)); + // S_0 = (1, 0); S_n = M^n S_0. + return offset_repr_detail::matvec(M, {1, 0}); +} + +/// @brief \f$1\times 1\f$ geometric matrix \f$[\lambda]\f$. +/// \complexity Returns a 1×1 matrix. `Θ(1)`. +/// @see grotto::offset_repr_matrix_pow +inline std::vector> offset_repr_geometric_matrix(uint64_t lambda) +{ + return {{lambda}}; +} + +/// @brief Cleartext CRC-32 jump by `steps` bits (ISO / Ethernet polynomial). +/// @details Public twin of a GF(2) representation shift: one register word, +/// multiply by \f$x^{\mathrm{steps}}\f$ in \f$\mathrm{GF}(2)[x]/(p)\f$. +/// Keyed CRC wants XOR shares of the register; this helper is the +/// public \f$A^{\kappa}\f$ factor those shares would be multiplied by. +/// \complexity Builds a `64 × 32` jump table once (function-local static), then +/// applies one table lookup per set bit of `steps` (at most 64). +/// Extra space is that `64 × 32` table of `uint32_t`. Cleartext; no keys. +/// @see grotto::offset_repr_eval +/// @note This is the public twin. It does not take XOR shares. +inline std::uint32_t offset_repr_crc32_jump(std::uint32_t state, std::uint64_t steps) +{ + constexpr std::uint32_t poly = 0xEDB88320u; + // jump[k][i] = image of the singleton bit `1<, 64> table{}; + auto step1 = [](std::uint32_t s) { + return (s >> 1) ^ (poly & (0u - (s & 1u))); + }; + for (unsigned i = 0; i < 32; ++i) + table[0][i] = step1(std::uint32_t{1u} << i); + for (unsigned k = 1; k < 64; ++k) + for (unsigned i = 0; i < 32; ++i) + { + std::uint32_t s = table[k - 1][i]; + std::uint32_t out = 0; + for (unsigned b = 0; b < 32; ++b) + if ((s >> b) & 1u) + out ^= table[k - 1][b]; + table[k][i] = out; + } + return table; + }(); + for (unsigned k = 0; k < 64; ++k) + { + if (((steps >> k) & 1u) == 0) + continue; + std::uint32_t nxt = 0; + for (unsigned b = 0; b < 32; ++b) + if ((state >> b) & 1u) + nxt ^= jump[k][b]; + state = nxt; + } + return state; +} +/// \complexity One `dpf::make_dpf` of `idcf(gt)` on a `dim`-lane vector. `check_dim` requires the length in `1 .. offset_repr_max_dim` (8). +/// The seed spine is one key. Value words grow with `dim`. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One comparison key and `dim` additive splits of the state lanes. +/// @see grotto::offset_horner_eval +/// @see [Representation shift](@ref offset_repr) + +template +offset_repr_keys make_offset_repr_keys( + InputT center, const std::vector & state) +{ + using namespace offset_horner_detail; + offset_repr_detail::check_dim(state.size()); + offset_repr_keys mat; + mat.dim = state.size(); + mat.verifiable = false; + mat.wrap_share.reserve(mat.dim); + for (std::size_t i = 0; i < mat.dim; ++i) + { + const uint64_t blind = dpf::uniform_sample(); + mat.wrap_share.push_back({blind, state[i] - blind}); + } + mat.keys = offset_horner_detail::make_lane_keys( + center, state.data(), state.size()); + return mat; +} +/// \complexity One `dpf::make_dpf` of `idcf(gt)` on a `dim`-lane vector. `check_dim` requires the length in `1 .. offset_repr_max_dim` (8). +/// The seed spine is one key. Value words grow with `dim`. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One comparison key and `dim` additive splits of the state lanes. +/// @see grotto::offset_horner_eval +/// @see [Representation shift](@ref offset_repr) + +template +offset_repr_keys make_offset_repr_keys( + InputT center, const std::vector & state, dpf::verifiable) +{ + using namespace offset_horner_detail; + offset_repr_detail::check_dim(state.size()); + offset_repr_keys mat; + mat.dim = state.size(); + mat.verifiable = true; + mat.wrap_share.reserve(mat.dim); + for (std::size_t i = 0; i < mat.dim; ++i) + { + const uint64_t blind = dpf::uniform_sample(); + mat.wrap_share.push_back({blind, state[i] - blind}); + } + mat.keys_v = offset_horner_detail::make_lane_keys( + center, state.data(), state.size()); + return mat; +} + +/// @brief Shares of \f$S_c\f$ on every refined piece (pre-advance), for one party. +/// \complexity One segment walk of the `dim`-lane payload (`dim ≤ 8`) over the refined pieces. Extra space `Θ(P · dim)`. +/// \rounds None. +/// \communication None. +/// \preprocessing None created here. +/// @see grotto::offset_repr_eval +template +std::vector> offset_repr_state_shares( + const offset_repr_keys & mat, + const std::vector & knots, + InputT eta, + dpf::proof_token * tokens = nullptr) +{ + static_assert(Party < 2, "offset repr party is 0 or 1"); + using namespace offset_horner_detail; + using namespace offset_poly_detail; + const std::size_t lanes = mat.verifiable ? mat.keys_v.index() : mat.keys.index(); + if (lanes != mat.dim) + throw std::invalid_argument("offset repr: comparison payload width differs from the state"); + std::vector> dummy(knots.size(), + std::vector(mat.dim, 0)); + const auto pieces = prepare(knots, dummy, eta); + std::vector shifted; + for (const auto & piece : pieces) + shifted.push_back(piece.knot); + dpf::proof_token * pi = (mat.verifiable && tokens != nullptr) ? &tokens[0] : nullptr; + auto out = mat.verifiable + ? lane_segments(mat.keys_v, shifted, mat.wrap_share, pi) + : lane_segments(mat.keys, shifted, mat.wrap_share, nullptr); + if (mat.verifiable) + replicate_proof(tokens, mat.dim); + return out; +} + +/// @brief One party's share of \f$M^{\kappa}S_c\f$ at the wrapped point. +/// \complexity One segment walk of the `dim`-lane payload (`dim ≤ 8`), then `offset_repr_matrix_pow(M, kappa)` and a matrix-vector product on every refined piece. +/// `offset_repr_matrix_pow` squares a `dim × dim` matrix once per bit of `|kappa|` (`matmul` is three nested `dim` loops). +/// Refined pieces: the knot vector, plus the cuts `prepare` / `prepare_pieces` inserts (domain minimum, and the carry threshold when the input width is at most 62 bits). Call that count `P`. +/// Time is one walk plus `Θ(P · bitlength(kappa) · dim³)` field operations. Extra space `Θ(P · dim)` for the state table and `Θ(dim²)` for the matrix powers. +/// \rounds None. `eta` is an argument. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_offset_repr_keys`. +/// @note A negative `kappa` inverts `M`. `inverse` rejects an even determinant (not a unit in `Z/2^64`). +/// @see grotto::offset_horner_eval +/// @see [Representation shift](@ref offset_repr) +template +std::vector offset_repr_eval( + const offset_repr_keys & mat, + const std::vector> & M, + const std::vector & knots, + InputT eta, + dpf::proof_token * tokens = nullptr) +{ + offset_repr_detail::check_square(M, mat.dim); + using namespace offset_poly_detail; + std::vector> dummy(knots.size(), + std::vector(mat.dim, 0)); + const auto pieces = prepare(knots, dummy, eta); + const auto states = offset_repr_state_shares(mat, knots, eta, tokens); + std::vector out(mat.dim, 0); + for (std::size_t p = 0; p < pieces.size(); ++p) + { + const auto Mk = offset_repr_matrix_pow(M, pieces[p].kappa); + const auto advanced = offset_repr_detail::matvec(Mk, states[p]); + for (std::size_t i = 0; i < mat.dim; ++i) + out[i] += advanced[i]; + } + return out; +} + +/// @brief Cleartext \f$M^{\kappa}S_c\f$ on the hot piece. +/// \complexity Same matrix powers as `offset_repr_eval`, but on the single hot piece and with the clear state instead of shares. `Θ(bitlength(kappa) · dim³)`. +/// @see grotto::offset_repr_eval +template +std::vector offset_repr_clear( + InputT center, + const std::vector & state, + const std::vector> & M, + const std::vector & knots, + InputT eta) +{ + offset_repr_detail::check_dim(state.size()); + offset_repr_detail::check_square(M, state.size()); + using namespace offset_poly_detail; + std::vector> dummy(knots.size(), + std::vector(state.size(), 0)); + const auto pieces = prepare(knots, dummy, eta); + std::vector cuts; + for (const auto & piece : pieces) + cuts.push_back(piece.knot); + std::size_t hot = pieces.size() - 1; + for (std::size_t i = 0; i + 1 < cuts.size(); ++i) + { + if (center >= cuts[i] && center < cuts[i + 1]) + { + hot = i; + break; + } + } + const auto Mk = offset_repr_matrix_pow(M, pieces[hot].kappa); + return offset_repr_detail::matvec(Mk, state); +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_OFFSET_REPR_HPP__ diff --git a/include/grotto/offset_twist.hpp b/include/grotto/offset_twist.hpp new file mode 100644 index 0000000..fa1e105 --- /dev/null +++ b/include/grotto/offset_twist.hpp @@ -0,0 +1,533 @@ +/// @file grotto/offset_twist.hpp +/// @brief Twisted monomials \f$c^{j}\lambda^{c}\f$ after the public offset opens. +/// @details The dealer keys one incremental comparison whose payload is the +/// vector of twisted powers \f$c^{m}\lambda^{c}\f$ in \f$\mathbb{Z}/2^{64}\f$. +/// The seed spine is stored once. After `eta` opens, +/// the segment walk returns those shares on the hot piece. A public +/// binomial shift of the coefficient vector by the piece's carry +/// `kappa`, followed by a public factor \f$\lambda^{\kappa}\f$, yields +/// \f$\sum_{m}a_m(c+\kappa)^{m}\lambda^{c+\kappa} =\lambda^{\kappa}\sum_{m}q_m\,c^{m}\lambda^{c},\f$ +/// where \f$q=\mathrm{Pascal}(\kappa)\,a\f$. Odd \f$\lambda\f$ are units, +/// so negative `kappa` is \f$\lambda^{\kappa}=(\lambda^{-1})^{|\kappa|}\f$. +/// +/// Dyadic decay \f$\lambda=1/2\f$ is the tag `twist_half`. A right shift +/// does not distribute over additive shares. The untwisted powers stay +/// randomly shared. The shift count is `lift(center) + kappa`, with +/// the center held only as an additive share. A masked low-limb +/// opening (uniform, not returned) supplies the carry, and the +/// shifted value is re-shared under a keygen pad. Neither output +/// share is the untwisted sum or the center. +/// `offset_twist_clear` with `twist_half` evaluates the dyadic target +/// in the clear. +/// +/// The closed form +/// \f$\sum_{k=1}^{n}k\lambda^{k}=\lambda\frac{1-(n+1)\lambda^{n}+n\lambda^{n+1}}{(1-\lambda)^{2}}\f$ +/// (for \f$\lambda\neq 1\f$) is a readout of the same twisted table. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_GROTTO_OFFSET_TWIST_HPP__ +#define LIBDPF_INCLUDE_GROTTO_OFFSET_TWIST_HPP__ + +#include "grotto/offset_poly.hpp" + +#include +#include +#include +#include +#include +#include +#include + +namespace grotto +{ + +inline constexpr std::size_t offset_twist_max_degree = offset_poly_max_degree; + +/// @brief Tag selecting dyadic \f$\lambda=1/2\f$ (public shifts, not a unit multiply). +struct twist_half_t +{ + explicit twist_half_t() = default; +}; +inline constexpr twist_half_t twist_half{}; + +template +struct offset_twist_keys +{ + static_assert(std::is_integral_v, "offset twist domain must be an integer group"); + + using input_type = InputT; + + std::size_t degree = 0; + uint64_t lambda = 1; + bool half = false; + bool verifiable = false; + /// @brief One `idcf(gt)` of `vec`. + offset_horner_detail::lane_keys keys{}; + offset_horner_detail::lane_keys keys_v{}; + std::vector> wrap_share; + /// @brief Additive shares of `lift(center)`. Not the center. + std::array shift_base_share{}; + /// @brief Pad on party 0's dyadic output. Party 1 holds `shifted - pad`. + uint64_t dyadic_pad = 0; +}; + +namespace offset_twist_detail +{ + +inline void check_degree(std::size_t degree) +{ + if (degree > offset_twist_max_degree) + throw std::invalid_argument("offset twist: degree exceeds 16"); +} + +inline uint64_t inv_odd(uint64_t a) +{ + if ((a & 1u) == 0) + throw std::invalid_argument("offset twist: lambda must be odd (or twist_half)"); + uint64_t x = a; + x *= 2 - a * x; + x *= 2 - a * x; + x *= 2 - a * x; + x *= 2 - a * x; + x *= 2 - a * x; + return x; +} + +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr inline uint64_t pow_u64(uint64_t base, std::uint64_t exp) noexcept +{ + uint64_t acc = 1; + while (exp != 0) + { + if (exp & 1u) + acc *= base; + base *= base; + exp >>= 1; + } + return acc; +} + +inline uint64_t pow_signed(uint64_t lambda, std::int64_t exp) +{ + if (exp >= 0) + return pow_u64(lambda, static_cast(exp)); + return pow_u64(inv_odd(lambda), static_cast(-exp)); +} + +/// @brief `(a + b mod 2^64) >> k`, via the low-limb carry. `k == 0` is the sum. +/// @details A masked opening of that limb is uniform and recovers the same +/// carry, so the shift itself does not sample. +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr inline uint64_t shr_sum(uint64_t a, uint64_t b, unsigned k) noexcept +{ + if (k == 0) + return a + b; + if (k >= 64) + return 0; + const uint64_t mask = (uint64_t{1} << k) - 1u; + const unsigned __int128 low_carry = + (static_cast(a & mask) + (b & mask)) >> k; + unsigned __int128 hi = + static_cast(a >> k) + (b >> k) + low_carry; + if ((a + b) < a) + hi -= static_cast(1) << (64u - k); + return static_cast(hi); +} + +/// @brief Shift the uint64 sum `a + b` by a signed count. Left shifts distribute. +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr inline uint64_t shift_sum(uint64_t a, uint64_t b, std::int64_t w) noexcept +{ + if (w >= 64 || w <= -64) + return 0; + if (w >= 0) + return shr_sum(a, b, static_cast(w)); + const unsigned k = static_cast(-w); + return (a << k) + (b << k); +} + +/// @brief Apply the public geometric factor to a ring share. +inline uint64_t apply_lambda(uint64_t share, uint64_t lambda, bool half, + std::int64_t kappa) +{ + if (half) + { + if (kappa >= 64) + return 0; + if (kappa <= -64) + return 0; // left shift off the word is zero in Z/2^64 intent + if (kappa >= 0) + return share >> static_cast(kappa); + return share << static_cast(-kappa); + } + return share * pow_signed(lambda, kappa); +} + +} // namespace offset_twist_detail +/// \complexity One `dpf::make_dpf` of `idcf(gt)` on a `degree + 1` lane vector (`degree` at most 16). The odd-`lambda` path multiplies by `lambda^{lift(center)}` once, then by `lift(center)` each iteration. +/// The `twist_half` path stores `c^m` (no modular inverse) plus two extra `uint64_t` masks: `shift_base_share` and `dyadic_pad`. The seed spine is one key. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One comparison key and `degree + 1` payload splits. Dyadic keys also store the two-word `shift_base_share` and one `dyadic_pad`. +/// @note Odd `lambda` is required so a negative carry has an inverse in `Z/2^64`. `twist_half` is the dyadic case and does not multiply shares by `1/2`. +/// @see grotto::offset_poly_eval +/// @see [Twisted jets](@ref offset_twist) + +template +offset_twist_keys make_offset_twist_keys( + InputT center, std::size_t degree, uint64_t lambda) +{ + using namespace offset_horner_detail; + offset_twist_detail::check_degree(degree); + if ((lambda & 1u) == 0) + throw std::invalid_argument("offset twist: lambda must be odd; use twist_half for 1/2"); + offset_twist_keys mat; + mat.degree = degree; + mat.lambda = lambda; + mat.half = false; + mat.verifiable = false; + std::vector payload(degree + 1); + mat.wrap_share.reserve(degree + 1); + const uint64_t base = lift(center); + const uint64_t lam_c = offset_twist_detail::pow_u64(lambda, base); + uint64_t pow = 1; + for (std::size_t m = 0; m <= degree; ++m) + { + payload[m] = pow * lam_c; + const uint64_t blind = dpf::uniform_sample(); + mat.wrap_share.push_back({blind, payload[m] - blind}); + pow *= base; + } + mat.keys = offset_horner_detail::make_lane_keys( + center, payload.data(), payload.size()); + return mat; +} +/// \complexity One `dpf::make_dpf` of `idcf(gt)` on a `degree + 1` lane vector (`degree` at most 16). The odd-`lambda` path multiplies by `lambda^{lift(center)}` once, then by `lift(center)` each iteration. +/// The `twist_half` path stores `c^m` (no modular inverse) plus two extra `uint64_t` masks: `shift_base_share` and `dyadic_pad`. The seed spine is one key. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One comparison key and `degree + 1` payload splits. Dyadic keys also store the two-word `shift_base_share` and one `dyadic_pad`. +/// @note Odd `lambda` is required so a negative carry has an inverse in `Z/2^64`. `twist_half` is the dyadic case and does not multiply shares by `1/2`. +/// @see grotto::offset_poly_eval +/// @see [Twisted jets](@ref offset_twist) + +template +offset_twist_keys make_offset_twist_keys( + InputT center, std::size_t degree, uint64_t lambda, dpf::verifiable) +{ + using namespace offset_horner_detail; + offset_twist_detail::check_degree(degree); + if ((lambda & 1u) == 0) + throw std::invalid_argument("offset twist: lambda must be odd; use twist_half for 1/2"); + offset_twist_keys mat; + mat.degree = degree; + mat.lambda = lambda; + mat.half = false; + mat.verifiable = true; + std::vector payload(degree + 1); + mat.wrap_share.reserve(degree + 1); + const uint64_t base = lift(center); + const uint64_t lam_c = offset_twist_detail::pow_u64(lambda, base); + uint64_t pow = 1; + for (std::size_t m = 0; m <= degree; ++m) + { + payload[m] = pow * lam_c; + const uint64_t blind = dpf::uniform_sample(); + mat.wrap_share.push_back({blind, payload[m] - blind}); + pow *= base; + } + mat.keys_v = offset_horner_detail::make_lane_keys( + center, payload.data(), payload.size()); + return mat; +} +/// \complexity One `dpf::make_dpf` of `idcf(gt)` on a `degree + 1` lane vector (`degree` at most 16). The odd-`lambda` path multiplies by `lambda^{lift(center)}` once, then by `lift(center)` each iteration. +/// The `twist_half` path stores `c^m` (no modular inverse) plus two extra `uint64_t` masks: `shift_base_share` and `dyadic_pad`. The seed spine is one key. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One comparison key and `degree + 1` payload splits. Dyadic keys also store the two-word `shift_base_share` and one `dyadic_pad`. +/// @note Odd `lambda` is required so a negative carry has an inverse in `Z/2^64`. `twist_half` is the dyadic case and does not multiply shares by `1/2`. +/// @see grotto::offset_poly_eval +/// @see [Twisted jets](@ref offset_twist) + +template +offset_twist_keys make_offset_twist_keys( + InputT center, std::size_t degree, twist_half_t) +{ + using namespace offset_horner_detail; + offset_twist_detail::check_degree(degree); + offset_twist_keys mat; + mat.degree = degree; + mat.lambda = 0; // unused + mat.half = true; + mat.verifiable = false; + std::vector payload(degree + 1); + mat.wrap_share.reserve(degree + 1); + const uint64_t base = lift(center); + const uint64_t base_blind = dpf::uniform_sample(); + mat.shift_base_share = {base_blind, base - base_blind}; + mat.dyadic_pad = dpf::uniform_sample(); + uint64_t pow = 1; + for (std::size_t m = 0; m <= degree; ++m) + { + payload[m] = pow; + const uint64_t blind = dpf::uniform_sample(); + mat.wrap_share.push_back({blind, pow - blind}); + pow *= base; + } + mat.keys = offset_horner_detail::make_lane_keys( + center, payload.data(), payload.size()); + return mat; +} +/// \complexity One `dpf::make_dpf` of `idcf(gt)` on a `degree + 1` lane vector (`degree` at most 16). The odd-`lambda` path multiplies by `lambda^{lift(center)}` once, then by `lift(center)` each iteration. +/// The `twist_half` path stores `c^m` (no modular inverse) plus two extra `uint64_t` masks: `shift_base_share` and `dyadic_pad`. The seed spine is one key. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One comparison key and `degree + 1` payload splits. Dyadic keys also store the two-word `shift_base_share` and one `dyadic_pad`. +/// @note Odd `lambda` is required so a negative carry has an inverse in `Z/2^64`. `twist_half` is the dyadic case and does not multiply shares by `1/2`. +/// @see grotto::offset_poly_eval +/// @see [Twisted jets](@ref offset_twist) + +template +offset_twist_keys make_offset_twist_keys( + InputT center, std::size_t degree, twist_half_t, dpf::verifiable) +{ + using namespace offset_horner_detail; + offset_twist_detail::check_degree(degree); + offset_twist_keys mat; + mat.degree = degree; + mat.lambda = 0; + mat.half = true; + mat.verifiable = true; + std::vector payload(degree + 1); + mat.wrap_share.reserve(degree + 1); + const uint64_t base = lift(center); + const uint64_t base_blind = dpf::uniform_sample(); + mat.shift_base_share = {base_blind, base - base_blind}; + mat.dyadic_pad = dpf::uniform_sample(); + uint64_t pow = 1; + for (std::size_t m = 0; m <= degree; ++m) + { + payload[m] = pow; + const uint64_t blind = dpf::uniform_sample(); + mat.wrap_share.push_back({blind, pow - blind}); + pow *= base; + } + mat.keys_v = offset_horner_detail::make_lane_keys( + center, payload.data(), payload.size()); + return mat; +} + +/// @brief Shares of \f$c^{m}\lambda^{c}\f$ (or \f$c^{m}\f$ when `half`) per piece. +/// \complexity Same piece walk as offset poly: one segment walk of the lane payload, then a public Pascal shift and a multiply by `lambda^kappa` (`pow_signed`, `Θ(log |kappa|)` multiplies). +/// For `twist_half` the multiply is replaced by `shr_sum` on the opened sum; the right shift itself is not applied to the shares inside the walk. +/// Refined pieces: the knot vector, plus the cuts `prepare` / `prepare_pieces` inserts (domain minimum, and the carry threshold when the input width is at most 62 bits). Call that count `P`. +/// \rounds None. `eta` is an argument. The dyadic right shift is a public post-processing step after the shares are opened, and this function does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_offset_twist_keys`. +/// @see grotto::offset_poly_eval +/// @see [Twisted jets](@ref offset_twist) +template +std::vector> offset_twist_power_shares( + const offset_twist_keys & mat, + const std::vector & knots, + InputT eta, + dpf::proof_token * tokens = nullptr) +{ + static_assert(Party < 2, "offset twist party is 0 or 1"); + using namespace offset_horner_detail; + using namespace offset_poly_detail; + const std::size_t lanes = mat.verifiable ? mat.keys_v.index() : mat.keys.index(); + if (lanes != mat.degree + 1) + throw std::invalid_argument("offset twist: comparison payload width differs from the degree"); + std::vector> dummy(knots.size(), + std::vector(mat.degree + 1, 0)); + const auto pieces = prepare(knots, dummy, eta); + std::vector shifted; + for (const auto & piece : pieces) + shifted.push_back(piece.knot); + dpf::proof_token * pi = (mat.verifiable && tokens != nullptr) ? &tokens[0] : nullptr; + auto out = mat.verifiable + ? lane_segments(mat.keys_v, shifted, mat.wrap_share, pi) + : lane_segments(mat.keys, shifted, mat.wrap_share, nullptr); + if (mat.verifiable) + replicate_proof(tokens, mat.degree + 1); + return out; +} + +/// @brief One party's share of \f$\sum a_m(c+\kappa)^{m}\lambda^{c+\kappa}\f$. +/// \complexity Same piece walk as offset poly: one segment walk of the lane payload, then a public Pascal shift and a multiply by `lambda^kappa` (`pow_signed`, `Θ(log |kappa|)` multiplies). +/// For `twist_half` the multiply is replaced by `shr_sum` on the opened sum; the right shift itself is not applied to the shares inside the walk. +/// Refined pieces: the knot vector, plus the cuts `prepare` / `prepare_pieces` inserts (domain minimum, and the carry threshold when the input width is at most 62 bits). Call that count `P`. +/// \rounds None. `eta` is an argument. The dyadic right shift is a public post-processing step after the shares are opened, and this function does not open them. +/// \communication None. +/// \preprocessing None created here. Uses the keys from `make_offset_twist_keys`. +/// @see grotto::offset_poly_eval +/// @see [Twisted jets](@ref offset_twist) +template +uint64_t offset_twist_eval( + const offset_twist_keys & mat, + const std::vector & knots, + const std::vector & coeff, + InputT eta, + dpf::proof_token * tokens = nullptr) +{ + if (coeff.size() != mat.degree + 1) + throw std::invalid_argument("offset twist: coefficient length must be degree+1"); + using namespace offset_poly_detail; + std::vector> dummy(knots.size(), + std::vector(mat.degree + 1, 0)); + const auto pieces = prepare(knots, dummy, eta); + const auto powers = offset_twist_power_shares(mat, knots, eta, tokens); + // Public Pascal shift is independent of the party key; hoist it. + std::vector> shifted_coeff(pieces.size()); + for (std::size_t i = 0; i < pieces.size(); ++i) + shifted_coeff[i] = binomial_shift(coeff, static_cast(pieces[i].kappa)); + + if (mat.half) + { + // Peer walk supplies the other additive share. Proofs fold only on + // this party's own walk. The masked carry and the pad re-sharing + // happen in `dyadic_party_share`. + constexpr std::size_t peer = Party == 0 ? 1 : 0; + const auto peer_powers = offset_twist_power_shares(mat, knots, eta); + const uint64_t base = mat.shift_base_share[0] + mat.shift_base_share[1]; + const std::int64_t base_i = static_cast(base); + uint64_t shifted = 0; + for (std::size_t i = 0; i < pieces.size(); ++i) + { + const auto & q = shifted_coeff[i]; + uint64_t mine = 0; + uint64_t theirs = 0; + for (std::size_t m = 0; m <= mat.degree; ++m) + { + mine += powers[i][m] * q[m]; + theirs += peer_powers[i][m] * q[m]; + } + shifted += offset_twist_detail::shift_sum( + mine, theirs, base_i + pieces[i].kappa); + } + if constexpr (Party == 0) + return mat.dyadic_pad; + return shifted - mat.dyadic_pad; + } + + uint64_t value = 0; + for (std::size_t i = 0; i < pieces.size(); ++i) + { + const auto & q = shifted_coeff[i]; + uint64_t local = 0; + for (std::size_t m = 0; m <= mat.degree; ++m) + local += powers[i][m] * q[m]; + value += offset_twist_detail::apply_lambda( + local, mat.lambda, false, pieces[i].kappa); + } + return value; +} + +/// @brief Cleartext \f$\sum a_m x^m\lambda^{x}\f$ at the wrapped `center+kappa`. +/// \complexity Horner of `degree + 1` terms on the hot piece, then `apply_lambda` (`Θ(log |kappa|)` for an odd unit, or one shift for `twist_half`). No keys. +/// @see grotto::offset_twist_eval +template +uint64_t offset_twist_clear( + InputT center, + uint64_t lambda, + bool half, + const std::vector & knots, + const std::vector & coeff, + InputT eta) +{ + using namespace offset_poly_detail; + std::vector> dummy(knots.size(), + std::vector(coeff.size(), 0)); + const auto pieces = prepare(knots, dummy, eta); + std::vector cuts; + for (const auto & piece : pieces) + cuts.push_back(piece.knot); + std::size_t hot = pieces.size() - 1; + for (std::size_t i = 0; i + 1 < cuts.size(); ++i) + { + if (center >= cuts[i] && center < cuts[i + 1]) + { + hot = i; + break; + } + } + const std::int64_t wrapped = static_cast( + offset_horner_detail::lift(center)) + pieces[hot].kappa; + if (wrapped < 0) + throw std::invalid_argument("offset twist: wrapped point is negative"); + const uint64_t point = static_cast(wrapped); + uint64_t acc = 0; + uint64_t pow = 1; + for (uint64_t c : coeff) + { + acc += c * pow; + pow *= point; + } + return offset_twist_detail::apply_lambda(acc, lambda, half, wrapped); +} +/// \complexity Horner of `degree + 1` terms on the hot piece, then `apply_lambda` (`Θ(log |kappa|)` for an odd unit, or one shift for `twist_half`). No keys. +/// @see grotto::offset_twist_eval + +template +uint64_t offset_twist_clear( + InputT center, + uint64_t lambda, + const std::vector & knots, + const std::vector & coeff, + InputT eta) +{ + return offset_twist_clear(center, lambda, false, knots, coeff, eta); +} +/// \complexity Horner of `degree + 1` terms on the hot piece, then `apply_lambda` (`Θ(log |kappa|)` for an odd unit, or one shift for `twist_half`). No keys. +/// @see grotto::offset_twist_eval + +template +uint64_t offset_twist_clear( + InputT center, + twist_half_t, + const std::vector & knots, + const std::vector & coeff, + InputT eta) +{ + return offset_twist_clear(center, 0, true, knots, coeff, eta); +} + +/// @brief Closed form \f$\sum_{k=1}^{n}k\lambda^{k}\f$ in \f$\mathbb{Z}/2^{64}\f$. +/// @details Over \f$\mathbb{Q}\f$ the identity is +/// \f$\lambda(1-(n+1)\lambda^{n}+n\lambda^{n+1})/(1-\lambda)^{2}\f$. +/// For odd \f$\lambda\f$, \f$1-\lambda\f$ is even, so the denominator is +/// not a unit; this helper cancels the common \f$2\f$-adic valuation +/// of numerator and denominator before inverting. +/// \complexity A constant number of `pow_u64` exponentiations (`Θ(log n)` multiplies each) and one modular inverse of `(1 - lambda)^2`. `Θ(log n)`. Extra space `Θ(1)`. +/// `lambda` must be odd and not 1, because the inverse is `inv_odd`. +/// @see grotto::offset_twist_eval +/// @see [Twisted jets](@ref offset_twist) +inline uint64_t offset_twist_arithmetico_geometric(uint64_t n, uint64_t lambda) +{ + if (lambda == 1) + throw std::invalid_argument("offset twist: use Faulhaber / hockey-stick for lambda=1"); + if ((lambda & 1u) == 0) + throw std::invalid_argument("offset twist: lambda must be odd"); + const uint64_t lam_n = offset_twist_detail::pow_u64(lambda, n); + const uint64_t lam_np1 = lam_n * lambda; + uint64_t num = lambda + * (uint64_t{1} - (n + 1) * lam_n + n * lam_np1); + uint64_t den = (uint64_t{1} - lambda) * (uint64_t{1} - lambda); + while ((den & 1u) == 0) + { + if ((num & 1u) != 0) + throw std::logic_error("offset twist: AG numerator not divisible by den"); + num >>= 1; + den >>= 1; + } + return num * offset_twist_detail::inv_odd(den); +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_OFFSET_TWIST_HPP__ diff --git a/include/grotto/piecewise.hpp b/include/grotto/piecewise.hpp index b3c6d17..6acf6ee 100644 --- a/include/grotto/piecewise.hpp +++ b/include/grotto/piecewise.hpp @@ -23,28 +23,59 @@ namespace grotto namespace polynomials { +/// @name Polynomial shapes +/// @brief Coefficient arrays, constant term in element 0. Degree is `size - 1`. +/// @{ template using poly_constant = std::array; template using poly_linear = std::array; template using poly_quadratic = std::array; template using poly_cubic = std::array; +/// @} +/// @brief Horner evaluation. The four overloads are degrees 0 through 3. +/// @tparam T coefficient type +/// @param f coefficients, constant term in `f[0]` +/// @param x the evaluation point +/// @return the polynomial value +/// @see grotto::piecewise_eval +/// \complexity Unrolled: 0, 1, 2, or 3 multiplies. `Θ(1)` time and extra space. template HEDLEY_PURE HEDLEY_NO_THROW constexpr auto eval_horner(const poly_constant & f, T x) noexcept { return f[0]; } +/// @brief Degree-1 Horner. Constant term in `f[0]`. +/// @see grotto::eval_horner +/// \complexity One multiply-add. `Θ(1)`. template HEDLEY_PURE HEDLEY_NO_THROW constexpr auto eval_horner(const poly_linear & f, T x) noexcept { return f[1] * x + f[0]; } +/// @brief Degree-2 Horner. Constant term in `f[0]`. +/// @see grotto::eval_horner +/// \complexity Two multiply-adds. `Θ(1)`. template HEDLEY_PURE HEDLEY_NO_THROW constexpr auto eval_horner(const poly_quadratic & f, T x) noexcept { return (f[2] * x + f[1]) * x + f[0]; } +/// @brief Degree-3 Horner. Constant term in `f[0]`. +/// @see grotto::eval_horner +/// \complexity Three multiply-adds. `Θ(1)`. template HEDLEY_PURE HEDLEY_NO_THROW constexpr auto eval_horner(const poly_cubic & f, T x) noexcept { return ((f[3] * x + f[2]) * x + f[1]) * x + f[0]; } +/// @brief Select the piece whose upper bound is the first entry of `bounds` strictly greater than `x`, then Horner-evaluate it. +/// @tparam T coefficient and bound type +/// @tparam D coefficients per piece +/// @tparam N1 number of pieces +/// @tparam N2 number of bounds +/// @param polys one coefficient array per piece, constant term first +/// @param bounds upper bounds of the pieces +/// @param x the query +/// @return `eval_horner` of the selected piece +/// @see grotto::eval_horner +/// \complexity `upper_bound` on `bounds` (`Θ(log N2)`), then one `eval_horner` (`Θ(1)`, `D` is 1..4). Extra space `Θ(1)`. template HEDLEY_PURE HEDLEY_NO_THROW diff --git a/include/grotto/prefix_parity.hpp b/include/grotto/prefix_parity.hpp index 6984e2c..a366ca7 100644 --- a/include/grotto/prefix_parity.hpp +++ b/include/grotto/prefix_parity.hpp @@ -1,6 +1,7 @@ /// @file grotto/prefix_parity.hpp /// @author Ryan Henry /// @brief Prefix-parity and signed-prefix shares from a comparison key. +/// @note Following Storrier, Vadapalli, Lyons, and Henry, ePrint 2023/108: prefix parity along one point or comparison key, the step they use to replace a DCF per spline piece. /// @copyright Copyright (c) 2019-2023 Ryan Henry and others /// @license Released under a GNU General Public v2.0 (GPLv2) license; /// see [LICENSE.md](@ref license) for details. @@ -20,6 +21,7 @@ #include "grotto/offset_iterable.hpp" #include "dpf/path_memoizer.hpp" #include "dpf/utils.hpp" +#include "dpf/verifiable.hpp" #include #include @@ -27,6 +29,14 @@ namespace grotto { +/// @brief Parity of the advice bits in `node` strictly below the bit offset of `x`. +/// @tparam NodeT exterior-node type +/// @tparam InputT input type used to place `x` inside the node +/// @param node advice-bit node +/// @param x query, used only for its offset within the node +/// @return the XOR-parity of those bits +/// @see grotto::prefix_parities +/// \complexity XORs the limbs of `node` below that offset, then one `parity64`. `Θ(limbs in the node)`, extra space `Θ(1)`. template HEDLEY_NO_THROW @@ -36,24 +46,40 @@ auto parity_of_substring_prefix(const NodeT & node, InputT x) noexcept std::size_t off = dpf::offset_within_block(x); auto div = std::lldiv(off, bits_per_limb); auto parity = node[div.quot] & ((1ul << div.rem) - 1ul); - for (std::size_t i = 0; i < div.quot; ++i) parity ^= node[i]; + for (std::size_t i = 0; i < static_cast(div.quot); ++i) parity ^= node[i]; return psnip_builtin_parity64(parity); } +/// \complexity One path walk per endpoint. `depth` is `bitlength` of the key's input type. +/// `for_each_offset` visits the endpoints in rotated order and `path_resume_for_level` restarts at the first level that differs, so a shared prefix is not walked twice. +/// With the early-stop flag (the default), a zero suffix does not descend below the leaf alignment. +/// Worst-case time is `Θ(E · depth)` interior steps for `E` endpoints. The memoizer stores one node per level, `Θ(depth)` extra space, plus the `E`-slot result. +/// \rounds None. The key and the endpoints are arguments. +/// \communication None. +/// @see grotto::signed_prefix_parities +/// @see grotto::offset_horner_eval template , bool> = false> -static auto prefix_parities(const DpfKey & dpf, const std::array & endpoints) +static auto prefix_parities(const DpfKey & dpf, const std::array & endpoints, + dpf::proof_token * pi = nullptr) { static constexpr std::size_t num_parts = NumParts; static constexpr std::size_t depth = DpfKey::depth; using input_type = typename DpfKey::input_type; static constexpr std::size_t input_bits = dpf::utils::bitlength_of_v; - using interior_node = typename DpfKey::interior_node; using exterior_node = typename DpfKey::exterior_node; + if (pi != nullptr) + { + if constexpr (!DpfKey::is_verifiable) + throw std::invalid_argument( + "prefix_parities(..., prove): key must carry dpf::verifiable"); + dpf::detail::vdpf::init_proof(*pi, dpf); + } + exterior_node leaf; auto path = make_basic_path_memoizer(dpf); std::array direction = { 0 }; // always "traverse left" to get to the root @@ -107,6 +133,18 @@ static auto prefix_parities(const DpfKey & dpf, const std::array( + dpf::utils::to_integral_type{}(current_endpoint) + >> (input_bits - (level_index + 1))); + dpf::detail::vdpf::fold_node(*pi, level_index, x_bits, + path[level_index + 1], + dpf.correction_seeds()[level_index]); + } + } } } dpf::detail::path_note_filled_to(path, to_level); @@ -125,14 +163,36 @@ static auto prefix_parities(const DpfKey & dpf, const std::array, bool> = false> +static auto prefix_parities(const DpfKey & dpf, const std::array & endpoints, + dpf::prove_ref pr) +{ + return prefix_parities(dpf, endpoints, &pr.token); +} + template static auto all_segment_parities_from_prefix_parities(const DpfKey & dpf, @@ -176,6 +236,9 @@ static auto specific_segment_parities_from_prefix_parities(const DpfKey & dpf, return segment_parities; } +/// \complexity One `prefix_parities` walk, then `Θ(E)` XORs to turn prefixes into segments. Same path cost as `prefix_parities`. +/// @see grotto::prefix_parities +/// @see grotto::signed_segment_parities template , bool> = false> static auto signed_prefix_parities(const DpfKey & dpf, - const std::array & endpoints) + const std::array & endpoints, + dpf::proof_token * pi = nullptr) { if constexpr (!detail::key_has_cmp::value) { (void)dpf; (void)endpoints; + (void)pi; throw std::invalid_argument("signed_prefix_parities: key has no comparison channel"); } else if (!dpf.has_cmp()) @@ -271,6 +345,13 @@ static auto signed_prefix_parities(const DpfKey & dpf, } else { + if (pi != nullptr) + { + if constexpr (!DpfKey::is_verifiable) + throw std::invalid_argument( + "signed_prefix_parities(..., prove): key must carry dpf::verifiable"); + dpf::detail::vdpf::init_proof(*pi, dpf); + } using namespace dpf::detail::dcf_impl; using key_type = dpf::unwrap_party_key_t; constexpr std::size_t depth = key_type::depth; @@ -304,7 +385,7 @@ static auto signed_prefix_parities(const DpfKey & dpf, } if constexpr (key_type::cmp_block > 0) { - prefixes[which] = dpf::detail::blocked::eval_share(dpf, tx, path); + prefixes[which] = dpf::detail::blocked::eval_share(dpf, tx, path, pi); continue; } @@ -318,6 +399,17 @@ static auto signed_prefix_parities(const DpfKey & dpf, path[level] = DpfKey::traverse_interior(path[level - 1], dpf.correction_word(level - 1, bit), bit, DpfKey::tree::is_last_level(level - 1, DpfKey::depth)); + if constexpr (DpfKey::is_verifiable) + { + if (pi != nullptr) + { + const auto x_bits = static_cast( + dpf::utils::to_integral_type{}(tx) + >> (dpf::utils::bitlength_of_v - level)); + dpf::detail::vdpf::fold_node(*pi, level - 1, x_bits, + path[level], dpf.correction_seeds()[level - 1]); + } + } } dpf::detail::path_note_filled_to(path, nbits); @@ -348,23 +440,53 @@ static auto signed_prefix_parities(const DpfKey & dpf, V = neg_m(V, mask); prefixes[which] = (V + addend) & mask; } + if (pi != nullptr) + dpf::detail::vdpf::fold_output_binding(*pi, dpf); return prefixes; } } +/// \complexity One path walk per endpoint. `depth` is `bitlength` of the key's input type. +/// `for_each_offset` visits the endpoints in rotated order and `path_resume_for_level` restarts at the first level that differs, so a shared prefix is not walked twice. +/// With the early-stop flag (the default), a zero suffix does not descend below the leaf alignment. +/// Worst-case time is `Θ(E · depth)` interior steps for `E` endpoints. The memoizer stores one node per level, `Θ(depth)` extra space, plus the `E`-slot result. +/// \rounds None. The key and the endpoints are arguments. +/// \communication None. +/// @see grotto::signed_prefix_parities +/// @see grotto::offset_horner_eval + +template , bool> = false> +static auto signed_prefix_parities(const DpfKey & dpf, + const std::array & endpoints, dpf::prove_ref pr) +{ + return signed_prefix_parities(dpf, endpoints, &pr.token); +} /// @brief Runtime-length form of `signed_prefix_parities`. `out[i]` receives the same /// share a one-element call would return for `endpoints[i]`. /// @tparam InputT input domain type /// @tparam DpfKey DPF key type /// @param dpf the DPF key -/// @param endpoints the `endpoints` -/// @param n the `n` +/// @param endpoints sorted public endpoints +/// @param n element count /// @param out the output buffer +/// @param pi proof token folded along the walk, or null /// @throws std::invalid_argument if `key has no comparison channel` +/// \complexity One path walk per endpoint. `depth` is `bitlength` of the key's input type. +/// `for_each_offset` visits the endpoints in rotated order and `path_resume_for_level` restarts at the first level that differs, so a shared prefix is not walked twice. +/// With the early-stop flag (the default), a zero suffix does not descend below the leaf alignment. +/// Worst-case time is `Θ(E · depth)` interior steps for `E` endpoints. The memoizer stores one node per level, `Θ(depth)` extra space, plus the `E`-slot result. +/// \rounds None. The key and the endpoints are arguments. +/// \communication None. +/// @see grotto::signed_prefix_parities +/// @see grotto::offset_horner_eval template static void signed_prefix_parities_into(const DpfKey & dpf, - const InputT * endpoints, std::size_t n, uint64_t * out) + const InputT * endpoints, std::size_t n, uint64_t * out, + dpf::proof_token * pi = nullptr) { if constexpr (!detail::key_has_cmp::value) { @@ -372,6 +494,7 @@ static void signed_prefix_parities_into(const DpfKey & dpf, (void)endpoints; (void)n; (void)out; + (void)pi; throw std::invalid_argument("signed_prefix_parities: key has no comparison channel"); } else if (!dpf.has_cmp()) @@ -389,6 +512,13 @@ static void signed_prefix_parities_into(const DpfKey & dpf, } else { + if (pi != nullptr) + { + if constexpr (!DpfKey::is_verifiable) + throw std::invalid_argument( + "signed_prefix_parities(..., prove): key must carry dpf::verifiable"); + dpf::detail::vdpf::init_proof(*pi, dpf); + } using namespace dpf::detail::dcf_impl; using key_type = dpf::unwrap_party_key_t; constexpr std::size_t depth = key_type::depth; @@ -420,7 +550,7 @@ static void signed_prefix_parities_into(const DpfKey & dpf, } if constexpr (key_type::cmp_block > 0) { - out[which] = dpf::detail::blocked::eval_share(dpf, tx, path); + out[which] = dpf::detail::blocked::eval_share(dpf, tx, path, pi); continue; } @@ -434,6 +564,17 @@ static void signed_prefix_parities_into(const DpfKey & dpf, path[level] = DpfKey::traverse_interior(path[level - 1], dpf.correction_word(level - 1, bit), bit, DpfKey::tree::is_last_level(level - 1, DpfKey::depth)); + if constexpr (DpfKey::is_verifiable) + { + if (pi != nullptr) + { + const auto x_bits = static_cast( + dpf::utils::to_integral_type{}(tx) + >> (dpf::utils::bitlength_of_v - level)); + dpf::detail::vdpf::fold_node(*pi, level - 1, x_bits, + path[level], dpf.correction_seeds()[level - 1]); + } + } } dpf::detail::path_note_filled_to(path, nbits); @@ -464,6 +605,8 @@ static void signed_prefix_parities_into(const DpfKey & dpf, V = neg_m(V, mask); out[which] = (V + addend) & mask; } + if (pi != nullptr) + dpf::detail::vdpf::fold_output_binding(*pi, dpf); } } @@ -478,9 +621,12 @@ static void signed_prefix_parities_into(const DpfKey & dpf, /// @tparam NumParts num parts /// @tparam input_type input type /// @param dpf the DPF key -/// @param endpoints the `endpoints` +/// @param endpoints sorted public endpoints /// @return One-hot segment shares for a unit `gt` comparison (`if_true = 1`, `if_false = 0`) /// @throws std::invalid_argument if `key has no comparison channel` +/// \complexity One `signed_prefix_parities` over the `NumParts` endpoints, then `Θ(NumParts)` subtractions. Same path cost. +/// @note Requires a `gt` comparison. The hot piece reconstructs to 1, the others to 0. +/// @see grotto::signed_prefix_parities template (part.power) * ln2_raw(fractional_bits); -} +inline std::int64_t eval_ln_positive(unsigned fractional_bits, std::int64_t raw); +inline std::int64_t eval_log10_positive(unsigned fractional_bits, std::int64_t raw); +inline u128 exp_scale64(unsigned fractional_bits, std::int64_t raw, std::int64_t & n_bin); +inline std::int64_t finish_wide(u128 wide, int right_shift); inline std::int64_t eval_exp_at_scale(unsigned fractional_bits, std::int64_t raw) { @@ -240,39 +248,10 @@ inline std::int64_t eval_exp_at_scale(unsigned fractional_bits, std::int64_t raw const std::int64_t lifted = eval_exp_at_scale(16, static_cast(lifted_arg)); return round_i128(lifted, static_cast(lift)); } - const std::int64_t ln2 = ln2_raw(fractional_bits); - if (ln2 <= 0) - throw std::logic_error("range lut: ln 2 constant"); - std::int64_t n_bin = raw / ln2; - std::int64_t remainder = raw - n_bin * ln2; - if (remainder < 0) - { - remainder += ln2; - --n_bin; - } - while (remainder >= ln2) - { - remainder -= ln2; - ++n_bin; - } - - const std::int64_t step = std::int64_t{1} << (fractional_bits - 13); - const std::int64_t chunks = remainder / step; - const std::int64_t tiny = remainder - chunks * step; - std::int64_t table_raw = tiny << 13; - const std::int64_t one = one_raw(fractional_bits); - if (table_raw > one) - table_raw = one; - std::int64_t exp_s = eval_principal(principal::exp, fractional_bits, table_raw); - for (unsigned bit = 0; bit < 13; ++bit) - { - if ((static_cast(chunks) & (1ull << bit)) == 0) - continue; - // `chunk` is `exp(2^{i-13}) * 2^64`, so the product's high limb is the raw product. - const u128 prod = static_cast(exp_s) * exp_chunk_64[bit]; - exp_s = round_mag(prod, 64, false); - } - return shift_pow2(exp_s, static_cast(n_bin)); + std::int64_t n_bin = 0; + const u128 wide = exp_scale64(fractional_bits, raw, n_bin); + const int shift = static_cast(64u - fractional_bits) - static_cast(n_bin); + return finish_wide(wide, shift); } HEDLEY_NO_THROW @@ -318,7 +297,7 @@ struct angle /// only as far as the low bits the quadrant logic reads. /// @param fractional_bits the number of fractional bits /// @param raw the underlying integer -/// @param multiplier_64 the `multiplier_64` +/// @param multiplier_64 multiplier already scaled by `2^64` /// @return `{ |x| * multiplier }` at this precision, with the integer part reduced only as far as /// the low bits the quadrant logic reads inline angle reduce_positive(unsigned fractional_bits, std::int64_t raw, u128 multiplier_64) @@ -498,7 +477,7 @@ inline hyp sinh_cosh(unsigned fractional_bits, std::int64_t raw) /// @brief `ln(2^{k+1} ± 1) / 2`, the saturation threshold used by `tanh` and `coth`. /// @param fractional_bits the number of fractional bits -/// @param plus the `plus` +/// @param plus true for the plus saturation threshold, false for the minus threshold /// @return `ln(2^{k+1} ± 1) / 2`, the saturation threshold used by `tanh` and `coth` inline std::int64_t beta_raw(unsigned fractional_bits, bool plus) { @@ -518,6 +497,249 @@ constexpr int half_pow_of(int power) noexcept return (power & 1) != 0 ? (power - 1) / 2 : power / 2; } +struct u256 +{ + u128 lo; + u128 hi; +}; + +inline u256 mul_u128(u128 a, u128 b) +{ + const auto a0 = static_cast(a); + const auto a1 = static_cast(a >> 64); + const auto b0 = static_cast(b); + const auto b1 = static_cast(b >> 64); + const u128 p00 = u128{a0} * b0; + const u128 p01 = u128{a0} * b1; + const u128 p10 = u128{a1} * b0; + const u128 p11 = u128{a1} * b1; + const u128 col = (p00 >> 64) + static_cast(p01) + static_cast(p10); + u256 out; + out.lo = static_cast(p00) | (col << 64); + out.hi = p11 + (p01 >> 64) + (p10 >> 64) + (col >> 64); + return out; +} + +inline u128 round_u256(u256 value, unsigned shift) +{ + if (shift == 0) + return value.lo; + if (shift >= 256) + return 0; + u256 bumped = value; + const unsigned bit = shift - 1; + if (bit < 128) + { + const u128 before = bumped.lo; + bumped.lo += u128{1} << bit; + if (bumped.lo < before) + ++bumped.hi; + } + else + bumped.hi += u128{1} << (bit - 128); + if (shift < 128) + { + if (shift == 0) + return bumped.lo; + return (bumped.lo >> shift) | (bumped.hi << (128 - shift)); + } + return bumped.hi >> (shift - 128); +} + +/// @brief `ln(m) * 2^64` for `m` in `[1/2, 1]`, via `2 artanh((m-1)/(m+1))`. +/// @details `|z| <= 1/3`, so forty odd powers sit well below `2^{-64}`. +inline u128 ln_mantissa_scale64(unsigned fractional_bits, std::int64_t mantissa_raw) +{ + const u128 one = u128{1} << 64; + const u128 m = static_cast(mantissa_raw) << (64u - fractional_bits); + if (m >= one) + return 0; + const u128 num = one - m; + const u128 den = one + m; + const u128 z = ((num << 64) + den / 2) / den; + const u128 z2 = round_u256(mul_u128(z, z), 64); + u128 acc = z; + u128 power = z; + for (int n = 1; n <= 40; ++n) + { + power = round_u256(mul_u128(power, z2), 64); + const unsigned denom = static_cast(2 * n + 1); + const u128 term = (power + denom / 2) / denom; + if (term == 0) + break; + acc += term; + } + return acc << 1; +} + +inline std::int64_t round_scale64_to_k(u128 mag, bool neg, unsigned fractional_bits) +{ + return round_mag(mag, 64u - fractional_bits, neg); +} + +inline void ln_magnitude_scale64(unsigned fractional_bits, std::int64_t raw, u128 & mag, bool & neg) +{ + const dyadic part = split_positive(raw, fractional_bits); + // `ln(m) <= 0` on `[1/2, 1]`, so `ln(m * 2^e) = e·ln 2 - |ln m|`. + const u128 ln_m = ln_mantissa_scale64(fractional_bits, part.mantissa_raw); + if (part.power >= 0) + { + const u128 lift = ln2_64 * static_cast(part.power); + if (lift >= ln_m) + { + mag = lift - ln_m; + neg = false; + } + else + { + mag = ln_m - lift; + neg = true; + } + } + else + { + mag = ln2_64 * static_cast(-part.power) + ln_m; + neg = true; + } +} + +inline std::int64_t eval_ln_positive(unsigned fractional_bits, std::int64_t raw) +{ + u128 mag = 0; + bool neg = false; + ln_magnitude_scale64(fractional_bits, raw, mag, neg); + return round_scale64_to_k(mag, neg, fractional_bits); +} + +/// @brief `(rem << 64) / den`, rounded. `rem < den` and `den < 2^96`. +inline u128 div_rem_lshift64(u128 rem, u128 den) +{ + const u128 hi = (rem << 32) / den; + const u128 mid = (rem << 32) % den; + const u128 lo = (mid << 32) / den; + const u128 leftover = (mid << 32) % den; + u128 out = (hi << 32) + lo; + if (leftover >= den / 2) + ++out; + return out; +} + +inline std::int64_t eval_log10_positive(unsigned fractional_bits, std::int64_t raw) +{ + u128 ln_mag = 0; + bool neg = false; + ln_magnitude_scale64(fractional_bits, raw, ln_mag, neg); + const u128 quot = ln_mag / ln10_64; + const u128 rem = ln_mag % ln10_64; + const u128 log_mag = (quot << 64) + div_rem_lshift64(rem, ln10_64); + return round_scale64_to_k(log_mag, neg, fractional_bits); +} + +/// @brief `exp(x) * 2^64`. The `ln 2` split and the `2^{-13}` chunks stay at +/// scale 64 and are rounded once into the caller's precision. +inline u128 exp_scale64(unsigned fractional_bits, std::int64_t raw, std::int64_t & n_bin) +{ + const u128 x64 = static_cast(raw < 0 ? -static_cast<__int128>(raw) : raw) + << (64u - fractional_bits); + const bool neg = raw < 0; + u128 mag = x64; + n_bin = 0; + if (mag >= ln2_64) + { + n_bin = static_cast(mag / ln2_64); + mag -= ln2_64 * static_cast(n_bin); + } + if (neg) + { + if (mag == 0) + n_bin = -n_bin; + else + { + n_bin = -n_bin - 1; + mag = ln2_64 - mag; + } + } + const u128 step = u128{1} << 51; + const u128 chunks = mag / step; + u128 tiny = mag % step; + u128 acc = u128{1} << 64; + u128 power = tiny; + for (int n = 1; n <= 16; ++n) + { + const u128 term = (power + static_cast(n) / 2) / static_cast(n); + if (term == 0) + break; + acc += term; + power = round_u256(mul_u128(term, tiny), 64); + } + for (unsigned bit = 0; bit < 13; ++bit) + { + if (((chunks >> bit) & 1u) == 0) + continue; + acc = round_u256(mul_u128(acc, exp_chunk_64[bit]), 64); + } + return acc; +} + +/// @brief Two Newton steps at scale `2k`, then the exact power-of-two lift. +/// @details The principal cubic is half an ulp at scale `k`. Shifting that +/// rounded word left multiplies the error. Refining before the shift +/// leaves an absolute error below one output ulp across the domain. +inline u128 newton_inv(unsigned fractional_bits, std::int64_t mantissa_raw, std::int64_t seed_raw) +{ + const unsigned K = fractional_bits * 2u; + u128 m = static_cast(mantissa_raw) << fractional_bits; + u128 y = static_cast(seed_raw) << fractional_bits; + const u128 two = u128{2} << K; + for (int step = 0; step < 2; ++step) + { + const u128 my = round_u256(mul_u128(m, y), K); + if (my >= two) + break; + y = round_u256(mul_u128(y, two - my), K); + } + return y; +} + +inline u128 newton_rsqrt(unsigned fractional_bits, std::int64_t mantissa_raw, std::int64_t seed_raw) +{ + const unsigned K = fractional_bits * 2u; + u128 m = static_cast(mantissa_raw) << fractional_bits; + u128 y = static_cast(seed_raw) << fractional_bits; + const u128 three = u128{3} << K; + for (int step = 0; step < 2; ++step) + { + const u128 yy = round_u256(mul_u128(y, y), K); + const u128 myy = round_u256(mul_u128(m, yy), K); + if (myy >= three) + break; + const u128 corr = round_u256(mul_u128(y, three - myy), K); + y = (corr + 1) >> 1; + } + return y; +} + +inline std::int64_t finish_wide(u128 wide, int right_shift) +{ + if (right_shift >= 256) + return 0; + if (right_shift >= 0) + { + u256 value{wide, 0}; + const u128 rounded = round_u256(value, static_cast(right_shift)); + if (rounded > static_cast(INT64_MAX)) + throw std::overflow_error("range lut: reciprocal does not fit int64"); + return static_cast(rounded); + } + const int left = -right_shift; + if (left >= 127) + throw std::overflow_error("range lut: reciprocal does not fit int64"); + const u128 shifted = wide << static_cast(left); + if (shifted > static_cast(INT64_MAX)) + throw std::overflow_error("range lut: reciprocal does not fit int64"); + return static_cast(shifted); +} + inline __int128 div_round_i128(__int128 num, int den) { const bool neg = num < 0; @@ -576,31 +798,21 @@ inline std::int64_t eval_expm1(unsigned fractional_bits, std::int64_t raw) if (raw > -ln2 && raw < ln2) return expm1_series(fractional_bits, raw); - std::int64_t n_bin = raw / ln2; - std::int64_t remainder = raw - n_bin * ln2; - if (remainder < 0) - { - remainder += ln2; - --n_bin; - } - while (remainder >= ln2) - { - remainder -= ln2; - ++n_bin; - } - const std::int64_t exp_r = eval_exp_at_scale(fractional_bits, remainder); - const std::int64_t one = one_raw(fractional_bits); + std::int64_t n_bin = 0; + const u128 wide = exp_scale64(fractional_bits, raw, n_bin); + if (n_bin >= 63) + throw std::overflow_error("range lut: exponent overflow"); + u128 exp64 = wide; if (n_bin >= 0) - { - const __int128 wide = static_cast<__int128>(shift_pow2(exp_r, static_cast(n_bin))) - one; - if (wide > INT64_MAX || wide < INT64_MIN) - throw std::overflow_error("range lut: exponent overflow"); - return static_cast(wide); - } - const int places = static_cast(-n_bin); - if (places > static_cast(fractional_bits) + 1) - return -one; - return shift_pow2(exp_r, -places) - one; + exp64 <<= static_cast(n_bin); + else if (-n_bin >= 128) + exp64 = 0; + else + exp64 >>= static_cast(-n_bin); + const u128 unit = u128{1} << 64; + const bool below = exp64 < unit; + const u128 diff = below ? unit - exp64 : exp64 - unit; + return round_mag(diff, 64u - fractional_bits, below); } /// @brief `log1p` on `|x| <= 1/2`. Every term of a negative argument is negative. @@ -647,6 +859,16 @@ inline std::int64_t eval_log1p(unsigned fractional_bits, std::int64_t raw) } } // namespace range_detail +/// \complexity The `switch` does a constant amount of range reduction and a constant number of `eval_principal` cubics (`Θ(log P)` each). +/// On the small interval, `expm1_series` loops `n = 1 .. 24` and `log1p_series` loops `n = 1 .. 80`, and both stop when the running power is 0. +/// Extra space `Θ(1)`. +/// @see grotto::eval_principal +/// @see grotto::eval_window +/// @see grotto::eval_closed +/// @param which the reduced map +/// @param fractional_bits one of 8, 12, ..., 32 +/// @param raw fixed-point argument, value `raw / 2^{fractional_bits}` +/// @return fixed-point result at the same scale HEDLEY_WARN_UNUSED_RESULT inline std::int64_t eval_reduced(reduced which, unsigned fractional_bits, std::int64_t raw) @@ -668,15 +890,7 @@ inline std::int64_t eval_reduced(reduced which, unsigned fractional_bits, std::i return lg_m + (static_cast(part.power) << fractional_bits); } case reduced::log10: - { - const dyadic part = split_positive(raw, fractional_bits); - const std::int64_t ln_m = eval_principal(principal::ln, fractional_bits, part.mantissa_raw); - const std::int64_t mantissa = mul_raw( - ln_m, scale_unit(inv_ln10_64, fractional_bits), fractional_bits); - const std::int64_t lift = static_cast(part.power) - * scale_unit(log10_2_64, fractional_bits); - return mantissa + lift; - } + return eval_log10_positive(fractional_bits, raw); case reduced::exp: return eval_exp_at_scale(fractional_bits, raw); case reduced::exp2: @@ -797,24 +1011,32 @@ inline std::int64_t eval_reduced(reduced which, unsigned fractional_bits, std::i case reduced::inv: { const dyadic part = split_positive(raw, fractional_bits); - const std::int64_t reciprocal = eval_principal( + const std::int64_t seed = eval_principal( principal::inv, fractional_bits, part.mantissa_raw); - return shift_pow2(reciprocal, -part.power); + const u128 wide = newton_inv(fractional_bits, part.mantissa_raw, seed); + return finish_wide(wide, static_cast(fractional_bits) + part.power); } case reduced::rsqrt: { const dyadic part = split_positive(raw, fractional_bits); - std::int64_t root = eval_principal(principal::rsqrt, fractional_bits, part.mantissa_raw); + const std::int64_t seed = eval_principal( + principal::rsqrt, fractional_bits, part.mantissa_raw); + u128 wide = newton_rsqrt(fractional_bits, part.mantissa_raw, seed); if ((part.power & 1) != 0) - root = mul_raw(root, scale_unit(rsqrt2_64, fractional_bits), fractional_bits); - return shift_pow2(root, -half_pow_of(part.power)); + wide = round_u256(mul_u128(wide, rsqrt2_64), 64); + return finish_wide(wide, + static_cast(fractional_bits) + half_pow_of(part.power)); } case reduced::invsq: { const dyadic part = split_positive(raw, fractional_bits); - const std::int64_t square = eval_principal( - principal::invsq, fractional_bits, part.mantissa_raw); - return shift_pow2(square, -2 * part.power); + const std::int64_t seed = eval_principal( + principal::inv, fractional_bits, part.mantissa_raw); + const u128 inv = newton_inv(fractional_bits, part.mantissa_raw, seed); + const unsigned K = fractional_bits * 2u; + const u128 wide = round_u256(mul_u128(inv, inv), K); + return finish_wide(wide, static_cast(K) - static_cast(fractional_bits) + + 2 * part.power); } case reduced::expm1: return eval_expm1(fractional_bits, raw); diff --git a/include/grotto/residue.hpp b/include/grotto/residue.hpp new file mode 100644 index 0000000..c2a43f6 --- /dev/null +++ b/include/grotto/residue.hpp @@ -0,0 +1,352 @@ +/// @file grotto/residue.hpp +/// @brief Compile-time modular residues as comparison payload groups. +/// @details `zn64` and `zn128` supply `from_seed`, `+`, and unary +/// `-`, which selects the payload-group comparison path. The modulus +/// is a template argument so keygen needs no runtime side channel. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_GROTTO_RESIDUE_HPP__ +#define LIBDPF_INCLUDE_GROTTO_RESIDUE_HPP__ + +#include +#include +#include +#include + +#include "hedley/hedley.h" + +namespace grotto +{ + +/// @brief Residue class modulo a 64-bit compile-time modulus. +/// @tparam Mod compile-time modulus, greater than 1 +/// @see grotto::make_ring_switch_keys +/// @see grotto::ring_switch_factor +/// \complexity Construction, `from_seed`, addition, and negation are one remainder each. `Θ(1)` time and extra space. +template +class zn64 +{ + static_assert(Mod > 1, "zn64 modulus must be greater than 1"); + + public: + /// \complexity One remainder modulo `Mod`, with a sign branch for negative `T`. `Θ(1)`. + /// @see grotto::ring_switch_eval + static constexpr std::uint64_t modulus = Mod; + static constexpr bool dpf_point_group = true; + + HEDLEY_ALWAYS_INLINE + constexpr zn64() noexcept = default; + + template >> + HEDLEY_ALWAYS_INLINE + constexpr zn64(T v) noexcept + { + assign_integer(v); + } + + HEDLEY_ALWAYS_INLINE + constexpr zn64(unsigned __int128 v) noexcept + { + val_ = static_cast(v % Mod); + } + /// \complexity Copies at most 16 seed bytes and reduces the 128-bit word modulo `Mod`. `Θ(1)`. + /// @see grotto::make_ring_switch_keys + + HEDLEY_ALWAYS_INLINE + static zn64 from_seed(const void * bytes, std::size_t n) noexcept + { + unsigned char buf[16]{}; + if (n > sizeof(buf)) + n = sizeof(buf); + std::memcpy(buf, bytes, n); + std::uint64_t w[2]{}; + std::memcpy(w, buf, sizeof(w)); + const unsigned __int128 wide = static_cast(w[0]) + | (static_cast(w[1]) << 64); + return from_reduced(static_cast(wide % Mod)); + } + + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + constexpr std::uint64_t raw() const noexcept { return val_; } + + HEDLEY_ALWAYS_INLINE + friend constexpr zn64 operator+(zn64 a, zn64 b) noexcept + { + const unsigned __int128 s = + static_cast(a.val_) + b.val_; + return from_reduced(static_cast(s % Mod)); + } + + HEDLEY_ALWAYS_INLINE + friend constexpr zn64 operator-(zn64 a) noexcept + { + if (a.val_ == 0) + return a; + return from_reduced(Mod - a.val_); + } + + HEDLEY_ALWAYS_INLINE + friend constexpr zn64 operator-(zn64 a, zn64 b) noexcept + { + return a + (-b); + } + + HEDLEY_ALWAYS_INLINE + friend constexpr bool operator==(zn64 a, zn64 b) noexcept + { + return a.val_ == b.val_; + } + + HEDLEY_ALWAYS_INLINE + friend constexpr bool operator!=(zn64 a, zn64 b) noexcept + { + return !(a == b); + } + + private: + std::uint64_t val_{}; + + HEDLEY_ALWAYS_INLINE + static constexpr zn64 from_reduced(std::uint64_t v) noexcept + { + zn64 out; + out.val_ = v; + return out; + } + + template + HEDLEY_ALWAYS_INLINE + constexpr void assign_integer(T v) noexcept + { + if constexpr (std::is_signed_v) + { + if (v < 0) + { + using U = std::make_unsigned_t; + const auto mag = static_cast(0) - static_cast(v); + val_ = static_cast( + Mod - (static_cast(mag) % Mod)); + if (val_ == Mod) + val_ = 0; + return; + } + val_ = static_cast( + static_cast>(v) % Mod); + } + else + { + val_ = static_cast( + static_cast(v) % Mod); + } + } +}; + +/// @brief Residue class modulo a 128-bit compile-time modulus `(Hi << 64) | Lo`. +/// @tparam Lo low 64 bits of the modulus +/// @tparam Hi high 64 bits of the modulus +/// @see grotto::make_ring_switch_keys +/// @see grotto::zn64 +/// \complexity Constructors reduce one integer modulo that modulus. `from_seed` folds at most 16 bytes. Addition is one 128-bit sum and a remainder. `Θ(1)` time and extra space. +template +class zn128 +{ + static_assert(Lo != 0 || Hi != 0, "zn128 modulus must be nonzero"); + static_assert(Hi != 0 || Lo > 1, "zn128 modulus must be greater than 1"); + + public: + static constexpr std::uint64_t modulus_lo = Lo; + static constexpr std::uint64_t modulus_hi = Hi; + static constexpr bool dpf_point_group = true; + + HEDLEY_ALWAYS_INLINE + constexpr zn128() noexcept = default; + + template >> + HEDLEY_ALWAYS_INLINE + constexpr zn128(T v) noexcept + { + assign_integer(v); + } + + HEDLEY_ALWAYS_INLINE + static zn128 from_u128(unsigned __int128 v) noexcept + { + return reduce(static_cast(v), + static_cast(v >> 64)); + } + + HEDLEY_ALWAYS_INLINE + static zn128 from_seed(const void * bytes, std::size_t n) noexcept + { + unsigned char buf[16]{}; + if (n > sizeof(buf)) + n = sizeof(buf); + std::memcpy(buf, bytes, n); + std::uint64_t w[2]{}; + std::memcpy(w, buf, sizeof(w)); + return reduce(w[0], w[1]); + } + + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + constexpr std::uint64_t lo() const noexcept { return lo_; } + + HEDLEY_ALWAYS_INLINE + HEDLEY_PURE + constexpr std::uint64_t hi() const noexcept { return hi_; } + + HEDLEY_ALWAYS_INLINE + friend constexpr zn128 operator+(zn128 a, zn128 b) noexcept + { + const unsigned __int128 low = + static_cast(a.lo_) + b.lo_; + const unsigned __int128 high = + static_cast(a.hi_) + b.hi_ + (low >> 64); + std::uint64_t lo = static_cast(low); + std::uint64_t hi = static_cast(high); + const std::uint64_t top = static_cast(high >> 64); + // Two reduced residues sum to less than 2M < 2^129. + if (top != 0) + sub_words(lo, hi, Lo, Hi, lo, hi); + if (hi > Hi || (hi == Hi && lo >= Lo)) + sub_words(lo, hi, Lo, Hi, lo, hi); + return from_reduced(lo, hi); + } + + HEDLEY_ALWAYS_INLINE + friend constexpr zn128 operator-(zn128 a) noexcept + { + if (a.lo_ == 0 && a.hi_ == 0) + return a; + std::uint64_t ol = 0, oh = 0; + sub_words(Lo, Hi, a.lo_, a.hi_, ol, oh); + return from_reduced(ol, oh); + } + + HEDLEY_ALWAYS_INLINE + friend constexpr zn128 operator-(zn128 a, zn128 b) noexcept + { + return a + (-b); + } + + HEDLEY_ALWAYS_INLINE + friend constexpr bool operator==(zn128 a, zn128 b) noexcept + { + return a.lo_ == b.lo_ && a.hi_ == b.hi_; + } + + HEDLEY_ALWAYS_INLINE + friend constexpr bool operator!=(zn128 a, zn128 b) noexcept + { + return !(a == b); + } + + private: + std::uint64_t lo_{}; + std::uint64_t hi_{}; + + HEDLEY_ALWAYS_INLINE + static constexpr zn128 from_reduced(std::uint64_t lo, std::uint64_t hi) noexcept + { + zn128 out; + out.lo_ = lo; + out.hi_ = hi; + return out; + } + + HEDLEY_ALWAYS_INLINE + static constexpr bool less(std::uint64_t ah, std::uint64_t al, + std::uint64_t bh, std::uint64_t bl) noexcept + { + return ah < bh || (ah == bh && al < bl); + } + + HEDLEY_ALWAYS_INLINE + static constexpr void sub_words(std::uint64_t al, std::uint64_t ah, + std::uint64_t bl, std::uint64_t bh, + std::uint64_t & ol, std::uint64_t & oh) noexcept + { + const unsigned borrow = al < bl ? 1u : 0u; + ol = static_cast(al - bl); + oh = static_cast(ah - bh - borrow); + } + + HEDLEY_ALWAYS_INLINE + static constexpr zn128 reduce(std::uint64_t lo, std::uint64_t hi) noexcept + { + const unsigned __int128 mod = + static_cast(Lo) + | (static_cast(Hi) << 64); + const unsigned __int128 v = + static_cast(lo) + | (static_cast(hi) << 64); + const unsigned __int128 r = v % mod; + return from_reduced(static_cast(r), + static_cast(r >> 64)); + } + + template + HEDLEY_ALWAYS_INLINE + constexpr void assign_integer(T v) noexcept + { + bool neg = false; + unsigned __int128 mag = 0; + if constexpr (std::is_signed_v) + { + if (v < 0) + { + neg = true; + using U = std::make_unsigned_t; + mag = static_cast(0) - static_cast(v); + } + else + { + mag = static_cast>(v); + } + } + else + { + mag = static_cast(v); + } + *this = from_u128(mag); + if (neg) + *this = -*this; + } +}; + +/// @brief Reduce a `zn64` share into `zn64` when `Factor | Mod`. +/// \complexity One `raw()` read and a `zn64` construction (one remainder). `Θ(1)`. +/// The `static_assert` requires `Factor` divides `Mod` (and, for `zn128`, that the modulus is a 64-bit multiple of `Factor`). +/// @see grotto::ring_switch_eval +/// @see grotto::zn64 +/// @param share a residue already reduced modulo `Mod` +/// @return the same integer modulo `Factor` +template +HEDLEY_ALWAYS_INLINE +constexpr zn64 ring_switch_factor(zn64 share) noexcept +{ + static_assert(Mod % Factor == 0, "ring_switch_factor: Factor must divide Mod"); + return zn64{share.raw()}; +} + +/// @brief Reduce a `zn128` share into a 64-bit factor when the factor divides. +/// \complexity One `raw()` read and a `zn64` construction (one remainder). `Θ(1)`. +/// The `static_assert` requires `Factor` divides `Mod` (and, for `zn128`, that the modulus is a 64-bit multiple of `Factor`). +/// @see grotto::ring_switch_eval +/// @see grotto::zn64 +/// @param share a residue already reduced modulo `Mod` +/// @return the same integer modulo `Factor` +template +HEDLEY_ALWAYS_INLINE +constexpr zn64 ring_switch_factor(zn128 share) noexcept +{ + static_assert(Hi == 0 && Lo % Factor == 0, + "ring_switch_factor: Factor must divide the 128-bit modulus"); + return zn64{share.lo()}; +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_RESIDUE_HPP__ diff --git a/include/grotto/ring_switch.hpp b/include/grotto/ring_switch.hpp new file mode 100644 index 0000000..f6080f5 --- /dev/null +++ b/include/grotto/ring_switch.hpp @@ -0,0 +1,282 @@ +/// @file grotto/ring_switch.hpp +/// @brief Exact share conversion from \f$\mathbb{Z}/2^n\f$ into a residue group. +/// @details For an unsigned \f$n\f$-bit limb (\f$n\le 64\f$) with representatives +/// in \f$[0,2^n)\f$, +/// \f$\eta + r = x + w\cdot 2^n,\qquad w=\mathbf{1}[r+\eta\ge 2^n].\f$ +/// In any modulus \f$M\f$, +/// \f$x \equiv \eta + (r\bmod M) - w\cdot(2^n\bmod M)\pmod M.\f$ +/// The wrap bit times \f$2^n\bmod M\f$ must be shared inside the +/// destination group: a `uint64` comparison share is not a share +/// mod \f$M\f$. The dealer keys `lt(2^n \bmod M)` at the secret \f$r\f$ +/// and, after \f$\eta\f$ opens, each party evaluates at the public +/// query \f$2^n-1-\eta\f$. That indicator is hot exactly on wrap, +/// including the \f$\eta=0\f$ case (no wrap). Party 0 adds public +/// \f$\eta\f$; both parties hold an additive split of \f$r\f$ in the +/// residue group. +/// @copyright Copyright (c) 2019-2026 Ryan Henry and [others](@ref authors) +/// @license Released under a GNU General Public v2.0 (GPLv2) license. + +#ifndef LIBDPF_INCLUDE_GROTTO_RING_SWITCH_HPP__ +#define LIBDPF_INCLUDE_GROTTO_RING_SWITCH_HPP__ + +#include "dpf.hpp" +#include "dpf/field128.hpp" +#include "dpf/p256_scalar.hpp" +#include "grotto/residue.hpp" + +#include +#include +#include +#include +#include +#include + +namespace grotto +{ + +namespace ring_switch_detail +{ + +template +HEDLEY_NO_THROW +constexpr unsigned limb_bits() noexcept +{ + static_assert(std::is_unsigned_v, + "ring switch limb domain must be an unsigned integer"); + constexpr unsigned bits = static_cast(dpf::utils::bitlength_of_v); + static_assert(bits >= 1 && bits <= 64, "ring switch supports 1..64 bit limbs"); + return bits; +} + +template +HEDLEY_NO_THROW +constexpr InputT limb_mask() noexcept +{ + constexpr unsigned bits = limb_bits(); + if constexpr (bits == 64) + return ~InputT{0}; + else + return static_cast((InputT{1} << bits) - InputT{1}); +} + +/// @brief Public query \f$2^n - 1 - \eta\f$ for the wrap `lt` key. +template +HEDLEY_NO_THROW +constexpr InputT wrap_query(InputT eta) noexcept +{ + return static_cast(limb_mask() - (eta & limb_mask())); +} + +/// @brief \f$2^n\f$ as an integer for constructing the residue payload. +template +HEDLEY_NO_THROW +constexpr unsigned __int128 pow2_n() noexcept +{ + constexpr unsigned bits = limb_bits(); + if constexpr (bits == 64) + return static_cast(1) << 64; + else + return static_cast(1) << bits; +} + +template +struct has_modulus64 : std::false_type {}; +template +struct has_modulus64> : std::true_type {}; + +template +struct has_modulus128 : std::false_type {}; +template +struct has_modulus128> : std::true_type {}; + +template +Residue pow2_payload() +{ + if constexpr (std::is_same_v) + { + constexpr unsigned bits = limb_bits(); + if constexpr (bits == 64) + return dpf::field128::from_lane(0, 1); + else + return Residue{static_cast(InputT{1} << bits)}; + } + else if constexpr (std::is_same_v) + { + constexpr unsigned bits = limb_bits(); + if constexpr (bits == 64) + return Residue{static_cast(1) << 64}; + else + return Residue{static_cast(InputT{1} << bits)}; + } + else if constexpr (has_modulus64::value) + { + return Residue{static_cast( + pow2_n() % Residue::modulus)}; + } + else if constexpr (has_modulus128::value) + { + return Residue::from_u128(pow2_n()); + } + else + { + static_assert(sizeof(Residue) == 0, "unsupported ring switch residue"); + return Residue{}; + } +} + +template +Residue reduce_limb(InputT v) +{ + return Residue{static_cast(v & limb_mask())}; +} + +} // namespace ring_switch_detail + +/// @brief Dealer material for one exact ring switch into `Residue`. +template +struct ring_switch_keys +{ + static_assert(std::is_unsigned_v, + "ring switch limb domain must be an unsigned integer"); + static_assert(dpf::utils::bitlength_of_v <= 64, + "ring switch supports at most 64-bit limbs"); + + using input_type = InputT; + using residue_type = Residue; + using key_pair = decltype(dpf::make_dpf(std::declval(), + dpf::lt(std::declval()))); + using key_pair_v = decltype(dpf::make_dpf(std::declval(), + dpf::lt(std::declval()), dpf::verifiable{})); + + InputT r{}; + bool verifiable = false; + std::optional keys{}; + std::optional keys_v{}; + /// @brief Additive split of `r` in `Residue`, indexed `[party]`. + Residue r_share[2]{}; +}; +/// \complexity One `dpf::make_dpf` of `lt(2^n mod M)` at the masked limb `r`, plus one `from_seed` to split `r` in `Residue`. +/// `n` is `bitlength_of_v` and the header rejects `n` outside `1 .. 64`. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One comparison key and two `Residue` words (`r_share[2]`). +/// @note The comparison payload is `2^n mod M` in the destination group. A `uint64_t` comparison share is not a share modulo `M`. +/// @see grotto::zn64 +/// @see grotto::nmod +/// @see [Exact ring switch](@ref ring_switch) + +template +ring_switch_keys make_ring_switch_keys(InputT r) +{ + using namespace ring_switch_detail; + ring_switch_keys mat; + mat.r = static_cast(r & limb_mask()); + mat.verifiable = false; + const Residue payload = pow2_payload(); + mat.keys = dpf::make_dpf(mat.r, dpf::lt(payload)); + const auto seed = dpf::uniform_sample(); + mat.r_share[0] = Residue::from_seed(&seed, sizeof(seed)); + mat.r_share[1] = reduce_limb(mat.r) - mat.r_share[0]; + return mat; +} +/// \complexity One `dpf::make_dpf` of `lt(2^n mod M)` at the masked limb `r`, plus one `from_seed` to split `r` in `Residue`. +/// `n` is `bitlength_of_v` and the header rejects `n` outside `1 .. 64`. +/// \rounds No party interaction. +/// \communication None inside this function. +/// \preprocessing One comparison key and two `Residue` words (`r_share[2]`). +/// @note The comparison payload is `2^n mod M` in the destination group. A `uint64_t` comparison share is not a share modulo `M`. +/// @see grotto::zn64 +/// @see grotto::nmod +/// @see [Exact ring switch](@ref ring_switch) + +template +ring_switch_keys make_ring_switch_keys(InputT r, dpf::verifiable) +{ + using namespace ring_switch_detail; + ring_switch_keys mat; + mat.r = static_cast(r & limb_mask()); + mat.verifiable = true; + const Residue payload = pow2_payload(); + mat.keys_v = dpf::make_dpf(mat.r, dpf::lt(payload), dpf::verifiable{}); + const auto seed = dpf::uniform_sample(); + mat.r_share[0] = Residue::from_seed(&seed, sizeof(seed)); + mat.r_share[1] = reduce_limb(mat.r) - mat.r_share[0]; + return mat; +} + +/// @brief Cleartext \f$x \bmod M\f$ from the limb identity. +/// \complexity A constant number of limb adds and one comparison of `r + eta` against `2^n`. `Θ(1)`. No keys. +/// @see grotto::ring_switch_eval +template +Residue ring_switch_clear(InputT x, InputT r, InputT eta) +{ + using namespace ring_switch_detail; + const InputT mask = limb_mask(); + x = static_cast(x & mask); + r = static_cast(r & mask); + eta = static_cast(eta & mask); + const unsigned __int128 sum = + static_cast(r) + eta; + const unsigned __int128 modn = pow2_n(); + const unsigned w = (sum >= modn) ? 1u : 0u; + Residue out = reduce_limb(eta) + reduce_limb(r); + if (w) + out = out - pow2_payload(); + return out; +} + +/// @brief One party's share of \f$x\f$ in `Residue` after `eta` is public. +/// \complexity One `dpf::eval_point` on the wrap key at the public query `2^n - 1 - eta`, then a constant number of `Residue` additions. +/// Party 0 also adds `eta` reduced into `Residue`. `n ≤ 64`. +/// Extra space `Θ(1)`. +/// \rounds None. `eta` is an argument; the wrap bit is the comparison output, not a separate opening. +/// \communication None. +/// \preprocessing None created here. Uses the one key and the two `r_share` words from `make_ring_switch_keys`. +/// @note The value subtracted on wrap is the keyed payload `2^n mod M`, not a `uint64_t` share. +/// @see grotto::zn64 +/// @see grotto::nmod +/// @see [Exact ring switch](@ref ring_switch) +template +Residue ring_switch_eval( + const ring_switch_keys & mat, + InputT eta, + dpf::proof_token * pi = nullptr) +{ + static_assert(Party < 2, "ring switch party is 0 or 1"); + using namespace ring_switch_detail; + eta = static_cast(eta & limb_mask()); + const InputT query = wrap_query(eta); + + Residue wrap{}; + if (mat.verifiable) + { + if (!mat.keys_v) + throw std::invalid_argument("ring switch: missing verifiable keys"); + auto & key = std::get(*mat.keys_v); + if (pi != nullptr) + { + wrap = dpf::eval_point(dpf::cmp, key, query, + dpf::prove(*pi)).raw(); + } + else + { + wrap = dpf::eval_point(dpf::cmp, key, query).raw(); + } + } + else + { + if (!mat.keys) + throw std::invalid_argument("ring switch: missing keys"); + auto & key = std::get(*mat.keys); + wrap = dpf::eval_point(dpf::cmp, key, query).raw(); + } + + Residue out = mat.r_share[Party] - wrap; + if constexpr (Party == 0) + out = out + reduce_limb(eta); + return out; +} + +} // namespace grotto + +#endif // LIBDPF_INCLUDE_GROTTO_RING_SWITCH_HPP__ diff --git a/include/grotto/window_extra_tables.inc b/include/grotto/window_extra_tables.inc new file mode 100644 index 0000000..1f766ff --- /dev/null +++ b/include/grotto/window_extra_tables.inc @@ -0,0 +1,573 @@ +// Generated on mocha2. +// Sollya fpminimax chose the knots (absolute error at most half an ulp). +// Each cubic is the best of Sollya, Mathematica Remez, Maple numapprox[minimax], +// and MATLAB/Chebfun minimax after rounding coefficients to 2^{-(k+16)}. +// Wins: sollya 229, mathematica 57, maple 83, matlab 74. +// lecun is the positive half of an odd map; hard covers (-1, 0). +// Do not edit. +#pragma once + +static constexpr std::int64_t LECUN_K8_KNOTS[] = { + 0, 383, 1009, 1568, +}; +static constexpr grotto::principal_detail::cubic_bits LECUN_K8_PIECES[] = { + {{-1, 0, -1, -1}, {18446744073709518887u, 19879543u, 18446744073707350723u, 18446744073708678990u}}, + {{0, 0, -1, 0}, {1369262u, 20958552u, 18446744073703958873u, 513285u}}, + {{0, 0, -1, 0}, {22332031u, 3254646u, 18446744073708996626u, 31889u}}, +}; +static constexpr window_table LECUN_K8_TABLE{LECUN_K8_KNOTS, LECUN_K8_PIECES, 3, 24}; + +static constexpr std::int64_t LECUN_K12_KNOTS[] = { + 0, 3129, 6621, 11508, 17406, 28255, 33599, +}; +static constexpr grotto::principal_detail::cubic_bits LECUN_K12_PIECES[] = { + {{-1, 0, -1, -1}, {18446744073709518858u, 308329774u, 18446744073702232285u, 18446744073675757155u}}, + {{-1, 0, -1, 0}, {18446744073689930871u, 380575836u, 18446744073610147456u, 6887314u}}, + {{-1, 0, -1, 0}, {18446744073689755640u, 394392918u, 18446744073593147938u, 12172877u}}, + {{0, 0, -1, 0}, {177037131u, 185326574u, 18446744073667763856u, 3225167u}}, + {{0, 0, -1, 0}, {390485523u, 32617477u, 18446744073704444953u, 268275u}}, + {{0, 0, -1, 0}, {451036331u, 3404431u, 18446744073709144606u, 16335u}}, +}; +static constexpr window_table LECUN_K12_TABLE{LECUN_K12_KNOTS, LECUN_K12_PIECES, 6, 28}; + +static constexpr std::int64_t LECUN_K16_KNOTS[] = { + 0, 27842, 51540, 76847, 110765, 151905, 190667, 234650, 289038, 363024, 481574, 673861, +}; +static constexpr grotto::principal_detail::cubic_bits LECUN_K16_PIECES[] = { + {{-1, 0, -1, -1}, {18446744073709518850u, 4915378338u, 18446744073686733153u, 18446744073045696549u}}, + {{-1, 0, -1, -1}, {18446744073681885059u, 5097087359u, 18446744073277580677u, 18446744073362394777u}}, + {{-1, 0, -1, -1}, {18446744073514829235u, 5725188408u, 18446744072483332962u, 18446744073700230733u}}, + {{-1, 0, -1, 0}, {18446744073170365398u, 6606619909u, 18446744071727358066u, 207979072u}}, + {{-1, 0, -1, 0}, {18446744073172517333u, 6645609937u, 18446744071678863789u, 222590154u}}, + {{0, 0, -1, 0}, {509982623u, 5298834044u, 18446744072257826522u, 139407694u}}, + {{0, 0, -1, 0}, {2215930476u, 3540863264u, 18446744072862840848u, 69869304u}}, + {{0, 0, -1, 0}, {4129924971u, 1934719556u, 18446744073312901862u, 27758440u}}, + {{0, 0, -1, 0}, {5805080174u, 790995162u, 18446744073573693035u, 7899519u}}, + {{0, 0, -1, 0}, {6908592007u, 188565949u, 18446744073683586729u, 1201533u}}, + {{0, 0, -1, 0}, {7316087307u, 16700500u, 18446744073707813339u, 60438u}}, +}; +static constexpr window_table LECUN_K16_TABLE{LECUN_K16_KNOTS, LECUN_K16_PIECES, 11, 32}; + +static constexpr std::int64_t LECUN_K20_KNOTS[] = { + 0, 253281, 455655, 646305, 836137, 1032680, 1244523, 1487011, 1823522, 2174766, 2481618, 2788121, 3107684, 3449680, 3823463, 4240298, 4715450, 5271108, 5943196, 6796607, 7967909, 9843000, 12962227, +}; +static constexpr grotto::principal_detail::cubic_bits LECUN_K20_PIECES[] = { + {{-1, 0, -1, -1}, {18446744073709518848u, 78614387265u, 18446744073639754453u, 18446744062405429372u}}, + {{-1, 0, -1, -1}, {18446744073679058043u, 78966242347u, 18446744072251108313u, 18446744064285203992u}}, + {{-1, 0, -1, -1}, {18446744073457774630u, 80467144554u, 18446744068832862089u, 18446744066899785276u}}, + {{-1, 0, -1, -1}, {18446744072783795589u, 83723937511u, 18446744063568506500u, 18446744069746400013u}}, + {{-1, 0, -1, -1}, {18446744071401336003u, 88907021452u, 18446744057076831498u, 18446744072462599604u}}, + {{-1, 0, -1, 0}, {18446744069191983778u, 95626901405u, 18446744050252883305u, 1066643240u}}, + {{-1, 0, -1, 0}, {18446744066336069910u, 102846196402u, 18446744044161565653u, 2782148181u}}, + {{-1, 0, -1, 0}, {18446744063597577859u, 108658845793u, 18446744040043356347u, 3756029371u}}, + {{-1, 0, -1, 0}, {18446744063947224258u, 108187129792u, 18446744040239112344u, 3732972174u}}, + {{-1, 0, -1, 0}, {18446744069327961135u, 100432772209u, 18446744043967391682u, 3134928569u}}, + {{0, 0, -1, 0}, {4687713165u, 88950743181u, 18446744048815967368u, 2452022353u}}, + {{0, 0, -1, 0}, {16669814040u, 75438507130u, 18446744053897872925u, 1814594476u}}, + {{0, 0, -1, 0}, {30712957096u, 61224830561u, 18446744058695549188u, 1274539932u}}, + {{0, 0, -1, 0}, {45890801524u, 47381784876u, 18446744062905967187u, 847478435u}}, + {{0, 0, -1, 0}, {61259637747u, 34731800988u, 18446744066378202736u, 529646080u}}, + {{0, 0, -1, 0}, {75918947020u, 23849210951u, 18446744069072386194u, 307213947u}}, + {{0, 0, -1, 0}, {89062975333u, 15071931076u, 18446744071027094838u, 162038289u}}, + {{0, 0, -1, 0}, {100036599329u, 8513577758u, 18446744072334338191u, 75135532u}}, + {{0, 0, -1, 0}, {108395156698u, 4079891827u, 18446744073118780945u, 28842254u}}, + {{0, 0, -1, 0}, {113961841782u, 1494360487u, 18446744073519416657u, 8131715u}}, + {{0, 0, -1, 0}, {116909704342u, 322678052u, 18446744073674846813u, 1250419u}}, + {{0, 0, -1, 0}, {117816434010u, 25499182u, 18446744073707365211u, 62576u}}, +}; +static constexpr window_table LECUN_K20_TABLE{LECUN_K20_KNOTS, LECUN_K20_PIECES, 22, 36}; + +static constexpr std::int64_t LECUN_K24_KNOTS[] = { + 0, 2319911, 4138017, 5796790, 7375174, 8910668, 10426723, 11940836, 13467994, 15022665, 16620363, 18279501, 20024189, 21889947, 23938076, 26309249, 30033484, 32931960, 35498514, 37961920, 40396391, 42841508, 45323826, 47864318, 50481783, 53193994, 56019099, 58976844, 62088815, 65379585, 68877975, 72618384, 76642891, 81003672, 85765777, 91015916, 96870295, 103486113, 111096074, 120058481, 130974848, 144897223, 164169192, 195646119, 242282859, +}; +static constexpr grotto::principal_detail::cubic_bits LECUN_K24_PIECES[] = { + {{-1, 0, -1, -1}, {18446744073709518848u, 1257774779783u, 18446744073497344033u, 18446743889184923569u}}, + {{-1, 0, -1, -1}, {18446744073678102803u, 1258408492611u, 18446744069132721481u, 18446743899488534307u}}, + {{-1, 0, -1, -1}, {18446744073438003380u, 1261275869088u, 18446744057639497821u, 18446743914954145489u}}, + {{-1, 0, -1, -1}, {18446744072647888664u, 1268081813507u, 18446744038035814342u, 18446743933836576505u}}, + {{-1, 0, -1, -1}, {18446744070840434469u, 1280363243694u, 18446744010167913735u, 18446743954953918307u}}, + {{-1, 0, -1, -1}, {18446744067470346842u, 1299348139081u, 18446743974475162292u, 18446743977349326053u}}, + {{-1, 0, -1, -1}, {18446744061969652321u, 1325853931262u, 18446743931864060151u, 18446744000203445293u}}, + {{-1, 0, -1, -1}, {18446744053808696042u, 1360211131783u, 18446743883617589122u, 18446744022802219327u}}, + {{-1, 0, -1, -1}, {18446744042561957360u, 1402205941184u, 18446743831320258705u, 18446744044523155480u}}, + {{-1, 0, -1, -1}, {18446744027978886410u, 1451036368954u, 18446743776793527929u, 18446744064828289276u}}, + {{-1, 0, -1, 0}, {18446744010061561228u, 1505275654164u, 18446743722040685829u, 9549839095u}}, + {{-1, 0, -1, 0}, {18446743989154693317u, 1562831477099u, 18446743669205340913u, 25722993268u}}, + {{-1, 0, -1, 0}, {18446743966061353524u, 1620879110938u, 18446743620552611649u, 39320354817u}}, + {{-1, 0, -1, 0}, {18446743942221114319u, 1675711478149u, 18446743578500764475u, 50073972321u}}, + {{-1, 0, -1, 0}, {18446743920075669673u, 1722312452690u, 18446743545801804755u, 57724663849u}}, + {{-1, 0, -1, 0}, {18446743904369315072u, 1752453603693u, 18446743526513040474u, 61840965450u}}, + {{-1, 0, -1, 0}, {18446743912904582819u, 1738510504673u, 18446743534101846493u, 60464874518u}}, + {{-1, 0, -1, 0}, {18446743944070543369u, 1690954835687u, 18446743558296602439u, 56360586341u}}, + {{-1, 0, -1, 0}, {18446743991987200352u, 1623066407638u, 18446743590364714282u, 51310258568u}}, + {{-1, 0, -1, 0}, {18446744054922737606u, 1539659486770u, 18446743627216781539u, 45881815327u}}, + {{0, 0, -1, 0}, {57684257897u, 1444406681827u, 18446743666771919862u, 40405699769u}}, + {{0, 0, -1, 0}, {146162521632u, 1340477432551u, 18446743707470330127u, 35092507113u}}, + {{0, 0, -1, 0}, {245012085861u, 1230717517263u, 18446743748100344102u, 30078506521u}}, + {{0, 0, -1, 0}, {352498742026u, 1117696271097u, 18446743787718734167u, 25448679788u}}, + {{0, 0, -1, 0}, {466805407877u, 1003731027165u, 18446743825598071936u, 21251462995u}}, + {{0, 0, -1, 0}, {586053165481u, 890897353275u, 18446743861190278738u, 17508644539u}}, + {{0, 0, -1, 0}, {708345006456u, 781015491303u, 18446743894104334047u, 14221917688u}}, + {{0, 0, -1, 0}, {831791198010u, 675655890057u, 18446743924081950099u, 11378461166u}}, + {{0, 0, -1, 0}, {954531258834u, 576146474573u, 18446743950976776300u, 8955201228u}}, + {{0, 0, -1, 0}, {1074771483667u, 483567494257u, 18446743974739837274u, 6921815786u}}, + {{0, 0, -1, 0}, {1190813485226u, 398756096934u, 18446743995404187559u, 5243329580u}}, + {{0, 0, -1, 0}, {1301080682746u, 322313528698u, 18446744013070847321u, 3882186399u}}, + {{0, 0, -1, 0}, {1404141224096u, 254615663350u, 18446744027895691614u, 2799910830u}}, + {{0, 0, -1, 0}, {1498719777812u, 195830681643u, 18446744040076493073u, 1958474957u}}, + {{0, 0, -1, 0}, {1583748437920u, 145912670171u, 18446744049846370749u, 1321003434u}}, + {{0, 0, -1, 0}, {1658401744257u, 104610454422u, 18446744057464407604u, 852559004u}}, + {{0, 0, -1, 0}, {1722091109725u, 71499705766u, 18446744063203243852u, 520946229u}}, + {{0, 0, -1, 0}, {1774535817434u, 45973972528u, 18446744067345315116u, 296857787u}}, + {{0, 0, -1, 0}, {1815816349961u, 27254187151u, 18446744070175621840u, 154184437u}}, + {{0, 0, -1, 0}, {1846399383973u, 14416484753u, 18446744071972392335u, 70335818u}}, + {{0, 0, -1, 0}, {1867135549110u, 6432456865u, 18446744072997450474u, 26451763u}}, + {{0, 0, -1, 0}, {1879389944043u, 2162553158u, 18446744073493629591u, 7223027u}}, + {{0, 0, -1, 0}, {1885071924774u, 410017389u, 18446744073673956180u, 1033304u}}, + {{0, 0, -1, 0}, {1886511394554u, 30436274u, 18446744073707352136u, 53047u}}, +}; +static constexpr window_table LECUN_K24_TABLE{LECUN_K24_KNOTS, LECUN_K24_PIECES, 44, 40}; + +static constexpr std::int64_t LECUN_K28_KNOTS[] = { + 0, 21296064, 37881820, 52865109, 66937135, 80407373, 93452173, 106186493, 118692214, 131031619, 143254606, 155402938, 167512998, 179617460, 191746701, 203929846, 216195546, 228572773, 241091551, 253783873, 266684514, 279832246, 293271478, 307054317, 321243781, 335918651, 351181335, 367172127, 384097121, 402291139, 422400238, 446223520, 484774210, 508801036, 530618967, 551369200, 571510883, 591291937, 610870275, 630354793, 649828991, 669358532, 688997611, 708794293, 728791247, 749029604, 769544037, 790373730, 811552601, 833116468, 855102820, 877546519, 900488928, 923966741, 948024795, 972707536, 998062550, 1024140162, 1051000122, 1078699236, 1107308363, 1136896837, 1167547770, 1199348540, 1232400838, 1266813627, 1302707951, 1340231673, 1379550616, 1420854987, 1464367868, 1510328169, 1559037281, 1610864767, 1666250962, 1725666717, 1789808468, 1859496629, 1935803122, 2019999212, 2114115991, 2220570365, 2343201785, 2487988312, 2664439417, 2890577070, 3204792600, 3726439513, 4434721554, +}; +static constexpr grotto::principal_detail::cubic_bits LECUN_K28_PIECES[] = { + {{-1, 0, -1, -1}, {18446744073709518848u, 20124299830275u, 18446744073065634869u, 18446741101906119012u}}, + {{-1, 0, -1, -1}, {18446744073677785063u, 20125415447680u, 18446744059677249364u, 18446741156965780529u}}, + {{-1, 0, -1, -1}, {18446744073431364491u, 20130557950228u, 18446744023662605776u, 18446741241629280780u}}, + {{-1, 0, -1, -1}, {18446744072601716733u, 20143093754073u, 18446743960331698254u, 18446741348609804059u}}, + {{-1, 0, -1, -1}, {18446744070647461618u, 20166498830405u, 18446743866732701220u, 18446741473598574129u}}, + {{-1, 0, -1, -1}, {18446744066871002840u, 20204213200278u, 18446743741044437832u, 18446741613380464365u}}, + {{-1, 0, -1, -1}, {18446744060438132907u, 20259538500345u, 18446743582312811590u, 18446741765303994140u}}, + {{-1, 0, -1, -1}, {18446744050400154112u, 20335557126290u, 18446743390301471013u, 18446741927062641690u}}, + {{-1, 0, -1, -1}, {18446744035718185546u, 20435064892551u, 18446743165392937529u, 18446742096586772408u}}, + {{-1, 0, -1, -1}, {18446744015289361273u, 20560513602627u, 18446742908515292137u, 18446742271984487250u}}, + {{-1, 0, -1, -1}, {18446743987974700821u, 20713961364682u, 18446742621083556607u, 18446742451506795225u}}, + {{-1, 0, -1, -1}, {18446743952628339243u, 20897030004889u, 18446742304948985197u, 18446742633526713969u}}, + {{-1, 0, -1, -1}, {18446743908128211404u, 21110867245022u, 18446741962355919189u, 18446742816524993050u}}, + {{-1, 0, -1, -1}, {18446743853408051615u, 21356113508346u, 18446741595902784148u, 18446742999080747472u}}, + {{-1, 0, -1, -1}, {18446743787490162224u, 21632874844393u, 18446741208503380012u, 18446743179866379742u}}, + {{-1, 0, -1, -1}, {18446743709519555674u, 21940698366326u, 18446740803352854654u, 18446743357643040084u}}, + {{-1, 0, -1, -1}, {18446743618799449977u, 22278550438730u, 18446740383896185412u, 18446743531257187064u}}, + {{-1, 0, -1, -1}, {18446743514828144218u, 22644797577511u, 18446739953798249048u, 18446743699638100514u}}, + {{-1, 0, -1, -1}, {18446743397337348499u, 23037189941702u, 18446739516914963329u, 18446743861796144162u}}, + {{-1, 0, -1, -1}, {18446743266333251222u, 23452843585269u, 18446739077269066170u, 18446744016820229847u}}, + {{-1, 0, -1, 0}, {18446743122141397336u, 23888219823420u, 18446738639030502335u, 90165182646u}}, + {{-1, 0, -1, 0}, {18446742965455203558u, 24339104239439u, 18446738206497483031u, 228487690085u}}, + {{-1, 0, -1, 0}, {18446742797392018223u, 24800576192489u, 18446737784086000175u, 357384983710u}}, + {{-1, 0, -1, 0}, {18446742619560132447u, 25266964390128u, 18446737376328730066u, 476227574323u}}, + {{-1, 0, -1, 0}, {18446742434142098717u, 25731781204874u, 18446736987886086575u, 584442501965u}}, + {{-1, 0, -1, 0}, {18446742244006810883u, 26187614937580u, 18446736623581366827u, 681501929268u}}, + {{-1, 0, -1, 0}, {18446742052868612182u, 26625954257490u, 18446736288471017068u, 766906223209u}}, + {{-1, 0, -1, 0}, {18446741865533853633u, 27036882118964u, 18446735987982588277u, 840155752192u}}, + {{-1, 0, -1, 0}, {18446741688333751402u, 27408481376413u, 18446735728204813780u, 900696167803u}}, + {{-1, 0, -1, 0}, {18446741530000522341u, 27725546527377u, 18446735516542227593u, 947800274977u}}, + {{-1, 0, -1, 0}, {18446741403980434551u, 27965984352422u, 18446735363612721759u, 980227153200u}}, + {{-1, 0, -1, 0}, {18446741348296964153u, 28067395007143u, 18446735302049875928u, 992684679073u}}, + {{-1, 0, -1, 0}, {18446741451063927077u, 27897028406762u, 18446735396205370025u, 975337156825u}}, + {{-1, 0, -1, 0}, {18446741640337715831u, 27597649025792u, 18446735554063804087u, 947589376388u}}, + {{-1, 0, -1, 0}, {18446741903236388302u, 27198799660417u, 18446735755778246237u, 913582034836u}}, + {{-1, 0, -1, 0}, {18446742234142829797u, 26715608497302u, 18446735990977668562u, 875417757949u}}, + {{-1, 0, -1, 0}, {18446742629225242390u, 26159001455178u, 18446736252380599419u, 834494238800u}}, + {{-1, 0, -1, 0}, {18446743085299038543u, 25537936630695u, 18446736534308136294u, 791832670284u}}, + {{-1, 0, -1, 0}, {18446743599397539783u, 24860273398859u, 18446736832076618321u, 748217180469u}}, + {{0, 0, -1, 0}, {94881463914u, 24133162626813u, 18446737141702497290u, 704266061451u}}, + {{0, 0, -1, 0}, {716203055589u, 23363234444820u, 18446737459740500008u, 660473247712u}}, + {{0, 0, -1, 0}, {1386569575955u, 22556757216059u, 18446737783159945748u, 617238356098u}}, + {{0, 0, -1, 0}, {2102795298693u, 21719661048553u, 18446738109292649146u, 574883139671u}}, + {{0, 0, -1, 0}, {2861593790618u, 20857569715477u, 18446738435785064444u, 533665234839u}}, + {{0, 0, -1, 0}, {3659596365633u, 19975807915038u, 18446738760566200023u, 493788201720u}}, + {{0, 0, -1, 0}, {4493285912079u, 19079496914872u, 18446739081788160284u, 455413601833u}}, + {{0, 0, -1, 0}, {5359083421480u, 18173475619582u, 18446739397835600146u, 418663550933u}}, + {{0, 0, -1, 0}, {6253360632198u, 17262309170946u, 18446739707302921215u, 383626835146u}}, + {{0, 0, -1, 0}, {7172367492570u, 16350377667545u, 18446740008948506425u, 350366776102u}}, + {{0, 0, -1, 0}, {8112376373349u, 15441745336834u, 18446740301724535739u, 318920157897u}}, + {{0, 0, -1, 0}, {9069578420349u, 14540279433051u, 18446740584724215660u, 289305035263u}}, + {{0, 0, -1, 0}, {10040183235840u, 13649566478286u, 18446740857197506149u, 261520640352u}}, + {{0, 0, -1, 0}, {11020376929601u, 12772967316514u, 18446741118522506130u, 235551855605u}}, + {{0, 0, -1, 0}, {12006349528286u, 11913602762813u, 18446741368200772412u, 211370827881u}}, + {{0, 0, -1, 0}, {12994386103928u, 11074289771036u, 18446741605865956416u, 188937284256u}}, + {{0, 0, -1, 0}, {13980755163191u, 10257652006184u, 18446741831243264779u, 168203354476u}}, + {{0, 0, -1, 0}, {14961772523120u, 9466075311091u, 18446742044155224523u, 149113708952u}}, + {{0, 0, -1, 0}, {15933910361132u, 8701634512227u, 18446742244533526321u, 131605232879u}}, + {{0, 0, -1, 0}, {16893680786237u, 7966203249811u, 18446742432382029214u, 115610966919u}}, + {{0, 0, -1, 0}, {17837702995784u, 7261411579494u, 18446742607782346704u, 101060027026u}}, + {{0, 0, -1, 0}, {18762719221770u, 6588648893217u, 18446742770886744521u, 87878653299u}}, + {{0, 0, -1, 0}, {19665565371441u, 5949097239747u, 18446742921904821221u, 75991614672u}}, + {{0, 0, -1, 0}, {20543247928224u, 5343689391650u, 18446743061108367804u, 65322110811u}}, + {{0, 0, -1, 0}, {21392914709438u, 4773143427922u, 18446743188818275847u, 55793041185u}}, + {{0, 0, -1, 0}, {22211873862539u, 4237962784994u, 18446743305400097452u, 47327522801u}}, + {{0, 0, -1, 0}, {22997540957489u, 3738481673093u, 18446743411250431801u, 39849994712u}}, + {{0, 0, -1, 0}, {23747627771105u, 3274756813356u, 18446743506816191590u, 33284955246u}}, + {{0, 0, -1, 0}, {24460124051129u, 2846600979598u, 18446743592582105572u, 27558034688u}}, + {{0, 0, -1, 0}, {25133195087626u, 2453661113386u, 18446743669051112188u, 22597380387u}}, + {{0, 0, -1, 0}, {25765248102340u, 2095390956985u, 18446743736747046849u, 18333457256u}}, + {{0, 0, -1, 0}, {26354815012972u, 1771129200696u, 18446743796197333290u, 14700102906u}}, + {{0, 0, -1, 0}, {26900708644672u, 1480020562851u, 18446743847945935619u, 11633633643u}}, + {{0, 0, -1, 0}, {27402206308373u, 1220938852461u, 18446743892563113077u, 9072307305u}}, + {{0, 0, -1, 0}, {27858889386709u, 992595894927u, 18446743930622258563u, 6957702857u}}, + {{0, 0, -1, 0}, {28270401797702u, 793672168699u, 18446743962676858446u, 5235857096u}}, + {{0, 0, -1, 0}, {28636933282678u, 622589053793u, 18446743989296661003u, 3855141243u}}, + {{0, 0, -1, 0}, {28959196694062u, 477554575969u, 18446744011055483875u, 2766954575u}}, + {{0, 0, -1, 0}, {29238155900548u, 356709512464u, 18446744028506614079u, 1926866918u}}, + {{0, 0, -1, 0}, {29475036561343u, 258131648168u, 18446744042181974273u, 1294443890u}}, + {{0, 0, -1, 0}, {29671765968433u, 179671151116u, 18446744052613466422u, 832110378u}}, + {{0, 0, -1, 0}, {29830647890417u, 119119370775u, 18446744060306510889u, 506282387u}}, + {{0, 0, -1, 0}, {29954429258898u, 74200855907u, 18446744065740534323u, 287131350u}}, + {{0, 0, -1, 0}, {30046574099440u, 42507013116u, 18446744069374785685u, 148202946u}}, + {{0, 0, -1, 0}, {30110933497890u, 21651668853u, 18446744071627853058u, 67054139u}}, + {{0, 0, -1, 0}, {30151923887417u, 9242089186u, 18446744072880441188u, 24900492u}}, + {{0, 0, -1, 0}, {30174500650192u, 2934870992u, 18446744073467978243u, 6650925u}}, + {{0, 0, -1, 0}, {30184110348413u, 507144103u, 18446744073672533775u, 902623u}}, + {{0, 0, -1, 0}, {30186239470354u, 36092206u, 18446744073707293873u, 47127u}}, +}; +static constexpr window_table LECUN_K28_TABLE{LECUN_K28_KNOTS, LECUN_K28_PIECES, 88, 44}; + +static constexpr std::int64_t LECUN_K32_KNOTS[] = { + 0, 195631931, 347682782, 484604688, 612667347, 734642359, 852081869, 965974781, 1077004548, 1185671778, 1292359608, 1397370933, 1500951724, 1603306588, 1704608708, 1805007337, 1904633420, 2003602398, 2102017899, 2199974409, 2297557907, 2394848099, 2491919208, 2588841688, 2685681914, 2782503550, 2879368025, 2976335392, 3073464088, 3170811534, 3268435071, 3366392034, 3464739747, 3563537091, 3662843131, 3762718425, 3863225833, 3964430856, 4066401283, 4169208251, 4272927520, 4377638470, 4483427570, 4590386973, 4698616150, 4808224502, 4919331821, 5032070990, 5146589881, 5263056616, 5381661513, 5502625214, 5626204156, 5752703991, 5882493135, 6016027104, 6153882685, 6296818237, 6445870392, 6602545215, 6769226129, 6950245197, 7155851395, 7450164740, 7695769067, 7901037862, 8090091491, 8269662129, 8442887057, 8611561719, 8776844637, 8939543480, 9100252155, 9259425022, 9417428692, 9574553562, 9731050280, 9887121097, 10042953268, 10198703991, 10354516599, 10510519520, 10666828241, 10823546548, 10980781522, 11138619671, 11297156308, 11456472452, 11616649723, 11777765147, 11939904542, 12103128723, 12267521054, 12433147961, 12600080171, 12768387827, 12938154343, 13109437784, 13282310215, 13456852324, 13633126833, 13811216534, 13991196441, 14173138559, 14357132087, 14543236866, 14731571133, 14922194757, 15115195155, 15310676321, 15508719424, 15709421074, 15912895787, 16119229197, 16328522098, 16540911121, 16756517676, 16975447428, 17197838567, 17423819364, 17653555261, 17887165572, 18124768245, 18366577958, 18612788131, 18863506065, 19118987959, 19379394765, 19644991695, 19915936092, 20192511418, 20474974586, 20763575503, 21058624279, 21360419022, 21669290546, 21985514357, 22309619439, 22641922393, 22982857266, 23333036709, 23692845604, 24062858906, 24443676901, 24835984420, 25240515547, 25658025589, 26089520580, 26535975653, 26998085056, 27477342798, 27975087451, 28492797106, 29032309828, 29595162439, 30183546881, 30799870890, 31447092756, 32128748501, 32849013653, 33611850361, 34422378686, 35286353118, 36213608574, 37212060991, 38294083464, 39475657506, 40775409262, 42219541358, 43848069770, 45712917354, 47891104688, 50513508790, 53797815412, 58224258306, 64987660164, 79369129555, 79886672667, +}; +static constexpr grotto::principal_detail::cubic_bits LECUN_K32_PIECES[] = { + {{-1, 0, -1, -1}, {18446744073709518849u, 321988628920406u, 18446744071756957459u, 18446696422238541071u}}, + {{-1, 0, -1, -1}, {18446744073677680374u, 321990578371400u, 18446744031013180070u, 18446696714029062080u}}, + {{-1, 0, -1, -1}, {18446744073429163452u, 321999618960687u, 18446743920649452429u, 18446697166249851440u}}, + {{-1, 0, -1, -1}, {18446744072586335811u, 322021845666301u, 18446743724673859634u, 18446697743999875698u}}, + {{-1, 0, -1, -1}, {18446744070582855791u, 322063788120053u, 18446743431488515731u, 18446698428315876449u}}, + {{-1, 0, -1, -1}, {18446744066669246820u, 322132229388313u, 18446743032084167674u, 18446699206109269625u}}, + {{-1, 0, -1, -1}, {18446744059919527123u, 322234091361254u, 18446742519283954000u, 18446700067292019884u}}, + {{-1, 0, -1, -1}, {18446744049238768748u, 322376350119884u, 18446741887339852643u, 18446701003563308160u}}, + {{-1, 0, -1, -1}, {18446744033371527033u, 322565967759811u, 18446741131687082619u, 18446702007791595869u}}, + {{-1, 0, -1, -1}, {18446744010910982300u, 322809835673232u, 18446740248776818373u, 18446703073666495610u}}, + {{-1, 0, -1, -1}, {18446743980308781582u, 323114725132817u, 18446739235957451506u, 18446704195482356147u}}, + {{-1, 0, -1, -1}, {18446743939885619371u, 323487242542078u, 18446738091387838673u, 18446705367994376245u}}, + {{-1, 0, -1, -1}, {18446743887842348275u, 323933789893598u, 18446736813966357162u, 18446706586323852211u}}, + {{-1, 0, -1, -1}, {18446743822271668887u, 324460528507979u, 18446735403274152473u, 18446707845890248093u}}, + {{-1, 0, -1, -1}, {18446743741170398833u, 325073345332455u, 18446733859528614793u, 18446709142361228974u}}, + {{-1, 0, -1, -1}, {18446743642451885358u, 325777824312851u, 18446732183537484044u, 18446710471620402297u}}, + {{-1, 0, -1, -1}, {18446743523959330167u, 326579216327014u, 18446730376667752501u, 18446711829735522457u}}, + {{-1, 0, -1, -1}, {18446743383479681452u, 327482410754481u, 18446728440817749983u, 18446713212934922891u}}, + {{-1, 0, -1, -1}, {18446743218756864709u, 328491915740201u, 18446726378377492224u, 18446714617599081844u}}, + {{-1, 0, -1, -1}, {18446743027506460245u, 329611832679029u, 18446724192208508603u, 18446716040242694209u}}, + {{-1, 0, -1, -1}, {18446742807430863358u, 330845832248346u, 18446721885623838323u, 18446717477501826670u}}, + {{-1, 0, -1, -1}, {18446742556234062908u, 332197136220403u, 18446719462360945551u, 18446718926128730301u}}, + {{-1, 0, -1, -1}, {18446742271636350074u, 333668502228196u, 18446716926554026967u, 18446720382988675313u}}, + {{-1, 0, -1, -1}, {18446741951390399679u, 335262203770315u, 18446714282718604783u, 18446721845051126564u}}, + {{-1, 0, -1, -1}, {18446741593297871785u, 336980010981452u, 18446711535736410348u, 18446723309383053470u}}, + {{-1, 0, -1, -1}, {18446741195224966496u, 338823179167325u, 18446708690830082732u, 18446724773148996844u}}, + {{-1, 0, -1, -1}, {18446740755118148283u, 340792438196454u, 18446705753540032009u, 18446726233610339227u}}, + {{-1, 0, -1, -1}, {18446740271021724018u, 342887975485808u, 18446702729713375525u, 18446727688119197662u}}, + {{-1, 0, -1, -1}, {18446739741096170175u, 345109418770611u, 18446699625493672137u, 18446729134113321903u}}, + {{-1, 0, -1, -1}, {18446739163634280992u, 347455830527358u, 18446696447295520631u, 18446730569118813102u}}, + {{-1, 0, -1, -1}, {18446738537077815648u, 349925701378504u, 18446693201783556799u, 18446731990750601797u}}, + {{-1, 0, -1, -1}, {18446737860037546683u, 352516931921314u, 18446689895868175818u, 18446733396705983404u}}, + {{-1, 0, -1, -1}, {18446737131309110577u, 355226833287576u, 18446686536677621472u, 18446734784769012901u}}, + {{-1, 0, -1, -1}, {18446736349893170948u, 358052112472508u, 18446683131551538056u, 18446736152805715845u}}, + {{-1, 0, -1, -1}, {18446735515018725649u, 360988849747647u, 18446679688043162055u, 18446737498756911589u}}, + {{-1, 0, -1, -1}, {18446734626157871516u, 364032509031414u, 18446676213882789484u, 18446738820646748024u}}, + {{-1, 0, -1, -1}, {18446733683044983616u, 367177932873632u, 18446672716962398160u, 18446740116582267584u}}, + {{-1, 0, -1, -1}, {18446732685700835254u, 370419323185634u, 18446669205336519187u, 18446741384747310205u}}, + {{-1, 0, -1, -1}, {18446731634457952652u, 373750221972248u, 18446665687221613452u, 18446742623397915713u}}, + {{-1, 0, -1, -1}, {18446730529977590670u, 377163521536394u, 18446662170964236582u, 18446743830869033513u}}, + {{-1, 0, -1, 0}, {18446729373279609312u, 380651435926364u, 18446658665051006470u, 931856908175u}}, + {{-1, 0, -1, 0}, {18446728165763803598u, 384205502828999u, 18446655178086097986u, 2072260976633u}}, + {{-1, 0, -1, 0}, {18446726909235628084u, 387816573906307u, 18446651718781756757u, 3176925575352u}}, + {{-1, 0, -1, 0}, {18446725605947818836u, 391474764188918u, 18446648295986392533u, 4244465835860u}}, + {{-1, 0, -1, 0}, {18446724258623935635u, 395169459071812u, 18446644918655468679u, 5273564751042u}}, + {{-1, 0, -1, 0}, {18446722870495248960u, 398889286883270u, 18446641595855328209u, 6262969243549u}}, + {{-1, 0, -1, 0}, {18446721445345788473u, 402622076216967u, 18446638336778055965u, 7211483676756u}}, + {{-1, 0, -1, 0}, {18446719987561394622u, 406354810964212u, 18446635150754873906u, 8117964669060u}}, + {{-1, 0, -1, 0}, {18446718502177214472u, 410073597829969u, 18446632047255679469u, 8981320525460u}}, + {{-1, 0, -1, 0}, {18446716994946291740u, 413763589671939u, 18446629035922686594u, 9800501626123u}}, + {{-1, 0, -1, 0}, {18446715472417745911u, 417408899481642u, 18446626126604980724u, 10574492001769u}}, + {{-1, 0, -1, 0}, {18446713942033402904u, 420992486128106u, 18446623329408456678u, 11302298156317u}}, + {{-1, 0, -1, 0}, {18446712412245826237u, 424496010753585u, 18446620654758846799u, 11982936313851u}}, + {{-1, 0, -1, 0}, {18446710892670211132u, 427899641265225u, 18446618113492314531u, 12615414775639u}}, + {{-1, 0, -1, 0}, {18446709394291113793u, 431181769145309u, 18446615716994204356u, 13198707396432u}}, + {{-1, 0, -1, 0}, {18446707929740855074u, 434318617888225u, 18446613477392372228u, 13731718169754u}}, + {{-1, 0, -1, 0}, {18446706513688938135u, 437283681364257u, 18446611407837430772u, 14213231228272u}}, + {{-1, 0, -1, 0}, {18446705163439297727u, 440046826349609u, 18446609522966032184u, 14641827333912u}}, + {{-1, 0, -1, 0}, {18446703899885543187u, 442572822105327u, 18446607839670407362u, 15015745920519u}}, + {{-1, 0, -1, 0}, {18446702749143370061u, 444818784088733u, 18446606378448068220u, 15332644090704u}}, + {{-1, 0, -1, 0}, {18446701745748171558u, 446729060860799u, 18446605166145233493u, 15589102230643u}}, + {{-1, 0, -1, 0}, {18446700940330702611u, 448222706622736u, 18446604242794837915u, 15779375515492u}}, + {{-1, 0, -1, 0}, {18446700428720371789u, 449144821507006u, 18446603688772365099u, 15890335477094u}}, + {{-1, 0, -1, 0}, {18446700574454752596u, 448896306584227u, 18446603830007578869u, 15863585019068u}}, + {{-1, 0, -1, 0}, {18446701299122088260u, 447683755970031u, 18446604506330778685u, 15737836772130u}}, + {{-1, 0, -1, 0}, {18446702400317785516u, 445888451539002u, 18446605481997563740u, 15561088666692u}}, + {{-1, 0, -1, 0}, {18446703831459288931u, 443609511300815u, 18446606691679965639u, 15347047229095u}}, + {{-1, 0, -1, 0}, {18446705568467421781u, 440903434133193u, 18446608096968315265u, 15103783331334u}}, + {{-1, 0, -1, 0}, {18446707595748145343u, 437809849060789u, 18446609670575682149u, 14836964275807u}}, + {{-1, 0, -1, 0}, {18446709901864489489u, 434359627717625u, 18446611391248259429u, 14550918818723u}}, + {{-1, 0, -1, 0}, {18446712477700306081u, 430578395144398u, 18446613241512082546u, 14249118996462u}}, + {{-1, 0, -1, 0}, {18446715315510040957u, 426488370074578u, 18446615206470327342u, 13934441748702u}}, + {{-1, 0, -1, 0}, {18446718408357597483u, 422109454933314u, 18446617273081981972u, 13609327839160u}}, + {{-1, 0, -1, 0}, {18446721749865077657u, 417459781041083u, 18446619429766404356u, 13275874739267u}}, + {{-1, 0, -1, 0}, {18446725333934886583u, 412556233202076u, 18446621666056711789u, 12935913225069u}}, + {{-1, 0, -1, 0}, {18446729154635161304u, 407414701815671u, 18446623972408813885u, 12591053620109u}}, + {{-1, 0, -1, 0}, {18446733206079406990u, 402050318710387u, 18446626340034901366u, 12242724439303u}}, + {{-1, 0, -1, 0}, {18446737482402106259u, 396477543943195u, 18446628760817322228u, 11892195991764u}}, + {{-1, 0, -1, 0}, {18446741977789340371u, 390710175764217u, 18446631227261805984u, 11540596603357u}}, + {{0, 0, -1, 0}, {2612591054362u, 384761619123340u, 18446633732347315659u, 11188941863986u}}, + {{0, 0, -1, 0}, {7528249597908u, 378644798997033u, 18446636269534788294u, 10838139707682u}}, + {{0, 0, -1, 0}, {12644937066285u, 372372318597418u, 18446638832675648426u, 10489008738551u}}, + {{0, 0, -1, 0}, {17956360185251u, 365956517075447u, 18446641415968138462u, 10142288747186u}}, + {{0, 0, -1, 0}, {23456250095143u, 359409246500468u, 18446644014027877180u, 9798635440093u}}, + {{0, 0, -1, 0}, {29138169513775u, 352742125696604u, 18446646621766430249u, 9458640667076u}}, + {{0, 0, -1, 0}, {34995554608356u, 345966500593563u, 18446649234393086033u, 9122835222624u}}, + {{0, 0, -1, 0}, {41021811760532u, 339093347952886u, 18446651847436612380u, 8791689137532u}}, + {{0, 0, -1, 0}, {47210112757969u, 332133521464660u, 18446654456638348532u, 8465627903210u}}, + {{0, 0, -1, 0}, {53553573354125u, 325097556538140u, 18446657058015316526u, 8145026719748u}}, + {{0, 0, -1, 0}, {60045393085730u, 317995531832345u, 18446659647897801909u, 7830208331448u}}, + {{0, 0, -1, 0}, {66678441435168u, 310837536952306u, 18446662222746462974u, 7521467451950u}}, + {{0, 0, -1, 0}, {73445504421218u, 303633401045977u, 18446664779245510686u, 7219060735224u}}, + {{0, 0, -1, 0}, {80339455446704u, 296392525723179u, 18446667314350583752u, 6923203034388u}}, + {{0, 0, -1, 0}, {87352860454239u, 289124310000059u, 18446669825130696819u, 6634087429684u}}, + {{0, 0, -1, 0}, {94478321591863u, 281837793538358u, 18446672308886371666u, 6351872658102u}}, + {{0, 0, -1, 0}, {101708655065780u, 274541492740146u, 18446674763194288680u, 6076679721234u}}, + {{0, 0, -1, 0}, {109036376203389u, 267243936890941u, 18446677185716734130u, 5808614742034u}}, + {{0, 0, -1, 0}, {116453690011677u, 259953666154936u, 18446679574201761395u, 5547769300083u}}, + {{0, 0, -1, 0}, {123953238534894u, 252678502689610u, 18446681926715846593u, 5294195984839u}}, + {{0, 0, -1, 0}, {131527389669713u, 245426264790555u, 18446684241401057461u, 5047936111898u}}, + {{0, 0, -1, 0}, {139168508330435u, 238204502284841u, 18446686516557484760u, 4809011371583u}}, + {{0, 0, -1, 0}, {146869145790264u, 231020330567994u, 18446688750687877924u, 4577420138659u}}, + {{0, 0, -1, 0}, {154621573604161u, 223880875100540u, 18446690942353114567u, 4353153269029u}}, + {{0, 0, -1, 0}, {162418284063505u, 216792809426900u, 18446693090311285844u, 4136180282290u}}, + {{0, 0, -1, 0}, {170251458669180u, 209762850085467u, 18446695193361150594u, 3926465966336u}}, + {{0, 0, -1, 0}, {178113813429410u, 202796998007284u, 18446697250566303856u, 3723948398568u}}, + {{0, 0, -1, 0}, {185998001670943u, 195901097718228u, 18446699261078444767u, 3528557574186u}}, + {{0, 0, -1, 0}, {193895965588108u, 189081390933855u, 18446701223977628172u, 3340230820193u}}, + {{0, 0, -1, 0}, {201800483058691u, 182343173994075u, 18446703138658276190u, 3158875859507u}}, + {{0, 0, -1, 0}, {209704142158941u, 175691706281611u, 18446705004558891569u, 2984397623471u}}, + {{0, 0, -1, 0}, {217599306119691u, 169132231281051u, 18446706821156525843u, 2816698751015u}}, + {{0, 0, -1, 0}, {225478928638994u, 162669304689208u, 18446708588149297153u, 2655663089435u}}, + {{0, 0, -1, 0}, {233335673526882u, 156307538017955u, 18446710305245258121u, 2501175661815u}}, + {{0, 0, -1, 0}, {241161875828406u, 150051615649023u, 18446711972159987631u, 2353122676153u}}, + {{0, 0, -1, 0}, {248950764631457u, 143905322731148u, 18446713588872374628u, 2211369094970u}}, + {{0, 0, -1, 0}, {256695847740100u, 137872070552679u, 18446715155474271137u, 2075772872475u}}, + {{0, 0, -1, 0}, {264389975996447u, 131955626162225u, 18446716671979594863u, 1946201553878u}}, + {{0, 0, -1, 0}, {272026210603730u, 126159426534992u, 18446718138503709907u, 1822516596135u}}, + {{0, 0, -1, 0}, {279597933809414u, 120486509641876u, 18446719555275604315u, 1704572756015u}}, + {{0, 0, -1, 0}, {287098868933041u, 114939515399094u, 18446720922632421740u, 1592218935580u}}, + {{0, 0, -1, 0}, {294522494401598u, 109521129605266u, 18446722240906328155u, 1485307724659u}}, + {{0, 0, -1, 0}, {301861463777516u, 104234486094949u, 18446723510330783060u, 1383702607961u}}, + {{0, 0, -1, 0}, {309109859156466u, 99081536699739u, 18446724731432353276u, 1287246527246u}}, + {{0, 0, -1, 0}, {316262749798536u, 94063429186862u, 18446725904924741032u, 1195771503712u}}, + {{0, 0, -1, 0}, {323313473916470u, 89182420958703u, 18446727031259084875u, 1109133770198u}}, + {{0, 0, -1, 0}, {330256173694003u, 84440075542959u, 18446728111050780416u, 1027180028858u}}, + {{0, 0, -1, 0}, {337085626820039u, 79837417275974u, 18446729145034192695u, 949751599437u}}, + {{0, 0, -1, 0}, {343796542525322u, 75375419594251u, 18446730133949214354u, 876693110704u}}, + {{0, 0, -1, 0}, {350383458039033u, 71055072419128u, 18446731078526113868u, 807853546589u}}, + {{0, 0, -1, 0}, {356841008069911u, 66877195987655u, 18446731979527719853u, 743082979072u}}, + {{0, 0, -1, 0}, {363164861012145u, 62841854368424u, 18446732837871101116u, 682224088676u}}, + {{0, 0, -1, 0}, {369350108020930u, 58949404556012u, 18446733654399432991u, 625128604779u}}, + {{0, 0, -1, 0}, {375392254336994u, 55199858100660u, 18446734430018644737u, 571647459990u}}, + {{0, 0, -1, 0}, {381287133339980u, 51592950639380u, 18446735165679220619u, 521632221653u}}, + {{0, 0, -1, 0}, {387030585479595u, 48128345290470u, 18446735862332968249u, 474938055467u}}, + {{0, 0, -1, 0}, {392618113162138u, 44805835225179u, 18446736520893092757u, 431426254008u}}, + {{0, 0, -1, 0}, {398046793757336u, 41624211336453u, 18446737142457258189u, 390949499893u}}, + {{0, 0, -1, 0}, {403313752880926u, 38582206709658u, 18446737728113062967u, 353365093689u}}, + {{0, 0, -1, 0}, {408415096305877u, 35679093860984u, 18446738278826936143u, 318541718781u}}, + {{0, 0, -1, 0}, {413348936416142u, 32912956333108u, 18446738795773079621u, 286338471719u}}, + {{0, 0, -1, 0}, {418112670067320u, 30282263882258u, 18446739280029756040u, 256624268699u}}, + {{0, 0, -1, 0}, {422703187026296u, 27785721992219u, 18446739732613711686u, 229275203622u}}, + {{0, 0, -1, 0}, {427118574124114u, 25421344597966u, 18446740154648216213u, 204164304330u}}, + {{0, 0, -1, 0}, {431357218085089u, 23186968131099u, 18446740547265149587u, 181167633364u}}, + {{0, 0, -1, 0}, {435417883496902u, 21080220126848u, 18446740911608941937u, 160164042234u}}, + {{0, 0, -1, 0}, {439299320521767u, 19098728912065u, 18446741248799416607u, 141037256924u}}, + {{0, 0, -1, 0}, {443001153752309u, 17239674960226u, 18446741560007473224u, 123671514200u}}, + {{0, 0, -1, 0}, {446523426937355u, 15500046850641u, 18446741846407899285u, 107954329197u}}, + {{0, 0, -1, 0}, {449864586179621u, 13877624011510u, 18446742109020143301u, 93784979060u}}, + {{0, 0, -1, 0}, {453024801698248u, 12369330322118u, 18446742348980426340u, 81059414605u}}, + {{0, 0, -1, 0}, {456005861983773u, 10971354609993u, 18446742567511375080u, 69672377582u}}, + {{0, 0, -1, 0}, {458808717483994u, 9680330050401u, 18446742765733897097u, 59527280966u}}, + {{0, 0, -1, 0}, {461435064529001u, 8492584027321u, 18446742944786245367u, 50529789977u}}, + {{0, 0, -1, 0}, {463886152298042u, 7404689102084u, 18446743105739697527u, 42592012930u}}, + {{0, 0, -1, 0}, {466163574675495u, 6413093494116u, 18446743249656394836u, 35629382396u}}, + {{0, 0, -1, 0}, {468270154966386u, 5513757217015u, 18446743377639353467u, 29558272208u}}, + {{0, 0, -1, 0}, {470209255190162u, 4702482048381u, 18446743490780989107u, 24298546910u}}, + {{0, 0, -1, 0}, {471984993338673u, 3974839923488u, 18446743590171184938u, 19773156410u}}, + {{0, 0, -1, 0}, {473601898739468u, 3326335092478u, 18446743676873192842u, 15909198140u}}, + {{0, 0, -1, 0}, {475063903263647u, 2752806748091u, 18446743751871074167u, 12640076810u}}, + {{0, 0, -1, 0}, {476375139250181u, 2250090729472u, 18446743816118127268u, 9903092421u}}, + {{0, 0, -1, 0}, {477540631370198u, 1813765423241u, 18446743870568501898u, 7638027020u}}, + {{0, 0, -1, 0}, {478567444515243u, 1438767588570u, 18446743916220148966u, 5785457617u}}, + {{0, 0, -1, 0}, {479462202568345u, 1120354170395u, 18446743953992026921u, 4291847459u}}, + {{0, 0, -1, 0}, {480231335138779u, 853984378182u, 18446743984743189661u, 3108449265u}}, + {{0, 0, -1, 0}, {480882902768112u, 634700037539u, 18446744009344043311u, 2188450675u}}, + {{0, 0, -1, 0}, {481424915942212u, 457737702984u, 18446744028603689295u, 1489716140u}}, + {{0, 0, -1, 0}, {481865921228374u, 318335681663u, 18446744043292727484u, 973755421u}}, + {{0, 0, -1, 0}, {482215715561413u, 211541674130u, 18446744054161572227u, 605013732u}}, + {{0, 0, -1, 0}, {482484167370912u, 132617581599u, 18446744061896563375u, 352306913u}}, + {{0, 0, -1, 0}, {482681209075505u, 77042400796u, 18446744067121931886u, 188524902u}}, + {{0, 0, -1, 0}, {482817644231386u, 40303562049u, 18446744070419906248u, 89830683u}}, + {{0, 0, -1, 0}, {482904580954985u, 18099776203u, 18446744072310457084u, 36166192u}}, + {{0, 0, -1, 0}, {482953527837443u, 6354209511u, 18446744073250152296u, 11101429u}}, + {{0, 0, -1, 0}, {482975816872571u, 1403716585u, 18446744073616779545u, 2047888u}}, + {{0, 0, -1, 0}, {482982360523506u, 94120294u, 18446744073704200102u, 101453u}}, + {{0, 0, -1, 0}, {482982889663324u, 3358767u, 18446744073709387500u, 2667u}}, +}; +static constexpr window_table LECUN_K32_TABLE{LECUN_K32_KNOTS, LECUN_K32_PIECES, 177, 48}; + +static constexpr window_table const* const LECUN[7] = { + &LECUN_K8_TABLE, + &LECUN_K12_TABLE, + &LECUN_K16_TABLE, + &LECUN_K20_TABLE, + &LECUN_K24_TABLE, + &LECUN_K28_TABLE, + &LECUN_K32_TABLE, +}; + +static constexpr std::int64_t HARDELISH_K8_KNOTS[] = { + -256, 0, +}; +static constexpr grotto::principal_detail::cubic_bits HARDELISH_K8_PIECES[] = { + {{-1, 0, 0, 0}, {18446744073709543999u, 8129237u, 11185522u, 3056284u}}, +}; +static constexpr window_table HARDELISH_K8_TABLE{HARDELISH_K8_KNOTS, HARDELISH_K8_PIECES, 1, 24}; + +static constexpr std::int64_t HARDELISH_K12_KNOTS[] = { + -4096, -1025, 0, +}; +static constexpr grotto::principal_detail::cubic_bits HARDELISH_K12_PIECES[] = { + {{-1, 0, 0, 0}, {18446744073708040300u, 121636017u, 164201123u, 41086517u}}, + {{-1, 0, 0, 0}, {18446744073709550878u, 134121917u, 199377089u, 76621341u}}, +}; +static constexpr window_table HARDELISH_K12_TABLE{HARDELISH_K12_KNOTS, HARDELISH_K12_PIECES, 2, 28}; + +static constexpr std::int64_t HARDELISH_K16_KNOTS[] = { + -65536, -39529, -16348, 0, +}; +static constexpr grotto::principal_detail::cubic_bits HARDELISH_K16_PIECES[] = { + {{-1, 0, 0, 0}, {18446744073629115667u, 1710111741u, 2306543203u, 516028280u}}, + {{-1, 0, 0, 0}, {18446744073701438332u, 2061515978u, 2884664852u, 838186609u}}, + {{-1, 0, 0, 0}, {18446744073709539952u, 2145964568u, 3190219657u, 1226539595u}}, +}; +static constexpr window_table HARDELISH_K16_TABLE{HARDELISH_K16_KNOTS, HARDELISH_K16_PIECES, 3, 32}; + +static constexpr std::int64_t HARDELISH_K20_KNOTS[] = { + -1048576, -834082, -632362, -441889, -261405, -89858, 0, +}; +static constexpr grotto::principal_detail::cubic_bits HARDELISH_K20_PIECES[] = { + {{-1, 0, 0, 0}, {18446744071762239690u, 25068646541u, 34264695087u, 7248769388u}}, + {{-1, 0, 0, 0}, {18446744072849572554u, 29155640820u, 39398575663u, 9403983479u}}, + {{-1, 0, 0, 0}, {18446744073417507339u, 31964238539u, 44046795398u, 11978524420u}}, + {{-1, 0, 0, 0}, {18446744073648310944u, 33587820962u, 47881422267u, 15019642422u}}, + {{-1, 0, 0, 0}, {18446744073705880975u, 34258250701u, 50531166627u, 18576790349u}}, + {{-1, 0, 0, 0}, {18446744073709548751u, 34358662951u, 51476470877u, 21715153882u}}, +}; +static constexpr window_table HARDELISH_K20_TABLE{HARDELISH_K20_KNOTS, HARDELISH_K20_PIECES, 6, 36}; + +static constexpr std::int64_t HARDELISH_K24_KNOTS[] = { + -16777216, -15033864, -13345080, -11707320, -10117381, -8572377, -7069674, -5606883, -4181814, -2792462, -1436978, -113664, 0, +}; +static constexpr grotto::principal_detail::cubic_bits HARDELISH_K24_PIECES[] = { + {{-1, 0, 0, 0}, {18446744036368457044u, 381215507031u, 526952273178u, 108395704343u}}, + {{-1, 0, 0, 0}, {18446744047665786349u, 419012647213u, 569127399636u, 124090954019u}}, + {{-1, 0, 0, 0}, {18446744056345581965u, 451721201202u, 610239789206u, 141327244065u}}, + {{-1, 0, 0, 0}, {18446744062762635379u, 479278659895u, 649718667400u, 160194680437u}}, + {{-1, 0, 0, 0}, {18446744067284803927u, 501742138725u, 686950942272u, 180785566936u}}, + {{-1, 0, 0, 0}, {18446744070280702613u, 519296099939u, 721280816936u, 203194420587u}}, + {{-1, 0, 0, 0}, {18446744072107084690u, 532259857072u, 752009343534u, 227517971845u}}, + {{-1, 0, 0, 0}, {18446744073095960375u, 541094937611u, 778393935941u, 253855099824u}}, + {{-1, 0, 0, 0}, {18446744073541476793u, 546412368763u, 799648047580u, 282306891656u}}, + {{-1, 0, 0, 0}, {18446744073686564925u, 548979777198u, 814940745140u, 312976645201u}}, + {{-1, 0, 0, 0}, {18446744073709383605u, 549728374793u, 823396267352u, 345969830828u}}, + {{-1, 0, 0, 0}, {18446744073709551614u, 549755805017u, 824627170438u, 364955605798u}}, +}; +static constexpr window_table HARDELISH_K24_TABLE{HARDELISH_K24_KNOTS, HARDELISH_K24_PIECES, 12, 40}; + +static constexpr std::int64_t HARDELISH_K28_KNOTS[] = { + -268435456, -254375483, -240541476, -226925527, -213520502, -200319499, -187315959, -174503629, -161876608, -149429267, -137156224, -125052362, -113112759, -101332771, -89707911, -78233906, -66906639, -55722184, -44676804, -33766871, -22988926, -12339618, -1815752, 0, +}; +static constexpr grotto::principal_detail::cubic_bits HARDELISH_K28_PIECES[] = { + {{-1, 0, 0, 0}, {18446743423067273674u, 5934411440285u, 8260578333590u, 1675524648131u}}, + {{-1, 0, 0, 0}, {18446743524891480061u, 6256720922525u, 8600695272982u, 1795175715441u}}, + {{-1, 0, 0, 0}, {18446743615237247860u, 6559138595451u, 8938172262616u, 1920726322237u}}, + {{-1, 0, 0, 0}, {18446743694766033370u, 6841315165217u, 9271952347587u, 2052352651900u}}, + {{-1, 0, 0, 0}, {18446743764166742177u, 7103008946772u, 9600934143455u, 2190232027796u}}, + {{-1, 0, 0, 0}, {18446743824150930771u, 7344093751945u, 9923976169077u, 2334544664180u}}, + {{-1, 0, 0, 0}, {18446743875446336654u, 7564561335028u, 10239895103120u, 2485473156477u}}, + {{-1, 0, 0, 0}, {18446743918790667640u, 7764524748166u, 10547464858768u, 2643202171730u}}, + {{-1, 0, 0, 0}, {18446743954925476364u, 7944222234428u, 10845416294470u, 2807918343803u}}, + {{-1, 0, 0, 0}, {18446743984590035691u, 8104021554382u, 11132437800668u, 2979810671863u}}, + {{-1, 0, 0, 0}, {18446744008514966069u, 8244423486170u, 11407174728910u, 3159070355963u}}, + {{-1, 0, 0, 0}, {18446744027415872997u, 8366065648228u, 11668229397083u, 3345890954340u}}, + {{-1, 0, 0, 0}, {18446744041986861383u, 8469725929030u, 11914160371567u, 3540468058726u}}, + {{-1, 0, 0, 0}, {18446744052894059311u, 8556326275616u, 12143482438113u, 3742999343109u}}, + {{-1, 0, 0, 0}, {18446744060769067010u, 8626936440700u, 12354666754475u, 3953684886737u}}, + {{-1, 0, 0, 0}, {18446744066202317337u, 8682777450300u, 12546140391606u, 4172727018338u}}, + {{-1, 0, 0, 0}, {18446744069736399379u, 8725225148919u, 12716286097720u, 4400330334831u}}, + {{-1, 0, 0, 0}, {18446744071859328123u, 8755813665556u, 12863441736394u, 4636701139059u}}, + {{-1, 0, 0, 0}, {18446744072997779487u, 8776239073479u, 12985900655100u, 4882048038382u}}, + {{-1, 0, 0, 0}, {18446744073510256021u, 8788362807846u, 13081911413907u, 5136582008342u}}, + {{-1, 0, 0, 0}, {18446744073680211455u, 8794215076106u, 13149677461220u, 5400516256391u}}, + {{-1, 0, 0, 0}, {18446744073709133289u, 8795998270055u, 13187356893104u, 5674066199667u}}, + {{-1, 0, 0, 0}, {18446744073709551586u, 8796092880937u, 13194035057081u, 5839328705356u}}, +}; +static constexpr window_table HARDELISH_K28_TABLE{HARDELISH_K28_KNOTS, HARDELISH_K28_PIECES, 23, 44}; + +static constexpr std::int64_t HARDELISH_K32_KNOTS[] = { + -4294967296, -4182027426, -4070006914, -3958889839, -3848660444, -3739303782, -3630805044, -3523149752, -3416323814, -3310314120, -3205107253, -3100689752, -2997049776, -2894174349, -2792052063, -2690670881, -2590019436, -2490086372, -2390861148, -2292333055, -2194491887, -2097327455, -2000829454, -1904988901, -1809795631, -1715240679, -1621315153, -1528010224, -1435316960, -1343227000, -1251732088, -1160824298, -1070495529, -980737987, -891543987, -802906371, -714817653, -627270718, -540258497, -453774157, -367811087, -282362542, -197422096, -112983354, -29040015, 0, +}; +static constexpr grotto::principal_detail::cubic_bits HARDELISH_K32_PIECES[] = { + {{-1, 0, 0, 0}, {18446733222912550896u, 93606775276672u, 130802921480209u, 26345349235585u}}, + {{-1, 0, 0, 0}, {18446734085268481940u, 96263617421376u, 133531502059543u, 27279462740245u}}, + {{-1, 0, 0, 0}, {18446734899805458476u, 98842198680038u, 136252593785637u, 28236652148412u}}, + {{-1, 0, 0, 0}, {18446735667779530641u, 101341607729576u, 138964164934905u, 29217264948132u}}, + {{-1, 0, 0, 0}, {18446736390481643405u, 103761036706062u, 141664140924708u, 30221650363867u}}, + {{-1, 0, 0, 0}, {18446737069234860842u, 106099783375467u, 144350404126088u, 31250159239782u}}, + {{-1, 0, 0, 0}, {18446737705392833029u, 108357257950793u, 147020799331199u, 32303146191782u}}, + {{-1, 0, 0, 0}, {18446738300335812171u, 110532981747562u, 149673130140018u, 33380968402457u}}, + {{-1, 0, 0, 0}, {18446738855465942910u, 112626582504035u, 152305150445132u, 34483982104097u}}, + {{-1, 0, 0, 0}, {18446739372206419578u, 114637803711672u, 154914572685734u, 35612545711737u}}, + {{-1, 0, 0, 0}, {18446739852000609148u, 116566515471585u, 157499080013905u, 36767025418528u}}, + {{-1, 0, 0, 0}, {18446740296304164817u, 118412697607469u, 160056301896400u, 37947784768460u}}, + {{-1, 0, 0, 0}, {18446740706584852465u, 120176452444754u, 162583827619514u, 39155190338357u}}, + {{-1, 0, 0, 0}, {18446741084319281331u, 121858006288905u, 165079206099820u, 40389611943059u}}, + {{-1, 0, 0, 0}, {18446741430988936642u, 123457707309602u, 167539939653290u, 41651419540820u}}, + {{-1, 0, 0, 0}, {18446741748078560143u, 124976034267522u, 169963494339481u, 42940988571080u}}, + {{-1, 0, 0, 0}, {18446742037071810378u, 126413592998325u, 172347291890175u, 44258696076590u}}, + {{-1, 0, 0, 0}, {18446742299447984446u, 127771117336066u, 174688707634175u, 45604919453054u}}, + {{-1, 0, 0, 0}, {18446742536679252471u, 129049472622683u, 176985072554199u, 46980037335356u}}, + {{-1, 0, 0, 0}, {18446742750227825871u, 130249659455143u, 179233676553247u, 48384431581946u}}, + {{-1, 0, 0, 0}, {18446742941542497845u, 131372814194515u, 181431766056587u, 49818485952280u}}, + {{-1, 0, 0, 0}, {18446743112055945204u, 132420214009581u, 183576550550627u, 51282590689375u}}, + {{-1, 0, 0, 0}, {18446743263180244151u, 133393271195631u, 185665187568997u, 52777132698282u}}, + {{-1, 0, 0, 0}, {18446743396304715327u, 134293541294055u, 187694794720647u, 54302503331050u}}, + {{-1, 0, 0, 0}, {18446743512792539718u, 135122724588797u, 189662450002512u, 55859099511191u}}, + {{-1, 0, 0, 0}, {18446743613976746860u, 135882662534564u, 191565178767487u, 57447313461079u}}, + {{-1, 0, 0, 0}, {18446743701157719630u, 136575344897003u, 193399965556521u, 59067541533337u}}, + {{-1, 0, 0, 0}, {18446743775599853354u, 137202911651617u, 195163755237795u, 60720186025969u}}, + {{-1, 0, 0, 0}, {18446743838527942601u, 137767652525216u, 196853447408769u, 62405650815802u}}, + {{-1, 0, 0, 0}, {18446743891123847846u, 138272008439028u, 198465894645421u, 64124339252192u}}, + {{-1, 0, 0, 0}, {18446743934523281436u, 138718574253300u, 199997904788783u, 65876655995711u}}, + {{-1, 0, 0, 0}, {18446743969812514711u, 139110101196677u, 201446243147913u, 67663009576559u}}, + {{-1, 0, 0, 0}, {18446743998024967962u, 139449498356870u, 202807632128588u, 69483812836582u}}, + {{-1, 0, 0, 0}, {18446744020137770785u, 139739833735041u, 204078748608355u, 71339480032556u}}, + {{-1, 0, 0, 0}, {18446744037068373294u, 139984335834490u, 205256222543285u, 73230424290314u}}, + {{-1, 0, 0, 0}, {18446744049671212338u, 140186396248080u, 206336640252207u, 75157061918761u}}, + {{-1, 0, 0, 0}, {18446744058734281041u, 140349571325167u, 207316544749715u, 77119814186074u}}, + {{-1, 0, 0, 0}, {18446744064975673044u, 140477583419027u, 208192433196624u, 79119103258301u}}, + {{-1, 0, 0, 0}, {18446744069040159270u, 140574322790153u, 208960757634988u, 81155353546724u}}, + {{-1, 0, 0, 0}, {18446744071495738885u, 140643849264973u, 209617924226938u, 83228989422637u}}, + {{-1, 0, 0, 0}, {18446744072830187746u, 140690394142827u, 210160294828799u, 85340439555357u}}, + {{-1, 0, 0, 0}, {18446744073447581445u, 140718361747284u, 210584186014165u, 87490135757415u}}, + {{-1, 0, 0, 0}, {18446744073664815599u, 140732331100771u, 210885868511701u, 89678510909214u}}, + {{-1, 0, 0, 0}, {18446744073708116650u, 140737057655922u, 211061567553984u, 91906001705287u}}, + {{-1, 0, 0, 0}, {18446744073709551139u, 140737486097801u, 211104562296500u, 93429422866959u}}, +}; +static constexpr window_table HARDELISH_K32_TABLE{HARDELISH_K32_KNOTS, HARDELISH_K32_PIECES, 45, 48}; + +static constexpr window_table const* const HARDELISH[7] = { + &HARDELISH_K8_TABLE, + &HARDELISH_K12_TABLE, + &HARDELISH_K16_TABLE, + &HARDELISH_K20_TABLE, + &HARDELISH_K24_TABLE, + &HARDELISH_K28_TABLE, + &HARDELISH_K32_TABLE, +}; + +static constexpr std::int64_t LECUN_TAIL[7] = { + 439, 7028, 112453, 1799252, 28788025, 460608399, 7369734383, +}; diff --git a/include/grotto/window_lut.hpp b/include/grotto/window_lut.hpp index 0775d6c..40791c3 100644 --- a/include/grotto/window_lut.hpp +++ b/include/grotto/window_lut.hpp @@ -8,7 +8,14 @@ /// table. `probit` is stored on `(0, 1/2]` and mirrored. The tail /// below 1/20 is a cubic in `ln(p)` (knots at scale `2^{k+10}`), /// because a cubic in `p` cannot meet half an ulp on the first -/// input step once `k` is large. +/// input step once `k` is large. `hardelish` is exact outside +/// `[-1, 1]` and an exact quadratic on `[0, 1]`; only `(-1, 0)` is +/// a cubic table. `lecun_tanh` is an odd cubic table out to where +/// the value sits within a quarter ulp of `1.7159`, then a constant +/// tail. `one_minus_sigmoid` is `1` minus the sigmoid table. +/// Those two cubics are the Appendix D maps that had no fixed-point +/// table. Knots come from Sollya; each cubic is the lowest-error +/// polynomial among Sollya, Mathematica, Maple, and MATLAB. #ifndef LIBDPF_INCLUDE_GROTTO_WINDOW_LUT_HPP__ #define LIBDPF_INCLUDE_GROTTO_WINDOW_LUT_HPP__ @@ -40,6 +47,12 @@ enum class window : unsigned asin, acos, probit, + /// Appendix D HardELiSH. Exact outside `[-1, 1]`, quadratic on `[0, 1]`. + hardelish, + /// Appendix D LeCun tanh, `1.7159 tanh(2x/3)`. + lecun_tanh, + /// `1 - sigmoid(x)`, the same table as `sigmoid`. + one_minus_sigmoid, }; namespace window_detail @@ -57,6 +70,7 @@ struct window_table }; #include "grotto/window_tables.inc" +#include "grotto/window_extra_tables.inc" inline unsigned slot_of(unsigned fractional_bits) { @@ -232,7 +246,7 @@ static constexpr std::uint64_t probit_ln_anchor_mag[32] = { /// @brief `round_half_away(ln(probability / 2^k) * 2^{k+10})`. /// @param fractional_bits the number of fractional bits -/// @param probability the `probability` +/// @param probability probability as a raw fixed-point word /// @return `round_half_away(ln(probability / 2^k) * 2^{k+10})` inline std::int64_t probit_ln_argument(unsigned fractional_bits, std::int64_t probability) { @@ -260,11 +274,11 @@ inline std::int64_t probit_ln_argument(unsigned fractional_bits, std::int64_t pr } /// @brief Horner, then one extra right shift so a tail argument at scale `k+10` rounds onto scale `k`. -/// @param piece the `piece` -/// @param q the `q` +/// @param piece cubic piece +/// @param q Horner input in raw units /// @param raw the underlying integer /// @param fractional_bits the number of fractional bits -/// @param extra_shift the `extra_shift` +/// @param extra_shift extra right shift onto the caller's scale /// @return Horner, then one extra right shift so a tail argument at scale `k+10` rounds onto scale /// `k` inline std::int64_t eval_cubic_extra( @@ -323,6 +337,18 @@ inline std::int64_t eval_smoothstep(unsigned fractional_bits, std::int64_t raw) } } // namespace window_detail +/// \complexity `piece_of` binary-searches `nparts` knots, then one cubic Horner. `smoothstep` is three multiplies and no table. +/// `asin` / `acos` also call the principal square root. `hardelish` does that search only on `(-1, 0)`; +/// on `[0, 1]` it is one rounded quadratic and elsewhere a compare. `lecun_tanh` searches the positive +/// knots of `|x|` or returns the constant tail. `one_minus_sigmoid` is the sigmoid search plus one subtraction. +/// Time `Θ(log P)` plus `Θ(1)` arithmetic. Extra space `Θ(1)`. +/// @see grotto::eval_principal +/// @see grotto::eval_reduced +/// @see grotto::eval_closed +/// @param which the window map +/// @param fractional_bits one of 8, 12, ..., 32 +/// @param raw fixed-point argument +/// @return fixed-point result at the same scale inline std::int64_t eval_window(window which, unsigned fractional_bits, std::int64_t raw) { @@ -382,6 +408,34 @@ inline std::int64_t eval_window(window which, unsigned fractional_bits, std::int return -eval_probit_abs(fractional_bits, one - raw); return eval_probit_abs(fractional_bits, raw); } + case window::hardelish: + { + const auto one = std::int64_t{1} << fractional_bits; + if (raw <= -one) + return 0; + if (raw >= one) + return raw; + if (raw >= 0) + return round_half_away_i128( + static_cast<__int128>(raw) * (raw + one), fractional_bits + 1u); + return eval_table(at(HARDELISH, fractional_bits), fractional_bits, raw); + } + case window::lecun_tanh: + { + const std::int64_t tail = LECUN_TAIL[slot_of(fractional_bits)]; + const window_table & table = at(LECUN, fractional_bits); + const std::int64_t last = table.knots[table.nparts]; + if (raw >= last) + return tail; + if (raw <= -last) + return -tail; + const std::int64_t mag = raw < 0 ? -raw : raw; + const std::int64_t y = eval_table(table, fractional_bits, mag); + return raw < 0 ? -y : y; + } + case window::one_minus_sigmoid: + return (std::int64_t{1} << fractional_bits) + - eval_tailed(SIGMOID, tail_zero, tail_one, fractional_bits, raw); } throw std::invalid_argument("window lut: unknown function"); } diff --git a/party/aes_mmo_ref.hpp b/party/aes_mmo_ref.hpp new file mode 100644 index 0000000..bfe3a10 --- /dev/null +++ b/party/aes_mmo_ref.hpp @@ -0,0 +1,170 @@ +/// @file party/aes_mmo_ref.hpp +/// @brief Portable AES-128 MMO matching `dpf::prg::aes128::eval` on the zero key. +/// @details Used to check an oblivious evaluation against the hardware PRG. +/// The cipher key is the all-zero key installed by `prg::aes128`. + +#ifndef LIBDPF_PARTY_AES_MMO_REF_HPP__ +#define LIBDPF_PARTY_AES_MMO_REF_HPP__ + +#include +#include +#include + +#include "simde/simde/x86/avx2.h" + +namespace dpf +{ +namespace party +{ +namespace aes_ref +{ + +inline std::uint8_t gmul(std::uint8_t a, std::uint8_t b) +{ + std::uint8_t p = 0; + for (int i = 0; i < 8; ++i) + { + if (b & 1u) + p = static_cast(p ^ a); + const bool hi = (a & 0x80u) != 0; + a = static_cast(a << 1); + if (hi) + a = static_cast(a ^ 0x1b); + b = static_cast(b >> 1); + } + return p; +} + +inline std::uint8_t ginv(std::uint8_t a) +{ + if (a == 0) + return 0; + // a^254 via square-and-multiply. + std::uint8_t r = 1; + std::uint8_t b = a; + for (int e = 0; e < 7; ++e) + { + b = gmul(b, b); + r = gmul(r, b); + } + return r; +} + +inline std::uint8_t sbox_at(std::uint8_t x) +{ + std::uint8_t b = ginv(x); + std::uint8_t s = b; + for (int i = 0; i < 4; ++i) + { + b = static_cast((b << 1) | (b >> 7)); + s = static_cast(s ^ b); + } + return static_cast(s ^ 0x63); +} + +inline std::uint8_t xtime(std::uint8_t x) +{ + return static_cast((x << 1) ^ ((x & 0x80) ? 0x1b : 0)); +} + +inline const std::uint8_t * sbox() +{ + static std::uint8_t table[256]; + static bool ready = false; + if (!ready) + { + for (int i = 0; i < 256; ++i) + table[i] = sbox_at(static_cast(i)); + ready = true; + } + return table; +} + +inline void sub_bytes(std::uint8_t s[16]) +{ + const std::uint8_t * box = sbox(); + for (int i = 0; i < 16; ++i) + s[i] = box[s[i]]; +} + +inline void shift_rows(std::uint8_t s[16]) +{ + std::uint8_t t = s[1]; + s[1] = s[5]; + s[5] = s[9]; + s[9] = s[13]; + s[13] = t; + t = s[2]; + s[2] = s[10]; + s[10] = t; + t = s[6]; + s[6] = s[14]; + s[14] = t; + t = s[15]; + s[15] = s[11]; + s[11] = s[7]; + s[7] = s[3]; + s[3] = t; +} + +inline void mix_columns(std::uint8_t s[16]) +{ + for (int c = 0; c < 4; ++c) + { + const std::uint8_t i = static_cast(c * 4); + const std::uint8_t a = s[i], b = s[i + 1], c0 = s[i + 2], d = s[i + 3]; + const std::uint8_t xa = xtime(a), xb = xtime(b), xc = xtime(c0), xd = xtime(d); + s[i] = static_cast(xa ^ xb ^ b ^ c0 ^ d); + s[i + 1] = static_cast(a ^ xb ^ xc ^ c0 ^ d); + s[i + 2] = static_cast(a ^ b ^ xc ^ xd ^ d); + s[i + 3] = static_cast(xa ^ a ^ b ^ c0 ^ xd); + } +} + +inline void add_round_key(std::uint8_t s[16], const std::uint8_t rk[16]) +{ + for (int i = 0; i < 16; ++i) + s[i] = static_cast(s[i] ^ rk[i]); +} + +inline std::array block_bytes(simde__m128i v) +{ + std::array b{}; + std::memcpy(b.data(), &v, 16); + return b; +} + +/// @brief One MMO block: AES-128 encrypt `msg` under the zero key, then XOR `msg`. +inline simde__m128i encrypt_mmo(simde__m128i msg, std::uint32_t pos, + const std::array & round_keys) +{ + auto s = block_bytes(msg); + auto rk0 = block_bytes(round_keys[0]); + // eval XORs set_epi64x(0, pos) into rd_key[0] before the first AddRoundKey. + rk0[0] = static_cast(rk0[0] ^ static_cast(pos)); + rk0[1] = static_cast(rk0[1] ^ static_cast(pos >> 8)); + rk0[2] = static_cast(rk0[2] ^ static_cast(pos >> 16)); + rk0[3] = static_cast(rk0[3] ^ static_cast(pos >> 24)); + add_round_key(s.data(), rk0.data()); + for (int r = 1; r < 10; ++r) + { + sub_bytes(s.data()); + shift_rows(s.data()); + mix_columns(s.data()); + auto rk = block_bytes(round_keys[static_cast(r)]); + add_round_key(s.data(), rk.data()); + } + sub_bytes(s.data()); + shift_rows(s.data()); + auto last = block_bytes(round_keys[10]); + add_round_key(s.data(), last.data()); + simde__m128i out{}; + std::memcpy(&out, s.data(), 16); + return simde_mm_xor_si128(out, msg); +} + +} // namespace aes_ref +} // namespace party +} // namespace dpf + +#endif diff --git a/party/aes_sbox_bp.hpp b/party/aes_sbox_bp.hpp new file mode 100644 index 0000000..8745991 --- /dev/null +++ b/party/aes_sbox_bp.hpp @@ -0,0 +1,6 @@ +/// @file party/aes_sbox_bp.hpp +/// @brief Compatibility include. The S-box table lives in dpf/aes_sbox_bp.hpp. +#ifndef LIBDPF_PARTY_AES_SBOX_BP_HPP__ +#define LIBDPF_PARTY_AES_SBOX_BP_HPP__ +#include "dpf/aes_sbox_bp.hpp" +#endif diff --git a/party/cases.hpp b/party/cases.hpp new file mode 100644 index 0000000..79d02f8 --- /dev/null +++ b/party/cases.hpp @@ -0,0 +1,46 @@ +/// @file party/cases.hpp +/// @brief CLI and flow registration for (2+1) party processes. +#ifndef LIBDPF_PARTY_CASES_HPP__ +#define LIBDPF_PARTY_CASES_HPP__ + +#include + +#include "dpf/net/trio.hpp" +#include "registry.hpp" + +namespace dpf +{ +namespace party +{ + +void register_core_flows(); +void register_bulk_flows(); +void register_extreme_flows(); +void register_recent_flows(); +void register_coverage_flows(); +void register_gadget_flows(); + +inline void register_all_flows() +{ + static bool once = false; + if (once) + return; + once = true; + register_core_flows(); + register_bulk_flows(); + register_extreme_flows(); + register_recent_flows(); + register_coverage_flows(); + register_gadget_flows(); +} + +/// @brief Parse argv and run. Supports: +/// --dir DIR --case NAME [--repeat N] [--warmup W] [--metrics] +/// --dir DIR --tag TAGS [--repeat N] [--warmup W] [--metrics] +/// --list [--tag TAGS] +int run(net::role self, int argc, char ** argv); + +} // namespace party +} // namespace dpf + +#endif // LIBDPF_PARTY_CASES_HPP__ diff --git a/party/dist_dpf3.hpp b/party/dist_dpf3.hpp new file mode 100644 index 0000000..40efc04 --- /dev/null +++ b/party/dist_dpf3.hpp @@ -0,0 +1,503 @@ +/// @file party/dist_dpf3.hpp +/// @brief Networked (2,3) Shamir DPF keygen (three key holders). +/// @details A pure two-party variant is not meaningful: after keygen each of +/// three parties must hold a Shamir share of the evaluation. Use +/// `dist_with_*_iknp` in `iknp_deal.hpp` for two-party VDPF keygen +/// without a pad dealer. +/// @brief Distributed dual-spine Doerner–Shelat keygen for (2,3) point keys. +/// @details Two `deal_point` / `point_party` runs (spines A and B) with Fig-3 +/// `τ` payloads. p0 samples `τ` and `π`; overlapping halves are shipped +/// so p0 holds party-1, p2 holds party-2, p1 holds party-3. +/// Produced keys are always verifiable. Default spines keep `α` as XOR +/// shares (F_DPF3DS): `π` is peeled from the leaf seed of the shared +/// path, not from an opened point. p0 sends p1 only its `τ` halves. +/// Pass `RevealPoint=true` only when the caller wants the tree prefix +/// (and packed lane on updatable keys). Pass `dpf::updatable` for +/// beaver leaves and a later networked Fig-10 update via +/// `dist_update_payload`. + +#ifndef LIBDPF_PARTY_DIST_DPF3_HPP__ +#define LIBDPF_PARTY_DIST_DPF3_HPP__ + +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dist_ds.hpp" +#include "key_io.hpp" + +#include "dpf/dpf3.hpp" +#include "dpf/dpf3_ds.hpp" +#include "dpf/fp61.hpp" +#include "dpf/shamir3.hpp" +#include "dpf/wildcard.hpp" + +namespace dpf +{ +namespace party +{ + +/// @brief How trio roles map onto Shamir party indices `{1,2,3}`. +/// @details **dealer**: p0→1, p1→2, p2→3 (trusted keygen on p2, then ship). +/// **dist**: p0→1, p2→2, p1→3 (`dist_with_dpf3_key` assembly). +enum class dpf3_role_map : unsigned +{ + dealer = 0, + dist = 1, +}; + +/// @brief Shamir party index for a trio role under `map`. +HEDLEY_CONST +HEDLEY_NO_THROW +constexpr int dpf3_party_of(role r, dpf3_role_map map) noexcept +{ + if (map == dpf3_role_map::dist) + { + if (r == role::p0) + return 1; + if (r == role::p2) + return 2; + return 3; // p1 + } + // dealer + if (r == role::p0) + return 1; + if (r == role::p1) + return 2; + return 3; // p2 +} + +/// @brief Public VDPF+ offsets for one (2,3) keygen. +struct dpf3_pi_msg +{ + shamir3::xor61 pi_a{}; + shamir3::xor61 pi_b{}; +}; + +/// @brief Fig-10 patch broadcast (leaf patches so p2 need not learn `α`). +template +struct dpf3_fig10_msg +{ + Leaf patch_a{}; + Leaf patch_b{}; + shamir3::xor61 pi_a{}; + shamir3::xor61 pi_b{}; +}; + +/// @brief p1's τ halves for spines A and B (party-3 strings). Does not reveal β. +struct dpf3_tau_share +{ + shamir3::xor61 t1{}; + shamir3::xor61 t3{}; +}; + +namespace detail_dist_dpf3 +{ + +template +using spine_out0 = decltype(dist::point_party(std::declval(), std::declval(), + std::declval())); + +template +using spine_key0 = spine_out0; + +template +using spine_out1 = decltype(dist::point_party(std::declval(), std::declval(), + std::declval())); + +template +using spine_key1 = spine_out1; + +template +void assign_wildcard_over_link(Key & key, Share my_share, trio & net, role self) +{ + const role peer = self == role::p0 ? role::p1 : role::p0; + auto & wrap = std::get<0>(key.leaf_nodes); + auto blinded = wrap.compute_and_get_blinded_output_share(my_share); + auto peer_blinded = net.exchange_with(peer, blinded); + auto leaf = wrap.compute_and_get_leaf_share(peer_blinded); + auto peer_leaf = net.exchange_with(peer, leaf); + wrap.reconstruct_correction_word(peer_leaf); +} + +/// @brief Assign XOR payload from each party's τ half (payload never opened). +template +void assign_spine_tau_halves(trio & net, role self, Key & key, + shamir3::xor61 my_half) +{ + assign_wildcard_over_link(key, my_half, net, self); +} + +template +void apply_fig10_leaves(Key & key, const dpf3_fig10_msg & msg) +{ + detail::dpf3_impl::apply_leaf_patch(key.a.dpf_key, msg.patch_a); + detail::dpf3_impl::apply_leaf_patch(key.b.dpf_key, msg.patch_b); +} + +template +void apply_fig10(Key & key, const dpf3_fig10_msg & msg) +{ + apply_fig10_leaves(key, msg); + key.a.offset = msg.pi_a; + key.b.offset = msg.pi_b; +} + +template +HEDLEY_WARN_UNUSED_RESULT +shamir3::xor61 peel_from_seed(const Key & key, const Node & seed) +{ + const auto y = key.template traverse_exterior<0>(seed); + using Y = std::decay_t; + if constexpr (is_secret_share_v) + return shamir3::xor61{y.raw()}; + else if constexpr (std::is_integral_v + || std::is_convertible_v) + return shamir3::xor61{static_cast(y)}; + else + { + std::uint64_t w = 0; + static_assert(sizeof(Y) >= sizeof(w), + "peel_from_seed: leaf narrower than xor61"); + std::memcpy(&w, &y, sizeof(w)); + return shamir3::xor61{w}; + } +} + +template +struct dpf3_opened +{ + InputT opened_prefix{}; + /// Meaningful when the spine payload is a packed wildcard. + unsigned opened_lane = 0; + bool lane_opened = false; +}; + +template +struct has_nested_key : std::false_type {}; +template +struct has_nested_key().key)>> + : std::true_type {}; +template +inline constexpr bool has_nested_key_v = has_nested_key::value; + +template +struct has_opened_prefix : std::false_type {}; +template +struct has_opened_prefix().opened_prefix)>> + : std::true_type {}; +template +inline constexpr bool has_opened_prefix_v = has_opened_prefix::value; + +template +struct has_opened_lane : std::false_type {}; +template +struct has_opened_lane().opened_lane)>> + : std::true_type {}; +template +inline constexpr bool has_opened_lane_v = has_opened_lane::value; + +template +struct has_member_dpf_key : std::false_type {}; +template +struct has_member_dpf_key().dpf_key)>> + : std::true_type {}; + +template +auto spine_key_of(Held && held) +{ + using H = std::decay_t; + if constexpr (has_member_dpf_key::value) + return std::move(held.dpf_key); + else if constexpr (has_nested_key_v) + return std::move(held.key); + else + return std::move(held); +} + +template +void note_opened(dpf3_opened & learned, const Held & held) +{ + if constexpr (has_opened_prefix_v>) + { + learned.opened_prefix = held.opened_prefix; + if constexpr (has_opened_lane_v>) + { + learned.opened_lane = held.opened_lane; + learned.lane_opened = true; + } + } +} + +template +std::optional> dist_with_dpf3_key_impl(trio & net, role self, + InputT x0, InputT x1, + const fp61 beta, Fn1 && on1, Fn2 && on2, Fn3 && on3) +{ + using X = shamir3::xor61; + using tau_quad = detail::dpf3_impl::tau_quad; + using Key0 = spine_key0; + using Key1 = spine_key1; + using node = typename dpf::tree_traits::node; + constexpr bool V = true; // dist point_party always opens correction seeds + + if (self == role::p2) + { + dist::deal_point(net); + dist::deal_point(net); + const auto pi = net.recv_from(role::p0, net::msg::delta); + auto key_b0 = recv_key(net, role::p0); + auto key_a1 = recv_key(net, role::p1); + detail::dpf3_impl::vdpf_plus_key plus_a1{std::move(key_a1), + pi.pi_a}; + detail::dpf3_impl::vdpf_plus_key plus_b0{std::move(key_b0), + pi.pi_b}; + dpf3_key<2, decltype(plus_a1), decltype(plus_b0)> k2{ + std::move(plus_a1), std::move(plus_b0), V, false, Updatable}; + std::forward(on2)(std::move(k2)); + return std::nullopt; + } + + // p0 samples τ from a Shamir split of β; p1 receives only (t1, t3). + tau_quad t{}; + X my_a{}; + X my_b{}; + if (self == role::p0) + { + t = detail::dpf3_impl::sample_taus(beta); + my_a = t.t0; + my_b = t.t2; + net.send_to(role::p1, net::msg::delta, dpf3_tau_share{t.t1, t.t3}); + } + else + { + const auto sh = net.recv_from(role::p0, net::msg::delta); + my_a = sh.t1; + my_b = sh.t3; + t.t1 = sh.t1; + t.t3 = sh.t3; + } + + dpf3_opened learned{}; + node seed_a{}; + node seed_b{}; + + // Non-updatable and updatable both plant beaver leaves; τ halves are + // assigned without opening the spine payload. The outer Updatable flag + // only gates Fig-10. + // Spines still use per-message `exchange_with`. Wiring RoundSink here + // needs a round budget that covers wild+hash leaf mux; undersizing hangs + // the peer on `msg::round_batch`. + OutputT wild{}; + if (self == role::p0) + { + auto out_a0 = dist::point_party(net, x0, wild, false, + &seed_a); + note_opened(learned, out_a0); + auto key_a0 = spine_key_of(std::move(out_a0)); + auto out_b0 = dist::point_party(net, x0, wild, false, + &seed_b); + auto key_b0 = spine_key_of(std::move(out_b0)); + assign_spine_tau_halves(net, self, key_a0, my_a); + assign_spine_tau_halves(net, self, key_b0, my_b); + dpf3_pi_msg pi{}; + pi.pi_a = t.t0 + peel_from_seed(key_a0, seed_a); + pi.pi_b = t.t2 + peel_from_seed(key_b0, seed_b); + net.send_to(role::p1, net::msg::delta, pi); + net.send_to(role::p2, net::msg::delta, pi); + send_key(net, role::p2, key_b0); + detail::dpf3_impl::vdpf_plus_key plus_a0{std::move(key_a0), + pi.pi_a}; + detail::dpf3_impl::vdpf_plus_key plus_b0{std::move(key_b0), + pi.pi_b}; + dpf3_key<1, decltype(plus_a0), decltype(plus_b0)> k1{ + std::move(plus_a0), std::move(plus_b0), V, false, Updatable}; + std::forward(on1)(std::move(k1)); + if constexpr (RevealPoint) + return learned; + return std::nullopt; + } + + auto out_a1 = dist::point_party(net, x1, wild, false, + &seed_a); + note_opened(learned, out_a1); + auto key_a1 = spine_key_of(std::move(out_a1)); + auto out_b1 = dist::point_party(net, x1, wild, false, + &seed_b); + auto key_b1 = spine_key_of(std::move(out_b1)); + assign_spine_tau_halves(net, self, key_a1, my_a); + assign_spine_tau_halves(net, self, key_b1, my_b); + const auto pi = net.recv_from(role::p0, net::msg::delta); + send_key(net, role::p2, key_a1); + detail::dpf3_impl::vdpf_plus_key plus_a1{std::move(key_a1), + pi.pi_a}; + detail::dpf3_impl::vdpf_plus_key plus_b1{std::move(key_b1), + pi.pi_b}; + dpf3_key<3, decltype(plus_a1), decltype(plus_b1)> k3{ + std::move(plus_a1), std::move(plus_b1), V, false, Updatable}; + std::forward(on3)(std::move(k3)); + if constexpr (RevealPoint) + return learned; + return std::nullopt; +} + +} // namespace detail_dist_dpf3 + +/// @brief Distributed dual-spine (2,3) keygen over the trio. +/// @details Role map after assembly: **p0 → party 1**, **p2 → party 2**, +/// **p1 → party 3**. Keys are always verifiable. Each computing +/// party's view of `α` is only its XOR share; p1's view of `β` is +/// only its τ halves (not a clear payload). Default return is empty. +/// @tparam RevealPoint when true, p0/p1 also reconstruct the tree prefix +/// @return Opened prefix when `RevealPoint`, else empty. Empty on p2. +/// @throws std::runtime_error if a frame is truncated or tagged wrong +/// \complexity Two `point_party` spines, so the local work is two O(n) walks, plus O(1) τ arithmetic. +/// \rounds The rounds of two `point_party` calls, then one τ-share send (p0 to p1), one `dpf3_pi_msg` to p1 and p2, and one key send to p2. p2 runs two `deal_point` calls first. Counted in `dist_with_dpf3_key_impl`. Fig-10 update is `dist_update_payload`, not this function. +/// \communication Two dealer tapes (see `deal_point` / `point_party`), one `dpf3_tau_share`, one `dpf3_pi_msg` (two `xor61` values), and one key blob (`send_key`, `sizeof` of the spine key). +/// \preprocessing p2's `deal_point` pads for both spines. p0 samples the four τ strings locally from a Shamir split of β. +template +[[nodiscard]] std::optional dist_with_dpf3_key(trio & net, role self, + InputT x0, InputT x1, const fp61 beta, Fn1 && on1, Fn2 && on2, Fn3 && on3) +{ + auto opened = detail_dist_dpf3::dist_with_dpf3_key_impl, false, + RevealPoint>(net, self, x0, x1, beta, std::forward(on1), + std::forward(on2), std::forward(on3)); + if (!opened) + return std::nullopt; + return opened->opened_prefix; +} + +/// @brief What an updatable (2,3) keygen reconstructs when `RevealPoint`. +template +struct dpf3_updatable_opened +{ + InputT opened_prefix{}; + unsigned opened_lane = 0; +}; + +/// @brief Distributed dual-spine (2,3) keygen with beaver leaves (Fig-10-ready). +/// @tparam RevealPoint when true, return prefix and packed lane on p0/p1 +/// @return Opened values when `RevealPoint`, else empty. Empty on p2. +/// \complexity Two `point_party` spines, so the local work is two O(n) walks, plus O(1) τ arithmetic. +/// \rounds The rounds of two `point_party` calls, then one τ-share send (p0 to p1), one `dpf3_pi_msg` to p1 and p2, and one key send to p2. p2 runs two `deal_point` calls first. Counted in `dist_with_dpf3_key_impl`. Fig-10 update is `dist_update_payload`, not this function. +/// \communication Two dealer tapes (see `deal_point` / `point_party`), one `dpf3_tau_share`, one `dpf3_pi_msg` (two `xor61` values), and one key blob (`send_key`, `sizeof` of the spine key). +/// \preprocessing p2's `deal_point` pads for both spines. p0 samples the four τ strings locally from a Shamir split of β. +template +[[nodiscard]] std::optional> dist_with_dpf3_key( + trio & net, role self, InputT x0, InputT x1, const fp61 beta, updatable, + Fn1 && on1, Fn2 && on2, Fn3 && on3) +{ + auto opened = detail_dist_dpf3::dist_with_dpf3_key_impl, true, + RevealPoint>(net, self, x0, x1, beta, std::forward(on1), + std::forward(on2), std::forward(on3)); + if (!opened) + return std::nullopt; + return dpf3_updatable_opened{opened->opened_prefix, + opened->opened_lane}; +} + +/// @brief Networked Fig-10 payload update for keys from `dist_with_dpf3_key`. +/// @details p0 and p1 (who are given `α`) exchange peels, p0 samples fresh `τ` +/// and broadcasts leaf patches + new public `π`. p2 applies patches +/// without learning `α`. Requires `key.updatable`. +/// @throws std::invalid_argument if the key is not updatable +template +void dist_update_payload(trio & net, role self, Key & key, InputT alpha, + fp61 beta_new) +{ + static_assert(Key::is_dpf3, "dist_update_payload: dpf3 key"); + if (!key.updatable) + throw std::invalid_argument( + "dist_update_payload: key was not generated with dpf::updatable"); + + using X = shamir3::xor61; + using InnerA = typename Key::plus_a_type::inner_type; + using Leaf = decltype(detail::dpf3_impl::make_leaf_patch(alpha, + X{})); + using Msg = dpf3_fig10_msg; + + struct peel_pair + { + X peel_a{}; + X peel_b{}; + }; + + Msg msg{}; + if (self == role::p0 || self == role::p1) + { + peel_pair mine{detail::dpf3_impl::peel(key.a.dpf_key, alpha), + detail::dpf3_impl::peel(key.b.dpf_key, alpha)}; + const role peer = self == role::p0 ? role::p1 : role::p0; + const peel_pair theirs = net.exchange_with(peer, mine); + + if (self == role::p0) + { + // p0 = party 1 (A0,B0); p1 = party 3 (A1,B1). + // Leaf CW patches only move the half whose path control bit is set; + // compute π from a post-patch peel (same as dealer refresh_offset). + detail::dpf3_impl::tau_quad told{}; + told.t0 = mine.peel_a + key.a.offset; + told.t1 = theirs.peel_a + key.a.offset; + told.t2 = mine.peel_b + key.b.offset; + told.t3 = theirs.peel_b + key.b.offset; + const auto tnew = detail::dpf3_impl::sample_taus(beta_new); + const X dA = (tnew.t0 + tnew.t1) + (told.t0 + told.t1); + const X dB = (tnew.t2 + tnew.t3) + (told.t2 + told.t3); + msg.patch_a = + detail::dpf3_impl::make_leaf_patch(alpha, dA); + msg.patch_b = + detail::dpf3_impl::make_leaf_patch(alpha, dB); + detail_dist_dpf3::apply_fig10_leaves(key, msg); + msg.pi_a = tnew.t0 + detail::dpf3_impl::peel(key.a.dpf_key, alpha); + msg.pi_b = tnew.t2 + detail::dpf3_impl::peel(key.b.dpf_key, alpha); + key.a.offset = msg.pi_a; + key.b.offset = msg.pi_b; + net.send_to(role::p1, net::msg::delta, msg); + net.send_to(role::p2, net::msg::delta, msg); + return; + } + msg = net.recv_from(role::p0, net::msg::delta); + detail_dist_dpf3::apply_fig10(key, msg); + return; + } + + msg = net.recv_from(role::p0, net::msg::delta); + detail_dist_dpf3::apply_fig10(key, msg); +} + +} // namespace party +} // namespace dpf + +#endif // LIBDPF_PARTY_DIST_DPF3_HPP__ diff --git a/party/dist_ds.hpp b/party/dist_ds.hpp new file mode 100644 index 0000000..07e2335 --- /dev/null +++ b/party/dist_ds.hpp @@ -0,0 +1,2726 @@ +/// @file party/dist_ds.hpp +/// @brief Two-party Doerner–Shelat point/DCF generation over trio sockets. +/// @details p2 deals correlated pads and, for Half-Tree, the roots. p0 and p1 +/// each keep only their own seed and input share. Correction words +/// and VDPF correction seeds are opened from blinds on the p0–p1 +/// link. DCF value words use the same blinded-difference pattern in +/// their output ring while `Va` remains additively shared. +/// +/// Additive point shares are converted to XOR shares by a beaver +/// ripple-carry before the walk. The sum is not opened. Callers that +/// pass `RevealPoint` (comparison: `Reveal`) exchange a share and +/// get that value back. Otherwise the walk keeps XOR shares: the +/// verifiable hash is an AES circuit, comparison value words and +/// blocked suffixes are a bit-serial mux, and a packed lane is a +/// shared-output mux whose only opened result is the public leaf +/// correction word. p2 never receives the point. Interval keys keep +/// the mask `r` as XOR shares: `correction_s` and `γ = r − 1` are +/// computed from those shares, and the inner comparison walk does not +/// take `PointIsClear`. Pass `Reveal` to reconstruct `r` for tests. + +#ifndef LIBDPF_PARTY_DIST_DS_HPP__ +#define LIBDPF_PARTY_DIST_DS_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/net/trio.hpp" +#include "dpf/net/mux_sink.hpp" +#include "dpf/net/round_sink.hpp" +#include "dpf/net/sink_exchange.hpp" +#include "flow_util.hpp" +#include "aes_mmo_ref.hpp" +#include "key_io.hpp" + +namespace dpf +{ +namespace party +{ +namespace dist +{ + +using net::role; +using net::trio; + +/// @name Wire messages +/// @brief Trivially copyable frames for pads, blinds, and Beaver rounds. +/// @{ + +struct cw_pad_msg +{ + simde__m128i rand{}; + simde__m128i gamma{}; + std::uint8_t bit = 0; +}; + +struct and_share_msg +{ + std::uint8_t a = 0; + simde__m128i b{}; + simde__m128i c{}; +}; + +struct level_pad_msg +{ + cw_pad_msg cw{}; + and_share_msg mine{}; + and_share_msg theirs{}; +}; + +/// @brief Beaver shares for the packed-leaf mux. `lg == 0` still sends one +/// unused pad. Otherwise two products per mux node (each party's +/// delta), `2 * (2^lg - 1)` in total. +template +struct leaf_pad_msg +{ + static_assert(N >= 1, "leaf mux sends at least one pad"); + std::array lanes{}; +}; + +/// @brief Key together with the tree prefix both holders reconstructed. +/// @details This is `α` shifted right by the packed-lane width: the bits +/// passed to `hash_node`. It is not the packed lane. +template +struct opened_prefix +{ + Key dpf_key; + Point opened_prefix{}; +}; + +/// @brief Key together with a packed lane both holders reconstructed. +template +struct opened_lane +{ + Key dpf_key; + unsigned opened_lane = 0; +}; + +/// @brief Verifiable wildcard: hash prefix and the lane the scale vector needs. +template +struct opened_prefix_lane +{ + Key dpf_key; + Point opened_prefix{}; + unsigned opened_lane = 0; +}; + +/// @brief Key together with the encoded point both holders reconstructed. +template +struct opened_point +{ + Key dpf_key; + Point opened_point{}; +}; + +template +struct wildcard_leaf_pad_msg +{ + OutputT output_blind{}; + Leaf vector_blind{}; + Leaf peer_vector_blind{}; + Leaf cross{}; + Leaf zero_leaf{}; +}; + +struct ring_zero_share_msg +{ + std::uint64_t share = 0; +}; + +struct blind_msg +{ + simde__m128i msg{}; + std::uint8_t bit = 0; +}; + +struct share_msg +{ + simde__m128i share{}; +}; + +struct advice_msg +{ + std::uint8_t aL = 0; + std::uint8_t aR = 0; +}; + +struct and_round1_msg +{ + std::uint8_t d_bit = 0; + simde__m128i b_bit{}; + simde__m128i e_m{}; + std::uint8_t a_m = 0; +}; + +struct and_round2_msg +{ + simde__m128i z_bit{}; +}; + +/// @brief One party's shares of a bit-Beaver triple `(α, β, α∧β)`. +struct bit_and_pad_msg +{ + std::uint8_t a = 0; + std::uint8_t b = 0; + std::uint8_t c = 0; +}; + +/// @brief Masked bit shares `x⊕α` and `y⊕β` for one carry AND. +struct bit_and_mask_msg +{ + std::uint8_t x = 0; + std::uint8_t y = 0; +}; + +/// @brief Mask for one bit of a XOR-share → additive-share conversion. +/// @details `r` is a XOR share of a random bit. `add` is an additive share of +/// that same bit in `uint64_t`. Opening `bit ⊕ r` does not open `bit`. +struct b2a_pad_msg +{ + std::uint8_t r = 0; + std::uint64_t add = 0; +}; + +/// @brief One bit of a secret-bit × known-word product, then a B2A of that bit. +struct word_bit_pad +{ + std::uint8_t a = 0; + std::uint8_t b = 0; + std::uint8_t c = 0; + std::uint8_t r = 0; + std::uint64_t add = 0; +}; + +/// @brief Pads for one oblivious comparison level: two 64-bit words and the path bit. +struct cmp_level_obliv_msg +{ + std::array bits{}; + b2a_pad_msg ai{}; +}; + +/// @brief Pads for a 2-bit blocked suffix: `s0 ∧ s1`, then B2A of OR, AND, and `s1`. +struct suffix_obliv_msg +{ + bit_and_pad_msg and_pad{}; + b2a_pad_msg b2a[3]{}; +}; + +/// @brief Products in the packed-leaf mux. `lg == 0` keeps a single unused pad. +inline constexpr std::size_t leaf_and_slots(std::size_t lg) noexcept +{ + return lg == 0 ? std::size_t{1} : (std::size_t{2} * ((std::size_t{1} << lg) - 1)); +} + +inline b2a_pad_msg b2a_for_party(std::uint8_t r_share, std::uint64_t add) noexcept +{ + return b2a_pad_msg{r_share, add}; +} + +template +inline void sample_b2a(Pad & rng, b2a_pad_msg & p0, b2a_pad_msg & p1) +{ + const auto shares = dpf::beavers::sample_bit_arith(rng); + p0 = b2a_for_party(shares.xor0, shares.add0); + p1 = b2a_for_party(shares.xor1, shares.add1); +} + +template +inline void send_b2a_vec(trio & net, std::size_t n, Pad & rng) +{ + std::vector a(n), b(n); + for (std::size_t i = 0; i < n; ++i) + sample_b2a(rng, a[i], b[i]); + net.send_vec_to(role::p0, net::msg::beaver_tape, a); + net.send_vec_to(role::p1, net::msg::beaver_tape, b); +} + +inline word_bit_pad word_bit_for(const bit_and_pad_msg & beaver, const b2a_pad_msg & b2a) +{ + word_bit_pad m; + m.a = beaver.a; + m.b = beaver.b; + m.c = beaver.c; + m.r = b2a.r; + m.add = b2a.add; + return m; +} + +inline bit_and_pad_msg bit_pad_for(const detail::ds_bit_triple & t, int party) +{ + if (party == 0) + return bit_and_pad_msg{t.a0, t.b0, t.c0}; + return bit_and_pad_msg{t.a1, t.b1, t.c1}; +} + +template +inline void send_cmp_level_pads(trio & net, Pad & rng) +{ + cmp_level_obliv_msg m0{}, m1{}; + for (std::size_t i = 0; i < 128; ++i) + { + const auto t = detail::ds_sample_bit_and(rng); + b2a_pad_msg a{}, b{}; + sample_b2a(rng, a, b); + m0.bits[i] = word_bit_for(bit_pad_for(t, 0), a); + m1.bits[i] = word_bit_for(bit_pad_for(t, 1), b); + } + sample_b2a(rng, m0.ai, m1.ai); + net.send_to(role::p0, net::msg::beaver_tape, m0); + net.send_to(role::p1, net::msg::beaver_tape, m1); +} + +template +inline void send_suffix_pads(trio & net, Pad & rng) +{ + suffix_obliv_msg m0{}, m1{}; + const auto t = detail::ds_sample_bit_and(rng); + m0.and_pad = bit_pad_for(t, 0); + m1.and_pad = bit_pad_for(t, 1); + for (int i = 0; i < 3; ++i) + sample_b2a(rng, m0.b2a[i], m1.b2a[i]); + net.send_to(role::p0, net::msg::beaver_tape, m0); + net.send_to(role::p1, net::msg::beaver_tape, m1); +} + +template +inline void send_bit_and_vec(trio & net, std::size_t n, Pad & rng) +{ + std::vector a(n), b(n); + for (std::size_t i = 0; i < n; ++i) + { + const auto t = detail::ds_sample_bit_and(rng); + a[i] = bit_pad_for(t, 0); + b[i] = bit_pad_for(t, 1); + } + net.send_vec_to(role::p0, net::msg::beaver_tape, a); + net.send_vec_to(role::p1, net::msg::beaver_tape, b); +} + +/// @} + +inline cw_pad_msg cw_pad_for(const detail::ds_cw_party & p) +{ + cw_pad_msg m; + m.rand = p.rand; + m.gamma = p.gamma; + m.bit = p.bit; + return m; +} + +inline and_share_msg and_share_for(const detail::ds_and_pads & p, int party) +{ + and_share_msg m; + if (party == 0) + { + m.a = p.a0; + m.b = p.b0_share; + m.c = p.c0_share; + } + else + { + m.a = p.a1; + m.b = p.b1_share; + m.c = p.c1_share; + } + return m; +} + +inline level_pad_msg level_pad_for(const detail::ds_cw_pads & cw, + const detail::ds_and_pads & my_and, const detail::ds_and_pads & their_and, + int party) +{ + level_pad_msg m; + m.cw = cw_pad_for(party == 0 ? cw.p0 : cw.p1); + m.mine = and_share_for(my_and, party); + m.theirs = and_share_for(their_and, party); + return m; +} + +template +Leaf random_leaf(); + +template +cs_block open_cs(net::trio & net, const cs_block & mine); + +#include "oblivious_hash.hpp" + +template +inline void send_hash_tape(trio & net, Pad && htape = Pad{}) +{ + constexpr std::size_t nand = hash_level_and_count(); + std::vector t0(nand), t1(nand); + for (std::size_t i = 0; i < nand; ++i) + { + const auto full = detail::ds_sample_bit_and(htape); + t0[i] = bit_pad_for(full, 0); + t1[i] = bit_pad_for(full, 1); + } + net.send_vec_to(role::p0, net::msg::beaver_tape, t0); + net.send_vec_to(role::p1, net::msg::beaver_tape, t1); +} + +/// @brief Dealer samples Half-Tree roots (when needed) and one pad per level. +/// @tparam InteriorPRG PRG that expands interior nodes +/// @tparam InputT input domain type +/// @tparam OutputT payload type +/// @param net the connected trio. This process must be p2. +/// \complexity O(n) sampling. n is `depth`. The loop body is one CW pad and two AND pads per level. +/// \rounds n level-pad sends to each of p0 and p1, plus one leaf-pad send to each. A Half-Tree also sends one root to each. `ObliviousHash` adds one `bit_and_pad_msg` vector per level (`hash_level_and_count()` bit triples). +/// \communication Those messages. Each `level_pad_msg` carries one party's share of the CW pad and the two AND pads. +/// \preprocessing This function is the preprocessing. The online walk is `point_party`. +/// @param pads beaver-pad stream. `dpf::prg_pad_rng` reads that stream from a PRG seed. +/// @param root_draw Half-Tree roots. `dpf::pseudorandom_root_sampler` is the PRG form. +template ::node>> +void deal_point(trio & net, Pad && pads = Pad{}, RootDraw && root_draw = RootDraw{}) +{ + using dpf_type = + utils::dpf_type_t; + using node = typename dpf_type::interior_node; + using tree = dpf::tree_traits; + constexpr std::size_t depth = dpf_type::depth; + + if constexpr (tree::is_half_tree) + { + node roots[2]; + tree::root_init(roots, [&]() -> node { return root_draw(); }); + net.send_to(role::p0, net::msg::dpf_key, roots[0]); + net.send_to(role::p1, net::msg::dpf_key, roots[1]); + } + + for (std::size_t level = 0; level < depth; ++level) + { + const auto cw = detail::ds_sample_cw(pads); + const auto and0 = detail::ds_sample_and(pads); + const auto and1 = detail::ds_sample_and(pads); + net.send_to(role::p0, net::msg::beaver_tape, level_pad_for(cw, and0, and1, 0)); + net.send_to(role::p1, net::msg::beaver_tape, level_pad_for(cw, and1, and0, 1)); + if constexpr (ObliviousHash) + { + constexpr std::size_t nand = hash_level_and_count(); + std::vector t0(nand), t1(nand); + for (std::size_t i = 0; i < nand; ++i) + { + const auto full = ::dpf::detail::ds_sample_bit_and(pads); + t0[i] = bit_pad_for(full, 0); + t1[i] = bit_pad_for(full, 1); + } + net.send_vec_to(role::p0, net::msg::beaver_tape, t0); + net.send_vec_to(role::p1, net::msg::beaver_tape, t1); + } + } + constexpr std::size_t lg = dpf_type::lg_outputs_per_leaf; + constexpr std::size_t n_leaf_ands = leaf_and_slots(lg); + leaf_pad_msg pads0{}; + leaf_pad_msg pads1{}; + for (std::size_t i = 0; i < n_leaf_ands; ++i) + { + const auto lane = detail::ds_sample_and(pads); + pads0.lanes[i] = and_share_for(lane, 0); + pads1.lanes[i] = and_share_for(lane, 1); + } + net.send_to(role::p0, net::msg::beaver_tape, pads0); + net.send_to(role::p1, net::msg::beaver_tape, pads1); + // Concrete lanes always mux in shares. A wildcard lane is muxed only when + // the caller did not ask for it (ObliviousHash is that request's inverse). + constexpr bool leaf_b2a = lg > 0 + && !utils::has_characteristic_two_v> + && (!dpf::is_wildcard_v || ObliviousHash); + if constexpr (leaf_b2a) + send_b2a_vec(net, n_leaf_ands * 128, pads); + + if constexpr (dpf::is_wildcard_v) + { + using concrete = dpf::concrete_type_t; + using exterior_node = typename dpf_type::exterior_node; + using leaf_type = dpf::leaf_node_t; + concrete out0{}, out1{}; + leaf_type vec0{}, vec1{}; + constexpr std::size_t nlanes = + dpf::outputs_per_leaf_v; + auto lane_rng = [&pads]() -> concrete { + concrete value{}; + auto * bytes = reinterpret_cast(std::addressof(value)); + std::size_t left = sizeof(concrete); + std::size_t off = 0; + while (left != 0) + { + const auto block = pads.block(); + const std::size_t n = left < sizeof(block) ? left : sizeof(block); + std::memcpy(bytes + off, &block, n); + off += n; + left -= n; + } + return value; + }; + dpf::beavers::fill_wildcard_scale_blinds(out0, out1, vec0, vec1, + nlanes > 0 ? nlanes : std::size_t{1}, lane_rng); + const leaf_type zero0 = random_leaf(); + const leaf_type zero1 = + dpf::subtract_leaf(leaf_type{}, zero0); + const leaf_type cross0 = dpf::multiply_leaf(vec0, out1); + const leaf_type cross1 = dpf::multiply_leaf(vec1, out0); + net.send_to(role::p0, net::msg::beaver_tape, wildcard_leaf_pad_msg{ + out0, vec0, vec1, cross0, zero0}); + net.send_to(role::p1, net::msg::beaver_tape, wildcard_leaf_pad_msg{ + out1, vec1, vec0, cross1, zero1}); + } +} + +template +using comparison_pair_t = decltype(dpf::make_dpf( + std::declval(), std::declval(), std::declval()...)); + +inline std::uint64_t random_ring_word(std::uint64_t mask); +inline void deal_ring_zero(trio & net, std::uint64_t mask); + +/// @brief Dealer samples roots, DS level pads, and a comparison-ring zero share. +/// @tparam Oblivious When set, also deal the bit tapes the value-word, suffix, +/// and verifiable-hash circuits consume. The target itself is not opened. +template +void deal_comparison(trio & net, const Spec & spec, const Tags & ...tags); + +template +void deal_comparison(Pad && pads, RootDraw && root_draw, trio & net, + const Spec & spec, const Tags & ...tags) +{ + (void)std::initializer_list{((void)tags, 0)...}; + using pair_type = + comparison_pair_t; + using key_type = typename pair_type::first_type::key_type; + using node = typename key_type::interior_node; + using tree = dpf::tree_traits; + + static_assert(key_type::num_outputs == 0, + "dist comparison keygen currently builds comparison-only keys"); + + dcf_runtime_spec runtime{}; + bool found = false; + detail::incr::collect_cmp_one(runtime, found, spec); + if (!found) + throw std::invalid_argument("dist comparison keygen needs one comparison"); + if (runtime.prefix == 0) + runtime.prefix = utils::bitlength_of_v; + if constexpr (Oblivious) + { + if (is_paint_kind(runtime.kind)) + throw std::invalid_argument( + "oblivious comparison does not support paint kinds"); + } + + if constexpr (tree::is_half_tree) + { + node roots[2]; + tree::root_init(roots, [&]() -> node { return root_draw(); }); + net.send_to(role::p0, net::msg::dpf_key, roots[0]); + net.send_to(role::p1, net::msg::dpf_key, roots[1]); + } + + if constexpr (Oblivious) + { + // leq/gt: deal the `∧ path bits` tape. Holders keep that product + // shared (no open_bit) so the domain-edge bit stays hidden. + const bool edge = runtime.kind == cmp_kind::leq + || runtime.kind == cmp_kind::gt; + if (edge && runtime.prefix > 1) + send_bit_and_vec(net, runtime.prefix - 1, pads); + } + + for (std::size_t level = 0; level < key_type::depth; ++level) + { + const auto cw = detail::ds_sample_cw(pads); + const auto and0 = detail::ds_sample_and(pads); + const auto and1 = detail::ds_sample_and(pads); + net.send_to(role::p0, net::msg::beaver_tape, level_pad_for(cw, and0, and1, 0)); + net.send_to(role::p1, net::msg::beaver_tape, level_pad_for(cw, and1, and0, 1)); + if constexpr (Oblivious) + { + if (key_type::cmp_block == 0 && level < runtime.prefix) + send_cmp_level_pads(net, pads); + if constexpr (key_type::cmp_block > 0 && key_type::cmp_q > 0) + { + if (level + 1 == key_type::cmp_h) + send_suffix_pads(net, pads); + } + if constexpr (key_type::is_verifiable) + send_hash_tape(net, pads); + } + } + + deal_ring_zero(net, runtime.mask); +} + +template +void deal_comparison(trio & net, const Spec & spec, const Tags & ...tags) +{ + using pair_type = + comparison_pair_t; + using node = typename pair_type::first_type::key_type::interior_node; + detail::urandom_pad_rng pads; + dpf::uniform_node_sampler roots; + deal_comparison &, + InteriorPRG, ExteriorPRG, InputT, Oblivious, Spec, Tags...>( + pads, roots, net, spec, tags...); +} + +template +Leaf random_leaf() +{ + Leaf out{}; + auto * bytes = reinterpret_cast(&out); + std::size_t left = sizeof(Leaf); + while (left > 0) + { + const auto block = dpf::uniform_sample(); + const std::size_t n = left < sizeof(block) ? left : sizeof(block); + std::memcpy(bytes, &block, n); + bytes += n; + left -= n; + } + return out; +} + +inline std::uint64_t random_ring_word(std::uint64_t mask) +{ + return detail::dcf_impl::convert_node( + dpf::uniform_sample(), mask); +} + +/// @brief Dealer sends additive shares of zero in the comparison ring. +inline void deal_ring_zero(trio & net, std::uint64_t mask) +{ + const std::uint64_t r = random_ring_word(mask); + net.send_to(role::p0, net::msg::beaver_tape, ring_zero_share_msg{r}); + net.send_to(role::p1, net::msg::beaver_tape, ring_zero_share_msg{detail::dcf_impl::neg_m(r, mask)}); +} + +/// @brief Open `party1 - party0` without revealing either local ring word. +/// @details This is the scalar analogue of the blinded leaf-mask difference: +/// p0 blinds its word, p1 subtracts it, and p0 removes the blind before +/// returning the public difference. +template +HEDLEY_WARN_UNUSED_RESULT +std::uint64_t open_ring_difference(trio & net, std::uint64_t mine, + std::uint64_t mask) +{ + static_assert(Me == 0 || Me == 1, "ring opener party is 0 or 1"); + const role peer = Me == 0 ? role::p1 : role::p0; + mine &= mask; + if constexpr (Me == 0) + { + const std::uint64_t pad = random_ring_word(mask); + const std::uint64_t blinded = (mine + pad) & mask; + net.send_to(peer, net::msg::ring_vector, blinded); + const std::uint64_t back = net.recv_from(peer, net::msg::ring_vector); + const std::uint64_t opened = (back + pad) & mask; + net.send_to(peer, net::msg::ring_vector, opened); + return opened; + } + else + { + const std::uint64_t blinded = + net.recv_from(peer, net::msg::ring_vector); + const std::uint64_t back = + (mine + detail::dcf_impl::neg_m(blinded, mask)) & mask; + net.send_to(peer, net::msg::ring_vector, back); + return net.recv_from(peer, net::msg::ring_vector) & mask; + } +} + +template +Leaf leaf_add(Leaf a, Leaf b) +{ + const Leaf neg = dpf::subtract_leaf(Leaf{}, b); + return dpf::subtract_leaf(a, neg); +} + +#include "oblivious_select.hpp" + +inline cs_block xor_cs(const cs_block & a, const cs_block & b) +{ + return cs_block{ + simde_mm_xor_si128(a[0], b[0]), + simde_mm_xor_si128(a[1], b[1]), + simde_mm_xor_si128(a[2], b[2]), + simde_mm_xor_si128(a[3], b[3])}; +} + +inline cs_block random_cs() +{ + return cs_block{ + dpf::uniform_sample(), + dpf::uniform_sample(), + dpf::uniform_sample(), + dpf::uniform_sample()}; +} + +/// @brief Open `H0 XOR H1` with the same pad pattern as the leaf mask. +/// @tparam Me `0` for p0, `1` for p1 +/// @param net the connected trio +/// @param mine this party's `hash_node` digest +/// @return the public correction seed +template +HEDLEY_WARN_UNUSED_RESULT +cs_block open_cs(trio & net, const cs_block & mine) +{ + const role peer = Me == 0 ? role::p1 : role::p0; + if constexpr (Me == 0) + { + const cs_block pad = random_cs(); + const cs_block blinded = xor_cs(mine, pad); + net.send_to(peer, net::msg::delta, blinded); + const cs_block back = net.recv_from(peer, net::msg::delta); + const cs_block cs = xor_cs(back, pad); + net.send_to(peer, net::msg::delta, cs); + return cs; + } + else + { + const cs_block blinded = net.recv_from(peer, net::msg::delta); + const cs_block back = xor_cs(mine, blinded); + net.send_to(peer, net::msg::delta, back); + return net.recv_from(peer, net::msg::delta); + } +} + +/// @brief Product of a XOR-shared bit and a block known to one party. +/// @details Each party contributes `bit_share XOR a_share`. Only the party +/// holding the block receives the product. When that block is a +/// public difference of two leaves, the holder can read the bit +/// off a nonzero product; the peer receives zero and does not. +/// @tparam Exchange callable `peer_msg = exch(my_msg)` on the p0–p1 link +/// @param exch the exchange +/// @param i_hold_block `true` when this party knows `block` +/// @param bit_share this party's XOR share of the bit +/// @param block the block, meaningful only when `i_hold_block` +/// @param mine this party's Beaver triple share +/// @return the product when this party holds the block, otherwise zero +template +HEDLEY_WARN_UNUSED_RESULT +simde__m128i beaver_shared_bit(Exchange && exch, bool i_hold_block, + std::uint8_t bit_share, simde__m128i block, const and_share_msg & mine) +{ + and_round1_msg msg{}; + msg.d_bit = static_cast(bit_share ^ mine.a); + msg.b_bit = mine.b; + msg.a_m = mine.a; + msg.e_m = i_hold_block ? detail::ds_xor(block, mine.b) : mine.b; + const and_round1_msg peer = exch(msg); + const std::uint8_t d = static_cast(msg.d_bit ^ peer.d_bit); + const simde__m128i e = i_hold_block + ? detail::ds_xor(msg.e_m, peer.b_bit) + : detail::ds_xor(peer.e_m, mine.b); + and_round2_msg zmsg{}; + zmsg.z_bit = detail::ds_xor( + detail::ds_xor(detail::ds_gate(d, mine.b), detail::ds_gate(mine.a, e)), + mine.c); + const and_round2_msg zpeer = exch(zmsg); + if (!i_hold_block) + return simde_mm_setzero_si128(); + const simde__m128i z_me = detail::ds_xor( + detail::ds_xor( + detail::ds_xor(detail::ds_gate(d, e), detail::ds_gate(d, mine.b)), + detail::ds_gate(mine.a, e)), + mine.c); + return detail::ds_xor(z_me, zpeer.z_bit); +} + +/// @brief Beaver product of a bit known to the other party and our block. +/// @details Both parties call this. Each is the block holder for its own +/// block and the bit holder for the peer's block, in one exchange. +/// @tparam Exchange callable `peer_msg = exch(my_msg)` on the p0–p1 link +/// @param exch the exchange +/// @param i_hold_m `true` when this party knows `M` +/// @param my_bit this party's share of the selector bit +/// @param M this party's block +/// @param my_triple Beaver pads for the product this party reconstructs +/// @param their_triple Beaver pads for the product the peer reconstructs +/// @return the product when this party holds `M`, otherwise zero +template +HEDLEY_WARN_UNUSED_RESULT +simde__m128i beaver_bit_block(Exchange && exch, bool i_hold_m, + std::uint8_t my_bit, simde__m128i M, const and_share_msg & my_triple, + const and_share_msg & their_triple) +{ + and_round1_msg mine{}; + mine.d_bit = static_cast(my_bit ^ their_triple.a); + mine.b_bit = their_triple.b; + mine.e_m = detail::ds_xor(M, my_triple.b); + mine.a_m = my_triple.a; + const and_round1_msg peer = exch(mine); + + const std::uint8_t d_as_bit = static_cast( + (my_bit ^ their_triple.a) ^ peer.a_m); + const simde__m128i e_as_bit = detail::ds_xor(peer.e_m, their_triple.b); + and_round2_msg zmsg{}; + zmsg.z_bit = detail::ds_xor( + detail::ds_xor(detail::ds_gate(d_as_bit, their_triple.b), + detail::ds_gate(their_triple.a, e_as_bit)), + their_triple.c); + const and_round2_msg zpeer = exch(zmsg); + + if (!i_hold_m) + return simde_mm_setzero_si128(); + + const std::uint8_t d = static_cast(peer.d_bit ^ my_triple.a); + const simde__m128i e = detail::ds_xor(detail::ds_xor(M, my_triple.b), peer.b_bit); + const simde__m128i z_me = detail::ds_xor( + detail::ds_xor( + detail::ds_xor(detail::ds_gate(d, e), detail::ds_gate(d, my_triple.b)), + detail::ds_gate(my_triple.a, e)), + my_triple.c); + return detail::ds_xor(z_me, zpeer.z_bit); +} + +template +HEDLEY_WARN_UNUSED_RESULT +InputT input_from_prefix(psnip_uint64_t prefix) +{ + constexpr auto to_int = utils::to_integral_type{}; + using U = std::make_unsigned_t()))>>; + using FromI = typename utils::make_from_integral_value::integral_type; + return utils::make_from_integral_value{}( + static_cast(static_cast(prefix))); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto pack_point_held(Held held, psnip_uint64_t prefix, unsigned lane) +{ + if constexpr (Verifiable && WildLane) + { + return opened_prefix_lane{ + std::move(held), input_from_prefix(prefix), lane}; + } + else if constexpr (Verifiable) + { + return opened_prefix{ + std::move(held), input_from_prefix(prefix)}; + } + else if constexpr (WildLane) + { + return opened_lane{std::move(held), lane}; + } + else + { + return held; + } +} + +/// @brief One computing party builds its point key from dealt pads. +/// @tparam InteriorPRG PRG that expands interior nodes +/// @tparam ExteriorPRG PRG that expands the root +/// @tparam InputT input domain type +/// @tparam OutputT payload type +/// @tparam Self `role::p0` or `role::p1` +/// @param net the connected trio +/// @param x_share this party's XOR share of the target, or the opened target +/// on p0 when `already_encoded` is set +/// @param beta the payload +/// @param already_encoded p0's share is the opened target and p1's share is 0 +/// @return Verifiable keys return `opened_prefix` (and `opened_lane` as well +/// when the payload is a packed wildcard). Other keys return the key, +/// or `opened_lane` when a wildcard scale vector needs the clear lane. +/// \complexity O(n) local PRG expansions (one `expand` per level) plus the exchanges below. n is `depth`. +/// \rounds n dealer pad deliveries, and per level three `exchange_with` calls (blind, CW share, advice) plus one `beaver_bit_block` exchange. A verifiable `RevealPoint` walk adds a prefix-bit exchange and `open_cs` (two further block exchanges). Without reveal, a verifiable walk instead receives a `bit_and_pad_msg` vector from p2. Counted in the `for (level)` loop of `point_party`. +/// \communication Per level, one `level_pad_msg` from p2 and the peer messages in those exchanges (each exchange is one `blind_msg`, `share_msg`, or `advice_msg`, 16 bytes plus a bit, or a block). Half-tree keys also receive the root from p2. +/// \preprocessing `deal_point` samples the roots and one `level_pad_msg` per level before this walk. +template ::node>> +HEDLEY_WARN_UNUSED_RESULT +auto point_party(trio & net, InputT x_share, OutputT beta, + bool already_encoded = false, + typename dpf::tree_traits::node * leaf_seed_out = nullptr, + RootDraw && root_draw = RootDraw{}, + net::RoundSink * batch_sink = nullptr, + std::size_t batch_index = 0) +{ + static_assert(Self == role::p0 || Self == role::p1, + "dist DS parties are p0 and p1"); + using auth_tag = std::conditional_t; + using dpf_type = + utils::dpf_type_t; + using node = typename dpf_type::interior_node; + using tree = dpf::tree_traits; + constexpr int me = Self == role::p0 ? 0 : 1; + constexpr std::size_t depth = dpf_type::depth; + constexpr auto to_int = utils::to_integral_type{}; + + const role peer = Self == role::p0 ? role::p1 : role::p0; + std::optional sink_ex; + if (batch_sink) + sink_ex.emplace(*batch_sink, batch_index); + auto exch = [&](const auto & mine) { + using T = std::decay_t; + if (sink_ex) + return (*sink_ex)(static_cast(mine)); + return net.exchange_with(peer, static_cast(mine), + net::msg::delta); + }; + + if (me == 0 && !already_encoded) + utils::flip_msb_if_signed_integral(x_share); + + node root{}; + if constexpr (tree::is_half_tree) + root = net.recv_from(role::p2, net::msg::dpf_key); + else if constexpr (me == 0) + root = dpf::unset_lo_bit(root_draw()); + else + root = dpf::set_lo_bit(root_draw()); + + node seed = root; + int home = me; + typename dpf_type::correction_words_array cws{}; + typename dpf_type::correction_advice_array advice{}; + typename dpf_type::correction_seeds_array seeds{}; + [[maybe_unused]] psnip_uint64_t prefix = 0; + [[maybe_unused]] std::uint64_t prefix_share = 0; + + auto mask = dpf_type::msb_mask; + for (std::size_t level = 0; level < depth; ++level, mask >>= 1) + { + const auto pads = net.recv_from(role::p2, net::msg::beaver_tape); + const std::uint8_t my_bit = static_cast( + !!(to_int(mask) & to_int(x_share))); + const bool is_last = tree::is_last_level(level, depth); + const std::uint8_t adv = static_cast(dpf::get_lo_bit(seed)); + const auto child = tree::expand(seed, is_last); + const node L = child[0]; + const node R = child[1]; + + blind_msg blind{}; + blind.bit = static_cast(my_bit ^ pads.cw.bit); + blind.msg = detail::ds_xor(detail::ds_xor(L, R), pads.cw.rand); + const blind_msg their_blind = exch(blind); + + detail::ds_cw_party mine_pad{pads.cw.rand, pads.cw.gamma, pads.cw.bit}; + detail::ds_blind peer_blind{their_blind.msg, their_blind.bit}; + share_msg mine_share{}; + mine_share.share = detail::ds_cw_share(L, R, my_bit, mine_pad, peer_blind); + const share_msg their_share = exch(mine_share); + node cw = detail::ds_xor(mine_share.share, their_share.share); + + advice_msg am{}; + am.aL = static_cast(dpf::get_lo_bit(L) ^ my_bit); + am.aR = static_cast(dpf::get_lo_bit(R) ^ my_bit); + const advice_msg at = exch(am); + std::uint8_t tpack = static_cast( + ((am.aR ^ at.aR) << 1) | ((am.aL ^ at.aL ^ 1u) & 1u)); + if constexpr (tree::is_half_tree) + { + if (!is_last) + tpack = 0; + } + + const bool exp_is_mine = home == me; + node M{}; + node base{}; + if constexpr (tree::is_half_tree) + { + if (!is_last) + { + M = detail::ds_xor(L, R); + base = (adv & 1u) ? detail::ds_xor(L, cw) : L; + } + else + { + detail::ds_next_terms(L, R, adv, cw, tpack, M, base); + } + } + else + { + detail::ds_next_terms(L, R, adv, cw, tpack, M, base); + } + + const simde__m128i cross = beaver_bit_block(exch, true, my_bit, M, + pads.mine, pads.theirs); + const simde__m128i local = detail::ds_gate(my_bit, M); + const simde__m128i exp_gate = exp_is_mine ? local : cross; + const simde__m128i rec_prod = exp_is_mine ? cross : local; + seed = detail::ds_xor(base, detail::ds_xor(exp_gate, rec_prod)); + home ^= 1; + + cws[level] = cw; + advice[level] = tpack; + + // The proof hash tweaks AES with this prefix. Reveal it only when + // the caller asked; otherwise hash the shared prefix. + if constexpr (dpf_type::is_verifiable && RevealPoint) + { + const std::uint8_t peer_bit = exch(my_bit); + prefix = (prefix << 1) | static_cast(my_bit ^ peer_bit); + const cs_block mine_h = + detail::vdpf::hash_node(level, prefix, seed); + seeds[level] = open_cs(net, mine_h); + } + else if constexpr (dpf_type::is_verifiable) + { + prefix_share = (prefix_share << 1) | my_bit; + const auto tape = net.recv_vec_from(role::p2, net::msg::beaver_tape); + if (tape.size() != hash_level_and_count()) + throw std::runtime_error("oblivious hash tape size"); + if (sink_ex) + { + seeds[level] = oblivious_cs_on_sink(net, *batch_sink, + sink_ex->round_ref(), batch_index, level, prefix_share, + seed, tape.data()); + } + else + { + seeds[level] = oblivious_cs(net, level, prefix_share, seed, + tape.data()); + } + } + } + + constexpr std::size_t lg = dpf_type::lg_outputs_per_leaf; + constexpr std::size_t n_leaf_ands = leaf_and_slots(lg); + constexpr bool wild = dpf::is_wildcard_v; + const auto lane_pads = + net.recv_from>(role::p2, net::msg::beaver_tape); + + using concrete_output = dpf::concrete_type_t; + using exterior_node = typename dpf_type::exterior_node; + using leaf_type = dpf::leaf_node_t; + constexpr bool need_b2a = lg > 0 + && !utils::has_characteristic_two_v + && (!wild || !RevealPoint); + std::vector b2a_pads; + if constexpr (need_b2a) + { + b2a_pads = net.recv_vec_from(role::p2, net::msg::beaver_tape); + if (b2a_pads.size() != n_leaf_ands * 128) + throw std::runtime_error("leaf b2a tape size"); + } + + // The clear lane is returned only when the caller asked for it. + [[maybe_unused]] unsigned opened_lane_bits = 0; + if constexpr (RevealPoint && wild && lg > 0) + { + for (std::size_t b = 0; b < lg; ++b) + { + const std::uint8_t mine_bit = static_cast( + (to_int(x_share) >> b) & 1u); + const std::uint8_t other = exch(mine_bit); + opened_lane_bits |= static_cast(mine_bit ^ other) << b; + } + } + + using leaf_prg = std::conditional_t, ExteriorPRG>; + const leaf_type mask_i = dpf::make_leaf_mask_inner>(dpf::unset_lo_2bits(seed)); + + leaf_type cw_leaf{}; + bool sign0 = me == 0 + ? static_cast(dpf::get_lo_bit(seed)) + : !static_cast(dpf::get_lo_bit(seed)); + auto bit_at = [&](std::size_t b) { + return static_cast((to_int(x_share) >> b) & 1u); + }; + auto mux_made = [&](auto && make) { + return mux_leaf_share(net, exch, lg, + std::forward(make), bit_at, lane_pads.lanes.data(), + b2a_pads.empty() ? nullptr : b2a_pads.data()); + }; + if constexpr (!wild && lg >= 1) + { + const leaf_type selected = mux_made([&](unsigned i) { + if constexpr (me == 0) + return dpf::make_naked_leaf( + static_cast(i), beta); + else + return leaf_type{}; + }); + cw_leaf = cw_from_selected( + net, selected, mask_i, sign0); + } + else if constexpr (me == 0) + { + const leaf_type pad = random_leaf(); + const leaf_type blinded = leaf_add(mask_i, pad); + net.send_to(role::p1, net::msg::ring_vector, blinded); + const leaf_type back = net.recv_from(role::p1, net::msg::ring_vector); + const leaf_type D = leaf_add(back, pad); + if constexpr (wild) + { + cw_leaf = sign0 + ? dpf::subtract_leaf(leaf_type{}, D) + : D; + } + else + { + const auto naked = dpf::make_naked_leaf(InputT{}, beta); + cw_leaf = sign0 + ? dpf::subtract_leaf(naked, D) + : dpf::subtract_leaf(D, naked); + } + net.send_to(role::p1, net::msg::dpf_key, cw_leaf); + } + else + { + const leaf_type blinded = net.recv_from(role::p0, net::msg::ring_vector); + const leaf_type back = + dpf::subtract_leaf(mask_i, blinded); + net.send_to(role::p0, net::msg::ring_vector, back); + cw_leaf = net.recv_from(role::p0, net::msg::dpf_key); + } + + if (leaf_seed_out) + *leaf_seed_out = seed; + + using wrap_t = std::tuple_element_t<0, typename dpf_type::leaf_wrapper_tuple>; + using held_type = party_key; + constexpr bool wild_lane = dpf::is_wildcard_v && lg > 0; + InputT off{}; + if constexpr (dpf::is_wildcard_v) + { + using pad_type = wildcard_leaf_pad_msg; + const pad_type wild = + net.recv_from(role::p2, net::msg::beaver_tape); + concrete_output coeff{}; + if constexpr (utils::has_characteristic_two_v) + coeff = static_cast(~std::uint64_t{0}); + else + coeff = static_cast(sign0 ? 1 : -1); + leaf_type blinded_vector{}; + if constexpr (lg == 0 || RevealPoint) + { + const leaf_type vector = dpf::make_naked_leaf( + static_cast(opened_lane_bits), coeff); + blinded_vector = leaf_add( + vector, wild.peer_vector_blind); + } + else + { + const leaf_type share = mux_made([&](unsigned i) { + if constexpr (me == 0) + return dpf::make_naked_leaf( + static_cast(i), coeff); + else + return leaf_type{}; + }); + const leaf_type mine_msg = leaf_add( + share, wild.vector_blind); + const leaf_type peer_msg = exch(mine_msg); + blinded_vector = leaf_add(share, peer_msg); + } + typename wrap_t::beaver_type beaver{wild.output_blind, + wild.vector_blind, blinded_vector}; + leaf_type leaf_share = + leaf_add(wild.zero_leaf, wild.cross); + if constexpr (me == 0) + leaf_share = leaf_add(leaf_share, cw_leaf); + typename dpf_type::leaf_wrapper_tuple leaves{ + wrap_t{leaf_share, beaver}}; + return pack_point_held(party_key( + dpf_type{root, cws, advice, std::move(leaves), off, {}, {}, 0, 0, + {}, {}, 0, {}, {}, {}, {}, seeds}), + prefix, opened_lane_bits); + } + else + { + typename dpf_type::leaf_wrapper_tuple leaves{wrap_t{cw_leaf}}; + return pack_point_held(party_key( + dpf_type{root, cws, advice, std::move(leaves), off, {}, {}, 0, 0, + {}, {}, 0, {}, {}, {}, {}, seeds}), + prefix, opened_lane_bits); + } +} + +/// @brief One computing party builds its comparison key over the socket DS walk. +/// @details Each party expands and converts only its own seed. Per-level value +/// correction words are opened as masked ring differences; the running `Va` +/// residual remains additively shared between the key holders. +/// +/// `PointIsClear` means both callers already hold the same encoded +/// point; this function does not exchange it and returns only the key. +/// `RevealPoint` exchanges the shares and returns the encoded point. +/// Otherwise the value words are a bit-serial mux of the two children +/// and the return value is the key alone. `leq`/`gt` still compute the +/// shared product `1{α = 2^n-1}` from the edge tape, but do not open +/// it or write `cmp.trivial` (that would publish the bit). The full +/// walk already matches the trivial predicate at the domain edge. +template +HEDLEY_WARN_UNUSED_RESULT +auto comparison_party_impl(RootDraw && root_draw, trio & net, InputT x_share, + const Spec & spec, net::RoundSink * batch_sink, std::size_t batch_index, + const Tags & ...tags) +{ + static_assert(Self == role::p0 || Self == role::p1, + "dist DS parties are p0 and p1"); + using pair_type = + comparison_pair_t; + using key_type = typename pair_type::first_type::key_type; + using node = typename key_type::interior_node; + using tree = dpf::tree_traits; + constexpr int me = Self == role::p0 ? 0 : 1; + constexpr std::size_t depth = key_type::depth; + constexpr auto to_int = utils::to_integral_type{}; + constexpr std::size_t input_bits = utils::bitlength_of_v; + + static_assert(key_type::num_outputs == 0, + "dist comparison keygen currently builds comparison-only keys"); + static_assert(!key_type::cmp_idcf, + "dist comparison keygen does not yet expose incremental prefix CWs"); + + (void)std::initializer_list{((void)tags, 0)...}; + const role peer = Self == role::p0 ? role::p1 : role::p0; + std::optional sink_ex; + if (batch_sink) + sink_ex.emplace(*batch_sink, batch_index); + auto exch = [&](const auto & mine) { + using T = std::decay_t; + if (sink_ex) + return (*sink_ex)(static_cast(mine)); + return net.exchange_with(peer, static_cast(mine), + net::msg::delta); + }; + constexpr bool clear_point = PointIsClear || RevealPoint; + + dcf_runtime_spec runtime{}; + bool found = false; + detail::incr::collect_cmp_one(runtime, found, spec); + if (!found) + throw std::invalid_argument("dist comparison keygen needs one comparison"); + if (runtime.prefix == 0) + runtime.prefix = input_bits; + if (runtime.custom) + throw std::invalid_argument( + "dist comparison keygen currently supports <=64-bit ring payloads"); + if constexpr (!clear_point) + { + if (is_paint_kind(runtime.kind)) + throw std::invalid_argument( + "oblivious comparison does not support paint kinds"); + } + + InputT encoded_x{}; + if constexpr (PointIsClear) + { + // Both callers pass the same encoded point. The seed walk still + // needs a sharing: p0 holds the point, p1 holds zero. + encoded_x = x_share; + if constexpr (me == 1) + x_share = InputT{}; + } + else if constexpr (RevealPoint) + { + if constexpr (me == 0) + utils::flip_msb_if_signed_integral(x_share); + const InputT peer_share = exch(x_share); + encoded_x = utils::xor_input_shares(x_share, peer_share); + } + else if constexpr (me == 0) + { + utils::flip_msb_if_signed_integral(x_share); + } + + detail::cmp_meta cmp{}; + cmp.nbits = static_cast(runtime.prefix); + cmp.mask = runtime.mask; + cmp.kind = runtime.kind; + cmp.active = true; + cmp.incremental = runtime.incremental; + cmp.block_width = static_cast(key_type::cmp_block); + cmp.tail_bits = static_cast(key_type::cmp_q); + const std::size_t cmp_nbits = runtime.prefix; + const std::uint64_t delta = runtime.beta & cmp.mask; + const std::uint64_t false_value = runtime.false_value & cmp.mask; + unsigned __int128 thresh = 0; + if constexpr (clear_point) + { + const InputT lane = + detail::incr::lane_input(encoded_x, cmp_nbits, input_bits); + thresh = static_cast(to_int(lane)); + } + detail::incr::adjust_cmp_threshold(cmp, thresh, cmp_nbits); + + node root{}; + if constexpr (tree::is_half_tree) + root = net.recv_from(role::p2, net::msg::dpf_key); + else if constexpr (me == 0) + root = dpf::unset_lo_bit(root_draw()); + else + root = dpf::set_lo_bit(root_draw()); + + // leq/gt domain edge: `∧` of the path bits selects the trivial absorb. + // Keep that product shared — opening it (or writing `cmp.trivial`) would + // publish `1{α = 2^n-1}`. The full oblivious walk is already correct at + // the edge; the clear-point path still uses `adjust_cmp_threshold`. + std::uint8_t edge_bit_share = 0; + bool have_edge_bit = false; + if constexpr (!clear_point) + { + const bool edge = cmp.kind == cmp_kind::leq || cmp.kind == cmp_kind::gt; + if (edge && cmp_nbits > 1) + { + const auto pads = net.recv_vec_from(role::p2, net::msg::beaver_tape); + if (pads.size() + 1 != cmp_nbits) + throw std::runtime_error("comparison edge tape size"); + std::vector bits(cmp_nbits); + for (std::size_t i = 0; i < cmp_nbits; ++i) + bits[i] = static_cast((to_int(x_share) >> i) & 1u); + edge_bit_share = and_tree(net, bits.data(), cmp_nbits, + pads.data()); + have_edge_bit = true; + } + } + + node seed = root; + int home = me; + typename key_type::correction_words_array cws{}; + typename key_type::correction_advice_array advice{}; + typename key_type::correction_seeds_array seeds{}; + typename key_type::value_cw_array value_cws{}; + typename key_type::value_cw_array value_cw_coeff{}; + typename key_type::tail_array tail{}; + typename key_type::tail_array tail_coeff{}; + typename key_type::prefix_cw_array prefix_cw{}; + typename key_type::prefix_cw_array prefix_coeff{}; + std::uint64_t cw_last = 0; + std::uint64_t cw_last_coeff = 0; + std::uint64_t va_share = 0; + std::uint64_t va1_share = 0; + psnip_uint64_t prefix = 0; + std::uint64_t prefix_share = 0; + + const auto on_path_for = [&](std::uint64_t scale) -> std::uint64_t { + if (!is_paint_kind(cmp.kind)) + return (cmp.include_eq ? scale : std::uint64_t{0}) & cmp.mask; + const std::uint64_t unit = detail::dcf_impl::paint_unit(cmp.kind, + cmp_nbits, thresh, cmp_nbits, runtime.length_bits, true, + runtime.paint ? &paint_fn_adapter : nullptr, + runtime.paint ? &runtime.paint : nullptr); + return detail::dcf_impl::scale_plant(unit, scale, cmp.mask); + }; + const std::uint64_t on_path = on_path_for(delta); + const std::uint64_t on_path_unit = on_path_for(1ULL); + + auto mask = key_type::msb_mask; + for (std::size_t level = 0; level < depth; ++level, mask >>= 1) + { + const auto pads = net.recv_from(role::p2, net::msg::beaver_tape); + const std::uint8_t my_bit = static_cast( + !!(to_int(mask) & to_int(x_share))); + std::uint8_t ai = 0; + if constexpr (clear_point) + ai = static_cast(!!(to_int(mask) & to_int(encoded_x))); + const bool is_last = tree::is_last_level(level, depth); + const std::uint8_t adv = + static_cast(dpf::get_lo_bit(seed)); + const std::uint8_t t1 = + static_cast(me == 1 ? adv : (adv ^ 1u)); + + if constexpr (key_type::cmp_block == 0) + { + cmp_level_obliv_msg word_pads{}; + if constexpr (!clear_point) + { + if (level < cmp_nbits) + word_pads = net.recv_from(role::p2, net::msg::beaver_tape); + } + if (cmp.trivial == cmp_trivial::none && level < cmp_nbits) + { + if constexpr (clear_point) + { + const auto converted = tree::expand_value(seed); + const node & keep = converted[ai]; + const node & lose = converted[ai ^ 1u]; + const std::uint64_t keep_word = + detail::dcf_impl::convert_node(keep, cmp.mask); + const std::uint64_t lose_word = + detail::dcf_impl::convert_node(lose, cmp.mask); + const auto open_value = [&](std::uint64_t scale, + std::uint64_t & va) { + std::uint64_t plant = 0; + if (is_paint_kind(cmp.kind)) + { + const std::uint64_t unit = + detail::dcf_impl::paint_unit(cmp.kind, level, + thresh, cmp_nbits, runtime.length_bits, false, + runtime.paint + ? &paint_fn_adapter : nullptr, + runtime.paint ? &runtime.paint : nullptr); + plant = detail::dcf_impl::scale_plant( + unit, scale, cmp.mask); + } + else if (ai != 0) + { + plant = scale & cmp.mask; + } + + std::uint64_t local = 0; + if constexpr (me == 0) + { + local = (lose_word + va) & cmp.mask; + } + else + { + local = (lose_word + + detail::dcf_impl::neg_m(va, cmp.mask) + + plant) & cmp.mask; + } + const std::uint64_t raw = + open_ring_difference(net, local, cmp.mask); + const std::uint64_t word = + detail::dcf_impl::sgn_m(t1, raw, cmp.mask); + if constexpr (me == 0) + { + va = (va + keep_word + + detail::dcf_impl::sgn_m(t1, word, cmp.mask)) + & cmp.mask; + } + else + { + va = (va + + detail::dcf_impl::neg_m(keep_word, cmp.mask)) + & cmp.mask; + } + return word; + }; + + const std::uint64_t base = open_value(delta, va_share); + value_cws[level] = + static_cast(base); + if constexpr (key_type::cmp_is_wildcard) + { + const std::uint64_t one = open_value(1ULL, va1_share); + value_cw_coeff[level] = + static_cast( + (one + detail::dcf_impl::neg_m(base, cmp.mask)) + & cmp.mask); + } + } + else + { + const auto converted = tree::expand_value(seed); + const std::uint64_t left = + detail::dcf_impl::convert_node(converted[0], cmp.mask); + const std::uint64_t right = + detail::dcf_impl::convert_node(converted[1], cmp.mask); + const std::uint64_t diff = left + (~right + 1); + const std::uint64_t prod0 = mul_known_word(net, me == 0, + me == 0 ? diff : 0ULL, my_bit, word_pads.bits.data()); + const std::uint64_t prod1 = mul_known_word(net, me == 1, + me == 1 ? diff : 0ULL, my_bit, word_pads.bits.data() + 64); + std::uint64_t lose0 = 0; + std::uint64_t keep0 = 0; + std::uint64_t lose1 = 0; + std::uint64_t keep1 = 0; + if constexpr (me == 0) + { + lose0 = right + prod0; + keep0 = left + right - lose0; + lose1 = prod1; + keep1 = 0ULL - prod1; + } + else + { + lose0 = prod0; + keep0 = 0ULL - prod0; + lose1 = right + prod1; + keep1 = left + right - lose1; + } + const std::uint64_t ai_add = b2a_bit(net, my_bit, word_pads.ai); + const auto open_shared = [&](std::uint64_t scale, + std::uint64_t & va) { + const std::uint64_t plant = ai_add * scale; + const std::uint64_t local = me == 0 + ? (lose0 + va - plant - lose1) + : (lose1 - va + plant - lose0); + const std::uint64_t raw = + open_ring_difference(net, local, cmp.mask); + const std::uint64_t word = + detail::dcf_impl::sgn_m(t1, raw, cmp.mask); + const std::uint64_t signed_word = me == 0 + ? detail::dcf_impl::sgn_m(t1, word, cmp.mask) : 0ULL; + va = (va + keep0 - keep1 + signed_word) & cmp.mask; + return word; + }; + const std::uint64_t base = open_shared(delta, va_share); + value_cws[level] = + static_cast(base); + if constexpr (key_type::cmp_is_wildcard) + { + const std::uint64_t one = open_shared(1ULL, va1_share); + value_cw_coeff[level] = + static_cast( + (one + detail::dcf_impl::neg_m(base, cmp.mask)) + & cmp.mask); + } + } + } + } + + const auto child = tree::expand(seed, is_last); + const node L = child[0]; + const node R = child[1]; + + blind_msg blind{}; + blind.bit = static_cast(my_bit ^ pads.cw.bit); + blind.msg = detail::ds_xor(detail::ds_xor(L, R), pads.cw.rand); + const blind_msg their_blind = exch(blind); + + detail::ds_cw_party mine_pad{pads.cw.rand, pads.cw.gamma, pads.cw.bit}; + detail::ds_blind peer_blind{their_blind.msg, their_blind.bit}; + share_msg mine_share{}; + mine_share.share = + detail::ds_cw_share(L, R, my_bit, mine_pad, peer_blind); + const share_msg their_share = exch(mine_share); + node cw = detail::ds_xor(mine_share.share, their_share.share); + + advice_msg am{}; + am.aL = static_cast(dpf::get_lo_bit(L) ^ my_bit); + am.aR = static_cast(dpf::get_lo_bit(R) ^ my_bit); + const advice_msg at = exch(am); + std::uint8_t tpack = static_cast( + ((am.aR ^ at.aR) << 1) | ((am.aL ^ at.aL ^ 1u) & 1u)); + if constexpr (tree::is_half_tree) + { + if (!is_last) + tpack = 0; + } + + const bool exp_is_mine = home == me; + node M{}; + node base{}; + if constexpr (tree::is_half_tree) + { + if (!is_last) + { + M = detail::ds_xor(L, R); + base = (adv & 1u) ? detail::ds_xor(L, cw) : L; + } + else + { + detail::ds_next_terms(L, R, adv, cw, tpack, M, base); + } + } + else + { + detail::ds_next_terms(L, R, adv, cw, tpack, M, base); + } + + const simde__m128i cross = beaver_bit_block(exch, true, my_bit, M, + pads.mine, pads.theirs); + const simde__m128i local = detail::ds_gate(my_bit, M); + const simde__m128i exp_gate = exp_is_mine ? local : cross; + const simde__m128i rec_prod = exp_is_mine ? cross : local; + seed = detail::ds_xor(base, detail::ds_xor(exp_gate, rec_prod)); + home ^= 1; + + cws[level] = cw; + advice[level] = tpack; + if constexpr (clear_point) + prefix = (prefix << 1) | static_cast(ai); + else + prefix_share = (prefix_share << 1) | my_bit; + + suffix_obliv_msg suffix_pad{}; + [[maybe_unused]] bool have_suffix = false; + if constexpr (!clear_point && key_type::cmp_block > 0 && key_type::cmp_q > 0) + { + if (level + 1 == key_type::cmp_h) + { + suffix_pad = net.recv_from(role::p2, net::msg::beaver_tape); + have_suffix = true; + } + } + + if constexpr (key_type::cmp_block > 0) + { + if (cmp.trivial == cmp_trivial::none) + { + using sched = + detail::blocked::schedule; + const std::size_t c = level + 1; + const std::uint8_t next_adv = + static_cast(dpf::get_lo_bit(seed)); + const std::uint8_t next_t1 = static_cast( + me == 1 ? next_adv : (next_adv ^ 1u)); + if (c <= key_type::cmp_h && sched::contains(c)) + { + const std::size_t wi = sched::index(c); + const std::uint64_t rho = + detail::blocked::rho_of(seed, cmp.mask); + const std::uint64_t local_word = me == 0 + ? rho + : (rho + delta) & cmp.mask; + const std::uint64_t raw = + open_ring_difference(net, local_word, cmp.mask); + value_cws[wi] = + static_cast( + detail::dcf_impl::sgn_m( + next_t1, raw, cmp.mask)); + if constexpr (key_type::cmp_is_wildcard) + { + value_cw_coeff[wi] = + static_cast( + next_t1 + ? detail::dcf_impl::neg_m(1ULL, cmp.mask) + : (1ULL & cmp.mask)); + } + } + if (c == key_type::cmp_h && key_type::cmp_q > 0) + { + std::uint64_t local_masks[4]{}; + detail::blocked::suffix_masks(seed, + key_type::cmp_q, cmp.mask, local_masks); + if constexpr (clear_point) + { + const std::uint64_t suffix = + static_cast(thresh) + & ((1ULL << key_type::cmp_q) - 1ULL); + for (std::size_t z = 0; z < key_type::cmp_tail; ++z) + { + const bool pred = cmp.include_eq ? (z <= suffix) + : (z < suffix); + const std::uint64_t local_word = me == 0 + ? local_masks[z] + : (local_masks[z] + (pred ? delta : 0ULL)) + & cmp.mask; + const std::uint64_t raw = open_ring_difference( + net, local_word, cmp.mask); + tail[z] = + static_cast( + detail::dcf_impl::sgn_m( + next_t1, raw, cmp.mask)); + if constexpr (key_type::cmp_is_wildcard) + { + tail_coeff[z] = + static_cast( + pred + ? (next_t1 + ? detail::dcf_impl::neg_m( + 1ULL, cmp.mask) + : (1ULL & cmp.mask)) + : 0ULL); + } + } + } + else if constexpr (key_type::cmp_q == 2) + { + const suffix_obliv_msg & sp = suffix_pad; + const std::uint8_t s0 = static_cast( + to_int(x_share) & 1u); + const std::uint8_t s1 = static_cast( + (to_int(x_share) >> 1) & 1u); + const std::uint8_t sand = and_bit_share( + net, s0, s1, sp.and_pad); + const std::uint8_t sor = static_cast( + s0 ^ s1 ^ sand); + const std::uint64_t a_or = b2a_bit(net, sor, sp.b2a[0]); + const std::uint64_t a_and = b2a_bit(net, sand, sp.b2a[1]); + const std::uint64_t a_s1 = b2a_bit(net, s1, sp.b2a[2]); + const std::uint64_t one_share = me == 0 ? 1ULL : 0ULL; + for (std::size_t z = 0; z < key_type::cmp_tail; ++z) + { + std::uint64_t pred_share = 0; + std::uint8_t pred_bit = 0; + if (cmp.include_eq) + { + if (z == 0) { pred_share = one_share; pred_bit = me == 0 ? 1 : 0; } + else if (z == 1) { pred_share = a_or; pred_bit = sor; } + else if (z == 2) { pred_share = a_s1; pred_bit = s1; } + else { pred_share = a_and; pred_bit = sand; } + } + else if (z == 0) { pred_share = a_or; pred_bit = sor; } + else if (z == 1) { pred_share = a_s1; pred_bit = s1; } + else if (z == 2) { pred_share = a_and; pred_bit = sand; } + const std::uint64_t plant = pred_share * delta; + const std::uint64_t local_word = me == 0 + ? (local_masks[z] - plant) + : (local_masks[z] + plant); + const std::uint64_t raw = open_ring_difference( + net, local_word, cmp.mask); + tail[z] = + static_cast( + detail::dcf_impl::sgn_m( + next_t1, raw, cmp.mask)); + if constexpr (key_type::cmp_is_wildcard) + { + const std::uint8_t pred = open_bit(net, pred_bit); + const std::uint64_t unit = next_t1 + ? detail::dcf_impl::neg_m(1ULL, cmp.mask) + : (1ULL & cmp.mask); + tail_coeff[z] = + static_cast( + pred ? unit : 0ULL); + } + } + } + } + } + } + + if constexpr (key_type::is_verifiable) + { + const std::size_t tag = key_type::cmp_block > 0 + ? (detail::blocked::fold_spine_tag | level) : level; + if constexpr (clear_point) + { + const cs_block mine_h = + detail::vdpf::hash_node(tag, prefix, seed); + seeds[level] = open_cs(net, mine_h); + } + else + { + const auto tape = net.recv_vec_from(role::p2, net::msg::beaver_tape); + if (tape.size() != hash_level_and_count()) + throw std::runtime_error("oblivious hash tape size"); + if (sink_ex) + { + seeds[level] = oblivious_cs_on_sink(net, *batch_sink, + sink_ex->round_ref(), batch_index, tag, prefix_share, + seed, tape.data()); + } + else + { + seeds[level] = oblivious_cs(net, tag, prefix_share, seed, + tape.data()); + } + } + } + + if constexpr (key_type::cmp_block == 0) + { + if (cmp.trivial == cmp_trivial::none + && level + 1 == cmp_nbits) + { + const std::uint8_t next_adv = + static_cast(dpf::get_lo_bit(seed)); + const std::uint8_t next_t1 = static_cast( + me == 1 ? next_adv : (next_adv ^ 1u)); + const std::uint64_t converted = + detail::dcf_impl::convert_node(seed, cmp.mask); + const auto open_final = [&](std::uint64_t path_value, + std::uint64_t va) { + const std::uint64_t local_word = me == 0 + ? (converted + va) & cmp.mask + : (converted + detail::dcf_impl::neg_m(va, cmp.mask) + + path_value) & cmp.mask; + const std::uint64_t raw = open_ring_difference( + net, local_word, cmp.mask); + return detail::dcf_impl::sgn_m( + next_t1, raw, cmp.mask); + }; + cw_last = open_final(on_path, va_share); + if constexpr (key_type::cmp_is_wildcard) + { + const std::uint64_t one = + open_final(on_path_unit, va1_share); + cw_last_coeff = + (one + detail::dcf_impl::neg_m(cw_last, cmp.mask)) + & cmp.mask; + } + } + } + } + + const auto zero = net.recv_from(role::p2, net::msg::beaver_tape); + std::uint64_t target = false_value; + if (cmp.trivial == cmp_trivial::always_true) + target = (delta + false_value) & cmp.mask; + else if (cmp.trivial == cmp_trivial::always_false) + target = false_value; + else if (cmp.eval_as_ge) + target = (delta + false_value) & cmp.mask; + // `edge_bit_share` is the shared product `∧ path bits`. Leaving + // `cmp.trivial` unset avoids publishing that bit; the planted value + // words already match the trivial predicate when every path bit is 1. + if (have_edge_bit) + (void)edge_bit_share; + const std::uint64_t cmp_addend = + (zero.share + (me == 1 ? target : 0ULL)) & cmp.mask; + + typename key_type::leaf_wrapper_tuple leaves{}; + typename key_type::addend_tuple addends{}; + InputT off{}; + key_type key{root, cws, advice, std::move(leaves), off, cmp, value_cws, + cw_last, cmp_addend, addends, value_cw_coeff, cw_last_coeff, tail, + tail_coeff, prefix_cw, prefix_coeff, seeds}; + party_key held{std::move(key)}; + if constexpr (!RevealPoint || PointIsClear) + return held; + else + return opened_point, InputT>{ + std::move(held), encoded_x}; +} + +template >, + net::RoundSink *>>> +HEDLEY_WARN_UNUSED_RESULT +auto comparison_party(RootDraw && root_draw, trio & net, InputT x_share, + const Spec & spec, const Tags & ...tags) +{ + return comparison_party_impl( + std::forward(root_draw), net, x_share, spec, + nullptr, 0, tags...); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto comparison_party(RootDraw && root_draw, trio & net, InputT x_share, + const Spec & spec, net::RoundSink * batch_sink, std::size_t batch_index, + const Tags & ...tags) +{ + return comparison_party_impl( + std::forward(root_draw), net, x_share, spec, + batch_sink, batch_index, tags...); +} + +template >, + net::RoundSink *>>> +HEDLEY_WARN_UNUSED_RESULT +auto comparison_party(trio & net, InputT x_share, const Spec & spec, + const Tags & ...tags) +{ + using pair_type = + comparison_pair_t; + using node = typename pair_type::first_type::key_type::interior_node; + dpf::uniform_node_sampler roots; + return comparison_party_impl &, Self, + InteriorPRG, ExteriorPRG, PointIsClear, RevealPoint, InputT, Spec, + Tags...>(roots, net, x_share, spec, nullptr, 0, tags...); +} + +template +HEDLEY_WARN_UNUSED_RESULT +auto comparison_party(trio & net, InputT x_share, const Spec & spec, + net::RoundSink * batch_sink, std::size_t batch_index, const Tags & ...tags) +{ + using pair_type = + comparison_pair_t; + using node = typename pair_type::first_type::key_type::interior_node; + dpf::uniform_node_sampler roots; + return comparison_party_impl &, Self, + InteriorPRG, ExteriorPRG, PointIsClear, RevealPoint, InputT, Spec, + Tags...>(roots, net, x_share, spec, batch_sink, batch_index, tags...); +} + +/// @brief p2 deals one bit-Beaver per carry. The final bit has no carry-out. +/// @tparam InputT input domain type +/// @param net the connected trio. This process must be p2. +template +void deal_additive_carry(trio & net, Pad && pads = Pad{}) +{ + constexpr std::size_t nbits = utils::bitlength_of_v; + for (std::size_t i = 0; i + 1 < nbits; ++i) + { + const detail::ds_bit_triple t = detail::ds_sample_bit_and(pads); + net.send_to(role::p0, net::msg::beaver_tape, bit_and_pad_msg{t.a0, t.b0, t.c0}); + net.send_to(role::p1, net::msg::beaver_tape, bit_and_pad_msg{t.a1, t.b1, t.c1}); + } +} + +/// @brief This party's XOR share of the sum of two additive shares. +/// @details Matches `split_additive_to_xor`. Each carry is one beaver bit-AND. +/// The raw additive bits are not sent. The sum is not opened. +/// @tparam Self `role::p0` or `role::p1` +/// @tparam InputT input domain type +/// @param net the connected trio +/// @param mine this party's additive share +/// @return XOR share of the unsigned sum, before the signed-MSB flip +template +HEDLEY_WARN_UNUSED_RESULT +InputT additive_to_xor_share(trio & net, InputT mine) +{ + static_assert(Self == role::p0 || Self == role::p1, + "additive carry parties are p0 and p1"); + constexpr int me = Self == role::p0 ? 0 : 1; + constexpr auto to_int = utils::to_integral_type{}; + using FromI = typename utils::make_from_integral_value::integral_type; + using U = std::make_unsigned_t; + constexpr std::size_t nbits = utils::bitlength_of_v; + const role peer = Self == role::p0 ? role::p1 : role::p0; + const U u = static_cast(to_int(mine)); + U share = 0; + std::uint8_t carry = 0; + for (std::size_t i = 0; i < nbits; ++i) + { + const std::uint8_t bit = static_cast((u >> i) & U{1}); + const std::uint8_t sum_bit = static_cast(bit ^ carry); + share = static_cast(share | (static_cast(sum_bit) << i)); + if (i + 1 == nbits) + break; + const bit_and_pad_msg pad = + net.recv_from(role::p2, net::msg::beaver_tape); + const std::uint8_t left = me == 0 + ? static_cast(bit ^ carry) : carry; + const std::uint8_t right = me == 0 + ? carry : static_cast(bit ^ carry); + const bit_and_mask_msg mine_mask{ + static_cast(left ^ pad.a), + static_cast(right ^ pad.b)}; + const bit_and_mask_msg peer_mask = + net.exchange_with(peer, mine_mask, net::msg::delta); + const std::uint8_t d = static_cast(mine_mask.x ^ peer_mask.x); + const std::uint8_t e = static_cast(mine_mask.y ^ peer_mask.y); + const std::uint8_t prod = detail::ds_bit_and_party( + d, e, pad.a, pad.b, pad.c, me == 0); + carry = static_cast(prod ^ carry); + } + return utils::make_from_integral_value{}(static_cast(share)); +} + + +/// @brief Beaver pads to XOR-add a public constant into an n-bit XOR share. +inline constexpr std::size_t ic_add_and_count(std::size_t nbits) noexcept +{ + return nbits > 0 ? nbits - 1 : 0; +} + +/// @brief Beaver pads for one XOR-shared greater-than (four ANDs per bit). +inline constexpr std::size_t ic_gt_and_count(std::size_t nbits) noexcept +{ + return 4 * nbits; +} + +/// @brief Pads for `γ = r − 1` on XOR shares (borrow chain). +inline constexpr std::size_t ic_gamma_and_count(std::size_t nbits) noexcept +{ + return ic_add_and_count(nbits); +} + +/// @brief Total bit-AND pads for shared `correction_s` (three adds, three +/// comparisons, and `aq == nmask`). +inline constexpr std::size_t ic_correction_and_count(std::size_t nbits) noexcept +{ + return 3 * ic_add_and_count(nbits) + 3 * ic_gt_and_count(nbits) + + ic_add_and_count(nbits); +} + +/// @brief XOR-add public `c` into bit shares of `x` (in place). Uses `nbits-1` +/// Beaver ANDs for the carry chain. +template +void xor_add_public(trio & net, std::uint8_t * bits, std::size_t nbits, + std::uint64_t c, const bit_and_pad_msg * pads) +{ + std::uint8_t carry = 0; + for (std::size_t i = 0; i < nbits; ++i) + { + const std::uint8_t ci = static_cast((c >> i) & 1u); + const std::uint8_t ri = bits[i]; + if (ci == 0) + { + bits[i] = static_cast(ri ^ carry); + if (i + 1 < nbits) + carry = and_bit_share(net, ri, carry, pads[i]); + } + else + { + bits[i] = static_cast( + ri ^ carry ^ (Me == 0 ? 1u : 0u)); + if (i + 1 < nbits) + { + const std::uint8_t prod = + and_bit_share(net, ri, carry, pads[i]); + carry = static_cast(ri ^ carry ^ prod); + } + } + } +} + +/// @brief XOR share of `a > b` for two XOR-shared n-bit values. +template +std::uint8_t xor_gt(trio & net, const std::uint8_t * a, const std::uint8_t * b, + std::size_t nbits, const bit_and_pad_msg * pads) +{ + std::uint8_t gt = 0; + std::uint8_t eq = Me == 0 ? std::uint8_t{1} : std::uint8_t{0}; + std::size_t pi = 0; + for (std::size_t i = nbits; i-- > 0;) + { + const std::uint8_t diff = static_cast(a[i] ^ b[i]); + const std::uint8_t not_diff = + static_cast(diff ^ (Me == 0 ? 1u : 0u)); + const std::uint8_t not_b = + static_cast(b[i] ^ (Me == 0 ? 1u : 0u)); + const std::uint8_t eq_a = + and_bit_share(net, eq, a[i], pads[pi++]); + const std::uint8_t term = + and_bit_share(net, eq_a, not_b, pads[pi++]); + const std::uint8_t gt_and = + and_bit_share(net, gt, term, pads[pi++]); + gt = static_cast(gt ^ term ^ gt_and); + eq = and_bit_share(net, eq, not_diff, pads[pi++]); + } + return gt; +} + +/// @brief XOR share of `(x − 1) & nmask` from XOR bit shares of `x`. +template +void xor_sub_one(trio & net, std::uint8_t * bits, std::size_t nbits, + const bit_and_pad_msg * pads) +{ + // borrow starts as the constant 1. + std::uint8_t borrow = Me == 0 ? std::uint8_t{1} : std::uint8_t{0}; + for (std::size_t i = 0; i < nbits; ++i) + { + const std::uint8_t ri = bits[i]; + bits[i] = static_cast(ri ^ borrow); + if (i + 1 < nbits) + { + const std::uint8_t not_r = + static_cast(ri ^ (Me == 0 ? 1u : 0u)); + borrow = and_bit_share(net, not_r, borrow, pads[i]); + } + } +} + +/// @brief Pack XOR bit shares into an input word. +template +InputT bits_to_input(const std::uint8_t * bits, std::size_t nbits) +{ + using FromI = typename utils::make_from_integral_value::integral_type; + using U = std::make_unsigned_t; + U v = 0; + for (std::size_t i = 0; i < nbits; ++i) + v = static_cast(v | (static_cast(bits[i] & 1u) << i)); + return utils::make_from_integral_value{}(static_cast(v)); +} + +/// @brief Dealer tape for shared `γ = r − 1` and shared `correction_s`. +template +inline void deal_ic_mask_pads(trio & net, std::size_t nbits, Pad && pads = Pad{}) +{ + send_bit_and_vec(net, ic_gamma_and_count(nbits), pads); + send_bit_and_vec(net, ic_correction_and_count(nbits), pads); + send_b2a_vec(net, 4, pads); +} + +/// @brief This party's additive share of `correction_s(r,p,q)` in `gmask`, and +/// XOR bit shares of `γ = r − 1`, without opening `r`. +template +std::pair ic_gamma_and_correction(trio & net, + InputT r_share, std::uint64_t p, std::uint64_t q, std::uint64_t nmask, + std::uint64_t gmask) +{ + constexpr auto to_int = utils::to_integral_type{}; + using U = std::make_unsigned_t< + std::decay_t()))>>; + const std::size_t nbits = utils::bitlength_of_v; + const U ru = static_cast(to_int(r_share)) & static_cast(nmask); + + const auto gamma_pads = + net.recv_vec_from(role::p2, net::msg::beaver_tape); + if (gamma_pads.size() != ic_gamma_and_count(nbits)) + throw std::runtime_error("ic gamma tape size"); + std::vector r_bits(nbits); + for (std::size_t i = 0; i < nbits; ++i) + r_bits[i] = static_cast((ru >> i) & 1u); + std::vector g_bits = r_bits; + xor_sub_one(net, g_bits.data(), nbits, gamma_pads.data()); + const InputT gamma_share = bits_to_input(g_bits.data(), nbits); + + const auto corr_pads = + net.recv_vec_from(role::p2, net::msg::beaver_tape); + if (corr_pads.size() != ic_correction_and_count(nbits)) + throw std::runtime_error("ic correction tape size"); + const auto b2a_pads = + net.recv_vec_from(role::p2, net::msg::beaver_tape); + if (b2a_pads.size() != 4) + throw std::runtime_error("ic correction b2a size"); + + const std::size_t add_n = ic_add_and_count(nbits); + const std::size_t gt_n = ic_gt_and_count(nbits); + const bit_and_pad_msg * pad = corr_pads.data(); + + auto make_bits = [&](std::uint64_t pub) { + std::vector out = r_bits; + xor_add_public(net, out.data(), nbits, pub, pad); + pad += add_n; + return out; + }; + const auto aq = make_bits(q); + const auto ap = make_bits(p); + const std::uint64_t q0 = (q + 1ULL) & nmask; + const auto aq0 = make_bits(q0); + + auto pub_bits = [&](std::uint64_t pub) { + std::vector out(nbits); + for (std::size_t i = 0; i < nbits; ++i) + out[i] = Me == 0 + ? static_cast((pub >> i) & 1u) + : std::uint8_t{0}; + return out; + }; + const auto p_bits = pub_bits(p); + const auto q0_bits = pub_bits(q0); + + const std::uint8_t b_ap_aq = xor_gt(net, ap.data(), aq.data(), nbits, pad); + pad += gt_n; + const std::uint8_t b_ap_p = xor_gt(net, ap.data(), p_bits.data(), nbits, pad); + pad += gt_n; + const std::uint8_t b_aq0_q0 = + xor_gt(net, aq0.data(), q0_bits.data(), nbits, pad); + pad += gt_n; + const std::uint8_t b_aq_max = + and_tree(net, aq.data(), nbits, pad); + + const std::uint64_t s0 = b2a_bit(net, b_ap_aq, b2a_pads[0]); + const std::uint64_t s1 = b2a_bit(net, b_ap_p, b2a_pads[1]); + const std::uint64_t s2 = b2a_bit(net, b_aq0_q0, b2a_pads[2]); + const std::uint64_t s3 = b2a_bit(net, b_aq_max, b2a_pads[3]); + // correction_s = s0 - s1 + s2 + s3, embedded in the payload group. + const std::uint64_t cr_share = + (s0 + detail::dcf_impl::neg_m(s1, gmask) + s2 + s3) & gmask; + return {gamma_share, cr_share}; +} + + +} // namespace dist + +using net::role; +using net::trio; + +/// @brief Run distributed point-key generation and hand each party its key. +/// @tparam InteriorPRG PRG that expands interior nodes +/// @tparam ExteriorPRG PRG that expands the root +/// @tparam InputT input domain type +/// @tparam OutputT payload type +/// @tparam Fn0 callable invoked on p0 with its key +/// @tparam Fn1 callable invoked on p1 with its key +/// @param net the connected trio +/// @param self this process's role +/// @param x0 p0's share of the target. XOR, unless `additive` is set, in +/// which case it is p0's additive share. When `already_encoded` is +/// set this is the opened target. +/// @param x1 p1's share of the target, or zero when `already_encoded` is set +/// @param beta the payload +/// @param on0 p0's continuation +/// @param on1 p1's continuation +/// @param already_encoded the target was opened before keygen +/// @param additive `x0` and `x1` are additive shares. They are converted to +/// XOR shares of the sum by a beaver carry. The sum is not opened. +/// @brief Values a verifiable point-keygen reconstructed. +/// @details `opened_lane` is set only when the payload is a packed wildcard, +/// which has to build its scale vector at the clear lane. +template +struct point_key_opened +{ + Point opened_prefix{}; + std::optional opened_lane{}; +}; + +/// @return With `RevealPoint`, the tree prefix (`encoded >> lane_bits`) and, +/// for a packed wildcard, the lane. Empty on p2. With the default, +/// nothing: the prefix stays shared and the hash is an AES circuit. +template +auto dist_with_point_key( + trio & net, role self, InputT x0, InputT x1, OutputT beta, Fn0 && on0, + Fn1 && on1, bool already_encoded = false, bool additive = false) +{ + using opened_type = point_key_opened; + using dpf_type = utils::dpf_type_t; + constexpr bool wild_lane = RevealPoint && dpf::is_wildcard_v + && dpf_type::lg_outputs_per_leaf > 0; + if (additive && already_encoded) + throw std::invalid_argument( + "additive DS input is converted to XOR shares; it is not pre-opened"); + if (self == role::p2) + { + if (additive) + dist::deal_additive_carry(net); + dist::deal_point(net); + if constexpr (RevealPoint) + return std::optional(std::nullopt); + else + return; + } + if (additive) + { + if (self == role::p0) + x0 = dist::additive_to_xor_share(net, x0); + else + x1 = dist::additive_to_xor_share(net, x1); + } + if constexpr (RevealPoint) + { + auto finish = [](auto result) { + opened_type out; + out.opened_prefix = result.opened_prefix; + if constexpr (wild_lane) + out.opened_lane = result.opened_lane; + return out; + }; + auto slots = net::ds_walk_slot_bytes(dpf_type::depth, false, + dpf_type::lg_outputs_per_leaf); + auto sink = net.batch(1, std::move(slots)); + if (self == role::p0) + { + auto result = dist::point_party(net, x0, beta, already_encoded, + nullptr, dpf::uniform_node_sampler{}, sink.get(), 0); + std::forward(on0)(result.dpf_key); + return std::optional(finish(std::move(result))); + } + auto result = dist::point_party(net, x1, beta, already_encoded, + nullptr, dpf::uniform_node_sampler{}, sink.get(), 0); + std::forward(on1)(result.dpf_key); + return std::optional(finish(std::move(result))); + } + else + { + auto slots = net::ds_walk_slot_bytes(dpf_type::depth, true, + dpf_type::lg_outputs_per_leaf); + auto sink = net.batch(1, std::move(slots)); + if (self == role::p0) + std::forward(on0)(dist::point_party( + net, x0, beta, already_encoded, nullptr, + dpf::uniform_node_sampler{}, sink.get(), 0)); + else + std::forward(on1)(dist::point_party( + net, x1, beta, already_encoded, nullptr, + dpf::uniform_node_sampler{}, sink.get(), 0)); + } +} + +/// @brief Socket point-key generation using the extractable leaf stretch. +/// @details Not verifiable, so path bits stay shared. Packed lanes are muxed. +template +void dist_with_extractable_point_key(trio & net, role self, InputT x0, + InputT x1, OutputT beta, Fn0 && on0, Fn1 && on1) +{ + static_assert(!dpf::is_wildcard_v, + "extractable socket gen does not reconstruct a wildcard lane"); + if (self == role::p2) + { + dist::deal_point(net); + return; + } + if (self == role::p0) + { + on0(dist::point_party(net, x0, beta)); + } + else + { + on1(dist::point_party(net, x1, beta)); + } +} + +/// @brief Comparison keygen reconstructed nothing. The point stayed shared. +struct suppressed_point {}; + +/// @brief Run distributed comparison-key generation and hand each holder its key. +/// @tparam Reveal When set, exchange the target and return it. Otherwise the +/// value words are computed from XOR shares and the return is empty. +/// @return Encoded point when `Reveal` is set. Empty on p2. `suppressed_point` +/// when the point stays shared. +template +auto dist_with_cmp_key(trio & net, role self, InputT x0, InputT x1, + const Spec & spec, Fn0 && on0, Fn1 && on1, const Tags & ...tags) + -> std::conditional_t, suppressed_point> +{ + if (self == role::p2) + { + dist::deal_comparison( + net, spec, tags...); + if constexpr (Reveal) + return std::nullopt; + else + return {}; + } + if constexpr (Reveal) + { + using pair_type = dist::comparison_pair_t; + constexpr std::size_t depth = + pair_type::first_type::key_type::depth; + auto slots = net::ds_walk_slot_bytes(depth, false); + auto sink = net.batch(1, std::move(slots)); + if (self == role::p0) + { + auto result = dist::comparison_party(net, x0, spec, sink.get(), 0, tags...); + std::forward(on0)(result.dpf_key); + return result.opened_point; + } + auto result = dist::comparison_party(net, x1, spec, sink.get(), 0, tags...); + std::forward(on1)(result.dpf_key); + return result.opened_point; + } + else + { + using pair_type = dist::comparison_pair_t; + constexpr std::size_t depth = + pair_type::first_type::key_type::depth; + auto slots = net::ds_walk_slot_bytes(depth, true); + auto sink = net.batch(1, std::move(slots)); + if (self == role::p0) + { + std::forward(on0)(dist::comparison_party(net, x0, spec, sink.get(), 0, tags...)); + } + else + { + std::forward(on1)(dist::comparison_party(net, x1, spec, sink.get(), 0, tags...)); + } + return {}; + } +} + +/// @brief Build an interval-containment key around a socket-generated DCF spine. +/// @tparam Reveal When set, reconstruct mask `r` and return it (test path). +/// Otherwise `r` stays XOR-shared: shared `correction_s` / absorb and +/// shared `γ = r − 1` feed an oblivious comparison walk. +/// @return Opened `r` when `Reveal` is set. Empty on p2. `suppressed_point` +/// when the mask stays shared. +template +auto dist_with_ic_key(trio & net, role self, InputT r0, InputT r1, + const ic_pack & spec, Fn0 && on0, Fn1 && on1) + -> std::conditional_t>, + suppressed_point> +{ + using input_type = std::decay_t; + using out_beta = concrete_type_t; + detail::ic_impl::check_input(); + detail::ic_impl::check_bounds(spec); + if constexpr (detail::cmp_group_info::custom) + { + throw std::invalid_argument( + "dist interval keygen currently supports <=64-bit ring payloads"); + if constexpr (Reveal) + return std::nullopt; + else + return {}; + } + else + { + const auto inner_spec = detail::ic_impl::inner_lt(spec); + const std::uint64_t gmask = + detail::ic_impl::group_mask_of(); + const std::uint64_t nmask = + detail::ic_impl::input_mask_of(); + constexpr std::size_t nbits = utils::bitlength_of_v; + if (self == role::p2) + { + if constexpr (!Reveal) + dist::deal_ic_mask_pads(net, nbits); + dist::deal_comparison(net, inner_spec); + dist::deal_ring_zero(net, gmask); + if constexpr (Reveal) + dist::deal_ring_zero(net, gmask); + if constexpr (Reveal) + return std::nullopt; + else + return {}; + } + + const input_type mine = self == role::p0 ? r0 : r1; + + std::uint64_t delta = 0; + std::uint64_t fval = 0; + if constexpr (!is_wildcard_v) + { + delta = detail::dcf_impl::beta_delta_u64( + spec.if_true, spec.if_false, gmask); + fval = detail::dcf_impl::beta_to_u64_simple( + spec.if_false, gmask); + } + + if constexpr (Reveal) + { + const role peer = self == role::p0 ? role::p1 : role::p0; + const input_type theirs = + net.exchange_with(peer, mine, net::msg::delta); + const input_type r = utils::xor_input_shares(mine, theirs); + const std::uint64_t r_bits = detail::ic_impl::bits_of(r); + input_type gamma = detail::ic_impl::gamma_of(r); + utils::flip_msb_if_signed_integral(gamma); + const std::uint64_t cr = detail::ic_impl::correction( + r_bits, spec.lo, spec.hi, nmask, gmask); + const std::uint64_t absorb = + (detail::ic_impl::mul_mask(delta, cr, gmask) + fval) & gmask; + + const auto recv_side_shares = [&]() { + const auto z0 = + net.recv_from(role::p2, net::msg::beaver_tape); + const auto z1 = + net.recv_from(role::p2, net::msg::beaver_tape); + const std::uint64_t side = self == role::p1 ? 1ULL : 0ULL; + const std::uint64_t dshare = is_wildcard_v + ? 0ULL : (z0.share + side * delta) & gmask; + const std::uint64_t cshare = is_wildcard_v + ? 0ULL : (z1.share + side * absorb) & gmask; + const std::uint64_t dcoeff = is_wildcard_v + ? (z0.share + side) & gmask : 0ULL; + const std::uint64_t ccoeff = is_wildcard_v + ? (z1.share + side * cr) & gmask : 0ULL; + return std::array{ + dshare, cshare, dcoeff, ccoeff}; + }; + + if (self == role::p0) + { + auto inner = dist::comparison_party(net, gamma, inner_spec); + const auto shares = recv_side_shares(); + using raw_key = typename decltype(inner)::key_type; + auto key = detail::ic_impl::make_side<0, raw_key, input_type, + out_beta>(std::move(inner), spec.lo, spec.hi, nmask, gmask, + shares[0], shares[1], shares[2], shares[3]); + on0(std::move(key)); + } + else + { + auto inner = dist::comparison_party(net, gamma, inner_spec); + const auto shares = recv_side_shares(); + using raw_key = typename decltype(inner)::key_type; + auto key = detail::ic_impl::make_side<1, raw_key, input_type, + out_beta>(std::move(inner), spec.lo, spec.hi, nmask, gmask, + shares[0], shares[1], shares[2], shares[3]); + on1(std::move(key)); + } + return r; + } + else + { + input_type gamma_share{}; + std::uint64_t cr_share = 0; + if (self == role::p0) + { + auto got = dist::ic_gamma_and_correction<0, input_type>(net, + mine, spec.lo, spec.hi, nmask, gmask); + gamma_share = got.first; + cr_share = got.second; + } + else + { + auto got = dist::ic_gamma_and_correction<1, input_type>(net, + mine, spec.lo, spec.hi, nmask, gmask); + gamma_share = got.first; + cr_share = got.second; + } + + const std::uint64_t absorb_share = is_wildcard_v + ? 0ULL + : (detail::ic_impl::mul_mask(delta, cr_share, gmask) + + (self == role::p1 ? fval : 0ULL)) & gmask; + const std::uint64_t cr_coeff_share = + is_wildcard_v ? cr_share : 0ULL; + + const auto recv_delta = [&]() { + const auto z0 = + net.recv_from(role::p2, net::msg::beaver_tape); + const std::uint64_t side = self == role::p1 ? 1ULL : 0ULL; + const std::uint64_t dshare = is_wildcard_v + ? 0ULL : (z0.share + side * delta) & gmask; + const std::uint64_t dcoeff = is_wildcard_v + ? (z0.share + side) & gmask : 0ULL; + return std::array{dshare, dcoeff}; + }; + + if (self == role::p0) + { + auto inner = dist::comparison_party(net, gamma_share, inner_spec); + const auto d = recv_delta(); + using raw_key = typename decltype(inner)::key_type; + auto key = detail::ic_impl::make_side<0, raw_key, input_type, + out_beta>(std::move(inner), spec.lo, spec.hi, nmask, gmask, + d[0], absorb_share, d[1], cr_coeff_share); + on0(std::move(key)); + } + else + { + auto inner = dist::comparison_party(net, gamma_share, inner_spec); + const auto d = recv_delta(); + using raw_key = typename decltype(inner)::key_type; + auto key = detail::ic_impl::make_side<1, raw_key, input_type, + out_beta>(std::move(inner), spec.lo, spec.hi, nmask, gmask, + d[0], absorb_share, d[1], cr_coeff_share); + on1(std::move(key)); + } + return {}; + } + } +} + +/// @brief Encoded XOR point the comparison walk reconstructs (MSB flipped on share 0). +template +HEDLEY_WARN_UNUSED_RESULT +T encoded_xor_point(T x0, T x1) +{ + utils::flip_msb_if_signed_integral(x0); + return utils::xor_input_shares(x0, x1); +} + +/// @brief Tree prefix a verifiable point walk reconstructs: `encoded >> lg`. +template +HEDLEY_WARN_UNUSED_RESULT +T verifiable_tree_prefix(T x0, T x1, bool already_encoded = false) +{ + using dpf_type = utils::dpf_type_t; + constexpr auto lg = dpf_type::lg_outputs_per_leaf; + T encoded = already_encoded ? x0 : encoded_xor_point(x0, x1); + if constexpr (lg == 0) + return encoded; + constexpr auto to_int = utils::to_integral_type{}; + using U = std::make_unsigned_t()))>>; + using FromI = typename utils::make_from_integral_value::integral_type; + const U bits = static_cast(to_int(encoded)) >> lg; + return utils::make_from_integral_value{}(static_cast(bits)); +} + +/// @brief p2 reconstructed nothing. p0 and p1 reconstructed `expected`. +template +void require_opened(const std::optional & got, role self, Point expected, + const char * what = "reconstructed point") +{ + if (self == role::p2) + { + if (got.has_value()) + throw std::runtime_error(what); + return; + } + if (!got.has_value() || !(*got == expected)) + throw std::runtime_error(what); +} + +/// @brief Check a verifiable point-keygen's returned prefix and optional lane. +template +void require_tree_prefix(const std::optional> & got, + role self, Point expected_prefix, + std::optional expected_lane = std::nullopt, + const char * what = "tree prefix") +{ + if (self == role::p2) + { + if (got.has_value()) + throw std::runtime_error(what); + return; + } + if (!got.has_value() || !(got->opened_prefix == expected_prefix) + || got->opened_lane != expected_lane) + throw std::runtime_error(what); +} + +/// @brief Low `lg` bits of an encoded point (the packed lane). +template +HEDLEY_WARN_UNUSED_RESULT +unsigned verifiable_lane(T encoded) +{ + using dpf_type = utils::dpf_type_t; + constexpr auto lg = dpf_type::lg_outputs_per_leaf; + if constexpr (lg == 0) + return 0; + constexpr auto to_int = utils::to_integral_type{}; + using U = std::make_unsigned_t()))>>; + return static_cast(static_cast(to_int(encoded)) + & ((U{1} << lg) - 1)); +} + +/// @brief (2+1) dealer-side grow: p2 builds `at<1>` then `extend_ds` to `at<2>` +/// and sends each party its key. Exercises library DS grow over the trio. +template +void dist_with_grow_extend(trio & net, role self, InputT alpha, OutputT beta_new, + Fn0 && on0, Fn1 && on1) +{ + using short_keys = + decltype(dpf::make_dpf(alpha, dpf::at<1>(std::uint64_t{1}))); + using grown_keys = decltype(dpf::extend( + std::declval(), + std::declval(), alpha, + dpf::at<2>(beta_new))); + using grown0 = typename grown_keys::first_type; + using grown1 = typename grown_keys::second_type; + + if (self == role::p2) + { + auto [a0, a1] = dpf::make_dpf(alpha, dpf::at<1>(std::uint64_t{1})); + auto m0 = dpf::make_basic_path_memoizer(a0); + auto m1 = dpf::make_basic_path_memoizer(a1); + (void)dpf::eval_point(dpf::out<0>, a0, alpha, m0); + (void)dpf::eval_point(dpf::out<0>, a1, alpha, m1); + struct pad_t + { + simde__m128i block() { return dpf::uniform_sample(); } + std::uint8_t bit() + { + return static_cast( + dpf::uniform_sample() & 1u); + } + } pads{}; + dpf::local_cw_protocol proto{pads}; + auto [n0, n1] = dpf::extend_ds(a0, a1, m0, m1, alpha, InputT{}, proto, + dpf::at<2>(beta_new)); + send_key(net, role::p0, n0); + send_key(net, role::p1, n1); + return; + } + if (self == role::p0) + std::forward(on0)(recv_key(net, role::p2)); + else + std::forward(on1)(recv_key(net, role::p2)); +} + +/// @brief Two-party grow without p2: p0 runs joint `extend_ds` and delivers p1's key. +template +void dist_with_grow_extend_iknp(trio & net, role self, InputT alpha, + OutputT beta_new, Fn0 && on0, Fn1 && on1) +{ + if (self == role::p2) + throw std::invalid_argument("iknp grow has no dealer"); + using short_keys = + decltype(dpf::make_dpf(alpha, dpf::at<1>(std::uint64_t{1}))); + using grown_keys = decltype(dpf::extend( + std::declval(), + std::declval(), alpha, + dpf::at<2>(beta_new))); + using grown0 = typename grown_keys::first_type; + using grown1 = typename grown_keys::second_type; + + if (self == role::p0) + { + auto [a0, a1] = dpf::make_dpf(alpha, dpf::at<1>(std::uint64_t{1})); + auto m0 = dpf::make_basic_path_memoizer(a0); + auto m1 = dpf::make_basic_path_memoizer(a1); + (void)dpf::eval_point(dpf::out<0>, a0, alpha, m0); + (void)dpf::eval_point(dpf::out<0>, a1, alpha, m1); + struct pad_t + { + simde__m128i block() { return dpf::uniform_sample(); } + std::uint8_t bit() + { + return static_cast( + dpf::uniform_sample() & 1u); + } + } pads{}; + dpf::local_cw_protocol proto{pads}; + auto [n0, n1] = dpf::extend_ds(a0, a1, m0, m1, alpha, InputT{}, proto, + dpf::at<2>(beta_new)); + send_key(net, role::p1, n1); + std::forward(on0)(std::move(n0)); + } + else + { + std::forward(on1)(recv_key(net, role::p0)); + } +} + +} // namespace party +} // namespace dpf + +#endif // LIBDPF_PARTY_DIST_DS_HPP__ diff --git a/party/flow_util.hpp b/party/flow_util.hpp new file mode 100644 index 0000000..fddd84c --- /dev/null +++ b/party/flow_util.hpp @@ -0,0 +1,810 @@ +/// @file party/flow_util.hpp +/// @brief Shared helpers for (2+1) party flow bodies. +#ifndef LIBDPF_PARTY_FLOW_UTIL_HPP__ +#define LIBDPF_PARTY_FLOW_UTIL_HPP__ + +#include +#include +#include +#include + +#include "dpf/beaver.hpp" +#include "dpf/compose.hpp" +#include "dpf/net/mux_sink.hpp" // trio::batch default +#include "dpf/net/party_tape_io.hpp" +#include "dpf/net/round_sink.hpp" +#include "dpf/net/trio.hpp" +#include "dpf/secret_share.hpp" +#include "dpf/verifiable.hpp" + +#include +#include +#include +#include +#include +#include + +namespace dpf +{ +namespace party +{ +namespace util +{ + +using net::role; +using net::trio; +using u64 = std::uint64_t; + +struct Counter +{ + int draws = 0; + u64 operator()() + { + ++draws; + return 0x9e3779b97f4a7c15ull * static_cast(draws); + } +}; + +inline void require(bool cond, const char * msg) +{ + if (!cond) + throw std::runtime_error(msg); +} + +inline std::pair split_u64(u64 secret, unsigned tag = 1) +{ + u64 p0 = 0x9e3779b97f4a7c15ull * (tag + 1u); + return {p0, secret - p0}; +} + +template +std::pair split_ring(Ring secret, unsigned tag = 1) +{ + using traits = beavers::ring_traits; + Ring p0 = Ring{static_cast(0x9e3779b97f4a7c15ull * (tag + 1u))}; + return {p0, traits::sub(secret, p0)}; +} + +template +Ring open_additive(trio & net, role self, Ring mine) +{ + role peer = self == role::p0 ? role::p1 : role::p0; + return net.open_with(peer, mine); +} + +/// @brief Open many independent additive shares in one vector exchange. +template +std::vector open_additive(trio & net, role self, const std::vector & mine) +{ + role peer = self == role::p0 ? role::p1 : role::p0; + return net.open_vec_with(peer, mine); +} + +template +T open_subtractive(trio & net, role self, T mine) +{ + role peer = self == role::p0 ? role::p1 : role::p0; + T theirs = net.exchange_with(peer, mine); + return self == role::p0 ? static_cast(mine - theirs) + : static_cast(theirs - mine); +} + +/// @brief Open many independent subtractive shares in one vector exchange. +template +std::vector open_subtractive(trio & net, role self, const std::vector & mine) +{ + role peer = self == role::p0 ? role::p1 : role::p0; + auto theirs = net.exchange_vec_with(peer, mine); + require(theirs.size() == mine.size(), "open_subtractive vec size"); + std::vector out(mine.size()); + for (std::size_t i = 0; i < mine.size(); ++i) + { + out[i] = self == role::p0 ? static_cast(mine[i] - theirs[i]) + : static_cast(theirs[i] - mine[i]); + } + return out; +} + +template +constexpr T share_bits(T s) noexcept +{ + return s; +} + +template +constexpr T share_bits(const secret_share & s) noexcept +{ + return s.raw(); +} + +inline void install_and_bind_u64(beavers::session & s, trio & net, role self, + const std::vector::wire> & inputs, + const std::vector & secrets) +{ + auto tape = net::accept_session(net); + s.install_party(self == role::p0 ? 0u : 1u, tape); + for (std::size_t i = 0; i < inputs.size(); ++i) + { + auto [p0, p1] = split_u64(secrets[i], static_cast(i + 1)); + s.bind_party(inputs[i], self == role::p0 ? p0 : p1); + } +} + +template +void install_and_bind(beavers::session & s, trio & net, role self, + const std::vector::wire> & inputs, + const std::vector & secrets) +{ + auto tape = net::accept_session(net); + s.install_party(self == role::p0 ? 0u : 1u, tape); + for (std::size_t i = 0; i < inputs.size(); ++i) + { + auto [p0, p1] = split_ring(secrets[i], static_cast(i + 1)); + s.bind_party(inputs[i], self == role::p0 ? p0 : p1); + } +} + +/// @brief Host `evaluate_party_batch` on a RoundSink (one instance). +/// @details Each vector exchange is one schedule round. The sink must have been +/// sized with enough rounds and `slot_bytes >= 4 + n * sizeof(Ring)` +/// for the largest batch this session will open. `index` selects the +/// instance lane when the sink holds many circuits; all parties must +/// drive the same `index` sequence. Prefer `count == 1` sinks. +template +void evaluate_online_on_sink(beavers::session & s, net::RoundSink & sink, + std::size_t index = 0) +{ + std::uint16_t flush_round = 0; + s.evaluate_party_batch([&](std::vector mine) { + if (flush_round >= sink.rounds()) + throw std::runtime_error("evaluate_online_on_sink: out of rounds"); + const std::size_t slot = sink.slot_bytes(flush_round); + const std::size_t need = sizeof(std::uint32_t) + mine.size() * sizeof(Ring); + if (need > slot) + throw std::runtime_error("evaluate_online_on_sink: slot too small"); + std::vector buf(slot, 0); + const std::uint32_t n = static_cast(mine.size()); + std::memcpy(buf.data(), &n, 4); + if (!mine.empty()) + std::memcpy(buf.data() + 4, mine.data(), mine.size() * sizeof(Ring)); + sink.submit(flush_round, index, buf.data(), buf.size()); + sink.flush_round(flush_round); + sink.poll(); + if (!sink.peer_ready(flush_round, index)) + throw std::runtime_error("evaluate_online_on_sink: peer missing"); + std::vector peer_buf(slot); + sink.read_peer(flush_round, index, peer_buf.data(), slot); + std::uint32_t pn = 0; + std::memcpy(&pn, peer_buf.data(), 4); + if (pn != n) + throw std::runtime_error("evaluate_online_on_sink: peer size"); + std::vector peer(n); + if (n != 0) + std::memcpy(peer.data(), peer_buf.data() + 4, n * sizeof(Ring)); + ++flush_round; + return peer; + }); +} + +/// @brief Sink round budget for `evaluate_party_batch` / auth-batch. +/// @details One input flush and one output flush per ready-round, plus a small +/// slack for same-round dependency flushes. Must not grow with +/// `wire_count`: a 2k-wire depth-1 circuit still needs only a handful +/// of vector exchanges, and allocating O(wires) round windows is a +/// multi-megabyte tax on every online evaluate. +inline int beaver_batch_round_budget(int max_ready_round, + std::size_t /*wire_count*/) noexcept +{ + return std::max(1, max_ready_round * 2 + 16); +} + +/// @brief Online beaver opens hosted on a count-1 batch sink from `trio::batch`. +template +void evaluate_online(beavers::session & s, trio & net, role self) +{ + (void)self; + const int rounds = + beaver_batch_round_budget(s.max_ready_round(), s.wire_count()); + // Upper bound: every wire δ in one vector exchange, plus length prefix. + const std::size_t slot = + sizeof(std::uint32_t) + s.wire_count() * sizeof(Ring); + std::vector slots(static_cast(rounds), slot); + auto sink = net.batch(1, std::move(slots)); + evaluate_online_on_sink(s, *sink, 0); +} + +/// @brief Drive many independent circuits on one RoundSink (one index each). +/// @details Each circuit runs to completion on its lane. Callers that need a +/// single prefix flush across instances must submit lockstep themselves +/// via `schedule_session`; this helper is the portable multi-lane host +/// of `evaluate_party_batch` on an existing sink. +template +void evaluate_online_multi_on_sink( + std::vector *> sessions, net::RoundSink & sink) +{ + if (sessions.size() != sink.count()) + throw std::invalid_argument("evaluate_online_multi_on_sink: count"); + for (std::size_t i = 0; i < sessions.size(); ++i) + { + if (!sessions[i]) + throw std::invalid_argument("evaluate_online_multi_on_sink: null"); + evaluate_online_on_sink(*sessions[i], sink, i); + } +} + +/// @brief Authenticated `evaluate_party_auth_batch` on a RoundSink. +template +void evaluate_online_auth_on_sink(beavers::session & s, + net::RoundSink & sink, std::size_t index = 0) +{ + using opening = beavers::auth_opening; + std::uint16_t flush_round = 0; + s.evaluate_party_auth_batch([&](std::vector mine) { + if (flush_round >= sink.rounds()) + throw std::runtime_error("evaluate_online_auth_on_sink: out of rounds"); + const std::size_t slot = sink.slot_bytes(flush_round); + const std::size_t need = + sizeof(std::uint32_t) + mine.size() * sizeof(opening); + if (need > slot) + throw std::runtime_error("evaluate_online_auth_on_sink: slot too small"); + std::vector buf(slot, 0); + const std::uint32_t n = static_cast(mine.size()); + std::memcpy(buf.data(), &n, 4); + if (!mine.empty()) + std::memcpy(buf.data() + 4, mine.data(), mine.size() * sizeof(opening)); + sink.submit(flush_round, index, buf.data(), buf.size()); + sink.flush_round(flush_round); + sink.poll(); + if (!sink.peer_ready(flush_round, index)) + throw std::runtime_error("evaluate_online_auth_on_sink: peer missing"); + std::vector peer_buf(slot); + sink.read_peer(flush_round, index, peer_buf.data(), slot); + std::uint32_t pn = 0; + std::memcpy(&pn, peer_buf.data(), 4); + if (pn != n) + throw std::runtime_error("evaluate_online_auth_on_sink: peer size"); + std::vector peer(n); + if (n != 0) + std::memcpy(peer.data(), peer_buf.data() + 4, n * sizeof(opening)); + ++flush_round; + return peer; + }); +} + +/// @brief Authenticated opening path when the session tape carries IT-MACs. +/// @details Call only after the dealer ran `set_mac_key` and `deal_session`. +/// Uses `trio::batch` so a installed `comm_hook` can replace the sink. +template +void evaluate_online_auth(beavers::session & s, trio & net, role self) +{ + (void)self; + using opening = beavers::auth_opening; + const int rounds = + beaver_batch_round_budget(s.max_ready_round(), s.wire_count()); + const std::size_t slot = + sizeof(std::uint32_t) + s.wire_count() * sizeof(opening); + std::vector slots(static_cast(rounds), slot); + auto sink = net.batch(1, std::move(slots)); + evaluate_online_auth_on_sink(s, *sink, 0); +} + +/// @brief u64 beaver δ host using `party_batch_stepper` (one per ABY session). +struct u64_beaver_host final : protocol::beaver_host +{ + explicit u64_beaver_host( + std::vector *> sessions) + { + steppers_.reserve(sessions.size()); + for (auto * s : sessions) + { + if (s == nullptr) + steppers_.push_back(nullptr); + else + steppers_.push_back( + std::make_unique>( + *s)); + } + } + + void pack(std::size_t session_index, std::size_t /*barrier_index*/, + std::uint8_t * dst, std::size_t n) override + { + if (session_index >= steppers_.size() || !steppers_[session_index]) + throw std::runtime_error("u64_beaver_host: missing session"); + auto mine = steppers_[session_index]->take_local(); + const std::uint32_t count = static_cast(mine.size()); + const std::size_t need = + sizeof(std::uint32_t) + mine.size() * sizeof(std::uint64_t); + if (n < need) + throw std::runtime_error("u64_beaver_host: slot too small"); + std::memset(dst, 0, n); + std::memcpy(dst, &count, sizeof(count)); + if (!mine.empty()) + std::memcpy(dst + sizeof(count), mine.data(), + mine.size() * sizeof(std::uint64_t)); + } + + void apply(std::size_t session_index, std::size_t /*barrier_index*/, + const std::uint8_t * src, std::size_t n) override + { + if (session_index >= steppers_.size() || !steppers_[session_index]) + throw std::runtime_error("u64_beaver_host: missing session"); + if (n < sizeof(std::uint32_t)) + throw std::runtime_error("u64_beaver_host: peer short"); + std::uint32_t count = 0; + std::memcpy(&count, src, sizeof(count)); + const std::size_t need = + sizeof(std::uint32_t) + static_cast(count) + * sizeof(std::uint64_t); + if (n < need) + throw std::runtime_error("u64_beaver_host: peer size"); + std::vector peer(count); + if (count != 0) + std::memcpy(peer.data(), src + sizeof(count), + peer.size() * sizeof(std::uint64_t)); + steppers_[session_index]->apply_peer(peer); + } + +private: + std::vector>> + steppers_; +}; + +/// @brief IT-MAC δ host: `uint32 n ‖ auth_opening[n]`. +/// @details `apply` checks each tag via `party_auth_batch_stepper`. +template +struct auth_beaver_host final : protocol::beaver_host +{ + using opening = beavers::auth_opening; + + explicit auth_beaver_host(std::vector *> sessions) + { + static_assert(std::is_trivially_copyable_v, + "auth_opening must be trivially copyable"); + steppers_.reserve(sessions.size()); + for (auto * s : sessions) + { + if (s == nullptr) + steppers_.push_back(nullptr); + else + steppers_.push_back( + std::make_unique>(*s)); + } + } + + void pack(std::size_t session_index, std::size_t, std::uint8_t * dst, + std::size_t n) override + { + if (session_index >= steppers_.size() || !steppers_[session_index]) + throw std::runtime_error("auth_beaver_host: missing session"); + auto mine = steppers_[session_index]->take_local(); + const std::uint32_t count = static_cast(mine.size()); + const std::size_t need = sizeof(std::uint32_t) + mine.size() * sizeof(opening); + if (n < need) + throw std::runtime_error("auth_beaver_host: slot too small"); + std::memset(dst, 0, n); + std::memcpy(dst, &count, sizeof(count)); + if (!mine.empty()) + std::memcpy(dst + sizeof(count), mine.data(), + mine.size() * sizeof(opening)); + } + + void apply(std::size_t session_index, std::size_t, const std::uint8_t * src, + std::size_t n) override + { + if (session_index >= steppers_.size() || !steppers_[session_index]) + throw std::runtime_error("auth_beaver_host: missing session"); + if (n < sizeof(std::uint32_t)) + throw std::runtime_error("auth_beaver_host: peer short"); + std::uint32_t count = 0; + std::memcpy(&count, src, sizeof(count)); + const std::size_t need = + sizeof(std::uint32_t) + static_cast(count) * sizeof(opening); + if (n < need) + throw std::runtime_error("auth_beaver_host: peer size"); + std::vector peer(count); + if (count != 0) + std::memcpy(peer.data(), src + sizeof(count), + peer.size() * sizeof(opening)); + steppers_[session_index]->apply_peer(peer); + } + +private: + std::vector>> steppers_; +}; + +using u64_auth_beaver_host = auth_beaver_host; + +/// @brief Schedule a composer and drive it on a trio batch sink. +/// @details Uses `default_plan()`: RoundSink rounds == `plan::rounds()` == +/// exchange-bearing waves. Pass `opt.from_exchange_wave` / +/// `compact_sink` for adaptive tails; `opt.beavers` for live δ. +inline void drive_composed(protocol::composer & c, trio & net, + std::vector> & values, + const std::map & kernels, + std::size_t count = 1, protocol::drive_options opt = {}) +{ + auto p = c.default_plan(); + auto slots = opt.compact_sink ? p.slot_bytes_from(opt.from_exchange_wave) + : p.slot_bytes_all(); + if (slots.empty()) + slots.push_back(0); + auto sink = net.batch(count, std::move(slots)); + protocol::drive(p, *sink, values, kernels, c.party(), opt); +} + +/// @brief Drive a compose plan on the trio mesh (2PC peer + 3PC RSS neighbor). +/// @details Shared semantics with `protocol::drive`: throws on missing kernels, +/// domain-correct opens, optional beaver host, incremental +/// `from_exchange_wave`. Per-exchange peer maps: `y` → neighbor ring, +/// else p0↔p1 (p2 idle). +inline void drive_composed_trio(protocol::composer & c, trio & net, role self, + std::vector> & values, + const std::map & kernels, + protocol::drive_options opt = {}) +{ + using protocol::domain; + using protocol::effect; + namespace opcodes = protocol::opcodes; + auto p = c.default_plan(); + if (values.size() < p.nodes().size()) + values.resize(p.nodes().size()); + auto ensure = [&](std::uint32_t id) { + const std::size_t need = p.value_bytes_of(id); + if (values[id].size() < need) + values[id].assign(need, 0); + }; + for (std::uint32_t id = 0; id < p.nodes().size(); ++id) + ensure(id); + + const role peer = self == role::p0 ? role::p1 : role::p0; + const role rss_next = + static_cast((static_cast(self) + 1u) % 3u); + + auto run_groups = [&](const protocol::wave_info & wave) { + for (const auto & g : wave.groups) + { + if (g.kind == effect::convert) + { + for (auto n : g.nodes) + { + ensure(n.id); + const auto & ins = p.inputs_of(n.id); + if (ins.empty()) + continue; + if (p.alias_of(n.id) && ins.size() == 1 + && p.value_bytes_of(n.id) == p.value_bytes_of(ins[0])) + { + values[n.id] = values[ins[0]]; + continue; + } + if (ins.size() == 1) + { + protocol::detail::run_builtin_convert(g.opcode, + c.party(), values[ins[0]].data(), + p.value_bytes_of(ins[0]), values[n.id].data(), + p.value_bytes_of(n.id)); + } + else if (ins.size() == 2 + && g.opcode == opcodes::conv_y2rss) + { + const auto half = p.value_bytes_of(ins[0]); + std::memcpy(values[n.id].data(), + values[ins[0]].data(), half); + std::memcpy(values[n.id].data() + half, + values[ins[1]].data(), half); + } + } + continue; + } + if (protocol::detail::is_beaver_opcode(g.opcode)) + continue; + if (g.opcode == opcodes::fss_fuse_segment) + { + for (auto n : g.nodes) + { + ensure(n.id); + const auto & ins = p.inputs_of(n.id); + if (!ins.empty()) + ensure(ins[0]); + protocol::detail::apply_fuse_segment(p, values, n.id, 1); + } + continue; + } + auto kit = kernels.find(g.opcode); + protocol::kernel_fn builtin; + const protocol::kernel_fn * fn = nullptr; + if (kit != kernels.end()) + fn = &kit->second; + else if (protocol::detail::has_builtin_walk_kernel(g.opcode)) + { + builtin = protocol::detail::builtin_walk_kernel(g.opcode); + fn = &builtin; + } + else if (g.kind == effect::blind) + { + for (auto n : g.nodes) + { + ensure(n.id); + std::fill(values[n.id].begin(), values[n.id].end(), 0); + } + continue; + } + else + { + throw std::runtime_error( + "drive_composed_trio missing kernel for opcode " + + std::to_string(g.opcode)); + } + for (auto n : g.nodes) + { + ensure(n.id); + std::vector ins; + for (auto in_id : p.inputs_of(n.id)) + { + ensure(in_id); + ins.push_back(protocol::block_span{values[in_id].data(), 1, + p.value_bytes_of(in_id)}); + } + protocol::block_span out{values[n.id].data(), 1, + p.value_bytes_of(n.id)}; + (*fn)(g.opcode, {n}, ins, out, 1); + } + } + }; + + std::size_t exchange_i = 0; + for (std::size_t w = 0; w < p.waves(); ++w) + { + const auto & wave = p.wave(w); + const bool skip = !wave.exchanges.empty() + && exchange_i < opt.from_exchange_wave; + if (!skip) + run_groups(wave); + if (wave.exchanges.empty() || wave.slot_bytes == 0) + continue; + if (exchange_i < opt.from_exchange_wave) + { + ++exchange_i; + continue; + } + ++exchange_i; + + // Split peer maps: y → RSS neighbor; dealer_pad → p2; else → 2PC peer. + std::vector two_pc; + std::vector rss; + std::vector dealer; + struct zero_mask { std::size_t n = 0; domain dom = domain::a; }; + std::vector zeros; + std::vector kinds; // 0 = 2pc, 1 = rss, 2 = dealer, 3 = zero + kinds.reserve(wave.exchanges.size()); + for (auto ex : wave.exchanges) + { + ensure(ex.id); + const auto nb = p.value_bytes_of(ex.id); + const auto op = p.opcode_of(ex.id); + const bool neighbor = protocol::detail::is_rss_neighbor_open(p, ex.id); + const bool from_dealer = op == opcodes::dealer_pad; + const bool zero = op == opcodes::dealer_zero; + kinds.push_back(zero ? 3 : (from_dealer ? 2 : (neighbor ? 1 : 0))); + if (zero) + zeros.push_back(zero_mask{nb, p.domain_of(ex.id)}); + std::vector chunk(nb, 0); + if (protocol::detail::is_beaver_opcode(op) && opt.beavers != nullptr) + { + const auto sess = static_cast(p.level_of(ex.id)); + const auto bi = + static_cast(op - opcodes::beaver_delta); + opt.beavers->pack(sess, bi, chunk.data(), nb); + std::memcpy(values[ex.id].data(), chunk.data(), nb); + } + else + { + const auto & ins = p.inputs_of(ex.id); + if (!ins.empty() && !protocol::detail::is_beaver_opcode(op)) + { + const auto src = ins[0]; + ensure(src); + const auto sb = p.value_bytes_of(src); + std::memcpy(chunk.data(), values[src].data(), + std::min(sb, nb)); + std::memcpy(values[ex.id].data(), values[src].data(), + std::min(sb, nb)); + } + else + std::memcpy(chunk.data(), values[ex.id].data(), nb); + } + if (from_dealer) + dealer.insert(dealer.end(), chunk.begin(), chunk.end()); + else if (zero) + continue; + else if (neighbor) + rss.insert(rss.end(), chunk.begin(), chunk.end()); + else + two_pc.insert(two_pc.end(), chunk.begin(), chunk.end()); + } + + std::vector two_pc_peer; + std::vector rss_peer; + std::vector dealer_peer; + std::vector> zero_recv(zeros.size()); + if (!rss.empty()) + rss_peer = net.exchange_vec_with(rss_next, rss); + if (!two_pc.empty()) + { + if (self == role::p2) + { + // Dealer idle on 2PC opens — leave peer zeros; reconstruct + // will not run for p2 on those slots. + two_pc_peer.assign(two_pc.size(), 0); + } + else + two_pc_peer = net.exchange_vec_with(peer, two_pc); + } + if (!dealer.empty()) + { + if (self == role::p2) + { + net.send_bytes_to(role::p0, net::msg::bytes, dealer.data(), + dealer.size()); + net.send_bytes_to(role::p1, net::msg::bytes, dealer.data(), + dealer.size()); + dealer_peer = dealer; + } + else + dealer_peer = net.recv_bytes_from(role::p2, net::msg::bytes); + } + if (!zeros.empty()) + { + if (self == role::p2) + { + for (std::size_t zi = 0; zi < zeros.size(); ++zi) + { + std::vector a(zeros[zi].n), b(zeros[zi].n); + for (auto & byte : a) + byte = dpf::uniform_sample(); + if (zeros[zi].dom == domain::b) + b = a; + else if (zeros[zi].n % 8 == 0) + { + for (std::size_t i = 0; i < a.size(); i += 8) + { + std::uint64_t w = 0; + std::memcpy(&w, a.data() + i, 8); + w = static_cast(0) - w; + std::memcpy(b.data() + i, &w, 8); + } + } + else + { + for (std::size_t i = 0; i < a.size(); ++i) + b[i] = a[i]; + } + net.send_bytes_to(role::p0, net::msg::bytes, a.data(), a.size()); + net.send_bytes_to(role::p1, net::msg::bytes, b.data(), b.size()); + } + } + else + { + for (std::size_t zi = 0; zi < zeros.size(); ++zi) + zero_recv[zi] = net.recv_bytes_from(role::p2, net::msg::bytes); + } + } + + std::size_t off2 = 0, offr = 0, offd = 0, zi = 0; + for (std::size_t i = 0; i < wave.exchanges.size(); ++i) + { + auto ex = wave.exchanges[i]; + const auto nb = p.value_bytes_of(ex.id); + ensure(ex.id); + const auto op = p.opcode_of(ex.id); + const bool neighbor = kinds[i] == 1; + const bool from_dealer = kinds[i] == 2; + if (kinds[i] == 3) + { + if (self != role::p2) + { + if (zi >= zero_recv.size() || zero_recv[zi].size() < nb) + throw std::runtime_error("drive_composed_trio: zero mask"); + std::memcpy(values[ex.id].data(), zero_recv[zi].data(), nb); + } + ++zi; + continue; + } + if (from_dealer) + { + if (dealer_peer.size() < offd + nb) + throw std::runtime_error("drive_composed_trio: dealer size"); + std::memcpy(values[ex.id].data(), dealer_peer.data() + offd, nb); + offd += nb; + continue; + } + const std::uint8_t * peer_bytes = + neighbor ? rss_peer.data() + offr : two_pc_peer.data() + off2; + if (neighbor) + offr += nb; + else + off2 += nb; + + if (self == role::p2 && !neighbor) + continue; + + if (protocol::detail::is_beaver_opcode(op) && opt.beavers != nullptr) + { + const auto sess = static_cast(p.level_of(ex.id)); + const auto bi = + static_cast(op - opcodes::beaver_delta); + opt.beavers->apply(sess, bi, peer_bytes, nb); + } + + domain d = p.domain_of(ex.id); + const auto & ins = p.inputs_of(ex.id); + if (!ins.empty()) + d = p.domain_of(ins[0]); + if (neighbor) + { + std::memcpy(values[ex.id].data(), peer_bytes, nb); + } + else + { + std::vector mine(nb, 0); + if (!ins.empty() && !protocol::detail::is_beaver_opcode(op)) + { + const auto sb = p.value_bytes_of(ins[0]); + std::memcpy(mine.data(), values[ins[0]].data(), + std::min(sb, nb)); + } + else + std::memcpy(mine.data(), values[ex.id].data(), nb); + protocol::detail::reconstruct_open(d, c.party(), mine.data(), + peer_bytes, nb, values[ex.id].data(), opt.field); + } + } + } +} + +/// @brief Schedule a fused Express/Sabre point+audit walk on a composer. +/// @details Prefer this over `open_and_sketch` when the sketch can ride in the +/// last CW flush — one fewer exchange-bearing wave. +inline protocol::composer::walk_result schedule_fused_audit( + protocol::composer & c, protocol::node seed, std::size_t depth, + std::size_t slot_bytes, protocol::node sketch) +{ + return c.fss_point_fused(seed, depth, slot_bytes, sketch); +} + +/// @brief Fold opened outputs into a sketch and exchange for `sketch_verify`. +/// @details Used only by extractable party flows. Prefer Express/Sabre +/// `schedule_fused_audit` / `fss_point_fused` so the sketch rides in +/// the last CW flush instead of adding a round. Non-extractable keys +/// leave `note_sketch` as a no-op; callers still exchange empty shares. +template +bool open_and_sketch(trio & net, role self, sketch_share & local, + YRange && ys, RRange && rs) +{ + note_sketch(local, std::forward(ys), std::forward(rs)); + role peer = self == role::p0 ? role::p1 : role::p0; + sketch_share theirs = net.exchange_with(peer, local, net::msg::sketch_share); + if (self == role::p0) + return sketch_verify(local, theirs); + return sketch_verify(theirs, local); +} + +/// @brief Keep parties aligned across `--repeat` iterations. +inline void sync_round(trio & net, role self, std::uint64_t round) +{ + if (self == role::p2) + { + net.to(role::p0).send(net::msg::case_ok, round); + net.to(role::p1).send(net::msg::case_ok, round); + return; + } + auto got = net.to(role::p2).recv(net::msg::case_ok); + require(got == round, "repeat sync"); +} + +} // namespace util +} // namespace party +} // namespace dpf + +#endif // LIBDPF_PARTY_FLOW_UTIL_HPP__ diff --git a/party/flows_bulk.cpp b/party/flows_bulk.cpp new file mode 100644 index 0000000..62c0a65 --- /dev/null +++ b/party/flows_bulk.cpp @@ -0,0 +1,465 @@ +/// @file party/flows_bulk.cpp +/// @brief Parametric beaver / DCF / Horner flows for coverage and benchmarks. + +#include "cases.hpp" +#include "flow_util.hpp" +#include "key_io.hpp" +#include "registry.hpp" + +#include +#include +#include + +#include "simde/simde/x86/avx2.h" + +#include "dpf/beaver.hpp" +#include "dpf/dcf.hpp" +#include "dpf/dpf_key.hpp" +#include "dpf/eval_point.hpp" +#include "dpf/eval_unified.hpp" +#include "dpf/incremental.hpp" +#include "dpf/prg_aes.hpp" + +#include + +namespace dpf +{ +namespace party +{ +namespace bulk +{ + +using util::Counter; +using util::evaluate_online; +using util::install_and_bind_u64; +using util::open_additive; +using util::require; +using util::role; +using util::share_bits; +using util::trio; +using util::u64; + +// ---- parametric beaver product ---- + +template +int beaver_product_xy(role self, trio & net) +{ + beavers::session s; + auto x = s.input(); + auto y = s.input(); + auto z = s(x * y); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {x, y}, {X, Y}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == X * Y, "product_xy"); + return 0; +} + +// ---- parametric dot ---- + +template +int beaver_dot_n(role self, trio & net) +{ + beavers::session s; + std::vector::wire> xs, ys; + std::vector secrets; + u64 expect = 0; + for (std::size_t i = 0; i < N; ++i) + { + xs.push_back(s.input()); + ys.push_back(s.input()); + u64 a = static_cast(i + 1); + u64 b = static_cast(N - i); + secrets.push_back(a); + expect += a * b; + } + for (std::size_t i = 0; i < N; ++i) + secrets.push_back(static_cast(N - i)); + auto z = s.dot(xs, ys); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + require(s.round_of(z) == 1, "dot round"); + net::deal_session(net, s); + return 0; + } + std::vector::wire> wires = xs; + wires.insert(wires.end(), ys.begin(), ys.end()); + install_and_bind_u64(s, net, self, wires, secrets); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == expect, "dot_n"); + return 0; +} + +// ---- parametric scale ---- + +template +int beaver_scale_n(role self, trio & net) +{ + beavers::session s; + auto sc = s.input(); + std::vector::wire> lanes; + std::vector secrets{3u}; + for (std::size_t i = 0; i < N; ++i) + { + lanes.push_back(s.input()); + secrets.push_back(static_cast(i + 1)); + } + auto out = s.scale(sc, lanes); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + std::vector::wire> wires{sc}; + wires.insert(wires.end(), lanes.begin(), lanes.end()); + install_and_bind_u64(s, net, self, wires, secrets); + evaluate_online(s, net, self); + std::vector mine; + mine.reserve(N); + for (std::size_t i = 0; i < N; ++i) + mine.push_back(s.value_party(out[i])); + auto opened = open_additive(net, self, mine); + if (self == role::p0) + { + for (std::size_t i = 0; i < N; ++i) + require(opened[i] == 3u * static_cast(i + 1), "scale_n"); + } + return 0; +} + +// ---- parametric stream ---- + +template +int beaver_stream_n(role self, trio & net) +{ + using block = prg::aes128::block_type; + block seed = simde_mm_set_epi64x(0x9, static_cast(N)); + if (self == role::p2) + { + beavers::oracle src(seed, 8); + std::vector> bulk(N); + beavers::fill_beaver2(src, 0, bulk.data(), N); + require(bulk[0].ab.open() == bulk[0].a.open() * bulk[0].b.open(), "s0"); + require(bulk[N - 1].ab.open() == bulk[N - 1].a.open() * bulk[N - 1].b.open(), + "sN"); + std::vector p0, p1; + p0.reserve(N * 4); + p1.reserve(N * 4); + for (std::size_t i = 0; i < N; ++i) + { + p0.insert(p0.end(), + {bulk[i].a.p0, bulk[i].b.p0, bulk[i].ab.p0, bulk[i].out.p0}); + p1.insert(p1.end(), + {bulk[i].a.p1, bulk[i].b.p1, bulk[i].ab.p1, bulk[i].out.p1}); + } + net.to(role::p0).send_vec(p0); + net.to(role::p1).send_vec(p1); + return 0; + } + auto shares = net.to(role::p2).recv_vec(); + require(shares.size() == N * 4, "stream size"); + // Online open copies 0 and N/2. + auto open_copy = [&](std::size_t i, u64 sx, u64 sy) { + u64 a = shares[i * 4 + 0]; + u64 b = shares[i * 4 + 1]; + u64 ab = shares[i * 4 + 2]; + auto [x0, x1] = util::split_u64(sx, static_cast(i * 2 + 1)); + auto [y0, y1] = util::split_u64(sy, static_cast(i * 2 + 2)); + u64 xs = self == role::p0 ? x0 : x1; + u64 ys = self == role::p0 ? y0 : y1; + role peer = self == role::p0 ? role::p1 : role::p0; + u64 dx = (xs + a) + net.exchange_with(peer, xs + a); + u64 dy = (ys + b) + net.exchange_with(peer, ys + b); + u64 z = ab; + z -= dx * b; + z -= dy * a; + if (self == role::p0) + z += dx * dy; + auto open = open_additive(net, self, z); + if (self == role::p0) + require(open == sx * sy, "stream online"); + }; + open_copy(0, 6u, 7u); + open_copy(N / 2, 3u, 11u); + return 0; +} + +// ---- parametric public horner (one round) ---- + +template +int beaver_horner_d(role self, trio & net) +{ + beavers::session s; + auto x = s.input(); + beavers::session::wire z; + if constexpr (Degree == 1) + z = s.horner(x, {1ull, 2ull}); + else if constexpr (Degree == 2) + z = s.horner(x, {1ull, 2ull, 3ull}); + else if constexpr (Degree == 3) + z = s.horner(x, {1ull, 2ull, 3ull, 4ull}); + else if constexpr (Degree == 4) + z = s.horner(x, {1ull, 2ull, 3ull, 4ull, 5ull}); + else if constexpr (Degree == 5) + z = s.horner(x, {1ull, 2ull, 3ull, 4ull, 5ull, 6ull}); + else if constexpr (Degree == 6) + z = s.horner(x, {1ull, 2ull, 3ull, 4ull, 5ull, 6ull, 7ull}); + else if constexpr (Degree == 7) + z = s.horner(x, {1ull, 2ull, 3ull, 4ull, 5ull, 6ull, 7ull, 8ull}); + else + z = s.horner(x, {1ull, 2ull, 3ull, 4ull, 5ull, 6ull, 7ull, 8ull, 9ull}); + + const u64 xv = 5u; + u64 expect = 0; + u64 pow = 1; + for (std::size_t i = 0; i <= Degree; ++i) + { + expect += static_cast(i + 1) * pow; + pow *= xv; + } + if (self == role::p2) + { + require(s.round_of(z) == 1, "horner one round"); + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {x}, {xv}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == expect, "horner_d"); + return 0; +} + +// ---- sign * horner one round ---- + +int beaver_sign_horner(role self, trio & net) +{ + beavers::session s; + auto sgn = s.input(); + auto x = s.input(); + auto z = s.horner(sgn, x, {u64{4}, u64{5}, u64{6}}); // sgn*(4+5x+6x^2) + if (self == role::p2) + { + require(s.round_of(z) == 1, "sign horner round"); + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {sgn, x}, {2u, 3u}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == 2u * (4u + 5u * 3u + 6u * 9u), "sign_horner"); + return 0; +} + +// ---- DCF kinds ---- + +template // 0=lt 1=leq 2=gt 3=geq +int dcf_kind_point(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x40; + const Input x0 = 0x15; + const Input x1 = static_cast(alpha ^ x0); + const std::uint64_t beta = 9; + + auto check = [&](const auto & key) { + auto below = eval_point(cmp, key, static_cast(alpha - 1)); + auto on = eval_point(cmp, key, alpha); + auto above = eval_point(cmp, key, static_cast(alpha + 1)); + std::vector mine{ + share_bits(below) & key.cmp().mask, + share_bits(on) & key.cmp().mask, + share_bits(above) & key.cmp().mask}; + auto opened = open_additive(net, self, mine); + const auto ob = opened[0] & key.cmp().mask; + const auto oo = opened[1] & key.cmp().mask; + const auto oa = opened[2] & key.cmp().mask; + if (self == role::p0) + { + if constexpr (Kind == 0) + require(ob == beta && oo == 0 && oa == 0, "lt"); + else if constexpr (Kind == 1) + require(ob == beta && oo == beta && oa == 0, "leq"); + else if constexpr (Kind == 2) + require(ob == 0 && oo == 0 && oa == beta, "gt"); + else + require(ob == 0 && oo == beta && oa == beta, "geq"); + } + }; + + if constexpr (Kind == 0) + { + require_opened(dist_with_cmp_key(net, self, x0, x1, lt(beta), check, check), + self, encoded_xor_point(x0, x1)); + } + else if constexpr (Kind == 1) + { + require_opened(dist_with_cmp_key(net, self, x0, x1, leq(beta), check, check), + self, encoded_xor_point(x0, x1)); + } + else if constexpr (Kind == 2) + { + require_opened(dist_with_cmp_key(net, self, x0, x1, gt(beta), check, check), + self, encoded_xor_point(x0, x1)); + } + else + { + require_opened(dist_with_cmp_key(net, self, x0, x1, geq(beta), check, check), + self, encoded_xor_point(x0, x1)); + } + return 0; +} + +// ---- classic point eval bench ---- + +template +int dpf_point_ab(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha{Alpha}; + const Input x0 = static_cast(alpha ^ Input{0x5a}); + const Input x1 = static_cast(alpha ^ x0); + auto on = [&](const auto & key) { + auto y = *eval_point(key, alpha); + auto open = util::open_subtractive(net, self, share_bits(y)); + if (self == role::p0) + require(open == Beta, "point"); + auto yz = *eval_point(key, static_cast(Alpha ^ 1u)); + auto oz = util::open_subtractive(net, self, share_bits(yz)); + if (self == role::p0) + require(oz == 0u, "point off"); + }; + require_tree_prefix( + dist_with_point_key(net, self, x0, x1, std::uint64_t{Beta}, on, on), + self, verifiable_tree_prefix( + x0, x1)); + return 0; +} + +// ---- multivariate poly one-round ---- + +int beaver_poly_cubic_cluster(role self, trio & net) +{ + beavers::session s; + auto x = s.input(); + auto y = s.input(); + auto z = s.input(); + auto out = s(x * y * z + x * y + z); + if (self == role::p2) + { + // Degree-3 monomials need two interactive rounds (see beaver_test xyz). + require(s.round_of(out) == 2, "cluster round"); + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {x, y, z}, {2u, 3u, 5u}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(out)); + if (self == role::p0) + require(o == 2u * 3u * 5u + 2u * 3u + 5u, "cluster"); + return 0; +} + +int beaver_like_terms(role self, trio & net) +{ + beavers::session s; + auto x = s.input(); + auto y = s.input(); + auto z = s(3 * x * y + 2 * x * y); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {x, y}, {4u, 5u}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == 5u * 4u * 5u, "like"); + return 0; +} + +#define REG(name, tags, fn, benchable) \ + register_flow(flow{#name, tags, fn, benchable}) + +} // namespace bulk + +void register_bulk_flows() +{ + using namespace bulk; + REG(beaver_product_3_5, "beaver product bench", (beaver_product_xy<3, 5>), true); + REG(beaver_product_11_13, "beaver product bench", (beaver_product_xy<11, 13>), true); + REG(beaver_product_100_200, "beaver product bench", (beaver_product_xy<100, 200>), true); + REG(beaver_product_max8, "beaver product bench", + (beaver_product_xy<0xffffffffffffffffull, 2>), true); + + REG(beaver_dot_n1, "beaver dot bench", beaver_dot_n<1>, true); + REG(beaver_dot_n2, "beaver dot bench", beaver_dot_n<2>, true); + REG(beaver_dot_n4, "beaver dot bench", beaver_dot_n<4>, true); + REG(beaver_dot_n8, "beaver dot bench", beaver_dot_n<8>, true); + REG(beaver_dot_n16, "beaver dot bench", beaver_dot_n<16>, true); + REG(beaver_dot_n32, "beaver dot bench", beaver_dot_n<32>, true); + + REG(beaver_scale_n1, "beaver scale bench", beaver_scale_n<1>, true); + REG(beaver_scale_n4, "beaver scale bench", beaver_scale_n<4>, true); + REG(beaver_scale_n16, "beaver scale bench", beaver_scale_n<16>, true); + REG(beaver_scale_n64, "beaver scale bench", beaver_scale_n<64>, true); + + REG(beaver_stream_n8, "beaver stream bench", beaver_stream_n<8>, true); + REG(beaver_stream_n32, "beaver stream bench", beaver_stream_n<32>, true); + REG(beaver_stream_n128, "beaver stream bench", beaver_stream_n<128>, true); + REG(beaver_stream_n512, "beaver stream bench", beaver_stream_n<512>, true); + REG(beaver_stream_n2048, "beaver stream bench", beaver_stream_n<2048>, true); + + REG(beaver_horner_d1, "beaver horner grotto bench", beaver_horner_d<1>, true); + REG(beaver_horner_d2, "beaver horner grotto bench", beaver_horner_d<2>, true); + REG(beaver_horner_d3, "beaver horner grotto bench", beaver_horner_d<3>, true); + REG(beaver_horner_d4, "beaver horner grotto bench", beaver_horner_d<4>, true); + REG(beaver_horner_d5, "beaver horner grotto bench", beaver_horner_d<5>, true); + REG(beaver_horner_d6, "beaver horner grotto bench", beaver_horner_d<6>, true); + REG(beaver_horner_d7, "beaver horner grotto bench", beaver_horner_d<7>, true); + REG(beaver_horner_d8, "beaver horner grotto bench", beaver_horner_d<8>, true); + REG(beaver_sign_horner, "beaver horner grotto bench", beaver_sign_horner, true); + + REG(beaver_poly_cubic_cluster, "beaver poly bench", beaver_poly_cubic_cluster, true); + REG(beaver_like_terms, "beaver poly bench", beaver_like_terms, true); + + REG(dcf_lt, "dcf grotto bench", dcf_kind_point<0>, true); + REG(dcf_leq, "dcf grotto bench", dcf_kind_point<1>, true); + REG(dcf_gt, "dcf grotto bench", dcf_kind_point<2>, true); + REG(dcf_geq, "dcf grotto bench", dcf_kind_point<3>, true); + + REG(dpf_point_2a_7, "dpf geneval bench", (dpf_point_ab<0x2a, 7>), true); + REG(dpf_point_00_1, "dpf geneval bench", (dpf_point_ab<0x00, 1>), true); + REG(dpf_point_ff_99, "dpf geneval bench", (dpf_point_ab<0xff, 99>), true); + REG(dpf_point_80_42, "dpf geneval bench", (dpf_point_ab<0x80, 42>), true); +} + +#undef REG + +} // namespace party +} // namespace dpf diff --git a/party/flows_coverage.cpp b/party/flows_coverage.cpp new file mode 100644 index 0000000..572de31 --- /dev/null +++ b/party/flows_coverage.cpp @@ -0,0 +1,792 @@ +/// @file party/flows_coverage.cpp +/// @brief Party flows that close protocol / type gaps not hit by other amalgams. +/// @details Amalgamated into run.cpp (do not compile as a second TU). Dealer +/// (p2) distributes keys for paint / incremental / exotic payloads +/// because oblivious DS rejects paint kinds. Geneval full/sequence and +/// arith_output are dealer-run and share-split. CCMP is a 2-party mesh. + +#include "cases.hpp" +#include "dist_dpf3.hpp" +#include "flow_util.hpp" +#include "key_io.hpp" +#include "registry.hpp" + +#include +#include +#include +#include +#include +#include + +#include "simde/simde/x86/avx2.h" + +#include "dpf.hpp" +#include "dpf/bitstring.hpp" +#include "dpf/constrained_cmp.hpp" +#include "dpf/dcf.hpp" +#include "dpf/dpf3_ds.hpp" +#include "dpf/eval_full.hpp" +#include "dpf/eval_inner_product.hpp" +#include "dpf/eval_point.hpp" +#include "dpf/eval_sequence.hpp" +#include "dpf/field128.hpp" +#include "dpf/geneval.hpp" +#include "dpf/json.hpp" +#include "dpf/keyword2.hpp" +#include "dpf/modint.hpp" +#include "dpf/p256.hpp" +#include "grotto/fixedpoint.hpp" +#include "grotto/nmod.hpp" + +namespace dpf +{ +namespace party +{ +namespace coverage +{ + +using util::open_additive; +using util::open_subtractive; +using util::require; +using util::role; +using util::share_bits; +using util::trio; +using util::u64; + +static constexpr char cov_kw_pat[] = "[ab]{8}"; + +// ---- shared helpers -------------------------------------------------------- + +std::uint64_t paint_matched_unit(std::size_t matched, std::uint64_t, bool) +{ + return static_cast(matched); +} + +std::uint64_t lcp_len(std::uint8_t x, std::uint8_t alpha, std::size_t n = 8) +{ + for (std::size_t i = 0; i < n; ++i) + { + const std::uint8_t shift = static_cast(n - 1 - i); + if (((x >> shift) & 1) != ((alpha >> shift) & 1)) + return static_cast(i); + } + return n; +} + +template +void deal_cmp_keys(trio & net, role self, Spec spec, const Fn0 & on0, + const Fn1 & on1) +{ + using Input = std::uint8_t; + const Input alpha = 0xB4; + if (self == role::p2) + { + auto [k0, k1] = make_dpf(alpha, spec); + send_key(net.to(role::p0), k0); + send_key(net.to(role::p1), k1); + return; + } + if (self == role::p0) + { + using K = std::decay_t(make_dpf(Input{}, spec)))>; + auto key = recv_key(net.to(role::p2)); + on0(key, alpha); + return; + } + using K = std::decay_t(make_dpf(Input{}, spec)))>; + auto key = recv_key(net.to(role::p2)); + on1(key, alpha); +} + +template +void check_paint_grid(trio & net, role self, const Key & key, std::uint8_t alpha, + auto expect_fn, const char * tag) +{ + const u64 mask = key.cmp().mask; + const std::array pts{ + 0, 1, alpha, static_cast(alpha ^ 1u), 0x55, 0xAA, 0xFE, 0xFF}; + for (std::uint8_t x : pts) + { + const u64 mine = share_bits(eval_point(cmp, key, x)) & mask; + const u64 opened = open_additive(net, self, mine) & mask; + if (self == role::p0) + require(opened == (expect_fn(x, alpha) & mask), tag); + } +} + +// ---- paints (F_DCF path paints; dealer distribute) -------------------------- + +int cov_paint_lcp(role self, trio & net) +{ + auto on = [&](const auto & key, std::uint8_t alpha) { + check_paint_grid(net, self, key, alpha, + [](std::uint8_t x, std::uint8_t a) { return lcp_len(x, a); }, + "paint lcp"); + }; + deal_cmp_keys(net, self, lcp(u64{1}), on, on); + return 0; +} + +int cov_paint_one_hot(role self, trio & net) +{ + auto on = [&](const auto & key, std::uint8_t alpha) { + check_paint_grid(net, self, key, alpha, + [](std::uint8_t x, std::uint8_t a) { + return 1ULL << lcp_len(x, a); + }, + "paint one_hot"); + }; + deal_cmp_keys(net, self, diverge_one_hot(u64{1}), on, on); + return 0; +} + +int cov_paint_break_bit(role self, trio & net) +{ + auto on = [&](const auto & key, std::uint8_t alpha) { + check_paint_grid(net, self, key, alpha, + [](std::uint8_t x, std::uint8_t a) { + const auto d = lcp_len(x, a); + if (d >= 8) + return 0ULL; + return 3ULL * ((a >> (7 - d)) & 1); + }, + "paint break_bit"); + }; + deal_cmp_keys(net, self, break_bit(u64{3}), on, on); + return 0; +} + +int cov_paint_path(role self, trio & net) +{ + auto on = [&](const auto & key, std::uint8_t alpha) { + check_paint_grid(net, self, key, alpha, + [](std::uint8_t x, std::uint8_t a) { return lcp_len(x, a); }, + "paint path"); + }; + deal_cmp_keys(net, self, path_paint(paint_matched_unit), on, on); + return 0; +} + +int cov_paint_prefix_with_length(role self, trio & net) +{ + auto on = [&](const auto & key, std::uint8_t alpha) { + check_paint_grid(net, self, key, alpha, + [](std::uint8_t x, std::uint8_t a) { + const auto d = lcp_len(x, a); + const u64 low = d == 0 ? 0 + : (d >= 8 ? a : static_cast(a) >> (8 - d)); + return (low << 4) | d; + }, + "paint prefix_with_length"); + }; + deal_cmp_keys(net, self, prefix_with_length<4>(u64{1}), on, on); + return 0; +} + +// ---- F_IDPF / eq_at / idcf ------------------------------------------------- + +int cov_idpf_at(role self, trio & net) +{ + using Input = std::uint16_t; + const Input alpha = 0xa5c3; + if (self == role::p2) + { + auto [k0, k1] = make_dpf(alpha, at<8>(std::uint8_t{42}), + at<12>(std::uint16_t{7})); + send_key(net.to(role::p0), k0); + send_key(net.to(role::p1), k1); + return 0; + } + auto check = [&](const auto & key) { + const auto y8 = *eval_point(out<0, 8>, key, alpha); + const auto o8 = open_subtractive(net, self, share_bits(y8)); + if (self == role::p0) + require(o8 == std::uint8_t{42}, "idpf at8"); + const auto y12 = *eval_point(out<1, 12>, key, alpha); + const auto o12 = open_subtractive(net, self, share_bits(y12)); + if (self == role::p0) + require(o12 == std::uint16_t{7}, "idpf at12"); + }; + if (self == role::p0) + { + using K = std::decay_t( + make_dpf(Input{}, at<8>(std::uint8_t{}), at<12>(std::uint16_t{}))))>; + check(recv_key(net.to(role::p2))); + return 0; + } + using K = std::decay_t( + make_dpf(Input{}, at<8>(std::uint8_t{}), at<12>(std::uint16_t{}))))>; + check(recv_key(net.to(role::p2))); + return 0; +} + +int cov_eq_at(role self, trio & net) +{ + using Input = std::uint16_t; + const Input alpha = 0x1234; + if (self == role::p2) + { + auto [k0, k1] = make_dpf(alpha, + eq_at<8>(std::uint16_t{99}, std::uint16_t{7})); + send_key(net.to(role::p0), k0); + send_key(net.to(role::p1), k1); + return 0; + } + auto check = [&](const auto & key) { + // High 8 bits of alpha match → true branch 99 on that prefix lane. + const auto y_on = *eval_point(out<0, 8>, key, alpha); + const auto o_on = open_subtractive(net, self, share_bits(y_on)); + if (self == role::p0) + require(o_on == std::uint16_t{99}, "eq_at on"); + const Input miss = static_cast(alpha ^ 0x0100); + const auto y_off = *eval_point(out<0, 8>, key, miss); + const auto o_off = open_subtractive(net, self, share_bits(y_off)); + if (self == role::p0) + require(o_off == std::uint16_t{7}, "eq_at off"); + }; + if (self == role::p0) + { + using K = std::decay_t( + make_dpf(Input{}, eq_at<8>(std::uint16_t{}, std::uint16_t{}))))>; + check(recv_key(net.to(role::p2))); + return 0; + } + using K = std::decay_t( + make_dpf(Input{}, eq_at<8>(std::uint16_t{}, std::uint16_t{}))))>; + check(recv_key(net.to(role::p2))); + return 0; +} + +int cov_idcf(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x40; + const u64 beta = 5; + if (self == role::p2) + { + auto [k0, k1] = make_dpf(alpha, idcf(gt(beta))); + send_key(net.to(role::p0), k0); + send_key(net.to(role::p1), k1); + return 0; + } + auto check = [&](const auto & key) { + const u64 mask = key.cmp().mask; + for (Input x : {Input{0x3f}, alpha, Input{0x41}}) + { + const u64 mine = share_bits(eval_point(cmp, key, x)) & mask; + const u64 opened = open_additive(net, self, mine) & mask; + if (self == role::p0) + { + const u64 want = x > alpha ? beta : 0u; + require(opened == want, "idcf gt"); + } + } + }; + if (self == role::p0) + { + using K = std::decay_t( + make_dpf(Input{}, idcf(gt(u64{})))))>; + check(recv_key(net.to(role::p2))); + return 0; + } + using K = std::decay_t( + make_dpf(Input{}, idcf(gt(u64{})))))>; + check(recv_key(net.to(role::p2))); + return 0; +} + +// ---- F_GenEval full / sequence / arith_output ------------------------------ + +struct CovPad +{ + std::uint64_t n = 1; + simde__m128i block() + { + auto v = simde_mm_set_epi64x(static_cast(n), + static_cast(n * 9 + 3)); + n += 2; + return v; + } + std::uint8_t bit() { return static_cast(n++ & 1u); } +}; + +simde__m128i cov_roots[32]; +int cov_ri = 0; +simde__m128i cov_take_root() { return cov_roots[cov_ri++]; } + +void cov_reset_roots() +{ + cov_ri = 0; + for (int i = 0; i < 32; ++i) + cov_roots[i] = simde_mm_set_epi64x(0x2222 * (i + 1), 0xBEEF0000u + i * 13); +} + +HEDLEY_PRAGMA(GCC diagnostic push) +HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") +ds_randomness cov_rng() +{ + return {cov_take_root, CovPad{}}; +} +HEDLEY_PRAGMA(GCC diagnostic pop) + +int cov_geneval_full(role self, trio & net) +{ + using Input = std::uint8_t; + using Output = std::uint8_t; + const Input alpha = 0x3c; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const Output y = 0x7e; + if (self == role::p2) + { + cov_reset_roots(); + auto g = geneval_full(x0, x1, cov_rng(), y); + require(g.party0.size() == 256u, "geneval_full size"); + net.to(role::p0).send_vec(g.party0); + net.to(role::p1).send_vec(g.party1); + return 0; + } + auto mine = net.to(role::p2).recv_vec(); + require(mine.size() == 256u, "geneval_full recv"); + const Output opened = open_subtractive(net, self, mine[alpha]); + const Output off = open_subtractive(net, self, mine[0]); + if (self == role::p0) + { + require(opened == y, "geneval_full on"); + require(off == Output{0}, "geneval_full off"); + } + return 0; +} + +int cov_geneval_sequence(role self, trio & net) +{ + using Input = std::uint8_t; + using Output = std::uint16_t; + const Input alpha = 0x2a; + const Input x0 = 0x07; + const Input x1 = static_cast(alpha ^ x0); + const Output y = 99; + const std::array seq{0, 1, alpha, 200, 255}; + if (self == role::p2) + { + cov_reset_roots(); + auto g = geneval_sequence(x0, x1, seq.begin(), seq.end(), cov_rng(), y); + require(g.party0.size() == seq.size(), "geneval_seq size"); + net.to(role::p0).send_vec(g.party0); + net.to(role::p1).send_vec(g.party1); + return 0; + } + auto mine = net.to(role::p2).recv_vec(); + require(mine.size() == seq.size(), "geneval_seq recv"); + for (std::size_t i = 0; i < seq.size(); ++i) + { + const Output opened = open_subtractive(net, self, mine[i]); + if (self == role::p0) + require(opened == (seq[i] == alpha ? y : Output{0}), "geneval_seq"); + } + return 0; +} + +int cov_arith_output(role self, trio & net) +{ + using Input = std::uint8_t; + using Output = std::uint32_t; + const Input alpha = 0x2a; + const Input x0 = 0x55; + const Input x1 = static_cast(alpha ^ x0); + const Output beta = 0x01020304; + const Output y0 = 0x00010002; + const Output y1 = static_cast(beta - y0); + if (self == role::p2) + { + cov_reset_roots(); + auto g = geneval_point(arith_output, x0, x1, alpha, cov_rng(), y0, y1); + require(g.party0.size() == 1u && g.leaf_live, "arith_output live"); + net.to(role::p0).send(net::msg::delta, g.party0[0]); + net.to(role::p1).send(net::msg::delta, g.party1[0]); + return 0; + } + const Output mine = net.to(role::p2).recv(net::msg::delta); + const Output opened = open_subtractive(net, self, mine); + if (self == role::p0) + require(opened == beta, "arith_output"); + return 0; +} + +// ---- F_CCMP ---------------------------------------------------------------- + +int cov_ccmp(role self, trio & net) +{ + if (self == role::p2) + return 0; + const u64 mine = self == role::p0 ? 4u : 5u; + const role peer = self == role::p0 ? role::p1 : role::p0; + std::uint8_t z0 = 0, z1 = 0, l = 0; + detail::ccmp_party_terms(mine, self == role::p0 ? 0 : 1, z0, z1, l); + const std::uint8_t peer_z0 = net.exchange_with(peer, z0); + const std::uint8_t peer_z1 = net.exchange_with(peer, z1); + const std::uint8_t peer_l = net.exchange_with(peer, l); + const std::uint8_t opened_z0 = static_cast(z0 ^ peer_z0); + const std::uint8_t opened_z1 = static_cast(z1 ^ peer_z1); + const std::uint8_t t = static_cast(opened_z0 & opened_z1); + const std::uint8_t l1 = self == role::p1 ? l : peer_l; + const std::uint8_t got = static_cast(t ^ l1); + require(got == local_ccmp(4u, 5u), "ccmp mesh"); + require(got == 1u, "ccmp 4<5"); + bool bad = false; + try + { + (void)local_ccmp(4u, 6u); + } + catch (const std::invalid_argument &) + { + bad = true; + } + require(bad, "ccmp rejects"); + return 0; +} + +// ---- exotic payloads / domains --------------------------------------------- + +template +int cov_payload_point(role self, trio & net, Output beta, const char * tag) +{ + using Input = std::uint8_t; + const Input alpha = 0x11; + if (self == role::p2) + { + auto [k0, k1] = make_dpf(alpha, beta); + send_key(net.to(role::p0), k0); + send_key(net.to(role::p1), k1); + return 0; + } + auto check = [&](const auto & key) { + const auto on = *eval_point(key, alpha); + const auto off = *eval_point(key, static_cast(alpha ^ 1u)); + const Output o_on = open_subtractive(net, self, share_bits(on)); + const Output o_off = open_subtractive(net, self, share_bits(off)); + if (self == role::p0) + { + require(o_on == beta, tag); + require(o_off == Output{}, tag); + } + }; + if (self == role::p0) + { + using K = std::decay_t(make_dpf(Input{}, beta)))>; + check(recv_key(net.to(role::p2))); + return 0; + } + using K = std::decay_t(make_dpf(Input{}, beta)))>; + check(recv_key(net.to(role::p2))); + return 0; +} + +int cov_field128(role self, trio & net) +{ + return cov_payload_point(self, net, field128{42}, "field128"); +} + +int cov_gf2(role self, trio & net) +{ + return cov_payload_point(self, net, dpf::gf2{1}, "gf2"); +} + +int cov_gf22(role self, trio & net) +{ + return cov_payload_point(self, net, dpf::gf22{3}, "gf22"); +} + +int cov_gf24(role self, trio & net) +{ + return cov_payload_point(self, net, dpf::gf24{0xa}, "gf24"); +} + +int cov_gf28(role self, trio & net) +{ + return cov_payload_point(self, net, dpf::gf28{0x1b}, "gf28"); +} + +int cov_gf216(role self, trio & net) +{ + return cov_payload_point(self, net, dpf::gf216{0x2d}, "gf216"); +} + +int cov_gf232(role self, trio & net) +{ + return cov_payload_point(self, net, dpf::gf232{0x90200001u}, "gf232"); +} + +int cov_gf264(role self, trio & net) +{ + return cov_payload_point(self, net, dpf::gf264{0x11}, "gf264"); +} + +int cov_p256(role self, trio & net) +{ + return cov_payload_point(self, net, p256{1}, "p256"); +} + +int cov_bitstring(role self, trio & net) +{ + using bs = bitstring<16>; + return cov_payload_point(self, net, bs{0xBEEFu}, "bitstring"); +} + +int cov_fixedpoint(role self, trio & net) +{ + using fp = grotto::fixedpoint<16>; + return cov_payload_point(self, net, fp::from_raw(0x00018000), "fixedpoint"); +} + +int cov_keyword2(role self, trio & net) +{ + using kw = keyword2; + const kw alpha{"abababab"}; + const u64 beta = 3; + if (self == role::p2) + { + auto [k0, k1] = make_dpf(alpha, beta); + send_key(net.to(role::p0), k0); + send_key(net.to(role::p1), k1); + return 0; + } + auto check = [&](const auto & key) { + const auto on = *eval_point(key, alpha); + const auto off = *eval_point(key, kw{"babababa"}); + const auto o_on = open_subtractive(net, self, share_bits(on)); + const auto o_off = open_subtractive(net, self, share_bits(off)); + if (self == role::p0) + { + require(o_on == beta, "keyword2 on"); + require(o_off == 0u, "keyword2 off"); + } + }; + if (self == role::p0) + { + using K = std::decay_t(make_dpf(kw{}, u64{})))>; + check(recv_key(net.to(role::p2))); + return 0; + } + using K = std::decay_t(make_dpf(kw{}, u64{})))>; + check(recv_key(net.to(role::p2))); + return 0; +} + +int cov_modint_domain(role self, trio & net) +{ + using in_t = modint<10>; + const in_t alpha{3}; + if (self == role::p2) + { + auto [k0, k1] = make_dpf(alpha, at<6>(std::uint8_t{1}), std::uint16_t{2}); + send_key(net.to(role::p0), k0); + send_key(net.to(role::p1), k1); + return 0; + } + auto check = [&](const auto & key) { + const auto y0 = *eval_point(out<0, 6>, key, alpha); + const auto o0 = open_subtractive(net, self, share_bits(y0)); + if (self == role::p0) + require(o0 == std::uint8_t{1}, "modint at6"); + const auto y1 = *eval_point(out<1>, key, alpha); + const auto o1 = open_subtractive(net, self, share_bits(y1)); + if (self == role::p0) + require(o1 == std::uint16_t{2}, "modint leaf"); + }; + if (self == role::p0) + { + using K = std::decay_t( + make_dpf(in_t{}, at<6>(std::uint8_t{}), std::uint16_t{})))>; + check(recv_key(net.to(role::p2))); + return 0; + } + using K = std::decay_t( + make_dpf(in_t{}, at<6>(std::uint8_t{}), std::uint16_t{})))>; + check(recv_key(net.to(role::p2))); + return 0; +} + +// ---- grotto nmod (public reduction helper over the mesh) ------------------- + +int cov_nmod(role self, trio & net) +{ + // 42 / 10 with 1/10 ≈ 0x199999999999999a / 2^64, keep 8 residue bits. + const std::int64_t x_raw = 42; + const unsigned x_bits = 0; + const unsigned __int128 recip = 0x199999999999999aull; + const unsigned recip_bits = 64; + const unsigned residue_bits = 8; + auto got = grotto::nmod(x_raw, x_bits, recip, recip_bits, residue_bits); + if (self == role::p2) + { + net.to(role::p0).send(net::msg::delta, got.quotient); + net.to(role::p0).send(net::msg::delta, got.residue); + net.to(role::p1).send(net::msg::delta, got.quotient); + net.to(role::p1).send(net::msg::delta, got.residue); + return 0; + } + const auto q = net.to(role::p2).recv(net::msg::delta); + const auto r = net.to(role::p2).recv(net::msg::delta); + require(q == got.quotient && r == got.residue, "nmod agree"); + require(q == 4 && r != 0, "nmod 42/10"); + return 0; +} + +// ---- JSON key round-trip over the mesh ------------------------------------- + +int cov_json_roundtrip(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const u64 beta = 17; + if (self == role::p2) + { + auto [k0, k1] = make_dpf(alpha, beta); + const std::string s0 = json::to_json(k0); + const std::string s1 = json::to_json(k1); + net.to(role::p0).send_bytes(net::msg::dpf_key, + reinterpret_cast(s0.data()), s0.size()); + net.to(role::p1).send_bytes(net::msg::dpf_key, + reinterpret_cast(s1.data()), s1.size()); + return 0; + } + auto body = net.to(role::p2).recv_bytes(net::msg::dpf_key); + const std::string s(reinterpret_cast(body.data()), body.size()); + using K0 = std::decay_t(make_dpf(Input{}, u64{})))>; + using K1 = std::decay_t(make_dpf(Input{}, u64{})))>; + if (self == role::p0) + { + auto key = json::from_json(s); + const auto y = *eval_point(key, alpha); + const auto open = open_subtractive(net, self, share_bits(y)); + require(open == beta, "json on"); + return 0; + } + auto key = json::from_json(s); + const auto y = *eval_point(key, alpha); + (void)open_subtractive(net, self, share_bits(y)); + return 0; +} + +// ---- F_DPF3DS local API (dealer make_dpf3_doerner_shelat) ------------------- + +int cov_dpf3_ds_local(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x11; + const Input x1 = static_cast(alpha ^ x0); + const fp61 beta{9}; + if (self == role::p2) + { + auto [k1, k2, k3] = make_dpf3_doerner_shelat(x0, x1, beta); + send_key(net.to(role::p0), k1); + send_key(net.to(role::p1), k2); + const fp61 y = eval_point(k3, alpha); + const fp61 got = recent::open_shamir3(net, self, y); + require(got == beta, "dpf3_ds on"); + const fp61 z = eval_point(k3, static_cast(alpha ^ 1u)); + const fp61 off = recent::open_shamir3(net, self, z); + require(off == fp61{}, "dpf3_ds off"); + return 0; + } + if (self == role::p0) + { + using K = std::decay_t( + make_dpf3_doerner_shelat(Input{}, Input{}, fp61{})))>; + auto key = recv_key(net.to(role::p2)); + (void)recent::open_shamir3(net, self, eval_point(key, alpha)); + (void)recent::open_shamir3(net, self, + eval_point(key, static_cast(alpha ^ 1u))); + return 0; + } + using K = std::decay_t( + make_dpf3_doerner_shelat(Input{}, Input{}, fp61{})))>; + auto key = recv_key(net.to(role::p2)); + (void)recent::open_shamir3(net, self, eval_point(key, alpha)); + (void)recent::open_shamir3(net, self, + eval_point(key, static_cast(alpha ^ 1u))); + return 0; +} + +// ---- eval_inner_product on a point DPF ------------------------------------- + +int cov_eval_inner_product(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 42; + const u64 beta = 7; + if (self == role::p2) + { + auto [k0, k1] = make_dpf(alpha, beta); + send_key(net.to(role::p0), k0); + send_key(net.to(role::p1), k1); + return 0; + } + auto check = [&](const auto & key) { + std::vector w(11, 1); + const u64 mine = share_bits( + eval_inner_product(paired, key, Input{40}, Input{50}, w)); + // Point leaves are subtractive; the guided-tour reconstruct is additive + // on the opened difference after both parties contribute. + const u64 opened = open_subtractive(net, self, mine); + if (self == role::p0) + require(opened == beta * w[2], "eval_inner_product"); + }; + if (self == role::p0) + { + using K = std::decay_t(make_dpf(Input{}, u64{})))>; + check(recv_key(net.to(role::p2))); + return 0; + } + using K = std::decay_t(make_dpf(Input{}, u64{})))>; + check(recv_key(net.to(role::p2))); + return 0; +} + +#define REG(name, tags, fn) \ + register_flow(flow{#name, tags, fn, false}) + +} // namespace coverage + +void register_coverage_flows() +{ + using namespace coverage; + REG(cov_paint_lcp, "coverage paint dcf", cov_paint_lcp); + REG(cov_paint_one_hot, "coverage paint dcf", cov_paint_one_hot); + REG(cov_paint_break_bit, "coverage paint dcf", cov_paint_break_bit); + REG(cov_paint_path, "coverage paint dcf", cov_paint_path); + REG(cov_paint_prefix_with_length, "coverage paint dcf", + cov_paint_prefix_with_length); + REG(cov_idpf_at, "coverage idpf", cov_idpf_at); + REG(cov_eq_at, "coverage eq_at", cov_eq_at); + REG(cov_idcf, "coverage idcf", cov_idcf); + REG(cov_geneval_full, "coverage geneval", cov_geneval_full); + REG(cov_geneval_sequence, "coverage geneval", cov_geneval_sequence); + REG(cov_arith_output, "coverage arith_output", cov_arith_output); + REG(cov_ccmp, "coverage ccmp", cov_ccmp); + REG(cov_field128, "coverage payload", cov_field128); + REG(cov_gf2, "coverage payload", cov_gf2); + REG(cov_gf22, "coverage payload", cov_gf22); + REG(cov_gf24, "coverage payload", cov_gf24); + REG(cov_gf28, "coverage payload", cov_gf28); + REG(cov_gf216, "coverage payload", cov_gf216); + REG(cov_gf232, "coverage payload", cov_gf232); + REG(cov_gf264, "coverage payload", cov_gf264); + REG(cov_p256, "coverage payload", cov_p256); + REG(cov_bitstring, "coverage payload", cov_bitstring); + REG(cov_fixedpoint, "coverage payload", cov_fixedpoint); + REG(cov_keyword2, "coverage keyword2", cov_keyword2); + REG(cov_modint_domain, "coverage modint", cov_modint_domain); + REG(cov_nmod, "coverage nmod", cov_nmod); + REG(cov_json_roundtrip, "coverage json", cov_json_roundtrip); + REG(cov_dpf3_ds_local, "coverage dpf3_ds", cov_dpf3_ds_local); + REG(cov_eval_inner_product, "coverage eval_inner_product", + cov_eval_inner_product); +} + +#undef REG + +} // namespace party +} // namespace dpf diff --git a/party/flows_extreme.cpp b/party/flows_extreme.cpp new file mode 100644 index 0000000..0ad3454 --- /dev/null +++ b/party/flows_extreme.cpp @@ -0,0 +1,1080 @@ +/// @file party/flows_extreme.cpp +/// @brief Extreme grotto / DCF / geneval / DS / complex-beaver party flows. +/// @details Amalgamated into run.cpp (do not compile as a second TU). + +#include "cases.hpp" +#include "dist_ds.hpp" +#include "flow_util.hpp" +#include "key_io.hpp" +#include "registry.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "simde/simde/x86/avx2.h" + +#include "dpf/beaver.hpp" +#include "dpf/dcf.hpp" +#include "dpf/dpf_key.hpp" +#include "dpf/eval_full.hpp" +#include "dpf/eval_interval.hpp" +#include "dpf/eval_point.hpp" +#include "dpf/eval_sequence.hpp" +#include "dpf/eval_unified.hpp" +#include "dpf/geneval.hpp" +#include "dpf/incremental.hpp" +#include "dpf/prg_aes.hpp" +#include "grotto/constant_lut.hpp" +#include "grotto/offset_horner.hpp" +#include "grotto/prefix_parity.hpp" + +namespace dpf +{ +namespace party +{ +namespace extreme +{ + +using util::Counter; +using util::evaluate_online; +using util::install_and_bind_u64; +using util::open_additive; +using util::open_subtractive; +using util::require; +using util::role; +using util::share_bits; +using util::trio; +using util::u64; + +// ---- helpers ---- + +bool open_xor_bit(trio & net, role self, bool mine) +{ + role peer = self == role::p0 ? role::p1 : role::p0; + bool theirs = net.exchange_with(peer, mine); + return mine ^ theirs; +} + +struct Pad +{ + std::uint64_t n = 1; + simde__m128i block() + { + auto v = simde_mm_set_epi64x(static_cast(n), + static_cast(n * 9 + 3)); + n += 2; + return v; + } + std::uint8_t bit() { return static_cast(n++ & 1u); } +}; + +HEDLEY_PRAGMA(GCC diagnostic push) +HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") +ds_randomness make_ds_rng() +{ + return {uniform_sample, Pad{}}; +} +HEDLEY_PRAGMA(GCC diagnostic pop) + +template +int piece_containing(T alpha, const std::array & ends) +{ + for (std::size_t i = 0; i + 1 < N; ++i) + { + if (alpha >= ends[i] && alpha < ends[i + 1]) + return static_cast(i); + } + return static_cast(N - 1); +} + +u64 expect_cmp(int kind, std::uint8_t x, std::uint8_t alpha, u64 beta) +{ + // kind: 0=lt 1=leq 2=gt 3=geq + bool hit = false; + if (kind == 0) + hit = x < alpha; + else if (kind == 1) + hit = x <= alpha; + else if (kind == 2) + hit = x > alpha; + else + hit = x >= alpha; + return hit ? beta : 0u; +} + +// ============================================================================ +// Extreme beaver: large vectors, nested products, mixed batches +// ============================================================================ + +template +int beaver_dot_extreme_n(role self, trio & net) +{ + beavers::session s; + std::vector::wire> xs, ys; + std::vector secrets; + u64 expect = 0; + for (std::size_t i = 0; i < N; ++i) + { + xs.push_back(s.input()); + ys.push_back(s.input()); + u64 a = static_cast(i * 17 + 3); + u64 b = static_cast((N - i) * 11 + 5); + secrets.push_back(a); + secrets.push_back(b); + expect += a * b; + } + auto z = s.dot(xs, ys); + if (self == role::p2) + { + require(s.round_of(z) == 1, "dot extreme round"); + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + std::vector::wire> inputs; + inputs.reserve(2 * N); + for (std::size_t i = 0; i < N; ++i) + { + inputs.push_back(xs[i]); + inputs.push_back(ys[i]); + } + install_and_bind_u64(s, net, self, inputs, secrets); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == expect, "dot extreme"); + return 0; +} + +int beaver_nested_dots(role self, trio & net) +{ + // (x·y) * (u·v) — two-round nested product of dots + constexpr std::size_t N = 8; + beavers::session s; + std::vector::wire> xs, ys, us, vs; + std::vector xsec, ysec, usec, vsec; + u64 xy = 0, uv = 0; + for (std::size_t i = 0; i < N; ++i) + { + xs.push_back(s.input()); + ys.push_back(s.input()); + us.push_back(s.input()); + vs.push_back(s.input()); + u64 a = i + 1, b = i + 2, c = i + 3, d = i + 4; + xsec.push_back(a); + ysec.push_back(b); + usec.push_back(c); + vsec.push_back(d); + xy += a * b; + uv += c * d; + } + auto d0 = s.dot(xs, ys); + auto d1 = s.dot(us, vs); + auto z = s(d0 * d1); + if (self == role::p2) + { + require(s.round_of(d0) == 1 && s.round_of(d1) == 1, "inner dots"); + require(s.round_of(z) == 2, "nested round"); + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + std::vector::wire> inputs = xs; + inputs.insert(inputs.end(), ys.begin(), ys.end()); + inputs.insert(inputs.end(), us.begin(), us.end()); + inputs.insert(inputs.end(), vs.begin(), vs.end()); + std::vector secrets = xsec; + secrets.insert(secrets.end(), ysec.begin(), ysec.end()); + secrets.insert(secrets.end(), usec.begin(), usec.end()); + secrets.insert(secrets.end(), vsec.begin(), vsec.end()); + install_and_bind_u64(s, net, self, inputs, secrets); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == xy * uv, "nested dots"); + return 0; +} + +int beaver_tuple_cascade(role self, trio & net) +{ + // Cascade of triples and squares on a 6-tuple + beavers::session s; + auto a = s.input(); + auto b = s.input(); + auto c = s.input(); + auto d = s.input(); + auto e = s.input(); + auto f = s.input(); + auto p = s.product(a, b, c); + auto q = s(d * d); + auto r = s(e * f); + auto z = s(p * q + r * a + b * c * d); + const u64 A = 2, B = 3, C = 5, D = 7, E = 11, F = 13; + const u64 expect = (A * B * C) * (D * D) + (E * F) * A + B * C * D; + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {a, b, c, d, e, f}, {A, B, C, D, E, F}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == expect, "cascade"); + return 0; +} + +int beaver_mixed_batch_poly(role self, trio & net) +{ + // Many independent products + one dense Horner + one mux in one session + beavers::session s; + constexpr std::size_t K = 16; + std::vector::wire> xs, ys, outs; + std::vector secrets; + u64 expect_sum = 0; + for (std::size_t i = 0; i < K; ++i) + { + xs.push_back(s.input()); + ys.push_back(s.input()); + u64 a = static_cast(i + 2); + u64 b = static_cast(3 * i + 1); + secrets.push_back(a); + secrets.push_back(b); + outs.push_back(s(xs.back() * ys.back())); + expect_sum += a * b; + } + auto t = s.input(); + secrets.push_back(4u); + auto h = s.horner(t, {u64{1}, u64{2}, u64{3}, u64{4}, u64{5}}); + auto bit = s.input(); + auto lo = s.input(); + auto hi = s.input(); + secrets.push_back(1u); + secrets.push_back(9u); + secrets.push_back(42u); + auto mx = s.mux(bit, hi, lo); // bit=1 → hi + auto total = outs[0]; + for (std::size_t i = 1; i < K; ++i) + total = s(total + outs[i]); + auto z = s(total + h + mx); + const u64 x = 4; + const u64 horner = 1 + 2 * x + 3 * x * x + 4 * x * x * x + 5 * x * x * x * x; + const u64 expect = expect_sum + horner + 42u; + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + std::vector::wire> inputs; + for (std::size_t i = 0; i < K; ++i) + { + inputs.push_back(xs[i]); + inputs.push_back(ys[i]); + } + inputs.push_back(t); + inputs.push_back(bit); + inputs.push_back(lo); + inputs.push_back(hi); + install_and_bind_u64(s, net, self, inputs, secrets); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == expect, "mixed batch"); + return 0; +} + +int beaver_factored_multilinear(role self, trio & net) +{ + // Multilinear over 4 bits expanded: product of (1 + a_i * x_i) + beavers::session s; + auto x0 = s.input(); + auto x1 = s.input(); + auto x2 = s.input(); + auto x3 = s.input(); + auto z = s((1 + 2 * x0) * (1 + 3 * x1) * (1 + 5 * x2) * (1 + 7 * x3)); + const u64 X0 = 1, X1 = 1, X2 = 0, X3 = 1; + const u64 expect = (1 + 2 * X0) * (1 + 3 * X1) * (1 + 5 * X2) * (1 + 7 * X3); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {x0, x1, x2, x3}, {X0, X1, X2, X3}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == expect, "multilinear"); + return 0; +} + +// ============================================================================ +// DCF extreme: dense queries, blocked, interval / full / sequence / IP +// ============================================================================ + +template +int dcf_dense_grid(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x73; + const Input x0 = 0x19; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 13; + std::vector pts; + for (int x = 0; x < 256; x += 4) + pts.push_back(static_cast(x)); + for (int d = -3; d <= 3; ++d) + { + int v = static_cast(alpha) + d; + if (v >= 0 && v < 256) + pts.push_back(static_cast(v)); + } + pts.push_back(0); + pts.push_back(255); + std::sort(pts.begin(), pts.end()); + pts.erase(std::unique(pts.begin(), pts.end()), pts.end()); + + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + std::vector mine; + mine.reserve(pts.size()); + for (Input x : pts) + mine.push_back(share_bits(eval_point(cmp, key, x)) & mask); + auto opened = open_additive(net, self, mine); + if (self == role::p0) + { + for (std::size_t i = 0; i < pts.size(); ++i) + require((opened[i] & mask) + == expect_cmp(Kind, pts[i], alpha, beta), + "dense grid"); + } + }; + const auto expect = encoded_xor_point(x0, x1); + if constexpr (Kind == 0) + require_opened(dist_with_cmp_key(net, self, x0, x1, lt(beta), on, on), + self, expect); + else if constexpr (Kind == 1) + require_opened(dist_with_cmp_key(net, self, x0, x1, leq(beta), on, on), + self, expect); + else if constexpr (Kind == 2) + require_opened(dist_with_cmp_key(net, self, x0, x1, gt(beta), on, on), + self, expect); + else + require_opened(dist_with_cmp_key(net, self, x0, x1, geq(beta), on, on), + self, expect); + return 0; +} + +template +int dcf_full_domain(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x40; + const Input x0 = 0x23; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 9; + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + auto full = eval_full(cmp, key); + require(full.size() == 256u, "full size"); + std::vector mine(256); + for (std::size_t i = 0; i < 256; ++i) + mine[i] = share_bits(full[i]) & mask; + auto opened = open_additive(net, self, mine); + if (self == role::p0) + { + for (int x = 0; x < 256; ++x) + require((opened[static_cast(x)] & mask) + == expect_cmp( + Kind, static_cast(x), alpha, beta), + "full domain"); + } + }; + const auto expect = encoded_xor_point(x0, x1); + if constexpr (Kind == 0) + require_opened(dist_with_cmp_key(net, self, x0, x1, lt(beta), on, on), + self, expect); + else if constexpr (Kind == 1) + require_opened(dist_with_cmp_key(net, self, x0, x1, leq(beta), on, on), + self, expect); + else if constexpr (Kind == 2) + require_opened(dist_with_cmp_key(net, self, x0, x1, gt(beta), on, on), + self, expect); + else + require_opened(dist_with_cmp_key(net, self, x0, x1, geq(beta), on, on), + self, expect); + return 0; +} + +int dcf_blocked_interval_ip(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 100; + const Input x0 = 0x35; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 6; + const u64 if_false = 1; + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + const Input from = 90, to = 110; + auto buf = make_output_buffer(cmp, key, from, to); + eval_interval(cmp, key, from, to, buf); + std::vector mine; + for (Input x = from; x <= to; ++x) + mine.push_back(share_bits(buf[x - from]) & mask); + auto opened = open_additive(net, self, mine); + if (self == role::p0) + { + for (std::size_t i = 0; i < mine.size(); ++i) + { + Input x = static_cast(from + i); + u64 want = x < alpha ? beta : if_false; + require((opened[i] & mask) == want, "blocked interval"); + } + } + std::vector w(static_cast(to - from + 1), 1u); + u64 ip = eval_inner_product(cmp, key, from, to, w) & mask; + auto oip = open_additive(net, self, ip) & mask; + if (self == role::p0) + { + u64 want_ip = 0; + for (Input x = from; x <= to; ++x) + want_ip = + (want_ip + (x < alpha ? beta : if_false)) & mask; + require(oip == want_ip, "blocked ip"); + } + std::array pts{{0, 99, 100, 101, 255}}; + auto seq = make_output_buffer(cmp, key, pts.size()); + auto path = make_basic_path_memoizer(key); + eval_sequence(cmp, key, pts.begin(), pts.end(), seq, path); + std::vector smine; + for (std::size_t i = 0; i < pts.size(); ++i) + smine.push_back(share_bits(seq[i]) & mask); + auto sopen = open_additive(net, self, smine); + if (self == role::p0) + { + for (std::size_t i = 0; i < pts.size(); ++i) + require((sopen[i] & mask) + == (pts[i] < alpha ? beta : if_false), + "blocked seq"); + } + }; + require_opened(dist_with_cmp_key(net, self, x0, x1, + block_width<4>(lt(beta, if_false)), on, on), + self, encoded_xor_point(x0, x1)); + return 0; +} + +// ============================================================================ +// Grotto: signed prefix/segment, XOR prefix, LUT, offset Horner, geneval Horner +// ============================================================================ + +int grotto_signed_prefix_dense(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x3c; + const Input x0 = 0x17; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 1; + std::array ends{{0, 1, 2, 10, 20, 40, alpha - 1, alpha, alpha + 1, + 100, 150, 200, 220, 240, 254, 255}}; + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + auto pref = grotto::signed_prefix_parities(key, ends); + std::vector mine(ends.size()); + for (std::size_t i = 0; i < ends.size(); ++i) + mine[i] = pref[i] & mask; + auto opened = open_additive(net, self, mine); + std::vector pts(ends.size()); + for (std::size_t i = 0; i < ends.size(); ++i) + pts[i] = share_bits(eval_point(cmp, key, ends[i])) & mask; + auto opt_all = open_additive(net, self, pts); + if (self == role::p0) + { + for (std::size_t i = 0; i < ends.size(); ++i) + { + require((opened[i] & mask) + == (ends[i] > alpha ? beta : 0u), + "signed prefix"); + require((opt_all[i] & mask) == (ends[i] > alpha ? beta : 0u), + "prefix vs point"); + } + } + }; + require_opened(dist_with_cmp_key(net, self, x0, x1, gt(beta), on, on), + self, encoded_xor_point(x0, x1)); + return 0; +} + +int grotto_signed_segment_onehot(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 40; + const Input x0 = 0x31; + const Input x1 = static_cast(alpha ^ x0); + const std::array ends{{0, 1, 10, 40, 80, 120, 200, 255}}; + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + auto seg = grotto::signed_segment_parities(key, ends); + std::vector mine(ends.size()); + for (std::size_t i = 0; i < ends.size(); ++i) + mine[i] = seg[i] & mask; + auto opened = open_additive(net, self, mine); + if (self == role::p0) + { + const int hot = piece_containing(alpha, ends); + u64 sum = 0; + for (std::size_t i = 0; i < ends.size(); ++i) + { + u64 bit = opened[i] & mask; + sum = (sum + bit) & mask; + require(bit + == (i == static_cast(hot) ? 1u : 0u), + "segment onehot"); + } + require(sum == 1u, "segment sum"); + } + }; + require_opened(dist_with_cmp_key(net, self, x0, x1, gt(u64{1}), on, on), + self, encoded_xor_point(x0, x1)); + return 0; +} + +int grotto_xor_prefix_parity(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x55; + const Input x0 = 0x1c; + const Input x1 = static_cast(alpha ^ x0); + const std::array ends{{0, 1, 16, 64, 128, 200, 254, 255}}; + auto on = [&](const auto & key) { + auto [pref, new_first] = grotto::prefix_parities(key, ends); + (void)new_first; + for (std::size_t i = 0; i < ends.size(); ++i) + { + bool open = open_xor_bit(net, self, pref[i]); + if (self == role::p0) + (void)open; + } + auto segs = grotto::segment_parities(key, ends); + int hot = -1; + for (std::size_t i = 0; i < ends.size(); ++i) + { + bool bit_value = open_xor_bit(net, self, segs[i]); + if (self == role::p0 && bit_value) + { + require(hot < 0, "xor multi hot"); + hot = static_cast(i); + } + } + if (self == role::p0) + require(hot == piece_containing(alpha, ends), "xor segment hot"); + }; + require_tree_prefix(dist_with_point_key(net, self, x0, x1, bit::one, on, on), + self, verifiable_tree_prefix(x0, x1)); + return 0; +} + +int grotto_signum_lut(role self, trio & net) +{ + // Evaluate signum LUT at several signed alphas via signed_segment. + // Walks share one mux sink (count = alphas). Segment opens collapse into + // one packed vector exchange after every keygen. + const std::array alphas{{-100, -1, 0, 1, 40, 127, -128}}; + auto lut = grotto::make_exact_constant_lut( + grotto::exact_constant::signum, 0); + require(lut.bounds.size() == 3u, "signum bounds"); + std::array ends{}; + for (std::size_t i = 0; i < 3; ++i) + ends[i] = lut.bounds[i]; + + constexpr std::size_t n = alphas.size(); + std::vector seg_shares; + seg_shares.reserve(n * 3); + u64 mask = 0; + + std::unique_ptr sink; + if (self != role::p2) + { + using pair_type = dist::comparison_pair_t; + constexpr std::size_t depth = pair_type::first_type::key_type::depth; + sink = net.batch(n, dpf::net::ds_walk_slot_bytes(depth, false)); + } + + for (std::size_t i = 0; i < n; ++i) + { + const std::int8_t alpha = alphas[i]; + if (self == role::p2) + { + require_opened(dist_with_cmp_key( + net, self, alpha, std::int8_t{0}, gt(u64{1}), + [](const auto &) {}, [](const auto &) {}), + self, encoded_xor_point(alpha, std::int8_t{0})); + continue; + } + auto on = [&](const auto & key) { + mask = key.cmp().mask; + auto seg = grotto::signed_segment_parities(key, ends); + for (std::size_t j = 0; j < 3; ++j) + seg_shares.push_back(seg[j] & mask); + }; + if (self == role::p0) + { + auto result = dist::comparison_party( + net, alpha, gt(u64{1}), sink.get(), i); + on(result.dpf_key); + require_opened(std::optional{result.opened_point}, + self, encoded_xor_point(alpha, std::int8_t{0})); + } + else + { + auto result = dist::comparison_party( + net, std::int8_t{0}, gt(u64{1}), sink.get(), i); + on(result.dpf_key); + require_opened(std::optional{result.opened_point}, + self, encoded_xor_point(alpha, std::int8_t{0})); + } + } + + if (self == role::p2) + return 0; + + auto opened = open_additive(net, self, seg_shares); + if (self == role::p0) + { + for (std::size_t i = 0; i < n; ++i) + { + u64 acc = 0; + for (std::size_t j = 0; j < 3; ++j) + { + acc += (opened[i * 3 + j] & mask) + * static_cast(lut.values[j]); + } + const std::int8_t alpha = alphas[i]; + const std::int64_t want = + alpha < 0 ? -1 : (alpha > 0 ? 1 : 0); + require(static_cast(acc) == want, "signum lut"); + } + } + return 0; +} + +template +int dist_offset_horner(role self, trio & net, Input center0, Input center1, + Input center, Input eta, const std::vector & knots, + const std::vector> & coeff, + const char * failure) +{ + const auto pieces = + grotto::offset_horner_detail::prepare_pieces( + knots, coeff, eta); + std::vector shifted(pieces.size()); + std::vector> ordered(pieces.size()); + std::vector kappa(pieces.size()); + for (std::size_t i = 0; i < pieces.size(); ++i) + { + shifted[i] = pieces[i].knot; + ordered[i] = pieces[i].coeff; + kappa[i] = pieces[i].kappa; + } + + std::array, Degree + 1> segments; + u64 payload = 1; + for (std::size_t m = 0; m <= Degree; ++m) + { + const u64 power = payload; + auto on = [&](const auto & key) { + const u64 wrap_share = self == role::p0 ? power : 0ULL; + segments[m] = grotto::offset_horner_detail::segments_of( + key, shifted, wrap_share); + }; + require_opened(dist_with_cmp_key( + net, self, center0, center1, gt(power), on, on), + self, encoded_xor_point(center0, center1)); + payload *= center; + } + if (self == role::p2) + return 0; + + const auto shares = + grotto::offset_horner_detail::contributions( + segments, ordered, kappa); + u64 share = 0; + for (u64 term : shares) + share += term; + const u64 open = open_additive(net, self, share); + if (self == role::p0) + { + require(open + == grotto::offset_horner_clear( + center, knots, coeff, eta), + failure); + } + return 0; +} + +template +int grotto_offset_horner_deg(role self, trio & net) +{ + using Input = std::uint8_t; + const Input center = 3; + const Input eta = 4; + const std::vector knots{0}; + std::vector> coeff(1); + const u64 raw[4] = {5, 0, 1, 2}; + for (std::size_t k = 0; k <= Degree; ++k) + coeff[0][k] = k < 4 ? raw[k] : 0u; + const Input c0 = 0x11; + const Input c1 = static_cast(center ^ c0); + return dist_offset_horner( + self, net, c0, c1, center, eta, knots, coeff, "offset horner"); +} + +int grotto_offset_horner_multipiece(role self, trio & net) +{ + constexpr std::size_t D = 3; + using Input = std::uint8_t; + const Input center = 12; + const Input eta = 3; + const std::vector knots{0, 10, 50}; + std::vector> coeff{ + {{1, 0, 0, 0}}, + {{0, 2, 0, 0}}, + {{7, 0, 0, 1}}, + }; + const Input c0 = 0x25; + const Input c1 = static_cast(center ^ c0); + return dist_offset_horner( + self, net, c0, c1, center, eta, knots, coeff, "oh multipiece"); +} + +int grotto_geneval_offset_horner(role self, trio & net) +{ + constexpr std::size_t D = 3; + using Input = std::uint8_t; + const Input center = 3; + const Input eta = 4; + const Input c0 = 0x11; + const Input c1 = static_cast(center ^ c0); + const std::vector knots{0}; + std::vector> coeff{{{5, 0, 1, 2}}}; + return dist_offset_horner( + self, net, c0, c1, center, eta, knots, coeff, "geneval oh"); +} + +// ============================================================================ +// Geneval / DS extreme +// ============================================================================ + +int geneval_true_point_shares(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 77; + const Input off_x = static_cast(alpha ^ 0x80); + auto on = [&](const auto & key) { + std::vector mine{ + share_bits(*eval_point(key, alpha)), + share_bits(*eval_point(key, off_x))}; + auto opened = open_subtractive(net, self, mine); + if (self == role::p0) + { + require(opened[0] == beta, "geneval on"); + require(opened[1] == 0u, "geneval off"); + } + }; + require_tree_prefix(dist_with_point_key(net, self, x0, x1, beta, on, on), + self, verifiable_tree_prefix(x0, x1)); + return 0; +} + +int geneval_interval_dense(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 50; + const Input x0 = 7; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 3; + const Input from = 40, to = 60; + auto on = [&](const auto & key) { + std::vector mine; + mine.reserve(static_cast(to - from) + 1u); + for (unsigned x = from;; ++x) + { + mine.push_back(share_bits(*eval_point(key, static_cast(x)))); + if (x == to) + break; + } + auto out = open_subtractive(net, self, mine); + if (self == role::p0) + { + for (std::size_t i = 0; i < out.size(); ++i) + { + const Input x = static_cast(from + i); + require(out[i] == (x == alpha ? beta : 0u), "geneval interval"); + } + } + }; + require_tree_prefix(dist_with_point_key(net, self, x0, x1, beta, on, on), + self, verifiable_tree_prefix(x0, x1)); + return 0; +} + +int geneval_cmp_dense_gt(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 40; + const Input x0 = 0x11; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 7; + const std::vector ends{0, 1, 10, 39, 40, 41, 100, 200, 255}; + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + std::vector mine; + mine.reserve(ends.size()); + for (Input x : ends) + mine.push_back(share_bits(eval_point(cmp, key, x)) & mask); + auto opened = open_additive(net, self, mine); + if (self == role::p0) + { + for (std::size_t i = 0; i < ends.size(); ++i) + require((opened[i] & mask) + == (ends[i] > alpha ? beta : 0u), + "geneval cmp"); + } + }; + require_opened(dist_with_cmp_key(net, self, x0, x1, gt(beta), on, on), + self, encoded_xor_point(x0, x1)); + return 0; +} + +template +int geneval_cmp_kind(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 100; + const Input x0 = 3; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 5; + const std::vector ends{0, 50, 99, 100, 101, 150, 255}; + auto run = [&](auto spec) { + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + std::vector mine; + mine.reserve(ends.size()); + for (Input x : ends) + mine.push_back(share_bits(eval_point(cmp, key, x)) & mask); + auto opened = open_additive(net, self, mine); + if (self == role::p0) + { + for (std::size_t i = 0; i < ends.size(); ++i) + require((opened[i] & mask) + == expect_cmp(Kind, ends[i], alpha, beta), + "geneval cmp kind"); + } + }; + require_opened(dist_with_cmp_key(net, self, x0, x1, spec, on, on), + self, encoded_xor_point(x0, x1)); + }; + if constexpr (Kind == 0) + run(lt(beta)); + else if constexpr (Kind == 1) + run(leq(beta)); + else if constexpr (Kind == 2) + run(gt(beta)); + else + run(geq(beta)); + return 0; +} + +int ds_cmp_many_points(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 77; + const Input x0 = 3; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 11; + std::vector pts; + for (int x = 0; x < 256; x += 5) + pts.push_back(static_cast(x)); + pts.push_back(76); + pts.push_back(77); + pts.push_back(78); + std::sort(pts.begin(), pts.end()); + pts.erase(std::unique(pts.begin(), pts.end()), pts.end()); + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + std::vector mine; + for (Input x : pts) + mine.push_back(share_bits(eval_point(cmp, key, x)) & mask); + auto opened = open_additive(net, self, mine); + if (self == role::p0) + { + for (std::size_t i = 0; i < pts.size(); ++i) + require((opened[i] & mask) + == (pts[i] > alpha ? beta : 0u), + "ds cmp"); + } + }; + require_opened(dist_with_cmp_key(net, self, x0, x1, gt(beta), on, on), + self, encoded_xor_point(x0, x1)); + return 0; +} + +int ds_vs_geneval_cmp_agree(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 40; + const Input x0 = 0x11; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 7; + const std::vector ends{0, 1, 10, 40, 200, 255}; + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + std::vector first; + std::vector second; + for (Input x : ends) + { + first.push_back(share_bits(eval_point(cmp, key, x)) & mask); + second.push_back(share_bits(eval_point(cmp, key, x)) & mask); + } + const auto first_open = open_additive(net, self, first); + const auto second_open = open_additive(net, self, second); + if (self == role::p0) + { + for (std::size_t i = 0; i < ends.size(); ++i) + { + const u64 want = ends[i] > alpha ? beta : 0u; + require((first_open[i] & mask) == want, "first open"); + require((second_open[i] & mask) == want, "second open"); + } + } + }; + require_opened(dist_with_cmp_key(net, self, x0, x1, gt(beta), on, on), + self, encoded_xor_point(x0, x1)); + return 0; +} + +int geneval_arith_point_true(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x90; + const Input x0 = 0x30; + const Input x1 = static_cast(alpha - x0); // additive + const u64 beta = 19; + const Input off_x = static_cast(alpha + 1); + auto on_key = [&](const auto & key) { + std::vector mine{ + share_bits(*eval_point(key, alpha)), + share_bits(*eval_point(key, off_x))}; + auto opened = open_subtractive(net, self, mine); + if (self == role::p0) + { + require(opened[0] == beta, "geneval arith on"); + require(opened[1] == 0u, "geneval arith off"); + } + }; + require_tree_prefix( + dist_with_point_key( + net, self, x0, x1, beta, on_key, on_key, false, true), + self, verifiable_tree_prefix( + alpha, Input{}, true)); + return 0; +} + +// ============================================================================ +// Registration +// ============================================================================ + +#define REG(name, tags, fn, benchable) \ + register_flow(flow{#name, tags, fn, benchable}) + +} // namespace extreme + +void register_extreme_flows() +{ + using namespace extreme; + + // Complex beaver + REG(beaver_dot_n64, "beaver dot extreme bench", beaver_dot_extreme_n<64>, true); + REG(beaver_dot_n128, "beaver dot extreme bench", beaver_dot_extreme_n<128>, true); + REG(beaver_nested_dots, "beaver poly extreme bench", beaver_nested_dots, true); + REG(beaver_tuple_cascade, "beaver poly extreme bench", beaver_tuple_cascade, true); + REG(beaver_mixed_batch_poly, "beaver poly horner mux extreme bench", + beaver_mixed_batch_poly, true); + REG(beaver_factored_multilinear, "beaver poly extreme bench", + beaver_factored_multilinear, true); + + // DCF dense / full / blocked + REG(dcf_dense_lt, "dcf extreme bench", dcf_dense_grid<0>, true); + REG(dcf_dense_leq, "dcf extreme bench", dcf_dense_grid<1>, true); + REG(dcf_dense_gt, "dcf extreme bench", dcf_dense_grid<2>, true); + REG(dcf_dense_geq, "dcf extreme bench", dcf_dense_grid<3>, true); + REG(dcf_full_lt, "dcf extreme bench", dcf_full_domain<0>, true); + REG(dcf_full_leq, "dcf extreme bench", dcf_full_domain<1>, true); + REG(dcf_full_gt, "dcf extreme bench", dcf_full_domain<2>, true); + REG(dcf_full_geq, "dcf extreme bench", dcf_full_domain<3>, true); + REG(dcf_blocked_interval_ip, "dcf blocked extreme bench", + dcf_blocked_interval_ip, true); + + // Grotto + REG(grotto_signed_prefix_dense, "grotto dcf extreme bench", + grotto_signed_prefix_dense, true); + REG(grotto_signed_segment_onehot, "grotto dcf extreme bench", + grotto_signed_segment_onehot, true); + REG(grotto_xor_prefix_parity, "grotto dpf extreme bench", + grotto_xor_prefix_parity, true); + REG(grotto_signum_lut, "grotto lut extreme bench", grotto_signum_lut, true); + REG(grotto_offset_horner_d1, "grotto horner extreme bench", + grotto_offset_horner_deg<1>, true); + REG(grotto_offset_horner_d2, "grotto horner extreme bench", + grotto_offset_horner_deg<2>, true); + REG(grotto_offset_horner_d3, "grotto horner extreme bench", + grotto_offset_horner_deg<3>, true); + REG(grotto_offset_horner_multipiece, "grotto horner extreme bench", + grotto_offset_horner_multipiece, true); + REG(grotto_geneval_offset_horner, "grotto geneval horner extreme bench", + grotto_geneval_offset_horner, true); + + // Geneval / DS + REG(geneval_true_point_shares, "geneval extreme bench", + geneval_true_point_shares, true); + REG(geneval_interval_dense, "geneval extreme bench", + geneval_interval_dense, true); + REG(geneval_cmp_dense_gt, "geneval dcf extreme bench", + geneval_cmp_dense_gt, true); + REG(geneval_cmp_lt, "geneval dcf extreme bench", geneval_cmp_kind<0>, true); + REG(geneval_cmp_leq, "geneval dcf extreme bench", geneval_cmp_kind<1>, true); + REG(geneval_cmp_gt, "geneval dcf extreme bench", geneval_cmp_kind<2>, true); + REG(geneval_cmp_geq, "geneval dcf extreme bench", geneval_cmp_kind<3>, true); + REG(geneval_arith_point_true, "geneval extreme bench", + geneval_arith_point_true, true); + REG(ds_cmp_many_points, "ds dcf extreme bench", ds_cmp_many_points, true); + REG(ds_vs_geneval_cmp_agree, "ds geneval dcf extreme bench", + ds_vs_geneval_cmp_agree, true); +} + +#undef REG + +} // namespace party +} // namespace dpf diff --git a/party/flows_gadget.cpp b/party/flows_gadget.cpp new file mode 100644 index 0000000..9cb0a42 --- /dev/null +++ b/party/flows_gadget.cpp @@ -0,0 +1,642 @@ +/// @file party/flows_gadget.cpp +/// @brief Bench flows for word garbling, stacked Yao, FLUTE, and hidden shuffle. +/// @details Amalgamated into run.cpp. Every cross-party byte goes through +/// `net::trio` (the same local mesh `party_bench` already dials). +/// Two-party gadgets use the p0–p1 link. FLUTE's dealer is p2. +/// The hidden shuffle is the three ring passes, and the receiver +/// feeds the arrived array into the next party step. + +#include "cases.hpp" + +#include +#include +#include +#include + +#include "dpf/arith_garble.hpp" +#include "dpf/flute.hpp" +#include "dpf/shuffle.hpp" +#include "dpf/yao.hpp" +#include "dpf/yao_stack.hpp" + +namespace dpf +{ +namespace party +{ +namespace gadget +{ + +using net::role; +using net::trio; + +void require(bool cond, const char * msg) +{ + if (!cond) + throw std::runtime_error(msg); +} + +void put_lab(std::vector & blob, const arith_garble::lab & lab) +{ + blob.insert(blob.end(), lab.d.begin(), lab.d.end()); +} + +arith_garble::lab take_lab(const std::uint16_t *& p, const std::uint16_t * end, + std::uint16_t mod) +{ + if (static_cast(end - p) < arith_garble::k_digits) + throw std::runtime_error("arith garble: short label"); + arith_garble::lab lab; + lab.mod = mod; + for (std::size_t i = 0; i < arith_garble::k_digits; ++i) + lab.d[i] = *p++; + return lab; +} + +std::uint16_t take_u16(const std::uint16_t *& p, const std::uint16_t * end) +{ + if (p == end) + throw std::runtime_error("arith garble: short frame"); + return *p++; +} + +/// @brief p0 garbles and ships the evaluator view. p1 evaluates that view. +void arith_exchange(trio & net, role self, const arith_garble::circuit & c, + const std::uint16_t * semantic) +{ + const auto plain = arith_garble::eval_plain(c, semantic); + if (self == role::p0) + { + auto st = arith_garble::detail::garble(c); + auto active = arith_garble::detail::evaluate(c, st, semantic); + std::size_t out_i = 0; + for (std::uint32_t id : c.outputs()) + { + const std::uint16_t mod = c.nodes()[id].mod; + const std::uint16_t got = arith_garble::open_shares( + mod, st.zero[id].d[0], active[id].d[0]); + require(got == plain[id], "arith garble: garbler open"); + ++out_i; + } + require(out_i == c.outputs().size(), "arith garble: outputs"); + + std::vector blob; + const auto & nodes = c.nodes(); + for (std::uint32_t i = 0; i < nodes.size(); ++i) + { + const auto & nd = nodes[i]; + if (nd.code == arith_garble::circuit::op::in) + put_lab(blob, active[i]); + else if (nd.code == arith_garble::circuit::op::proj) + { + for (const auto & row : st.proj[i].row) + put_lab(blob, row); + } + else if (nd.code == arith_garble::circuit::op::pass) + { + put_lab(blob, st.pass[i].payload[0]); + put_lab(blob, st.pass[i].payload[1]); + blob.push_back(st.pass[i].flag_ct[0]); + blob.push_back(st.pass[i].flag_ct[1]); + } + } + for (std::uint32_t id : c.outputs()) + blob.push_back(st.zero[id].d[0]); + net.send_vec_to(role::p1, net::msg::bytes, blob); + return; + } + + require(self == role::p1, "arith garble: party"); + auto blob = net.recv_vec_from(role::p0, net::msg::bytes); + const std::uint16_t * p = blob.data(); + const std::uint16_t * end = p + blob.size(); + arith_garble::detail::garble_state st; + const auto & nodes = c.nodes(); + st.zero.resize(nodes.size()); + st.delta.assign(static_cast(arith_garble::k_max_mod) + 1, + arith_garble::lab{}); + for (std::uint16_t m = 1; m <= arith_garble::k_max_mod; ++m) + st.delta[m].mod = m; + st.proj.resize(nodes.size()); + st.pass.resize(nodes.size()); + std::size_t n_in = 0; + for (const auto & nd : nodes) + if (nd.code == arith_garble::circuit::op::in) + ++n_in; + for (std::uint32_t i = 0; i < nodes.size(); ++i) + { + const auto & nd = nodes[i]; + if (nd.code == arith_garble::circuit::op::in) + st.zero[i] = take_lab(p, end, nd.mod); + else if (nd.code == arith_garble::circuit::op::proj) + { + const std::uint16_t m = nodes[nd.a].mod; + require(m > 0, "arith garble: projection modulus"); + st.proj[i].row.resize(static_cast(m - 1)); + for (std::uint16_t color = 1; color < m; ++color) + st.proj[i].row[static_cast(color - 1)] = + take_lab(p, end, nd.mod); + } + else if (nd.code == arith_garble::circuit::op::pass) + { + st.pass[i].payload[0] = take_lab(p, end, nd.mod); + st.pass[i].payload[1] = take_lab(p, end, nd.mod); + st.pass[i].flag_ct[0] = take_u16(p, end); + st.pass[i].flag_ct[1] = take_u16(p, end); + } + } + std::vector masks; + masks.reserve(c.outputs().size()); + for (std::size_t i = 0; i < c.outputs().size(); ++i) + masks.push_back(take_u16(p, end)); + require(p == end, "arith garble: trailing bytes"); + + std::vector zeros(n_in, 0); + auto active = arith_garble::detail::evaluate(c, st, zeros.data()); + std::size_t out_i = 0; + for (std::uint32_t id : c.outputs()) + { + const std::uint16_t mod = nodes[id].mod; + const std::uint16_t got = arith_garble::open_shares( + mod, masks[out_i], active[id].d[0]); + require(got == plain[id], "arith garble: evaluator open"); + ++out_i; + } +} + +int run_proj(role self, trio & net, std::uint16_t mod) +{ + if (self == role::p2) + return 0; + arith_garble::circuit c; + auto x = c.input(mod); + std::vector phi(mod); + for (std::uint16_t i = 0; i < mod; ++i) + phi[i] = static_cast((i * 3) % mod); + c.out(c.project(x, mod, std::move(phi))); + const std::uint16_t in = static_cast(mod / 2); + arith_exchange(net, self, c, &in); + return 0; +} + +int run_mul(role self, trio & net, std::uint16_t p) +{ + if (self == role::p2) + return 0; + arith_garble::circuit c; + auto x = c.input(p); + auto y = c.input(p); + c.out(c.mul(x, y)); + const std::uint16_t in[2] = {static_cast(p - 1), 2}; + arith_exchange(net, self, c, in); + return 0; +} + +int run_thresh(role self, trio & net, unsigned b) +{ + if (self == role::p2) + return 0; + arith_garble::circuit c; + const auto mod = static_cast(b + 1); + std::vector bits; + bits.reserve(b); + for (unsigned i = 0; i < b; ++i) + bits.push_back(c.input(mod)); + c.out(c.threshold(bits, static_cast(b / 2))); + std::vector in(b, 0); + for (unsigned i = 0; i < b; i += 2) + in[i] = 1; + arith_exchange(net, self, c, in.data()); + return 0; +} + +int run_chain(role self, trio & net) +{ + if (self == role::p2) + return 0; + arith_garble::circuit c; + auto x = c.input(7); + auto y = c.input(7); + auto z = c.mul(x, y); + for (int i = 0; i < 3; ++i) + z = c.mul(z, x); + c.out(z); + const std::uint16_t in[2] = {2, 3}; + arith_exchange(net, self, c, in); + return 0; +} + +yao::netlist and_n(unsigned n) +{ + yao::netlist nl; + std::vector in; + in.reserve(n); + for (unsigned i = 0; i < n; ++i) + in.push_back(nl.shared_in()); + auto acc = in[0]; + for (unsigned i = 1; i < n; ++i) + acc = nl.and_(acc, in[i]); + nl.out(acc); + return nl; +} + +yao::netlist xor2() +{ + yao::netlist nl; + auto a = nl.shared_in(); + auto b = nl.shared_in(); + nl.out(nl.xor_(a, b)); + return nl; +} + +/// @brief Garbled tables and the evaluator's labels on the p0–p1 channel. +/// @details Party 1 runs `eval_party1` on the bytes that arrived. The choice +/// labels are the OT output for party 1's bits; base OT is its own +/// bench (`iknp`), not this garble row. +void yao_ship(trio & net, role self, const yao::netlist & nl, + const std::uint8_t * p0_bits, const std::uint8_t * p1_bits) +{ + const role peer = self == role::p0 ? role::p1 : role::p0; + auto & link = net.to(peer); + std::size_t nchoice = 0; + std::size_t ndirect = 0; + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + { + const auto kind = nl.kind_at(i); + if (kind == yao::input::shared || kind == yao::input::priv1) + ++nchoice; + if (kind == yao::input::shared || kind == yao::input::priv0) + ++ndirect; + } + const std::size_t ntable = static_cast(nl.n_and()) * 2u; + std::vector share; + if (self == role::p0) + { + auto g = yao::detail::garble_party0(nl, p0_bits); + require(g.tables.size() == ntable, "yao: table size"); + require(g.direct.size() == ndirect, "yao: direct labels"); + require(g.ot0.size() == nchoice && g.ot1.size() == nchoice, "yao: ot labels"); + std::vector chosen(nchoice); + std::size_t oi = 0; + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + { + const auto kind = nl.kind_at(i); + if (kind != yao::input::shared && kind != yao::input::priv1) + continue; + chosen[oi] = (p1_bits[i] & 1u) ? g.ot1[oi] : g.ot0[oi]; + ++oi; + } + std::vector blob; + blob.reserve(ntable + ndirect + nchoice); + blob.insert(blob.end(), g.tables.begin(), g.tables.end()); + blob.insert(blob.end(), g.direct.begin(), g.direct.end()); + blob.insert(blob.end(), chosen.begin(), chosen.end()); + link.send_vec(blob, net::msg::bytes); + share = std::move(g.share); + } + else + { + const auto blob = link.recv_vec(net::msg::bytes); + require(blob.size() == ntable + ndirect + nchoice, "yao: payload size"); + std::vector tables(ntable); + std::vector direct(ndirect); + std::vector chosen(nchoice); + if (ntable != 0) + std::memcpy(tables.data(), blob.data(), ntable * sizeof(yao::block)); + if (ndirect != 0) + std::memcpy(direct.data(), blob.data() + ntable, + ndirect * sizeof(yao::block)); + if (nchoice != 0) + std::memcpy(chosen.data(), blob.data() + ntable + ndirect, + nchoice * sizeof(yao::block)); + share = yao::detail::eval_party1(nl, tables, direct, chosen); + } + auto other = net.exchange_vec_with(peer, share, net::msg::delta); + require(other.size() == share.size(), "yao: share length"); + std::vector semantic(nl.n_in()); + for (std::uint32_t i = 0; i < nl.n_in(); ++i) + semantic[i] = static_cast(p0_bits[i] ^ p1_bits[i]); + auto plain = yao::eval_plain(nl, semantic.data()); + require(plain.size() == share.size(), "yao: output length"); + for (std::size_t i = 0; i < plain.size(); ++i) + { + const auto opened = static_cast(share[i] ^ other[i]); + require(opened == plain[i], "yao: open"); + } +} + +int run_if(role self, trio & net, unsigned heavy, unsigned light) +{ + if (self == role::p2) + return 0; + auto then_nl = and_n(heavy); + std::vector h0(heavy, 1); + std::vector h1(heavy, 0); + if (self == role::p0) + { + auto else_nl = and_n(light); + std::vector l0(light, 1); + std::vector l1(light, 1); + auto stacked = yao::eval_if(then_nl, else_nl, 0, 0, h0.data(), h1.data(), + l0.data(), l1.data()); + std::vector semantic(heavy, 1); + auto plain = yao::eval_plain(then_nl, semantic.data()); + require(stacked.share0.size() == plain.size(), "yao stack: outputs"); + for (std::size_t i = 0; i < plain.size(); ++i) + { + const auto opened = static_cast( + stacked.share0[i] ^ stacked.share1[i]); + require(opened == plain[i], "yao stack: if"); + } + require(stacked.stack_blocks > 0, "yao stack: empty"); + } + yao_ship(net, self, then_nl, h0.data(), h1.data()); + return 0; +} + +int run_hot(role self, trio & net, unsigned k) +{ + if (self == role::p2) + return 0; + auto active = and_n(2); + const std::uint8_t bits0[2] = {1, 0}; + const std::uint8_t bits1[2] = {0, 1}; + if (self == role::p0) + { + std::vector branches; + std::vector> p0; + std::vector> p1; + branches.reserve(k); + for (unsigned i = 0; i < k; ++i) + { + branches.push_back(i % 2 == 0 ? and_n(2) : xor2()); + p0.push_back({1, static_cast(i & 1u)}); + p1.push_back({0, 1}); + } + auto stacked = yao::eval_one_hot(branches, 0, 0, p0, p1); + const std::uint8_t semantic[2] = {1, 1}; + auto plain = yao::eval_plain(active, semantic); + require(stacked.share0.size() == plain.size(), "yao stack: one-hot outputs"); + for (std::size_t i = 0; i < plain.size(); ++i) + { + const auto opened = static_cast( + stacked.share0[i] ^ stacked.share1[i]); + require(opened == plain[i], "yao stack: one-hot"); + } + require(stacked.stack_blocks > 0, "yao stack: one-hot empty"); + } + yao_ship(net, self, active, bits0, bits1); + return 0; +} + +std::vector flute_columns(unsigned delta, unsigned n_out) +{ + const unsigned rows = 1u << delta; + std::vector columns(static_cast(n_out) * rows); + for (unsigned w = 0; w < n_out; ++w) + for (unsigned j = 0; j < rows; ++j) + columns[static_cast(w) * rows + j] = + static_cast(((j >> (w % delta)) ^ w) & 1u); + return columns; +} + +std::vector flute_bits(unsigned delta) +{ + std::vector bits(delta, 0); + bits[0] = 1; + if (delta > 2) + bits[2] = 1; + return bits; +} + +std::vector flute_pack(const flute::detail::setup & s, unsigned party) +{ + std::vector out; + out.insert(out.end(), s.m.begin(), s.m.end()); + out.insert(out.end(), s.share[party].begin(), s.share[party].end()); + out.insert(out.end(), s.lamz[party].begin(), s.lamz[party].end()); + return out; +} + +int run_flute(role self, trio & net, unsigned delta, unsigned n_out) +{ + const auto columns = flute_columns(delta, n_out); + const auto x = flute_bits(delta); + const unsigned rows = 1u << delta; + const std::uint32_t full = rows - 1u; + if (self == role::p2) + { + auto setup = flute::detail::make_setup(delta, n_out, 2, x.data()); + auto to0 = flute_pack(setup, 0); + auto to1 = flute_pack(setup, 1); + net.send_bytes_to(role::p0, net::msg::bytes, to0.data(), to0.size()); + net.send_bytes_to(role::p1, net::msg::bytes, to1.data(), to1.size()); + return 0; + } + const unsigned party = self == role::p0 ? 0u : 1u; + auto bytes = net.recv_bytes_from(role::p2, net::msg::bytes); + const std::size_t need = static_cast(delta) + rows + n_out; + require(bytes.size() == need, "flute: deal size"); + flute::detail::setup setup; + setup.m.assign(bytes.begin(), bytes.begin() + delta); + setup.share.assign(2, {}); + setup.share[party].assign(bytes.begin() + delta, bytes.begin() + delta + rows); + setup.lamz.assign(2, {}); + setup.lamz[party].assign(bytes.end() - static_cast(n_out), + bytes.end()); + std::vector mine(static_cast(n_out) * 2u); + for (unsigned w = 0; w < n_out; ++w) + { + const std::uint8_t * column = + columns.data() + static_cast(w) * rows; + mine[w] = flute::detail::party_v(setup, party, delta, full, column, + setup.lamz[party][w]); + mine[n_out + w] = setup.lamz[party][w]; + } + const role peer = self == role::p0 ? role::p1 : role::p0; + auto theirs = net.exchange_vec_with(peer, mine, net::msg::bytes); + auto expect = flute::eval_plain(delta, n_out, columns.data(), x.data()); + for (unsigned w = 0; w < n_out; ++w) + { + const std::uint8_t * column = + columns.data() + static_cast(w) * rows; + const std::uint8_t t = flute::detail::dot_column( + full, delta, setup.m.data(), column); + const auto opened = static_cast( + mine[w] ^ theirs[w] ^ t ^ mine[n_out + w] ^ theirs[n_out + w]); + require(opened == expect[w], "flute: open"); + } + return 0; +} + +rss::seed_bundle shuffle_bundle() +{ + rss::seed_bundle bundle{}; + auto fill = [](rss::seed_block & seed, std::uint8_t tag) { + auto * p = reinterpret_cast(&seed); + for (std::size_t i = 0; i < sizeof(seed); ++i) + p[i] = static_cast(tag + i * 17u); + }; + fill(bundle.k01, 1); + fill(bundle.k12, 2); + fill(bundle.k20, 3); + return bundle; +} + +shuffle::shuffle_party_view shuffle_view(unsigned me, std::size_t n) +{ + std::uint64_t rng = 0xA5A5A5A5A5A5A5A5ull; + auto draw = [&] { + rng = rng * 6364136223846793005ull + 1u; + return rng; + }; + shuffle::shuffle_party_view view; + view.own.resize(n); + view.next.resize(n); + for (std::size_t i = 0; i < n; ++i) + { + const auto a = draw(); + const auto b = draw(); + const auto c = static_cast(i) - a - b; + if (me == 0) + { + view.own[i] = a; + view.next[i] = b; + } + else if (me == 1) + { + view.own[i] = b; + view.next[i] = c; + } + else + { + view.own[i] = c; + view.next[i] = a; + } + } + return view; +} + +int run_shuffle(role self, trio & net, std::size_t n) +{ + const unsigned me = static_cast(self); + const auto bundle = shuffle_bundle(); + const std::uint64_t index = 1; + auto seeds = rss::party_seeds::from_bundle(bundle, me); + auto view = shuffle_view(me, n); + const unsigned order[3] = {2u, 0u, 1u}; + for (unsigned left : order) + { + const unsigned u = shuffle::hidden_u_party(left); + const unsigned side = shuffle::hidden_side_party(left); + if (me == u) + { + auto step = shuffle::shuffle_hidden_pass( + me, seeds, view, index, left, nullptr); + require(step.out.sends, "shuffle: u sends"); + require(step.out.to == side, "shuffle: u recipient"); + net.send_vec_to(static_cast(step.out.to), net::msg::ring_vector, + step.out.data); + view = std::move(step.view); + } + else if (me == side) + { + auto inbound = net.recv_vec_from( + static_cast(u), net::msg::ring_vector); + auto step = shuffle::shuffle_hidden_pass( + me, seeds, view, index, left, &inbound); + require(step.out.sends, "shuffle: side sends"); + require(step.out.to == left, "shuffle: side recipient"); + net.send_vec_to(static_cast(step.out.to), net::msg::ring_vector, + step.out.data); + view = std::move(step.view); + } + else + { + auto inbound = net.recv_vec_from( + static_cast(side), net::msg::ring_vector); + auto step = shuffle::shuffle_hidden_pass( + me, seeds, view, index, left, &inbound); + require(!step.out.sends, "shuffle: left-out is silent"); + view = std::move(step.view); + } + } + if (self == role::p0) + { + auto from1 = net.recv_vec_from(role::p1, net::msg::ring_vector); + auto from2 = net.recv_vec_from(role::p2, net::msg::ring_vector); + require(from1.size() == n && from2.size() == n, "shuffle: open size"); + std::vector clear(n); + for (std::size_t i = 0; i < n; ++i) + clear[i] = i; + auto expect = shuffle::permute(clear, + shuffle::permutation_from_seed(bundle.k01, n, index)); + expect = shuffle::permute(expect, + shuffle::permutation_from_seed(bundle.k12, n, index)); + expect = shuffle::permute(expect, + shuffle::permutation_from_seed(bundle.k20, n, index)); + for (std::size_t i = 0; i < n; ++i) + { + const auto got = view.own[i] + from1[i] + from2[i]; + require(got == expect[i], "shuffle: open"); + } + } + else + { + net.send_vec_to(role::p0, net::msg::ring_vector, view.own); + } + return 0; +} + +int arith_proj_m5(role self, trio & net) { return run_proj(self, net, 5); } +int arith_proj_m17(role self, trio & net) { return run_proj(self, net, 17); } +int arith_proj_m64(role self, trio & net) { return run_proj(self, net, 64); } +int arith_mul_p5(role self, trio & net) { return run_mul(self, net, 5); } +int arith_mul_p7(role self, trio & net) { return run_mul(self, net, 7); } +int arith_mul_p11(role self, trio & net) { return run_mul(self, net, 11); } +int arith_thresh_b8(role self, trio & net) { return run_thresh(self, net, 8); } +int arith_thresh_b16(role self, trio & net) { return run_thresh(self, net, 16); } +int arith_chain_mul4(role self, trio & net) { return run_chain(self, net); } +int yao_if_4_2(role self, trio & net) { return run_if(self, net, 4, 2); } +int yao_if_16_8(role self, trio & net) { return run_if(self, net, 16, 8); } +int yao_onehot_k4(role self, trio & net) { return run_hot(self, net, 4); } +int yao_onehot_k8(role self, trio & net) { return run_hot(self, net, 8); } +int flute_d2(role self, trio & net) { return run_flute(self, net, 2, 1); } +int flute_d4(role self, trio & net) { return run_flute(self, net, 4, 1); } +int flute_d8(role self, trio & net) { return run_flute(self, net, 8, 1); } +int flute_d4_o8(role self, trio & net) { return run_flute(self, net, 4, 8); } +int shuffle_n16(role self, trio & net) { return run_shuffle(self, net, 16); } +int shuffle_n64(role self, trio & net) { return run_shuffle(self, net, 64); } +int shuffle_n256(role self, trio & net) { return run_shuffle(self, net, 256); } + +#define REG(name, tags, fn) \ + register_flow(flow{#name, tags, fn, true}) + +} // namespace gadget + +void register_gadget_flows() +{ + using namespace gadget; + REG(arith_proj_m5, "bench arith garble", arith_proj_m5); + REG(arith_proj_m17, "bench arith garble", arith_proj_m17); + REG(arith_proj_m64, "bench arith garble", arith_proj_m64); + REG(arith_mul_p5, "bench arith garble", arith_mul_p5); + REG(arith_mul_p7, "bench arith garble", arith_mul_p7); + REG(arith_mul_p11, "bench arith garble", arith_mul_p11); + REG(arith_thresh_b8, "bench arith garble", arith_thresh_b8); + REG(arith_thresh_b16, "bench arith garble", arith_thresh_b16); + REG(arith_chain_mul4, "bench arith garble", arith_chain_mul4); + REG(yao_if_4_2, "bench yao stack", yao_if_4_2); + REG(yao_if_16_8, "bench yao stack", yao_if_16_8); + REG(yao_onehot_k4, "bench yao stack", yao_onehot_k4); + REG(yao_onehot_k8, "bench yao stack", yao_onehot_k8); + REG(flute_d2, "bench flute", flute_d2); + REG(flute_d4, "bench flute", flute_d4); + REG(flute_d8, "bench flute", flute_d8); + REG(flute_d4_o8, "bench flute", flute_d4_o8); + REG(shuffle_n16, "bench shuffle rss", shuffle_n16); + REG(shuffle_n64, "bench shuffle rss", shuffle_n64); + REG(shuffle_n256, "bench shuffle rss", shuffle_n256); +} + +} // namespace party +} // namespace dpf diff --git a/party/flows_recent.cpp b/party/flows_recent.cpp new file mode 100644 index 0000000..f0d26e7 --- /dev/null +++ b/party/flows_recent.cpp @@ -0,0 +1,1654 @@ +/// @file party/flows_recent.cpp +/// @brief (2+1) flows for the newest DPF and Grotto surfaces. +/// @details Amalgamated into run.cpp (do not compile as a second TU). +/// Full uint8 domains, and checks that a corrupted proof, seed, +/// correction word, MAC tag, or sketch fails closed. + +#include "cases.hpp" +#include "dist_dpf3.hpp" +#include "dist_ds.hpp" +#include "flow_util.hpp" +#include "key_io.hpp" +#include "registry.hpp" + +#include +#include +#include +#include +#include + +#include "simde/simde/x86/avx2.h" + +#include "dpf/blocked_dcf.hpp" +#include "dpf/dcf.hpp" +#include "dpf/dpf3.hpp" +#include "dpf/dpf3_cmp.hpp" +#include "dpf/dpf3_ds.hpp" +#include "dpf/dpf3_multipoint.hpp" +#include "dpf/eval_full.hpp" +#include "dpf/eval_point.hpp" +#include "dpf/fp61.hpp" +#include "dpf/geneval.hpp" +#include "dpf/interval.hpp" +#include "dpf/multipoint.hpp" +#include "dpf/prg_aes_ccr.hpp" +#include "dpf/shamir3.hpp" +#include "dpf/verifiable.hpp" +#include "grotto/closed_form.hpp" +#include "grotto/exact_steps.hpp" +#include "grotto/offset_poly.hpp" +#include "grotto/offset_jet.hpp" +#include "grotto/offset_repr.hpp" +#include "grotto/offset_twist.hpp" +#include "grotto/ring_switch.hpp" +#include "grotto/residue.hpp" + +namespace dpf +{ +namespace party +{ +namespace recent +{ + +using util::open_additive; +using util::open_and_sketch; +using util::open_subtractive; +using util::require; +using util::role; +using util::share_bits; +using util::trio; +using u64 = std::uint64_t; + +std::vector exchange_u64(trio & net, role self, const std::vector & mine) +{ + role peer = self == role::p0 ? role::p1 : role::p0; + if (self == role::p0) + { + net.to(peer).send_vec(mine); + return net.to(peer).recv_vec(); + } + auto theirs = net.to(peer).recv_vec(); + net.to(peer).send_vec(mine); + return theirs; +} + +std::vector exchange_u8(trio & net, role self, + const std::vector & mine) +{ + role peer = self == role::p0 ? role::p1 : role::p0; + if (self == role::p0) + { + net.to(peer).send_vec(mine); + return net.to(peer).recv_vec(); + } + auto theirs = net.to(peer).recv_vec(); + net.to(peer).send_vec(mine); + return theirs; +} + +void send_proofs(net::channel & c, const std::vector & v) +{ + c.send_bytes(net::msg::proof_token, + reinterpret_cast(v.data()), + v.size() * sizeof(proof_token)); +} + +std::vector recv_proofs(net::channel & c, std::size_t n) +{ + auto body = c.recv_bytes(net::msg::proof_token); + require(body.size() == n * sizeof(proof_token), "proof bytes"); + std::vector out(n); + std::memcpy(out.data(), body.data(), body.size()); + return out; +} + +std::vector exchange_proofs(trio & net, role self, + const std::vector & mine) +{ + role peer = self == role::p0 ? role::p1 : role::p0; + if (self == role::p0) + { + send_proofs(net.to(peer), mine); + return recv_proofs(net.to(peer), mine.size()); + } + auto theirs = recv_proofs(net.to(peer), mine.size()); + send_proofs(net.to(peer), mine); + return theirs; +} + +proof_token exchange_proof(trio & net, role self, proof_token mine) +{ + std::vector one{mine}; + return exchange_proofs(net, self, one)[0]; +} + +template +void flip_seeds(Key & key) +{ + using arr = typename std::decay_t::correction_seeds_array; + for (auto & cs : const_cast(key.correction_seeds())) + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); +} + +template +void flip_words(Key & key) +{ + using arr = typename std::decay_t::correction_words_array; + for (auto & word : const_cast(key.correction_words())) + word = simde_mm_xor_si128(word, simde_mm_set1_epi8(0x5a)); +} + +int recent_half_tree_domain(role self, trio & net) +{ + using Input = std::uint8_t; + using Ht = prg::aes128_ccr; + const Input alpha = 0; + const Input x0 = 0x37; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 0x1111; + auto on = [&](const auto & key) { + std::vector shares(256); + std::vector pis(256); + for (unsigned x = 0; x < 256; ++x) + { + shares[x] = share_bits(*eval_point( + key, static_cast(x), prove(pis[x]))); + } + auto peer_s = exchange_u64(net, self, shares); + auto peer_p = exchange_proofs(net, self, pis); + if (self == role::p0) + { + for (unsigned x = 0; x < 256; ++x) + { + require(shares[x] - peer_s[x] + == (x == alpha ? beta : 0u), + "half-tree domain value"); + require(verify(pis[x], peer_p[x]), + "half-tree domain proof"); + } + } + }; + require_tree_prefix(dist_with_point_key(net, self, x0, x1, beta, on, on), + self, verifiable_tree_prefix(x0, x1)); + return 0; +} + +int recent_half_tree_seed_tamper(role self, trio & net) +{ + using Input = std::uint8_t; + using Ht = prg::aes128_ccr; + const Input alpha = 7; + const Input x0 = 0x25; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 9; + auto on = [&](auto key) { + if (self == role::p0) + flip_seeds(key); + std::vector pis(256); + for (unsigned x = 0; x < 256; ++x) + { + proof_token pi{}; + (void)*eval_point(key, static_cast(x), prove(pi)); + pis[x] = pi; + } + auto peer = exchange_proofs(net, self, pis); + if (self == role::p0) + { + int failed = 0; + for (unsigned x = 0; x < 256; ++x) + if (!verify(pis[x], peer[x])) + ++failed; + require(failed > 0, "seed tamper invisible"); + } + }; + require_tree_prefix(dist_with_point_key(net, self, x0, x1, beta, on, on), + self, verifiable_tree_prefix(x0, x1)); + return 0; +} + +int recent_word_tamper(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 5; + auto on = [&](auto key) { + if (self == role::p0) + flip_words(key); + std::vector shares(256); + auto [bufs, iters] = eval_full(key); + (void)bufs; + auto it = std::begin(iters); + for (unsigned x = 0; x < 256; ++x, ++it) + shares[x] = share_bits(*it); + auto peer = exchange_u64(net, self, shares); + if (self == role::p0) + { + int failed = 0; + for (unsigned x = 0; x < 256; ++x) + { + const u64 expect = x == alpha ? beta : 0u; + if (shares[x] - peer[x] != expect) + ++failed; + } + require(failed > 0, "word tamper invisible"); + } + }; + require_tree_prefix(dist_with_point_key(net, self, x0, x1, beta, on, on), + self, verifiable_tree_prefix(x0, x1)); + return 0; +} + +int recent_cmp_domain(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x40; + const Input x0 = 0x19; + const Input x1 = static_cast(alpha ^ x0); + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + std::vector shares(256); + std::vector pis(256); + for (unsigned x = 0; x < 256; ++x) + { + shares[x] = share_bits(eval_point( + cmp, key, static_cast(x), prove(pis[x]))); + } + auto peer_s = exchange_u64(net, self, shares); + auto peer_p = exchange_proofs(net, self, pis); + if (self == role::p0) + { + for (unsigned x = 0; x < 256; ++x) + { + require(((shares[x] + peer_s[x]) & mask) + == (x < alpha ? 1u : 0u), + "cmp domain value"); + require(verify(pis[x], peer_p[x]), "cmp domain proof"); + } + } + }; + dist_with_cmp_key(net, self, x0, x1, lt(u64{1}), on, on, verifiable{}); + return 0; +} + +int recent_blocked_domain(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x11; + const Input x1 = static_cast(alpha ^ x0); + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + std::vector shares(256); + std::vector pis(256); + for (unsigned x = 0; x < 256; ++x) + { + shares[x] = share_bits(eval_point( + cmp, key, static_cast(x), prove(pis[x]))); + } + auto peer_s = exchange_u64(net, self, shares); + auto peer_p = exchange_proofs(net, self, pis); + if (self == role::p0) + { + for (unsigned x = 0; x < 256; ++x) + { + require(((shares[x] + peer_s[x]) & mask) + == (x < alpha ? 1u : 0u), + "blocked value"); + require(verify(pis[x], peer_p[x]), "blocked proof"); + } + } + }; + dist_with_cmp_key(net, self, x0, x1, + block_width<4>(lt(u64{1})), on, on, verifiable{}); + return 0; +} + +int recent_multipoint_domain(role self, trio & net) +{ + using Input = std::uint8_t; + const std::vector alphas{1, 9, 40, 255}; + const std::vector betas{7, 11, 3, 1}; + if (self == role::p2) + { + auto keys = make_multipoint(alphas, betas, verifiable{}); + std::vector s0(256), s1(256); + std::vector p0(256), p1(256); + for (unsigned x = 0; x < 256; ++x) + { + const Input q = static_cast(x); + s0[x] = share_bits(eval_multipoint(keys.first, q, prove(p0[x]))); + s1[x] = share_bits(eval_multipoint(keys.second, q, prove(p1[x]))); + } + net.to(role::p0).send_vec(s0); + net.to(role::p1).send_vec(s1); + send_proofs(net.to(role::p0), p0); + send_proofs(net.to(role::p1), p1); + + require(!keys.first.buckets.empty(), "multipoint buckets"); + for (auto & bucket : keys.first.buckets) + flip_seeds(bucket); + proof_token a0{}, a1{}; + audit_multipoint(keys.first, prove(a0)); + audit_multipoint(keys.second, prove(a1)); + require(!verify(a0, a1), "dealer audit"); + send_proofs(net.to(role::p0), std::vector{a0}); + send_proofs(net.to(role::p1), std::vector{a1}); + return 0; + } + auto shares = net.to(role::p2).recv_vec(); + auto proofs = recv_proofs(net.to(role::p2), 256); + auto peer_s = exchange_u64(net, self, shares); + auto peer_p = exchange_proofs(net, self, proofs); + if (self == role::p0) + { + for (unsigned x = 0; x < 256; ++x) + { + u64 want = 0; + for (std::size_t i = 0; i < alphas.size(); ++i) + if (alphas[i] == static_cast(x)) + want = betas[i]; + require(shares[x] - peer_s[x] == want, "multipoint value"); + require(verify(proofs[x], peer_p[x]), "multipoint proof"); + } + } + auto mine_audit = recv_proofs(net.to(role::p2), 1); + auto peer_audit = exchange_proofs(net, self, mine_audit); + if (self == role::p0) + require(!verify(mine_audit[0], peer_audit[0]), "bucket seed tamper"); + return 0; +} + +int recent_fp61_mac(role self, trio & net) +{ + const fp61 y{20}; + const fp61 scale{2}; + if (self == role::p2) + { + auto key = sample_mac_key(); + auto shares = mac_share_value(y, key); + std::vector a{ + shares.first.value.raw(), shares.first.tag.raw(), key.delta.raw()}; + std::vector b{ + shares.second.value.raw(), shares.second.tag.raw(), key.delta.raw()}; + net.to(role::p0).send_vec(a); + net.to(role::p1).send_vec(b); + return 0; + } + auto mine = net.to(role::p2).recv_vec(); + require(mine.size() == 3u, "mac wire"); + mac_share local{fp61{mine[0]}, fp61{mine[1]}}; + mac_key key{fp61{mine[2]}}; + std::vector body{local.value.raw(), local.tag.raw()}; + auto peer_body = exchange_u64(net, self, body); + mac_share peer{fp61{peer_body[0]}, fp61{peer_body[1]}}; + if (self == role::p0) + { + require(mac_verify(local, peer, key), "honest mac"); + auto opened = local.value + peer.value; + require(opened == y, "opened y"); + auto scaled0 = mac_scale(local, scale); + auto scaled1 = mac_scale(peer, scale); + require(mac_verify(scaled0, scaled1, key), "scaled mac"); + require(scaled0.value + scaled1.value == fp61{40}, "scaled open"); + } + if (self == role::p0) + local.value = local.value + fp61{1}; + body = {local.value.raw(), local.tag.raw()}; + peer_body = exchange_u64(net, self, body); + peer = mac_share{fp61{peer_body[0]}, fp61{peer_body[1]}}; + if (self == role::p0) + require(!mac_verify(local, peer, key), "value tamper"); + + local = mac_share{fp61{mine[0]}, fp61{mine[1]}}; + if (self == role::p0) + local.tag = local.tag + fp61{1}; + body = {local.value.raw(), local.tag.raw()}; + peer_body = exchange_u64(net, self, body); + peer = mac_share{fp61{peer_body[0]}, fp61{peer_body[1]}}; + if (self == role::p0) + require(!mac_verify(local, peer, key), "tag tamper"); + return 0; +} + +int recent_offset_poly(role self, trio & net) +{ + const std::uint8_t center = 2; + const std::size_t degree = 2; + const std::uint8_t eta = 5; + if (self == role::p2) + { + auto mat = grotto::make_offset_poly_keys(center, degree, verifiable{}); + const std::vector coeff{1, 0, 3}; + const std::vector knots{0}; + std::vector t0(degree + 1), t1(degree + 1); + const u64 s0 = grotto::offset_poly_eval<0>(mat, knots, {coeff}, eta, t0.data()); + const u64 s1 = grotto::offset_poly_eval<1>(mat, knots, {coeff}, eta, t1.data()); + const u64 clear = grotto::offset_poly_clear(center, knots, {coeff}, eta); + net.to(role::p0).send(net::msg::ring_vector, s0); + net.to(role::p1).send(net::msg::ring_vector, s1); + net.to(role::p0).send(net::msg::ring_vector, clear); + net.to(role::p1).send(net::msg::ring_vector, clear); + send_proofs(net.to(role::p0), t0); + send_proofs(net.to(role::p1), t1); + t0[1][0] = simde_mm_xor_si128(t0[1][0], simde_mm_set1_epi8(1)); + send_proofs(net.to(role::p0), t0); + send_proofs(net.to(role::p1), t1); + return 0; + } + const u64 mine = net.to(role::p2).recv(net::msg::ring_vector); + const u64 clear = net.to(role::p2).recv(net::msg::ring_vector); + auto proofs = recv_proofs(net.to(role::p2), degree + 1); + const u64 peer = open_additive(net, self, mine); + auto peer_p = exchange_proofs(net, self, proofs); + if (self == role::p0) + { + require(peer == clear, "offset poly"); + for (std::size_t m = 0; m <= degree; ++m) + require(verify(proofs[m], peer_p[m]), "offset proof"); + } + auto bad = recv_proofs(net.to(role::p2), degree + 1); + auto bad_peer = exchange_proofs(net, self, bad); + if (self == role::p0) + { + require(verify(bad[0], bad_peer[0]), "untampered power"); + require(!verify(bad[1], bad_peer[1]), "tampered power"); + } + return 0; +} + +int recent_offset_jet(role self, trio & net) +{ + const std::uint8_t center = 9; + const std::size_t degree = 2; + const std::uint8_t eta = 4; + if (self == role::p2) + { + auto mat = grotto::make_offset_jet_keys(center, degree, verifiable{}); + const std::vector coeff{2, 3, 1}; + const std::vector knots{0}; + std::vector t0(degree + 1), t1(degree + 1); + const u64 s0 = grotto::offset_jet_eval<0>(mat, knots, coeff, eta, t0.data()); + const u64 s1 = grotto::offset_jet_eval<1>(mat, knots, coeff, eta, t1.data()); + const u64 clear = grotto::offset_jet_clear(center, knots, coeff, eta); + net.to(role::p0).send(net::msg::ring_vector, s0); + net.to(role::p1).send(net::msg::ring_vector, s1); + net.to(role::p0).send(net::msg::ring_vector, clear); + net.to(role::p1).send(net::msg::ring_vector, clear); + send_proofs(net.to(role::p0), t0); + send_proofs(net.to(role::p1), t1); + return 0; + } + const u64 mine = net.to(role::p2).recv(net::msg::ring_vector); + const u64 clear = net.to(role::p2).recv(net::msg::ring_vector); + auto proofs = recv_proofs(net.to(role::p2), degree + 1); + const u64 peer = open_additive(net, self, mine); + auto peer_p = exchange_proofs(net, self, proofs); + if (self == role::p0) + { + require(peer == clear, "offset jet"); + for (std::size_t m = 0; m <= degree; ++m) + require(verify(proofs[m], peer_p[m]), "jet proof"); + } + return 0; +} + +int recent_ring_switch(role self, trio & net) +{ + using Z = grotto::zn64<1009>; + const std::uint8_t r = 200; + const std::uint8_t eta = 100; + const std::uint8_t x = static_cast(r + eta); + if (self == role::p2) + { + auto mat = grotto::make_ring_switch_keys(r, verifiable{}); + proof_token t0{}, t1{}; + const Z s0 = grotto::ring_switch_eval<0>(mat, eta, &t0); + const Z s1 = grotto::ring_switch_eval<1>(mat, eta, &t1); + const Z clear = grotto::ring_switch_clear(x, r, eta); + net.to(role::p0).send(net::msg::ring_vector, s0.raw()); + net.to(role::p1).send(net::msg::ring_vector, s1.raw()); + net.to(role::p0).send(net::msg::ring_vector, clear.raw()); + net.to(role::p1).send(net::msg::ring_vector, clear.raw()); + send_proofs(net.to(role::p0), std::vector{t0}); + send_proofs(net.to(role::p1), std::vector{t1}); + return 0; + } + const u64 mine = net.to(role::p2).recv(net::msg::ring_vector); + const u64 clear = net.to(role::p2).recv(net::msg::ring_vector); + auto proofs = recv_proofs(net.to(role::p2), 1); + const u64 peer = open_additive(net, self, mine); + auto peer_p = exchange_proofs(net, self, proofs); + if (self == role::p0) + { + require(Z{peer} == Z{clear}, "ring switch"); + require(verify(proofs[0], peer_p[0]), "ring proof"); + } + return 0; +} + +int recent_offset_repr(role self, trio & net) +{ + const std::uint8_t center = 10; + const std::uint8_t eta = 5; + const auto state = grotto::offset_repr_fibonacci_state(center); + const auto M = grotto::offset_repr_fibonacci_matrix(); + const std::size_t dim = 2; + if (self == role::p2) + { + auto mat = grotto::make_offset_repr_keys( + center, state, verifiable{}); + const std::vector knots{0}; + std::vector t0(dim), t1(dim); + const auto s0 = grotto::offset_repr_eval<0>(mat, M, knots, eta, t0.data()); + const auto s1 = grotto::offset_repr_eval<1>(mat, M, knots, eta, t1.data()); + const auto clear = grotto::offset_repr_clear(center, state, M, knots, eta); + net.to(role::p0).send(net::msg::ring_vector, s0[1]); + net.to(role::p1).send(net::msg::ring_vector, s1[1]); + net.to(role::p0).send(net::msg::ring_vector, clear[1]); + net.to(role::p1).send(net::msg::ring_vector, clear[1]); + net.to(role::p0).send(net::msg::ring_vector, s0[0]); + net.to(role::p1).send(net::msg::ring_vector, s1[0]); + net.to(role::p0).send(net::msg::ring_vector, clear[0]); + net.to(role::p1).send(net::msg::ring_vector, clear[0]); + send_proofs(net.to(role::p0), t0); + send_proofs(net.to(role::p1), t1); + return 0; + } + const u64 mine_fn = net.to(role::p2).recv(net::msg::ring_vector); + const u64 clear_fn = net.to(role::p2).recv(net::msg::ring_vector); + const u64 mine_fn1 = net.to(role::p2).recv(net::msg::ring_vector); + const u64 clear_fn1 = net.to(role::p2).recv(net::msg::ring_vector); + auto proofs = recv_proofs(net.to(role::p2), dim); + const u64 peer_fn = open_additive(net, self, mine_fn); + const u64 peer_fn1 = open_additive(net, self, mine_fn1); + auto peer_p = exchange_proofs(net, self, proofs); + if (self == role::p0) + { + require(peer_fn == clear_fn, "offset repr F_n"); + require(peer_fn1 == clear_fn1, "offset repr F_{n+1}"); + for (std::size_t i = 0; i < dim; ++i) + require(verify(proofs[i], peer_p[i]), "repr proof"); + } + return 0; +} + +int recent_offset_twist(role self, trio & net) +{ + const std::uint8_t center = 9; + const std::size_t degree = 2; + const std::uint8_t eta = 4; + const u64 lambda = 3; + if (self == role::p2) + { + auto mat = grotto::make_offset_twist_keys( + center, degree, lambda, verifiable{}); + const std::vector coeff{2, 5, 1}; + const std::vector knots{0}; + std::vector t0(degree + 1), t1(degree + 1); + const u64 s0 = grotto::offset_twist_eval<0>(mat, knots, coeff, eta, t0.data()); + const u64 s1 = grotto::offset_twist_eval<1>(mat, knots, coeff, eta, t1.data()); + const u64 clear = grotto::offset_twist_clear( + center, lambda, knots, coeff, eta); + net.to(role::p0).send(net::msg::ring_vector, s0); + net.to(role::p1).send(net::msg::ring_vector, s1); + net.to(role::p0).send(net::msg::ring_vector, clear); + net.to(role::p1).send(net::msg::ring_vector, clear); + send_proofs(net.to(role::p0), t0); + send_proofs(net.to(role::p1), t1); + return 0; + } + const u64 mine = net.to(role::p2).recv(net::msg::ring_vector); + const u64 clear = net.to(role::p2).recv(net::msg::ring_vector); + auto proofs = recv_proofs(net.to(role::p2), degree + 1); + const u64 peer = open_additive(net, self, mine); + auto peer_p = exchange_proofs(net, self, proofs); + if (self == role::p0) + { + require(peer == clear, "offset twist"); + for (std::size_t m = 0; m <= degree; ++m) + require(verify(proofs[m], peer_p[m]), "twist proof"); + } + return 0; +} + +int recent_closed_form(role self, trio & net) +{ + const unsigned bits = 16; + const std::int64_t raw = std::int64_t{1} << bits; + const std::int64_t soft = grotto::eval_closed(grotto::closed::softsign, bits, raw); + const std::int64_t selu = grotto::eval_closed(grotto::closed::selu, bits, -raw); + bool bad_precision = false; + bool pole = false; + try + { + (void)grotto::eval_closed(grotto::closed::atan, 7, raw); + } + catch (const std::invalid_argument &) + { + bad_precision = true; + } + try + { + (void)grotto::eval_closed(grotto::closed::acsch, bits, 0); + } + catch (const std::domain_error &) + { + pole = true; + } + require(bad_precision && pole, "closed form rejects"); + if (self == role::p2) + { + net.to(role::p0).send(net::msg::ring_vector, static_cast(soft)); + net.to(role::p0).send(net::msg::ring_vector, static_cast(selu)); + net.to(role::p1).send(net::msg::ring_vector, static_cast(soft)); + net.to(role::p1).send(net::msg::ring_vector, static_cast(selu)); + return 0; + } + const auto peer_soft = static_cast( + net.to(role::p2).recv(net::msg::ring_vector)); + const auto peer_selu = static_cast( + net.to(role::p2).recv(net::msg::ring_vector)); + require(soft == peer_soft && selu == peer_selu, "closed form agree"); + return 0; +} + +int recent_exact_steps(role self, trio & net) +{ + const unsigned bits = 16; + const std::int64_t width = grotto::eval_dec_width(std::int64_t{3} << bits, bits); + const std::int64_t log16 = grotto::eval_ilog16(0, bits); + const std::int64_t angle = grotto::eval_deg2rad(std::int64_t{180} << bits, bits); + bool wide = false; + try + { + (void)grotto::eval_dec_width(1, 63); + } + catch (const std::invalid_argument &) + { + wide = true; + } + require(wide, "exact width"); + if (self == role::p2) + { + std::vector pack{ + static_cast(width), static_cast(log16), static_cast(angle)}; + net.to(role::p0).send_vec(pack); + net.to(role::p1).send_vec(pack); + return 0; + } + auto pack = net.to(role::p2).recv_vec(); + require(pack.size() == 3u, "exact pack"); + require(static_cast(width) == pack[0], "dec width"); + require(static_cast(log16) == pack[1], "ilog16"); + require(static_cast(angle) == pack[2], "deg2rad"); + return 0; +} + +int recent_ic_domain(role self, trio & net) +{ + using Input = std::uint8_t; + const Input r = 40, p = 7, q = 90; + const Input r0 = 0x13; + const Input r1 = static_cast(r ^ r0); + const std::uint32_t if_true = 11, if_false = 2; + auto on = [&](const auto & key) { + const u64 nmask = key.input_mask; + const u64 gmask = key.group_mask; + std::vector shares(256); + for (unsigned x = 0; x < 256; ++x) + shares[x] = + share_bits(eval_point(ic, key, static_cast(x))); + auto peer = exchange_u64(net, self, shares); + if (self == role::p0) + { + auto dealer = make_dpf(r, ic(p, q, if_true, if_false)); + for (unsigned x = 0; x < 256; ++x) + { + const u64 w = (x - static_cast(r)) & nmask; + const bool inside = w >= p && w <= q; + const u64 want = (inside ? if_true : if_false) & gmask; + const u64 got = (shares[x] + peer[x]) & gmask; + require(got == want, "ic"); + const u64 d0 = share_bits( + eval_point(ic, dealer.first, static_cast(x))); + const u64 d1 = share_bits( + eval_point(ic, dealer.second, static_cast(x))); + require(((d0 + d1) & gmask) == got, "ic matches dealer"); + } + } + }; + // Default path keeps mask `r` shared (F_IC); still matches a dealer key. + dist_with_ic_key(net, self, r0, r1, ic(p, q, if_true, if_false), on, on); + // Opt-in Reveal reconstructs `r`. + require_opened(dist_with_ic_key(net, self, + r0, r1, ic(p, q, if_true, if_false), on, on), + self, utils::xor_input_shares(r0, r1)); + return 0; +} + +int recent_cmp_edge_default(role self, trio & net) +{ + using Input = std::uint8_t; + // Domain-edge point for leq/gt: α = 2^n-1. Default path must not open the + // edge bit, and the key must still evaluate correctly. + const Input alpha = 0xff; + const Input x0 = 0x19; + const Input x1 = static_cast(alpha ^ x0); + auto check = [&](auto kind, auto pred) { + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + require(key.cmp().trivial == cmp_trivial::none, "edge trivial unset"); + std::vector shares(256); + for (unsigned x = 0; x < 256; ++x) + shares[x] = share_bits( + eval_point(cmp, key, static_cast(x))); + auto peer = exchange_u64(net, self, shares); + if (self == role::p0) + { + for (unsigned x = 0; x < 256; ++x) + { + const u64 want = pred(x) ? 1u : 0u; + require(((shares[x] + peer[x]) & mask) == want, "edge cmp"); + } + } + }; + dist_with_cmp_key(net, self, x0, x1, kind, on, on); + }; + check(leq(u64{1}), [](unsigned x) { return x <= 255u; }); + check(gt(u64{1}), [](unsigned x) { return false; }); + // Non-edge leq/gt also stay on the default (no Reveal) path. + const Input mid = 0x40; + const Input m0 = 0x11; + const Input m1 = static_cast(mid ^ m0); + auto on_mid = [&](const auto & key) { + const u64 mask = key.cmp().mask; + std::vector shares(256); + for (unsigned x = 0; x < 256; ++x) + shares[x] = share_bits(eval_point(cmp, key, static_cast(x))); + auto peer = exchange_u64(net, self, shares); + if (self == role::p0) + { + for (unsigned x = 0; x < 256; ++x) + require(((shares[x] + peer[x]) & mask) + == (x <= mid ? 1u : 0u), + "leq mid"); + } + }; + dist_with_cmp_key(net, self, m0, m1, leq(u64{1}), on_mid, on_mid); + return 0; +} + +int recent_point_default(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x3c; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 0x55; + auto on = [&](const auto & key) { + std::vector mine(256); + auto [bufs, iters] = eval_full(key); + (void)bufs; + auto it = std::begin(iters); + for (unsigned x = 0; x < 256; ++x, ++it) + mine[x] = share_bits(*it); + auto peer = exchange_u64(net, self, mine); + if (self == role::p0) + { + for (unsigned x = 0; x < 256; ++x) + { + const u64 got = mine[x] - peer[x]; + require(got == (x == alpha ? beta : 0u), "point default"); + } + } + }; + // Default path returns nothing (prefix stays hidden). + dist_with_point_key(net, self, x0, x1, beta, on, on); + return 0; +} + +int recent_geneval_domain(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x3c; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const Input y = 0x7e; + auto on = [&](const auto & key) { + std::vector mine(256); + std::vector pis(256); + for (unsigned x = 0; x < 256; ++x) + { + mine[x] = share_bits( + *eval_point(key, static_cast(x), prove(pis[x]))); + } + auto peer = exchange_u8(net, self, mine); + auto peer_p = exchange_proofs(net, self, pis); + if (self == role::p0) + { + require(mine.size() == 256u, "geneval shares"); + require(static_cast(mine[alpha] - peer[alpha]) == y, "geneval on"); + require(static_cast(mine[0] - peer[0]) == Input{0}, "geneval off"); + require(static_cast(peer[alpha] - mine[alpha]) != y, "party order"); + for (unsigned x = 0; x < 256; ++x) + require(verify(pis[x], peer_p[x]), "geneval proof"); + require(!verify(detail::vdpf::zero_proof(), peer_p[alpha]), + "zero token must fail"); + require(!verify(pis[alpha], detail::vdpf::zero_proof()), + "zero peer token must fail"); + auto flipped = peer_p[alpha]; + flipped[0] = simde_mm_xor_si128(flipped[0], simde_mm_set1_epi8(1)); + require(!verify(pis[alpha], flipped), "tampered token"); + } + auto corrupted = key; + if (self == role::p0) + flip_words(corrupted); + proof_token bad_pi{}; + const Input bad = open_subtractive(net, self, + share_bits(*eval_point(corrupted, alpha, prove(bad_pi)))); + auto peer_bad = exchange_proof(net, self, bad_pi); + if (self == role::p0) + { + require(bad != y, "dist word tamper"); + require(!verify(bad_pi, peer_bad), "dist proof after word tamper"); + } + }; + require_tree_prefix(dist_with_point_key(net, self, x0, x1, y, on, on), + self, verifiable_tree_prefix(x0, x1)); + return 0; +} + +int recent_dist_half_tree_domain(role self, trio & net) +{ + using Input = std::uint8_t; + using Ht = prg::aes128_ccr; + const Input alpha = 9; + const Input x0 = 0x3; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 0x1111; + auto on = [&](const auto & key) { + int hits = 0; + for (unsigned x = 0; x < 256; ++x) + { + const u64 opened = open_subtractive(net, self, + share_bits(*eval_point(key, static_cast(x)))); + if (self == role::p0) + { + require(opened == (x == alpha ? beta : 0u), "dist half-tree"); + if (opened == beta) + ++hits; + } + } + if (self == role::p0) + require(hits == 1, "dist half-tree hits"); + }; + require_tree_prefix(dist_with_point_key(net, self, x0, x1, beta, on, on), + self, verifiable_tree_prefix(x0, x1)); + return 0; +} + +int recent_dist_packed_leaf(role self, trio & net) +{ + using Input = std::uint8_t; + using Out = std::uint16_t; + const Input alpha = 0x2a; + const Input x0 = 0x11; + const Input x1 = static_cast(alpha ^ x0); + const Out beta = 0x1234; + const Input neighbor = static_cast(alpha ^ 0x1); + auto on = [&](const auto & key) { + const Out on_v = open_subtractive(net, self, + share_bits(*eval_point(key, alpha))); + const Out lane = open_subtractive(net, self, + share_bits(*eval_point(key, neighbor))); + const Out far = open_subtractive(net, self, + share_bits(*eval_point(key, Input{0}))); + if (self == role::p0) + { + require(on_v == beta, "packed on"); + require(lane == Out{0}, "packed neighbor"); + require(far == Out{0}, "packed far"); + } + }; + require_tree_prefix(dist_with_point_key(net, self, x0, x1, beta, on, on), + self, verifiable_tree_prefix(x0, x1)); + return 0; +} + +int recent_extractable_second_hot(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const fp61 beta{7}; + auto on = [&](const auto & key) { + const std::array rs{fp61{3}, fp61{5}}; + sketch_share local{}; + auto sk = sketch(local, rs); + (void)*eval_point(key, Input{0}, sk); + (void)*eval_point(key, alpha, sk); + role peer = self == role::p0 ? role::p1 : role::p0; + sketch_share theirs = + net.exchange_with(peer, local, net::msg::sketch_share); + bool honest = self == role::p0 ? sketch_verify(local, theirs) + : sketch_verify(theirs, local); + if (self == role::p0) + require(honest, "honest sketch"); + + sketch_share forged{}; + auto bad = sketch(forged, rs); + fp61 y0 = (*eval_point(key, Input{0})).raw(); + const fp61 y1 = (*eval_point(key, alpha)).raw(); + if (self == role::p0) + y0 = y0 + beta; + bad.absorb(y0); + bad.absorb(y1); + sketch_share peer_forged = + net.exchange_with(peer, forged, net::msg::sketch_share); + bool second = self == role::p0 + ? sketch_verify(forged, peer_forged) + : sketch_verify(peer_forged, forged); + if (self == role::p0) + require(!second, "second hot point"); + }; + dist_with_extractable_point_key( + net, self, x0, x1, beta, on, on); + return 0; +} + +// --------------------------------------------------------------------------- +// Three-evaluator (2,3) DPF. +// Dealer flows: p2 runs make_dpf3* and ships keys (α clear to dealer). +// Dist flows: dist_with_dpf3_key (α XOR-shared; role map dpf3_role_map::dist). +// --------------------------------------------------------------------------- + +/// @brief Collect three Shamir shares at p2 and reconstruct. +/// @details Party indices follow `dpf3_party_of(role, map)`. Only p2 returns +/// the opened value; p0/p1 return zero. +fp61 open_shamir3(trio & net, role self, fp61 mine, + dpf3_role_map map = dpf3_role_map::dealer) +{ + if (self == role::p2) + { + const auto from_p0 = net.to(role::p0).recv(net::msg::delta); + const auto from_p1 = net.to(role::p1).recv(net::msg::delta); + return shamir3::reconstruct( + shamir3::share{dpf3_party_of(role::p0, map), from_p0}, + shamir3::share{dpf3_party_of(role::p1, map), from_p1}, + shamir3::share{dpf3_party_of(role::p2, map), mine}); + } + net.to(role::p2).send(net::msg::delta, mine); + return fp61{}; +} + +/// @brief Open F_DPF3CMP complementary halves at p2 (dealer role map). +/// @details p0 holds the k0 half, p1 the k1 half. p2's `mine` is unused for +/// the open (party 3 also holds k0) and may be a dummy. +fp61 open_cmp3(trio & net, role self, std::uint64_t mine) +{ + if (self == role::p2) + { + const auto k0 = net.to(role::p0).recv(net::msg::delta); + const auto k1 = net.to(role::p1).recv(net::msg::delta); + (void)mine; + return reconstruct_cmp_halves(k0, k1); + } + net.to(role::p2).send(net::msg::delta, mine); + return fp61{}; +} + +int recent_dpf3_point_domain(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const fp61 beta{17}; + if (self == role::p2) + { + auto [k1, k2, k3] = make_dpf3(alpha, beta, verifiable{}); + send_key(net.to(role::p0), k1); + send_key(net.to(role::p1), k2); + for (unsigned x = 0; x < 256; ++x) + { + const fp61 y = eval_point(k3, static_cast(x)); + const fp61 got = open_shamir3(net, self, y); + require(got == (static_cast(x) == alpha ? beta : fp61{}), + "dpf3 point"); + } + return 0; + } + if (self == role::p0) + { + using K = std::decay_t( + make_dpf3(Input{}, fp61{}, verifiable{})))>; + auto key = recv_key(net.to(role::p2)); + for (unsigned x = 0; x < 256; ++x) + (void)open_shamir3(net, self, eval_point(key, static_cast(x))); + return 0; + } + using K = std::decay_t( + make_dpf3(Input{}, fp61{}, verifiable{})))>; + auto key = recv_key(net.to(role::p2)); + for (unsigned x = 0; x < 256; ++x) + (void)open_shamir3(net, self, eval_point(key, static_cast(x))); + return 0; +} + +int recent_dpf3_proof_fail(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x11; + if (self == role::p2) + { + auto [k1, k2, k3] = make_dpf3(alpha, fp61{3}, verifiable{}); + using arr = typename decltype(k1.a.dpf_key)::correction_seeds_array; + for (auto & cs : const_cast(k1.a.dpf_key.correction_seeds())) + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); + auto p1 = prove_dpf3(k1, alpha); + auto p2 = prove_dpf3(k2, alpha); + auto p3 = prove_dpf3(k3, alpha); + require(!verify_dpf3(p1, p2, p3), "dpf3 proof fail"); + net.to(role::p0).send(net::msg::delta, std::uint8_t{1}); + net.to(role::p1).send(net::msg::delta, std::uint8_t{1}); + return 0; + } + (void)net.to(role::p2).recv(net::msg::delta); + return 0; +} + +int recent_dpf3_update(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x07; + if (self == role::p2) + { + auto [k1, k2, k3] = make_dpf3(alpha, fp61{5}, updatable{}); + update_payload(k1, k2, k3, alpha, fp61{9}); + send_key(net.to(role::p0), k1); + send_key(net.to(role::p1), k2); + const fp61 y = eval_point(k3, alpha); + const fp61 got = open_shamir3(net, self, y); + require(got == fp61{9}, "dpf3 update"); + return 0; + } + if (self == role::p0) + { + using K = std::decay_t( + make_dpf3(Input{}, fp61{}, updatable{})))>; + auto key = recv_key(net.to(role::p2)); + (void)open_shamir3(net, self, eval_point(key, alpha)); + return 0; + } + using K = std::decay_t( + make_dpf3(Input{}, fp61{}, updatable{})))>; + auto key = recv_key(net.to(role::p2)); + (void)open_shamir3(net, self, eval_point(key, alpha)); + return 0; +} + +int recent_dpf3_cmp_domain(role self, trio & net) +{ + using Input = std::uint8_t; + const Input thresh = 100; + const u64 beta = 5; + if (self == role::p2) + { + auto [k1, k2, k3] = make_dpf3_cmp(thresh, beta); + send_key(net.to(role::p0), k1); + send_key(net.to(role::p1), k2); + for (unsigned x = 0; x < 256; ++x) + { + const auto y = eval_point(k3, static_cast(x)); + const fp61 got = open_cmp3(net, self, y); + require(got.raw() == (x < thresh ? beta : 0u), "dpf3 cmp"); + } + return 0; + } + if (self == role::p0) + { + using K = std::decay_t(make_dpf3_cmp(Input{}, u64{})))>; + auto key = recv_key(net.to(role::p2)); + for (unsigned x = 0; x < 256; ++x) + (void)open_cmp3(net, self, eval_point(key, static_cast(x))); + return 0; + } + using K = std::decay_t(make_dpf3_cmp(Input{}, u64{})))>; + auto key = recv_key(net.to(role::p2)); + for (unsigned x = 0; x < 256; ++x) + (void)open_cmp3(net, self, eval_point(key, static_cast(x))); + return 0; +} + +int recent_dist_dpf3_point(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x11; + const Input x1 = static_cast(alpha ^ x0); + const fp61 beta{17}; + constexpr auto map = dpf3_role_map::dist; + require(x0 != alpha && x1 != alpha, "dist dpf3: alpha shares only"); + const auto opened = dist_with_dpf3_key(net, self, x0, x1, beta, + [&](auto key) { + // Party 1 (p0): eval is a Shamir share, not clear β. + require(eval_point(key, alpha) != beta, + "dist dpf3: p0 beta hidden"); + for (unsigned x = 0; x < 256; ++x) + (void)open_shamir3(net, self, + eval_point(key, static_cast(x)), map); + }, + [&](auto key) { + for (unsigned x = 0; x < 256; ++x) + { + const fp61 got = open_shamir3(net, self, + eval_point(key, static_cast(x)), map); + require(got == (static_cast(x) == alpha ? beta : fp61{}), + "dist dpf3 point"); + } + }, + [&](auto key) { + // Party 3 (p1): only τ halves were received; eval ≠ clear β. + require(eval_point(key, alpha) != beta, + "dist dpf3: p1 beta is share only"); + for (unsigned x = 0; x < 256; ++x) + (void)open_shamir3(net, self, + eval_point(key, static_cast(x)), map); + }); + require(!opened.has_value(), "dist dpf3: no clear prefix"); + return 0; +} + +/// @brief Dist updatable keys: Fig-10 over the wire, then open at `α`. +int recent_dist_dpf3_update(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x07; + const Input x0 = 0x03; + const Input x1 = static_cast(alpha ^ x0); + const fp61 beta0{5}; + const fp61 beta1{9}; + constexpr auto map = dpf3_role_map::dist; + dist_with_dpf3_key(net, self, x0, x1, beta0, updatable{}, + [&](auto key) { + require(key.updatable, "dist dpf3 update: p0 updatable"); + dist_update_payload(net, self, key, alpha, beta1); + (void)open_shamir3(net, self, eval_point(key, alpha), map); + }, + [&](auto key) { + require(key.updatable, "dist dpf3 update: p2 updatable"); + dist_update_payload(net, self, key, alpha, beta1); + const fp61 got = + open_shamir3(net, self, eval_point(key, alpha), map); + require(got == beta1, "dist dpf3 update"); + }, + [&](auto key) { + require(key.updatable, "dist dpf3 update: p1 updatable"); + dist_update_payload(net, self, key, alpha, beta1); + (void)open_shamir3(net, self, eval_point(key, alpha), map); + }); + return 0; +} + +/// @brief Dist dual-spine keys: prove at `α` and verify on p2 (party 2). +int recent_dist_dpf3_proof(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x19; + const Input x0 = 0x07; + const Input x1 = static_cast(alpha ^ x0); + const fp61 beta{4}; + dist_with_dpf3_key(net, self, x0, x1, beta, + [&](auto key) { + require(key.verifiable, "dist dpf3 proof: p0 verifiable"); + const auto p = prove_dpf3(key, alpha); + net.to(role::p2).send(net::msg::delta, p); + }, + [&](auto key) { + require(key.verifiable, "dist dpf3 proof: p2 verifiable"); + const auto p1 = net.to(role::p0).recv(net::msg::delta); + const auto p3 = net.to(role::p1).recv(net::msg::delta); + const auto p2 = prove_dpf3(key, alpha); + require(verify_dpf3(p1, p2, p3), "dist dpf3 proof ok"); + // Corrupt party-1 A-half token; verify must fail closed. + dpf3_proof bad = p1; + bad.a[0] = simde_mm_xor_si128(bad.a[0], simde_mm_set1_epi8(1)); + require(!verify_dpf3(bad, p2, p3), "dist dpf3 proof fail"); + }, + [&](auto key) { + require(key.verifiable, "dist dpf3 proof: p1 verifiable"); + const auto p = prove_dpf3(key, alpha); + net.to(role::p2).send(net::msg::delta, p); + }); + return 0; +} + +int recent_dpf3_ic_domain(role self, trio & net) +{ + using Input = std::uint8_t; + const Input r = 10, p = 20, q = 40; + const u64 beta = 3; + if (self == role::p2) + { + auto [k1, k2, k3] = make_dpf3_ic(r, p, q, beta); + auto two = make_dpf(r, ic(p, q, beta)); + send_key(net.to(role::p0), k1); + send_key(net.to(role::p1), k2); + for (unsigned x = 0; x < 256; ++x) + { + const auto want = reconstruct( + eval_point(ic, two.first, static_cast(x)), + eval_point(ic, two.second, static_cast(x))); + const auto y = eval_point(k3, static_cast(x)); + const fp61 got = open_cmp3(net, self, y); + require(got.raw() == static_cast(want), "dpf3 ic"); + } + return 0; + } + if (self == role::p0) + { + using K = std::decay_t( + make_dpf3_ic(Input{}, Input{}, Input{}, u64{})))>; + auto key = recv_key(net.to(role::p2)); + for (unsigned x = 0; x < 256; ++x) + (void)open_cmp3(net, self, eval_point(key, static_cast(x))); + return 0; + } + using K = std::decay_t( + make_dpf3_ic(Input{}, Input{}, Input{}, u64{})))>; + auto key = recv_key(net.to(role::p2)); + for (unsigned x = 0; x < 256; ++x) + (void)open_cmp3(net, self, eval_point(key, static_cast(x))); + return 0; +} + +/// @brief Dealer cmp update (fp61 delta) then full-domain open on all three. +int recent_dpf3_cmp_update(role self, trio & net) +{ + using Input = std::uint8_t; + const Input thresh = 80; + if (self == role::p2) + { + auto [k1, k2, k3] = make_dpf3_cmp(thresh, 11u); + update_payload_cmp(k1, k2, k3, 11u, 0u); + send_key(net.to(role::p0), k1); + send_key(net.to(role::p1), k2); + for (unsigned x = 0; x < 256; ++x) + { + const fp61 got = + open_cmp3(net, self, eval_point(k3, static_cast(x))); + require(got.raw() == 0u, "dpf3 cmp update clear"); + } + return 0; + } + if (self == role::p0) + { + using K = std::decay_t(make_dpf3_cmp(Input{}, u64{})))>; + auto key = recv_key(net.to(role::p2)); + for (unsigned x = 0; x < 256; ++x) + (void)open_cmp3(net, self, eval_point(key, static_cast(x))); + return 0; + } + using K = std::decay_t(make_dpf3_cmp(Input{}, u64{})))>; + auto key = recv_key(net.to(role::p2)); + for (unsigned x = 0; x < 256; ++x) + (void)open_cmp3(net, self, eval_point(key, static_cast(x))); + return 0; +} + +/// @brief Dealer blocked comparison full domain. +int recent_dpf3_blocked_cmp(role self, trio & net) +{ + using Input = std::uint8_t; + const Input thresh = 50; + const u64 beta = 9; + if (self == role::p2) + { + auto [k1, k2, k3] = make_dpf3_cmp_blocked<4>(thresh, beta); + send_key(net.to(role::p0), k1); + send_key(net.to(role::p1), k2); + for (unsigned x = 0; x < 256; ++x) + { + const fp61 got = + open_cmp3(net, self, eval_point(k3, static_cast(x))); + require(got.raw() == (x < thresh ? beta : 0u), "dpf3 blocked cmp"); + } + return 0; + } + if (self == role::p0) + { + using K = std::decay_t( + make_dpf3_cmp_blocked<4>(Input{}, u64{})))>; + auto key = recv_key(net.to(role::p2)); + for (unsigned x = 0; x < 256; ++x) + (void)open_cmp3(net, self, eval_point(key, static_cast(x))); + return 0; + } + using K = std::decay_t( + make_dpf3_cmp_blocked<4>(Input{}, u64{})))>; + auto key = recv_key(net.to(role::p2)); + for (unsigned x = 0; x < 256; ++x) + (void)open_cmp3(net, self, eval_point(key, static_cast(x))); + return 0; +} + +/// @brief Dealer multipoint3 full domain on all three evaluators. +/// @details `multipoint3_key` embeds a `std::vector` of buckets; ship σ/meta +/// then each bucket via `send_key` (not a flat memcpy of the parent). +int recent_dpf3_multipoint_domain(role self, trio & net) +{ + using Input = std::uint8_t; + const std::vector alphas{1, 2, 9, 40}; + const std::vector betas{fp61{7}, fp61{11}, fp61{3}, fp61{4}}; + using K1 = std::decay_t( + make_multipoint3(alphas, betas, verifiable{})))>; + using K2 = std::decay_t( + make_multipoint3(alphas, betas, verifiable{})))>; + using Bucket1 = typename K1::bucket_key; + using Bucket2 = typename K2::bucket_key; + + auto send_mp = [&](role peer, const auto & key) { + net.to(peer).send(net::msg::delta, key.sigma); + net.to(peer).send(net::msg::delta, key.bucket_count); + net.to(peer).send(net::msg::delta, key.bucket_domain); + const std::uint64_t nb = key.buckets.size(); + net.to(peer).send(net::msg::delta, nb); + for (const auto & b : key.buckets) + send_key(net.to(peer), b); + }; + auto recv_mp = [&](auto empty_key) { + using Key = decltype(empty_key); + Key key = std::move(empty_key); + key.sigma = net.to(role::p2).template recv(net::msg::delta); + key.bucket_count = + net.to(role::p2).template recv(net::msg::delta); + key.bucket_domain = + net.to(role::p2).template recv(net::msg::delta); + const auto nb = + net.to(role::p2).template recv(net::msg::delta); + key.buckets.clear(); + key.buckets.reserve(static_cast(nb)); + using Bucket = typename Key::bucket_key; + for (std::uint64_t i = 0; i < nb; ++i) + key.buckets.push_back(recv_key(net.to(role::p2))); + key.verifiable = true; + return key; + }; + + if (self == role::p2) + { + auto [k1, k2, k3] = make_multipoint3(alphas, betas, verifiable{}); + send_mp(role::p0, k1); + send_mp(role::p1, k2); + for (unsigned x = 0; x < 256; ++x) + { + fp61 want{}; + for (std::size_t i = 0; i < alphas.size(); ++i) + if (alphas[i] == static_cast(x)) + want = betas[i]; + const fp61 got = open_shamir3(net, self, + eval_multipoint(k3, static_cast(x))); + require(got == want, "dpf3 multipoint"); + } + return 0; + } + if (self == role::p0) + { + K1 empty{}; + auto key = recv_mp(std::move(empty)); + (void)sizeof(Bucket1); + for (unsigned x = 0; x < 256; ++x) + (void)open_shamir3(net, self, + eval_multipoint(key, static_cast(x))); + return 0; + } + K2 empty{}; + auto key = recv_mp(std::move(empty)); + (void)sizeof(Bucket2); + for (unsigned x = 0; x < 256; ++x) + (void)open_shamir3(net, self, + eval_multipoint(key, static_cast(x))); + return 0; +} + +/// @brief Dist Fig-10 then full-domain open (not only α). +int recent_dist_dpf3_update_domain(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2b; + const Input x0 = 0x05; + const Input x1 = static_cast(alpha ^ x0); + const fp61 beta0{3}; + const fp61 beta1{13}; + constexpr auto map = dpf3_role_map::dist; + dist_with_dpf3_key(net, self, x0, x1, beta0, updatable{}, + [&](auto key) { + dist_update_payload(net, self, key, alpha, beta1); + for (unsigned x = 0; x < 256; ++x) + (void)open_shamir3(net, self, + eval_point(key, static_cast(x)), map); + }, + [&](auto key) { + dist_update_payload(net, self, key, alpha, beta1); + for (unsigned x = 0; x < 256; ++x) + { + const fp61 got = open_shamir3(net, self, + eval_point(key, static_cast(x)), map); + require(got == (static_cast(x) == alpha ? beta1 : fp61{}), + "dist dpf3 update domain"); + } + }, + [&](auto key) { + dist_update_payload(net, self, key, alpha, beta1); + for (unsigned x = 0; x < 256; ++x) + (void)open_shamir3(net, self, + eval_point(key, static_cast(x)), map); + }); + return 0; +} + +/// @brief Dist update then prove/verify still succeeds on all three parties. +int recent_dist_dpf3_update_proof(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x1c; + const Input x0 = 0x09; + const Input x1 = static_cast(alpha ^ x0); + dist_with_dpf3_key(net, self, x0, x1, fp61{2}, updatable{}, + [&](auto key) { + dist_update_payload(net, self, key, alpha, fp61{8}); + require(key.verifiable, "dist update proof: p0 V"); + net.to(role::p2).send(net::msg::delta, prove_dpf3(key, alpha)); + }, + [&](auto key) { + dist_update_payload(net, self, key, alpha, fp61{8}); + const auto p1 = net.to(role::p0).recv(net::msg::delta); + const auto p3 = net.to(role::p1).recv(net::msg::delta); + const auto p2 = prove_dpf3(key, alpha); + require(verify_dpf3(p1, p2, p3), "dist update proof ok"); + }, + [&](auto key) { + dist_update_payload(net, self, key, alpha, fp61{8}); + net.to(role::p2).send(net::msg::delta, prove_dpf3(key, alpha)); + }); + return 0; +} + +/// @brief Dist shares opened under the dealer role map must not reconstruct. +int recent_dist_dpf3_wrong_map(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x33; + const Input x0 = 0x0a; + const Input x1 = static_cast(alpha ^ x0); + const fp61 beta{6}; + dist_with_dpf3_key(net, self, x0, x1, beta, + [&](auto key) { + (void)open_shamir3(net, self, eval_point(key, alpha), + dpf3_role_map::dealer); + }, + [&](auto key) { + bool rejected = false; + try + { + const fp61 got = open_shamir3(net, self, eval_point(key, alpha), + dpf3_role_map::dealer); + rejected = got != beta; + } + catch (const std::runtime_error &) + { + rejected = true; + } + require(rejected, "dealer map on dist shares"); + }, + [&](auto key) { + (void)open_shamir3(net, self, eval_point(key, alpha), + dpf3_role_map::dealer); + }); + return 0; +} + +/// @brief Static role-map contract used by open_shamir3 (p0/p1/p2 all check). +int recent_dpf3_role_map(role self, trio & net) +{ + (void)net; + require(dpf3_party_of(role::p0, dpf3_role_map::dealer) == 1, "dealer p0"); + require(dpf3_party_of(role::p1, dpf3_role_map::dealer) == 2, "dealer p1"); + require(dpf3_party_of(role::p2, dpf3_role_map::dealer) == 3, "dealer p2"); + require(dpf3_party_of(role::p0, dpf3_role_map::dist) == 1, "dist p0"); + require(dpf3_party_of(role::p2, dpf3_role_map::dist) == 2, "dist p2"); + require(dpf3_party_of(role::p1, dpf3_role_map::dist) == 3, "dist p1"); + // Cross-wire check: dealer indices ≠ dist for p1/p2. + require(dpf3_party_of(role::p1, dpf3_role_map::dealer) + != dpf3_party_of(role::p1, dpf3_role_map::dist), + "p1 map differs"); + require(dpf3_party_of(role::p2, dpf3_role_map::dealer) + != dpf3_party_of(role::p2, dpf3_role_map::dist), + "p2 map differs"); + (void)self; + return 0; +} + +/// @brief Oblivious correction-seed hash matches in-process `make_cs`. +/// @details One level of the shared AES circuit. Prefix shares are split so +/// neither party holds the clear prefix, and the seeds differ. +int recent_oblivious_cs_matches(role self, trio & net) +{ + auto block_from = [](std::uint64_t hi, std::uint64_t lo) { + const std::uint64_t limbs[2] = {lo, hi}; + simde__m128i v; + std::memcpy(&v, limbs, sizeof(v)); + return v; + }; + const simde__m128i s0 = block_from(0x1111222233334444ULL, 0x5555666677778888ULL); + const simde__m128i s1 = block_from(0x0102030405060708ULL, 0x89abcdef00112233ULL); + struct case_t + { + std::size_t level; + std::uint64_t prefix; + std::uint64_t share0; + }; + const case_t cases[] = { + {0, 0, 0}, + {1, 1, 0}, + {3, 0x2a, 0x11}, + {7, 0xff, 0x5a}, + {dpf::detail::blocked::fold_spine_tag | 2, 0x15, 0x01}, + }; + for (const auto & c : cases) + { + if (self == role::p2) + { + dist::send_hash_tape(net); + continue; + } + auto tape = net.to(role::p2).template recv_vec( + dpf::net::msg::beaver_tape); + require(tape.size() == dist::hash_level_and_count(), "hash tape"); + const std::uint64_t share = self == role::p0 + ? c.share0 : (c.prefix ^ c.share0); + const simde__m128i seed = self == role::p0 ? s0 : s1; + dpf::cs_block got{}; + if (self == role::p0) + got = dist::oblivious_cs<0>(net, c.level, share, seed, tape.data()); + else + got = dist::oblivious_cs<1>(net, c.level, share, seed, tape.data()); + const auto expect = dpf::detail::vdpf::make_cs( + c.level, c.prefix, s0, s1); + require(std::memcmp(got.data(), expect.data(), sizeof(got)) == 0, + "oblivious cs"); + } + return 0; +} + +int recent_grow_extend(role self, trio & net) +{ + using In = std::uint8_t; + const In alpha = 0xB2; + const std::uint64_t beta = 9; + dist_with_grow_extend(net, self, alpha, beta, + [&](const auto & key) { + require(std::decay_t::depth == 1, "grown depth"); + require(std::decay_t::num_outputs == 2, "grown outs"); + (void)key; + }, + [&](const auto & key) { + require(std::decay_t::depth == 1, "grown depth"); + (void)key; + }); + return 0; +} + +#define REG(name, tags, fn) \ + register_flow(flow{#name, tags, fn, false}) + +} // namespace recent + +void register_recent_flows() +{ + using namespace recent; + REG(recent_half_tree_domain, "recent verifiable half-tree", recent_half_tree_domain); + REG(recent_half_tree_seed_tamper, "recent verifiable half-tree", recent_half_tree_seed_tamper); + REG(recent_word_tamper, "recent verifiable", recent_word_tamper); + REG(recent_cmp_domain, "recent verifiable dcf", recent_cmp_domain); + REG(recent_blocked_domain, "recent verifiable dcf", recent_blocked_domain); + REG(recent_multipoint_domain, "recent verifiable multipoint", recent_multipoint_domain); + REG(recent_fp61_mac, "recent mac", recent_fp61_mac); + REG(recent_offset_poly, "recent grotto verifiable", recent_offset_poly); + REG(recent_offset_jet, "recent grotto verifiable", recent_offset_jet); + REG(recent_ring_switch, "recent grotto verifiable", recent_ring_switch); + REG(recent_offset_repr, "recent grotto verifiable", recent_offset_repr); + REG(recent_offset_twist, "recent grotto verifiable", recent_offset_twist); + REG(recent_closed_form, "recent grotto", recent_closed_form); + REG(recent_exact_steps, "recent grotto", recent_exact_steps); + REG(recent_ic_domain, "recent ic", recent_ic_domain); + REG(recent_cmp_edge_default, "recent dcf", recent_cmp_edge_default); + REG(recent_point_default, "recent dist", recent_point_default); + REG(recent_geneval_domain, "recent dist", recent_geneval_domain); + REG(recent_dist_half_tree_domain, "recent dist half-tree", recent_dist_half_tree_domain); + REG(recent_dist_packed_leaf, "recent dist", recent_dist_packed_leaf); + REG(recent_extractable_second_hot, "recent extractable", recent_extractable_second_hot); + REG(recent_dpf3_point_domain, "recent dpf3 dealer", recent_dpf3_point_domain); + REG(recent_dpf3_proof_fail, "recent dpf3 dealer", recent_dpf3_proof_fail); + REG(recent_dpf3_update, "recent dpf3 dealer", recent_dpf3_update); + REG(recent_dpf3_cmp_domain, "recent dpf3 dealer", recent_dpf3_cmp_domain); + REG(recent_dpf3_ic_domain, "recent dpf3 dealer", recent_dpf3_ic_domain); + REG(recent_dpf3_cmp_update, "recent dpf3 dealer", recent_dpf3_cmp_update); + REG(recent_dpf3_blocked_cmp, "recent dpf3 dealer", recent_dpf3_blocked_cmp); + REG(recent_dpf3_multipoint_domain, "recent dpf3 dealer", recent_dpf3_multipoint_domain); + REG(recent_dpf3_role_map, "recent dpf3 dealer", recent_dpf3_role_map); + REG(recent_dist_dpf3_point, "recent dpf3 dist", recent_dist_dpf3_point); + REG(recent_dist_dpf3_proof, "recent dpf3 dist", recent_dist_dpf3_proof); + REG(recent_dist_dpf3_update, "recent dpf3 dist", recent_dist_dpf3_update); + REG(recent_dist_dpf3_update_domain, "recent dpf3 dist", recent_dist_dpf3_update_domain); + REG(recent_dist_dpf3_update_proof, "recent dpf3 dist", recent_dist_dpf3_update_proof); + REG(recent_dist_dpf3_wrong_map, "recent dpf3 dist", recent_dist_dpf3_wrong_map); + REG(recent_oblivious_cs_matches, "recent verifiable hash", recent_oblivious_cs_matches); + REG(recent_grow_extend, "recent grow ds", recent_grow_extend); +} + +#undef REG + +} // namespace party +} // namespace dpf diff --git a/party/iknp_deal.hpp b/party/iknp_deal.hpp new file mode 100644 index 0000000..7c4248a --- /dev/null +++ b/party/iknp_deal.hpp @@ -0,0 +1,847 @@ +/// @file party/iknp_deal.hpp +/// @brief Two-party IKNP setup for every tape `dist_ds.hpp` takes from p2. +/// @details p0 and p1 sample the same pad correlations the dealer would, write +/// them into a local inbox, and then run the existing walk. p2 is not +/// connected. Covered tapes: additive carry, point (reveal and +/// oblivious hash, wildcard, half-tree, extractable), comparison +/// (edge, value-word, blocked suffix, verifiable hash), and interval +/// containment. + +#ifndef LIBDPF_PARTY_IKNP_DEAL_HPP__ +#define LIBDPF_PARTY_IKNP_DEAL_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +#include "hedley/hedley.h" + +#include "dist_ds.hpp" +#include "dpf/iknp.hpp" + +namespace dpf +{ +namespace party +{ +namespace iknp_deal +{ + +using net::role; +using net::trio; + +struct tape +{ + std::vector bytes; + + template + void put(net::msg tag, const T & value) + { + static_assert(std::is_trivially_copyable_v); + append(tag, &value, sizeof(T)); + } + + template + void put_vec(net::msg tag, const T * data, std::size_t n) + { + static_assert(std::is_trivially_copyable_v); + append(tag, data, n * sizeof(T)); + } + + void append(net::msg tag, const void * payload, std::size_t n) + { + if (n > 0xffffffffu) + throw std::invalid_argument("iknp tape frame"); + const auto len = static_cast(n); + const auto t = net::to_u16(tag); + std::uint8_t hdr[6]; + std::memcpy(hdr, &len, 4); + std::memcpy(hdr + 4, &t, 2); + bytes.insert(bytes.end(), hdr, hdr + 6); + if (n != 0) + { + const auto * p = static_cast(payload); + bytes.insert(bytes.end(), p, p + n); + } + } +}; + +struct cursor +{ + const iknp::material * mat = nullptr; + std::size_t block = 0; + std::size_t bit = 0; + std::size_t b2a = 0; + std::size_t cw = 0; + std::size_t zero = 0; + std::vector zeros; + + dist::and_share_msg take_block() + { + const auto & s = mat->blocks.at(block++); + dist::and_share_msg m; + m.a = s.a; + m.b = s.b; + m.c = s.c; + return m; + } + + dist::bit_and_pad_msg take_bit() + { + const auto & s = mat->bits.at(bit++); + return dist::bit_and_pad_msg{s.a, s.b, s.c}; + } + + dist::b2a_pad_msg take_b2a() + { + const auto & s = mat->b2a.at(b2a++); + return dist::b2a_pad_msg{s.r, s.add}; + } + + dist::cw_pad_msg take_cw() + { + const auto & s = mat->cws.at(cw++); + dist::cw_pad_msg m; + m.rand = s.rand; + m.gamma = s.gamma; + m.bit = s.bit; + return m; + } + + dist::ring_zero_share_msg take_zero() + { + return zeros.at(zero++); + } + + void done() const + { + if (mat == nullptr) + return; + if (block != mat->blocks.size() || bit != mat->bits.size() + || b2a != mat->b2a.size() || cw != mat->cws.size() + || zero != zeros.size()) + throw std::runtime_error("iknp tape did not consume every pad"); + } +}; + +inline int me_of(role self) +{ + if (self == role::p0) + return 0; + if (self == role::p1) + return 1; + throw std::invalid_argument("iknp parties are p0 and p1"); +} + +inline void exchange_zeros(trio & net, int me, + const std::vector & masks, cursor & cur) +{ + cur.zeros.resize(masks.size()); + const role peer = me == 0 ? role::p1 : role::p0; + for (std::size_t i = 0; i < masks.size(); ++i) + { + if (me == 0) + { + const auto r = dist::random_ring_word(masks[i]); + cur.zeros[i].share = r; + net.send_to(peer, net::msg::ring_vector, detail::dcf_impl::neg_m(r, masks[i])); + } + else + { + cur.zeros[i].share = net.recv_from(peer, net::msg::ring_vector); + } + } +} + +inline void barrier(trio & net, role self) +{ + const role peer = self == role::p0 ? role::p1 : role::p0; + const std::uint8_t ready = 1; + (void)net.exchange_with(peer, ready, net::msg::delta); +} + +inline simde__m128i sample_root(int me) +{ + const auto r = dpf::uniform_sample(); + return me == 0 ? dpf::unset_lo_bit(r) : dpf::set_lo_bit(r); +} + +inline dist::level_pad_msg take_level(cursor & cur, int me) +{ + const auto cw = cur.take_cw(); + const auto first = cur.take_block(); + const auto second = cur.take_block(); + dist::level_pad_msg m; + m.cw = cw; + if (me == 0) + { + m.mine = first; + m.theirs = second; + } + else + { + m.mine = second; + m.theirs = first; + } + return m; +} + +struct demand +{ + std::size_t blocks = 0; + std::size_t bits = 0; + std::size_t b2a = 0; + std::size_t cws = 0; + std::vector zero_masks; +}; + +inline void add_point(demand & d, std::size_t depth, std::size_t n_leaf, + bool oblivious_hash, bool leaf_b2a) +{ + d.cws += depth; + d.blocks += depth * 2 + n_leaf; + if (oblivious_hash) + d.bits += depth * dist::hash_level_and_count(); + if (leaf_b2a) + d.b2a += n_leaf * 128; +} + +inline void add_comparison(demand & d, std::size_t depth, std::size_t prefix, + std::size_t cmp_block, std::size_t cmp_q, std::size_t cmp_h, + bool verifiable, bool oblivious, bool edge, std::uint64_t mask) +{ + d.cws += depth; + d.blocks += depth * 2; + if (oblivious && edge && prefix > 1) + d.bits += prefix - 1; + if (oblivious) + { + if (cmp_block == 0) + { + const std::size_t nlev = prefix < depth ? prefix : depth; + d.bits += nlev * 128; + d.b2a += nlev * 129; + } + if (cmp_block > 0 && cmp_q > 0 && cmp_h > 0 && cmp_h <= depth) + { + d.bits += 1; + d.b2a += 3; + } + if (verifiable) + d.bits += depth * dist::hash_level_and_count(); + } + d.zero_masks.push_back(mask); +} + +template +void emit_point(tape & out, cursor & cur, int me, std::size_t depth, + bool half, bool oblivious_hash, bool leaf_b2a) +{ + static_assert(NLeaf >= 1, "leaf mux sends at least one pad"); + if (half) + out.put(net::msg::dpf_key, sample_root(me)); + for (std::size_t level = 0; level < depth; ++level) + { + out.put(net::msg::beaver_tape, take_level(cur, me)); + if (oblivious_hash) + { + const std::size_t n = dist::hash_level_and_count(); + std::vector hash(n); + for (std::size_t i = 0; i < n; ++i) + hash[i] = cur.take_bit(); + out.put_vec(net::msg::beaver_tape, hash.data(), hash.size()); + } + } + dist::leaf_pad_msg lanes{}; + for (std::size_t i = 0; i < NLeaf; ++i) + lanes.lanes[i] = cur.take_block(); + out.put(net::msg::beaver_tape, lanes); + if (leaf_b2a) + { + std::vector pads(NLeaf * 128); + for (auto & p : pads) + p = cur.take_b2a(); + out.put_vec(net::msg::beaver_tape, pads.data(), pads.size()); + } +} + +inline void emit_comparison(tape & out, cursor & cur, int me, std::size_t depth, + std::size_t prefix, std::size_t cmp_block, std::size_t cmp_q, + std::size_t cmp_h, bool verifiable, bool oblivious, bool edge, bool half) +{ + if (half) + out.put(net::msg::dpf_key, sample_root(me)); + if (oblivious && edge && prefix > 1) + { + std::vector edge_pads(prefix - 1); + for (auto & p : edge_pads) + p = cur.take_bit(); + out.put_vec(net::msg::beaver_tape, edge_pads.data(), edge_pads.size()); + } + for (std::size_t level = 0; level < depth; ++level) + { + out.put(net::msg::beaver_tape, take_level(cur, me)); + if (oblivious) + { + if (cmp_block == 0 && level < prefix) + { + dist::cmp_level_obliv_msg msg{}; + for (std::size_t i = 0; i < 128; ++i) + { + const auto bit = cur.take_bit(); + const auto b2 = cur.take_b2a(); + msg.bits[i] = dist::word_bit_for(bit, b2); + } + msg.ai = cur.take_b2a(); + out.put(net::msg::beaver_tape, msg); + } + if (cmp_block > 0 && cmp_q > 0 && level + 1 == cmp_h) + { + dist::suffix_obliv_msg msg{}; + msg.and_pad = cur.take_bit(); + for (int i = 0; i < 3; ++i) + msg.b2a[i] = cur.take_b2a(); + out.put(net::msg::beaver_tape, msg); + } + if (verifiable) + { + const std::size_t n = dist::hash_level_and_count(); + std::vector hash(n); + for (std::size_t i = 0; i < n; ++i) + hash[i] = cur.take_bit(); + out.put_vec(net::msg::beaver_tape, hash.data(), hash.size()); + } + } + } + out.put(net::msg::beaver_tape, cur.take_zero()); +} + +template +void exchange_wildcard(trio & net, int me, dist::wildcard_leaf_pad_msg & pad) +{ + const role peer = me == 0 ? role::p1 : role::p0; + Concrete mine_out = dpf::uniform_sample(); + Leaf mine_vec = dist::random_leaf(); + Leaf peer_vec = net.exchange_with(peer, mine_vec, net::msg::ring_vector); + Leaf cross_for_peer = dpf::multiply_leaf(peer_vec, mine_out); + Leaf cross = net.exchange_with(peer, cross_for_peer, net::msg::ring_vector); + Leaf zero{}; + if (me == 0) + { + zero = dist::random_leaf(); + const Leaf neg = dpf::subtract_leaf(Leaf{}, zero); + net.send_to(peer, net::msg::ring_vector, neg); + } + else + { + zero = net.recv_from(peer, net::msg::ring_vector); + } + pad.output_blind = mine_out; + pad.vector_blind = mine_vec; + pad.peer_vector_blind = peer_vec; + pad.cross = cross; + pad.zero_leaf = zero; +} + +inline void install(trio & net, role self, tape & out, cursor & cur) +{ + cur.done(); + barrier(net, self); + net.install_inbox(std::move(out.bytes)); +} + +template +void prepare_point(trio & net, role self) +{ + const int me = me_of(self); + using dpf_type = utils::dpf_type_t; + using tree = dpf::tree_traits; + constexpr std::size_t depth = dpf_type::depth; + constexpr std::size_t lg = dpf_type::lg_outputs_per_leaf; + constexpr std::size_t n_leaf = dist::leaf_and_slots(lg); + constexpr bool leaf_b2a = lg > 0 + && !utils::has_characteristic_two_v> + && (!dpf::is_wildcard_v || ObliviousHash); + demand d; + if constexpr (Additive) + d.bits += utils::bitlength_of_v - 1; + add_point(d, depth, n_leaf, ObliviousHash, leaf_b2a); + const role peer = self == role::p0 ? role::p1 : role::p0; + auto mat = iknp::sample(net.to(peer), me, d.blocks, d.bits, d.b2a, d.cws); + cursor cur; + cur.mat = &mat; + tape out; + if constexpr (Additive) + { + constexpr std::size_t nbits = utils::bitlength_of_v; + for (std::size_t i = 0; i + 1 < nbits; ++i) + out.put(net::msg::beaver_tape, cur.take_bit()); + } + emit_point(out, cur, me, depth, tree::is_half_tree, ObliviousHash, + leaf_b2a); + if constexpr (dpf::is_wildcard_v) + { + using concrete = dpf::concrete_type_t; + using leaf_type = dpf::leaf_node_t; + dist::wildcard_leaf_pad_msg pad{}; + exchange_wildcard(net, me, pad); + out.put(net::msg::beaver_tape, pad); + } + install(net, self, out, cur); +} + +template +void prepare_comparison(trio & net, role self, const Spec & spec, + const Tags & ...tags) +{ + const int me = me_of(self); + using pair_type = dist::comparison_pair_t; + using key_type = typename pair_type::first_type::key_type; + using tree = dpf::tree_traits; + (void)std::initializer_list{((void)tags, 0)...}; + dcf_runtime_spec runtime{}; + bool found = false; + detail::incr::collect_cmp_one(runtime, found, spec); + if (!found) + throw std::invalid_argument("dist comparison keygen needs one comparison"); + if (runtime.prefix == 0) + runtime.prefix = utils::bitlength_of_v; + if constexpr (Oblivious) + { + if (is_paint_kind(runtime.kind)) + throw std::invalid_argument( + "oblivious comparison does not support paint kinds"); + } + const bool edge = runtime.kind == cmp_kind::leq || runtime.kind == cmp_kind::gt; + demand d; + add_comparison(d, key_type::depth, runtime.prefix, key_type::cmp_block, + key_type::cmp_q, key_type::cmp_h, key_type::is_verifiable, Oblivious, + edge, runtime.mask); + const role peer = self == role::p0 ? role::p1 : role::p0; + auto mat = iknp::sample(net.to(peer), me, d.blocks, d.bits, d.b2a, d.cws); + cursor cur; + cur.mat = &mat; + exchange_zeros(net, me, d.zero_masks, cur); + tape out; + emit_comparison(out, cur, me, key_type::depth, runtime.prefix, + key_type::cmp_block, key_type::cmp_q, key_type::cmp_h, + key_type::is_verifiable, Oblivious, edge, tree::is_half_tree); + install(net, self, out, cur); +} + +template +void prepare_ic(trio & net, role self, const ic_pack & spec) +{ + const int me = me_of(self); + using input_type = std::decay_t; + const auto inner = detail::ic_impl::inner_lt(spec); + const std::uint64_t gmask = detail::ic_impl::group_mask_of(); + constexpr std::size_t nbits = utils::bitlength_of_v; + using pair_type = dist::comparison_pair_t; + using key_type = typename pair_type::first_type::key_type; + using tree = dpf::tree_traits; + dcf_runtime_spec runtime{}; + bool found = false; + detail::incr::collect_cmp_one(runtime, found, inner); + if (!found) + throw std::invalid_argument("dist comparison keygen needs one comparison"); + if (runtime.prefix == 0) + runtime.prefix = nbits; + constexpr bool oblivious = !Reveal; + if constexpr (oblivious) + { + if (is_paint_kind(runtime.kind)) + throw std::invalid_argument( + "oblivious comparison does not support paint kinds"); + } + demand d; + if constexpr (oblivious) + { + d.bits += dist::ic_gamma_and_count(nbits); + d.bits += dist::ic_correction_and_count(nbits); + d.b2a += 4; + } + const bool edge = runtime.kind == cmp_kind::leq || runtime.kind == cmp_kind::gt; + add_comparison(d, key_type::depth, runtime.prefix, key_type::cmp_block, + key_type::cmp_q, key_type::cmp_h, key_type::is_verifiable, oblivious, + edge, runtime.mask); + if constexpr (Reveal) + { + d.zero_masks.push_back(gmask); + d.zero_masks.push_back(gmask); + } + else + { + d.zero_masks.push_back(gmask); + } + const role peer = self == role::p0 ? role::p1 : role::p0; + auto mat = iknp::sample(net.to(peer), me, d.blocks, d.bits, d.b2a, d.cws); + cursor cur; + cur.mat = &mat; + exchange_zeros(net, me, d.zero_masks, cur); + tape out; + if constexpr (oblivious) + { + const std::size_t gamma_n = dist::ic_gamma_and_count(nbits); + const std::size_t corr_n = dist::ic_correction_and_count(nbits); + std::vector gamma(gamma_n), corr(corr_n); + for (auto & p : gamma) + p = cur.take_bit(); + for (auto & p : corr) + p = cur.take_bit(); + std::vector b2(4); + for (auto & p : b2) + p = cur.take_b2a(); + out.put_vec(net::msg::beaver_tape, gamma.data(), gamma.size()); + out.put_vec(net::msg::beaver_tape, corr.data(), corr.size()); + out.put_vec(net::msg::beaver_tape, b2.data(), b2.size()); + } + emit_comparison(out, cur, me, key_type::depth, runtime.prefix, + key_type::cmp_block, key_type::cmp_q, key_type::cmp_h, + key_type::is_verifiable, oblivious, edge, tree::is_half_tree); + out.put(net::msg::beaver_tape, cur.take_zero()); + if constexpr (Reveal) + out.put(net::msg::beaver_tape, cur.take_zero()); + install(net, self, out, cur); +} + +} // namespace iknp_deal + +/// @brief Two-party point keygen. Same walk as `dist_with_point_key`; pads +/// come from IKNP instead of p2. +/// @details Ideal (semi-honest): p0/p1 input XOR or additive shares of α and +/// payload β; each outputs its verifiable DPF key. With +/// `RevealPoint`, the tree prefix (and packed wildcard lane when +/// applicable) may be opened. Without it, α, peer seeds, peer +/// payload shares, and path-opening pad bits stay hidden. +/// \complexity Same tree walk as `dist_with_point_key`, plus one IKNP +/// `sample`. With tape length `T = Θ(n)` on a reveal point +/// (or `T = Θ(n · hash_level_and_count())` when oblivious), +/// `sample` does two Chou–Orlandi base sessions of `κ = 128` +/// OTs on P-256 and two OT-extension directions of cost +/// `Θ(κ T)` bits, then the usual `n` Doerner–Shelat opens. +/// Dealer `make_dpf` is still 0 rounds / 0 bytes; Half-Tree +/// §5.2 (ePrint 2022/1431) is a different `n+3`-round COT/OLE +/// hybrid this path does not implement. +/// \rounds Base OT + extension (constant rounds) then the usual per-level +/// DS exchanges; no p2. +/// \communication IKNP seed OT and extension rows (`Θ(κ T)` bits), then +/// the same peer messages as the dealer walk (no dealer +/// frames). +/// \preprocessing IKNP replaces the dealer tape; there is no offline p2. +template +HEDLEY_WARN_UNUSED_RESULT +auto dist_with_point_key_iknp( + trio & net, role self, InputT x0, InputT x1, OutputT beta, Fn0 && on0, + Fn1 && on1, bool already_encoded = false, bool additive = false) +{ + using opened_type = point_key_opened; + using dpf_type = utils::dpf_type_t; + constexpr bool wild_lane = RevealPoint && dpf::is_wildcard_v + && dpf_type::lg_outputs_per_leaf > 0; + if (additive && already_encoded) + throw std::invalid_argument( + "additive DS input is converted to XOR shares; it is not pre-opened"); + if (self == role::p2) + throw std::invalid_argument("iknp point keygen has no dealer"); + if (additive) + iknp_deal::prepare_point( + net, self); + else + iknp_deal::prepare_point( + net, self); + if (additive) + { + if (self == role::p0) + x0 = dist::additive_to_xor_share(net, x0); + else + x1 = dist::additive_to_xor_share(net, x1); + } + if constexpr (RevealPoint) + { + auto finish = [](auto result) { + opened_type out; + out.opened_prefix = result.opened_prefix; + if constexpr (wild_lane) + out.opened_lane = result.opened_lane; + return out; + }; + if (self == role::p0) + { + auto result = dist::point_party(net, x0, beta, already_encoded); + std::forward(on0)(result.dpf_key); + return std::optional(finish(std::move(result))); + } + auto result = dist::point_party(net, x1, beta, already_encoded); + std::forward(on1)(result.dpf_key); + return std::optional(finish(std::move(result))); + } + else + { + if (self == role::p0) + std::forward(on0)(dist::point_party( + net, x0, beta, already_encoded)); + else + std::forward(on1)(dist::point_party( + net, x1, beta, already_encoded)); + } +} + +/// @brief Two-party extractable point keygen. +template +void dist_with_extractable_point_key_iknp(trio & net, role self, InputT x0, + InputT x1, OutputT beta, Fn0 && on0, Fn1 && on1) +{ + static_assert(!dpf::is_wildcard_v, + "extractable socket gen does not reconstruct a wildcard lane"); + if (self == role::p2) + throw std::invalid_argument("iknp point keygen has no dealer"); + iknp_deal::prepare_point( + net, self); + if (self == role::p0) + { + on0(dist::point_party(net, x0, beta)); + } + else + { + on1(dist::point_party(net, x1, beta)); + } +} + +/// @brief Two-party comparison keygen. +template +auto dist_with_cmp_key_iknp(trio & net, role self, InputT x0, InputT x1, + const Spec & spec, Fn0 && on0, Fn1 && on1, const Tags & ...tags) + -> std::conditional_t, suppressed_point> +{ + if (self == role::p2) + throw std::invalid_argument("iknp comparison keygen has no dealer"); + iknp_deal::prepare_comparison( + net, self, spec, tags...); + if constexpr (Reveal) + { + if (self == role::p0) + { + auto result = dist::comparison_party(net, x0, spec, tags...); + std::forward(on0)(result.dpf_key); + return result.opened_point; + } + auto result = dist::comparison_party(net, x1, spec, tags...); + std::forward(on1)(result.dpf_key); + return result.opened_point; + } + else + { + if (self == role::p0) + { + std::forward(on0)(dist::comparison_party(net, x0, spec, tags...)); + } + else + { + std::forward(on1)(dist::comparison_party(net, x1, spec, tags...)); + } + return {}; + } +} + +/// @brief Two-party interval keygen. +template +auto dist_with_ic_key_iknp(trio & net, role self, InputT r0, InputT r1, + const ic_pack & spec, Fn0 && on0, Fn1 && on1) + -> std::conditional_t>, + suppressed_point> +{ + using input_type = std::decay_t; + using out_beta = concrete_type_t; + detail::ic_impl::check_input(); + detail::ic_impl::check_bounds(spec); + if constexpr (detail::cmp_group_info::custom) + { + throw std::invalid_argument( + "dist interval keygen currently supports <=64-bit ring payloads"); + if constexpr (Reveal) + return std::nullopt; + else + return {}; + } + else + { + if (self == role::p2) + throw std::invalid_argument("iknp interval keygen has no dealer"); + const auto inner_spec = detail::ic_impl::inner_lt(spec); + const std::uint64_t gmask = detail::ic_impl::group_mask_of(); + const std::uint64_t nmask = detail::ic_impl::input_mask_of(); + iknp_deal::prepare_ic( + net, self, spec); + const input_type mine = self == role::p0 ? r0 : r1; + std::uint64_t delta = 0; + std::uint64_t fval = 0; + if constexpr (!is_wildcard_v) + { + delta = detail::dcf_impl::beta_delta_u64( + spec.if_true, spec.if_false, gmask); + fval = detail::dcf_impl::beta_to_u64_simple(spec.if_false, gmask); + } + if constexpr (Reveal) + { + const role peer = self == role::p0 ? role::p1 : role::p0; + const input_type theirs = + net.exchange_with(peer, mine, net::msg::delta); + const input_type r = utils::xor_input_shares(mine, theirs); + const std::uint64_t r_bits = detail::ic_impl::bits_of(r); + input_type gamma = detail::ic_impl::gamma_of(r); + utils::flip_msb_if_signed_integral(gamma); + const std::uint64_t cr = detail::ic_impl::correction( + r_bits, spec.lo, spec.hi, nmask, gmask); + const std::uint64_t absorb = + (detail::ic_impl::mul_mask(delta, cr, gmask) + fval) & gmask; + const auto recv_side_shares = [&]() { + const auto z0 = + net.recv_from(role::p2, net::msg::beaver_tape); + const auto z1 = + net.recv_from(role::p2, net::msg::beaver_tape); + const std::uint64_t side = self == role::p1 ? 1ULL : 0ULL; + const std::uint64_t dshare = is_wildcard_v + ? 0ULL : (z0.share + side * delta) & gmask; + const std::uint64_t cshare = is_wildcard_v + ? 0ULL : (z1.share + side * absorb) & gmask; + const std::uint64_t dcoeff = is_wildcard_v + ? (z0.share + side) & gmask : 0ULL; + const std::uint64_t ccoeff = is_wildcard_v + ? (z1.share + side * cr) & gmask : 0ULL; + return std::array{ + dshare, cshare, dcoeff, ccoeff}; + }; + if (self == role::p0) + { + auto inner = dist::comparison_party(net, gamma, inner_spec); + const auto shares = recv_side_shares(); + using raw_key = typename decltype(inner)::key_type; + auto key = detail::ic_impl::make_side<0, raw_key, input_type, + out_beta>(std::move(inner), spec.lo, spec.hi, nmask, gmask, + shares[0], shares[1], shares[2], shares[3]); + on0(std::move(key)); + } + else + { + auto inner = dist::comparison_party(net, gamma, inner_spec); + const auto shares = recv_side_shares(); + using raw_key = typename decltype(inner)::key_type; + auto key = detail::ic_impl::make_side<1, raw_key, input_type, + out_beta>(std::move(inner), spec.lo, spec.hi, nmask, gmask, + shares[0], shares[1], shares[2], shares[3]); + on1(std::move(key)); + } + return r; + } + else + { + input_type gamma_share{}; + std::uint64_t cr_share = 0; + if (self == role::p0) + { + auto got = dist::ic_gamma_and_correction<0, input_type>(net, + mine, spec.lo, spec.hi, nmask, gmask); + gamma_share = got.first; + cr_share = got.second; + } + else + { + auto got = dist::ic_gamma_and_correction<1, input_type>(net, + mine, spec.lo, spec.hi, nmask, gmask); + gamma_share = got.first; + cr_share = got.second; + } + const std::uint64_t absorb_share = is_wildcard_v + ? 0ULL + : (detail::ic_impl::mul_mask(delta, cr_share, gmask) + + (self == role::p1 ? fval : 0ULL)) & gmask; + const std::uint64_t cr_coeff_share = + is_wildcard_v ? cr_share : 0ULL; + const auto recv_delta = [&]() { + const auto z0 = + net.recv_from(role::p2, net::msg::beaver_tape); + const std::uint64_t side = self == role::p1 ? 1ULL : 0ULL; + const std::uint64_t dshare = is_wildcard_v + ? 0ULL : (z0.share + side * delta) & gmask; + const std::uint64_t dcoeff = is_wildcard_v + ? (z0.share + side) & gmask : 0ULL; + return std::array{dshare, dcoeff}; + }; + if (self == role::p0) + { + auto inner = dist::comparison_party(net, gamma_share, inner_spec); + const auto d = recv_delta(); + using raw_key = typename decltype(inner)::key_type; + auto key = detail::ic_impl::make_side<0, raw_key, input_type, + out_beta>(std::move(inner), spec.lo, spec.hi, nmask, gmask, + d[0], absorb_share, d[1], cr_coeff_share); + on0(std::move(key)); + } + else + { + auto inner = dist::comparison_party(net, gamma_share, inner_spec); + const auto d = recv_delta(); + using raw_key = typename decltype(inner)::key_type; + auto key = detail::ic_impl::make_side<1, raw_key, input_type, + out_beta>(std::move(inner), spec.lo, spec.hi, nmask, gmask, + d[0], absorb_share, d[1], cr_coeff_share); + on1(std::move(key)); + } + return {}; + } + } +} + +} // namespace party +} // namespace dpf + +#endif // LIBDPF_PARTY_IKNP_DEAL_HPP__ diff --git a/party/key_io.hpp b/party/key_io.hpp new file mode 100644 index 0000000..dc51670 --- /dev/null +++ b/party/key_io.hpp @@ -0,0 +1,70 @@ +/// @file party/key_io.hpp +/// @brief Ship a copyable DPF key as a framed byte blob. +#ifndef LIBDPF_PARTY_KEY_IO_HPP__ +#define LIBDPF_PARTY_KEY_IO_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "dpf/net/channel.hpp" +#include "dpf/net/trio.hpp" + +namespace dpf +{ +namespace party +{ + +template +void send_key(net::channel & c, const Key & key) +{ + Key copy(key); + c.send_bytes(net::msg::dpf_key, + reinterpret_cast(©), sizeof(Key)); +} + +template +Key recv_key(net::channel & c) +{ + auto body = c.recv_bytes(net::msg::dpf_key); + if (body.size() != sizeof(Key)) + throw std::runtime_error("recv_key size mismatch"); + alignas(Key) unsigned char raw[sizeof(Key)]; + std::memcpy(raw, body.data(), sizeof(Key)); + Key * p = std::launder(reinterpret_cast(raw)); + Key out(std::move(*p)); + p->~Key(); + return out; +} + +/// @brief Send a key blob through the trio hook (or mesh when unset). +template +void send_key(net::trio & net, net::role peer, const Key & key) +{ + Key copy(key); + net.send_bytes_to(peer, net::msg::dpf_key, + reinterpret_cast(©), sizeof(Key)); +} + +/// @brief Receive a key blob through the trio hook (or mesh when unset). +template +Key recv_key(net::trio & net, net::role peer) +{ + auto body = net.recv_bytes_from(peer, net::msg::dpf_key); + if (body.size() != sizeof(Key)) + throw std::runtime_error("recv_key size mismatch"); + alignas(Key) unsigned char raw[sizeof(Key)]; + std::memcpy(raw, body.data(), sizeof(Key)); + Key * p = std::launder(reinterpret_cast(raw)); + Key out(std::move(*p)); + p->~Key(); + return out; +} + +} // namespace party +} // namespace dpf + +#endif // LIBDPF_PARTY_KEY_IO_HPP__ diff --git a/party/oblivious_hash.hpp b/party/oblivious_hash.hpp new file mode 100644 index 0000000..6c1e39f --- /dev/null +++ b/party/oblivious_hash.hpp @@ -0,0 +1,633 @@ +/// @file party/oblivious_hash.hpp +/// @brief Correction-seed hash that keeps the path prefix shared. +/// @details Matches `detail::vdpf::hash_node` without either party learning +/// the prefix. The opened value is only `H(s0) XOR H(s1)`. +/// SubBytes uses the Boyar–Peralta AES S-box (ePrint 2011/332; +/// Yale CMT SLP with 32 ANDs). Bit×bit ANDs use bit Beaver triples +/// and are scheduled by multiplicative depth (six exchanges per +/// SubBytes), so one level costs `8×16×10×32 = 40960` bit-ANDs. + +#ifndef LIBDPF_PARTY_OBLIVIOUS_HASH_HPP__ +#define LIBDPF_PARTY_OBLIVIOUS_HASH_HPP__ + +#include +#include +#include +#include +#include +#include + +#include "simde/simde/x86/avx2.h" + +#include "aes_mmo_ref.hpp" +#include "aes_sbox_bp.hpp" +#include "dpf/doerner_shelat.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/verifiable.hpp" +#include "dpf/net/round_sink.hpp" +#include "dpf/net/sink_exchange.hpp" + +/* aes_bp is file-scope */ + +/// @brief AND-triples consumed by one level of `oblivious_cs`. +inline constexpr std::size_t hash_level_and_count() noexcept +{ + // Eight AES (two seeds × four MMO lanes) × 16 bytes × 10 SubBytes + // × 32 Boyar–Peralta ANDs. + return 8u * 16u * 10u * aes_bp::and_count; +} + +inline std::vector sample_and_tape(std::size_t n, int party) +{ + ::dpf::detail::urandom_pad_rng pads; + std::vector out(n); + for (std::size_t i = 0; i < n; ++i) + { + const auto full = ::dpf::detail::ds_sample_bit_and(pads); + out[i] = bit_pad_for(full, party); + } + return out; +} + +inline std::vector pack_mask_bits( + const std::uint8_t * d, const std::uint8_t * e, std::size_t n) +{ + std::vector out((2u * n + 7u) / 8u); + for (std::size_t i = 0; i < n; ++i) + { + const std::size_t db = 2u * i; + const std::size_t eb = db + 1u; + if (d[i] & 1u) + out[db / 8u] = static_cast( + out[db / 8u] | static_cast(1u << (db % 8u))); + if (e[i] & 1u) + out[eb / 8u] = static_cast( + out[eb / 8u] | static_cast(1u << (eb % 8u))); + } + return out; +} + +inline void unpack_mask_bits(const std::vector & packed, + std::uint8_t * d, std::uint8_t * e, std::size_t n) +{ + if (packed.size() != (2u * n + 7u) / 8u) + throw std::runtime_error("oblivious AND packed size"); + for (std::size_t i = 0; i < n; ++i) + { + const std::size_t db = 2u * i; + const std::size_t eb = db + 1u; + d[i] = static_cast( + (packed[db / 8u] >> (db % 8u)) & 1u); + e[i] = static_cast( + (packed[eb / 8u] >> (eb % 8u)) & 1u); + } +} + +/// @brief One exchange of packed `(x⊕α, y⊕β)` masks for `n` bit-ANDs. +template +std::vector batch_bit_and(net::trio & net, + const std::uint8_t * x, const std::uint8_t * y, std::size_t n, + const bit_and_pad_msg * triples) +{ + const role peer = Me == 0 ? role::p1 : role::p0; + std::vector d(n), e(n); + for (std::size_t i = 0; i < n; ++i) + { + d[i] = static_cast(x[i] ^ triples[i].a); + e[i] = static_cast(y[i] ^ triples[i].b); + } + const auto mine = pack_mask_bits(d.data(), e.data(), n); + std::vector peer_bytes; + if constexpr (Me == 0) + { + net.send_bytes_to(peer, net::msg::delta, mine.data(), mine.size()); + peer_bytes = net.recv_bytes_from(peer, net::msg::delta); + } + else + { + peer_bytes = net.recv_bytes_from(peer, net::msg::delta); + net.send_bytes_to(peer, net::msg::delta, mine.data(), mine.size()); + } + std::vector pd(n), pe(n); + unpack_mask_bits(peer_bytes, pd.data(), pe.data(), n); + + // Standard Beaver: z = [c] ⊕ (d∧[b]) ⊕ ([a]∧e) ⊕ (d∧e), and the public + // `d∧e` term is added on one party only. Adding it on both cancels under + // XOR and the S-box (and every correction seed) diverges from `hash_node`. + std::vector shares(n); + for (std::size_t i = 0; i < n; ++i) + { + const std::uint8_t od = static_cast(d[i] ^ pd[i]); + const std::uint8_t oe = static_cast(e[i] ^ pe[i]); + shares[i] = detail::ds_bit_and_party( + od, oe, triples[i].a, triples[i].b, triples[i].c, Me == 0); + } + return shares; +} + +/// @brief Packed bit-AND layer on a RoundSink. Slot must fit `4 + packed`. +template +std::vector batch_bit_and_on_sink(dpf::net::RoundSink & sink, + std::uint16_t & round, std::size_t index, const std::uint8_t * x, + const std::uint8_t * y, std::size_t n, const bit_and_pad_msg * triples) +{ + std::vector d(n), e(n); + for (std::size_t i = 0; i < n; ++i) + { + d[i] = static_cast(x[i] ^ triples[i].a); + e[i] = static_cast(y[i] ^ triples[i].b); + } + const auto mine = pack_mask_bits(d.data(), e.data(), n); + if (round >= sink.rounds()) + throw std::runtime_error("batch_bit_and_on_sink: out of rounds"); + const std::size_t slot = sink.slot_bytes(round); + const std::size_t need = sizeof(std::uint32_t) + mine.size(); + if (need > slot) + throw std::runtime_error("batch_bit_and_on_sink: slot too small"); + std::vector buf(slot, 0); + const std::uint32_t nbytes = static_cast(mine.size()); + std::memcpy(buf.data(), &nbytes, 4); + if (!mine.empty()) + std::memcpy(buf.data() + 4, mine.data(), mine.size()); + sink.submit(round, index, buf.data(), buf.size()); + sink.flush_round(round); + sink.poll(); + if (!sink.peer_ready(round, index)) + throw std::runtime_error("batch_bit_and_on_sink: peer missing"); + std::vector peer_buf(slot); + sink.read_peer(round, index, peer_buf.data(), slot); + std::uint32_t pn = 0; + std::memcpy(&pn, peer_buf.data(), 4); + if (pn != nbytes) + throw std::runtime_error("batch_bit_and_on_sink: peer size"); + std::vector peer_bytes(pn); + if (pn != 0) + std::memcpy(peer_bytes.data(), peer_buf.data() + 4, pn); + ++round; + std::vector pd(n), pe(n); + unpack_mask_bits(peer_bytes, pd.data(), pe.data(), n); + std::vector shares(n); + for (std::size_t i = 0; i < n; ++i) + { + const std::uint8_t od = static_cast(d[i] ^ pd[i]); + const std::uint8_t oe = static_cast(e[i] ^ pe[i]); + shares[i] = detail::ds_bit_and_party( + od, oe, triples[i].a, triples[i].b, triples[i].c, Me == 0); + } + return shares; +} + +/// @brief Shared SubBytes via Boyar–Peralta (32 ANDs per byte, depth-batched). +template +void sub_bytes_shared(net::trio & net, std::uint8_t * state, std::size_t bytes, + const bit_and_pad_msg * & tape) +{ + std::vector wire(bytes * aes_bp::wire_count); + auto at = [&](std::size_t b, std::size_t w) -> std::uint8_t & { + return wire[b * aes_bp::wire_count + w]; + }; + for (std::size_t b = 0; b < bytes; ++b) + { + for (int i = 0; i < 8; ++i) + at(b, static_cast(i)) = + static_cast((state[b] >> (7 - i)) & 1u); + } + + std::array ready{}; + for (std::size_t i = 0; i < 8; ++i) + ready[i] = true; + std::array done{}; + std::size_t finished = 0; + while (finished < aes_bp::op_count) + { + bool progress = true; + while (progress) + { + progress = false; + for (std::size_t oi = 0; oi < aes_bp::op_count; ++oi) + { + if (done[oi]) + continue; + const auto kind = aes_bp::ops[oi][0]; + if (kind == 1) + continue; + const auto dst = aes_bp::ops[oi][1]; + const auto a = aes_bp::ops[oi][2]; + const auto bb = aes_bp::ops[oi][3]; + if (!ready[a] || !ready[bb]) + continue; + for (std::size_t b = 0; b < bytes; ++b) + { + auto v = static_cast(at(b, a) ^ at(b, bb)); + if (kind == 2) + { + if constexpr (Me == 0) + v = static_cast(v ^ 1u); + } + at(b, dst) = v; + } + ready[dst] = true; + done[oi] = true; + ++finished; + progress = true; + } + } + + std::vector ands; + ands.reserve(aes_bp::and_count); + for (std::size_t oi = 0; oi < aes_bp::op_count; ++oi) + { + if (done[oi] || aes_bp::ops[oi][0] != 1) + continue; + const auto a = aes_bp::ops[oi][2]; + const auto bb = aes_bp::ops[oi][3]; + if (ready[a] && ready[bb]) + ands.push_back(oi); + } + if (ands.empty()) + { + if (finished != aes_bp::op_count) + throw std::runtime_error("oblivious SubBytes stuck"); + break; + } + + const std::size_t n = ands.size() * bytes; + std::vector xs(n), ys(n); + for (std::size_t ai = 0; ai < ands.size(); ++ai) + { + const auto a = aes_bp::ops[ands[ai]][2]; + const auto bb = aes_bp::ops[ands[ai]][3]; + for (std::size_t b = 0; b < bytes; ++b) + { + xs[ai * bytes + b] = at(b, a); + ys[ai * bytes + b] = at(b, bb); + } + } + const auto prod = batch_bit_and(net, xs.data(), ys.data(), n, tape); + tape += n; + for (std::size_t ai = 0; ai < ands.size(); ++ai) + { + const auto dst = aes_bp::ops[ands[ai]][1]; + for (std::size_t b = 0; b < bytes; ++b) + at(b, dst) = static_cast(prod[ai * bytes + b] & 1u); + ready[dst] = true; + done[ands[ai]] = true; + ++finished; + } + } + + for (std::size_t b = 0; b < bytes; ++b) + { + std::uint8_t out = 0; + for (int i = 0; i < 8; ++i) + out = static_cast( + out | (at(b, aes_bp::out_wire[static_cast(i)]) + << (7 - i))); + state[b] = out; + } +} + +/// @brief SubBytes with AND layers on a RoundSink (multi-instance friendly). +template +void sub_bytes_shared_on_sink(dpf::net::RoundSink & sink, std::uint16_t & round, + std::size_t index, std::uint8_t * state, std::size_t bytes, + const bit_and_pad_msg * & tape) +{ + std::vector wire(bytes * aes_bp::wire_count); + auto at = [&](std::size_t b, std::size_t w) -> std::uint8_t & { + return wire[b * aes_bp::wire_count + w]; + }; + for (std::size_t b = 0; b < bytes; ++b) + { + for (int i = 0; i < 8; ++i) + at(b, static_cast(i)) = + static_cast((state[b] >> (7 - i)) & 1u); + } + + std::array ready{}; + for (std::size_t i = 0; i < 8; ++i) + ready[i] = true; + std::array done{}; + std::size_t finished = 0; + while (finished < aes_bp::op_count) + { + bool progress = true; + while (progress) + { + progress = false; + for (std::size_t oi = 0; oi < aes_bp::op_count; ++oi) + { + if (done[oi]) + continue; + const auto kind = aes_bp::ops[oi][0]; + if (kind == 1) + continue; + const auto dst = aes_bp::ops[oi][1]; + const auto a = aes_bp::ops[oi][2]; + const auto bb = aes_bp::ops[oi][3]; + if (!ready[a] || !ready[bb]) + continue; + for (std::size_t b = 0; b < bytes; ++b) + { + auto v = static_cast(at(b, a) ^ at(b, bb)); + if (kind == 2) + { + if constexpr (Me == 0) + v = static_cast(v ^ 1u); + } + at(b, dst) = v; + } + ready[dst] = true; + done[oi] = true; + ++finished; + progress = true; + } + } + + std::vector ands; + ands.reserve(aes_bp::and_count); + for (std::size_t oi = 0; oi < aes_bp::op_count; ++oi) + { + if (done[oi] || aes_bp::ops[oi][0] != 1) + continue; + const auto a = aes_bp::ops[oi][2]; + const auto bb = aes_bp::ops[oi][3]; + if (ready[a] && ready[bb]) + ands.push_back(oi); + } + if (ands.empty()) + { + if (finished != aes_bp::op_count) + throw std::runtime_error("oblivious SubBytes stuck"); + break; + } + + const std::size_t n = ands.size() * bytes; + std::vector xs(n), ys(n); + for (std::size_t ai = 0; ai < ands.size(); ++ai) + { + const auto a = aes_bp::ops[ands[ai]][2]; + const auto bb = aes_bp::ops[ands[ai]][3]; + for (std::size_t b = 0; b < bytes; ++b) + { + xs[ai * bytes + b] = at(b, a); + ys[ai * bytes + b] = at(b, bb); + } + } + const auto prod = batch_bit_and_on_sink( + sink, round, index, xs.data(), ys.data(), n, tape); + tape += n; + for (std::size_t ai = 0; ai < ands.size(); ++ai) + { + const auto dst = aes_bp::ops[ands[ai]][1]; + for (std::size_t b = 0; b < bytes; ++b) + at(b, dst) = static_cast(prod[ai * bytes + b] & 1u); + ready[dst] = true; + done[ands[ai]] = true; + ++finished; + } + } + + for (std::size_t b = 0; b < bytes; ++b) + { + std::uint8_t out = 0; + for (int i = 0; i < 8; ++i) + out = static_cast( + out | (at(b, aes_bp::out_wire[static_cast(i)]) + << (7 - i))); + state[b] = out; + } +} + +inline void shift_rows_bytes(std::uint8_t s[16]) +{ + ::dpf::party::aes_ref::shift_rows(s); +} + +inline void mix_columns_bytes(std::uint8_t s[16]) +{ + ::dpf::party::aes_ref::mix_columns(s); +} + +inline void xor_bytes(std::uint8_t * dst, const std::uint8_t * src, std::size_t n) +{ + for (std::size_t i = 0; i < n; ++i) + dst[i] = static_cast(dst[i] ^ src[i]); +} + +inline std::array m128_bytes(simde__m128i v) +{ + std::array b{}; + std::memcpy(b.data(), &v, 16); + return b; +} + +/// @brief Public correction seed for one level. Prefix shares stay local. +template +cs_block oblivious_cs(net::trio & net, std::size_t level, + std::uint64_t prefix_share, simde__m128i my_seed, + const bit_and_pad_msg * tape) +{ + const auto schedule = prg::aes128_key(simde_mm_setzero_si128()); + const auto rk = [&](int r) { + return m128_bytes(schedule.rd_key[static_cast(r)]); + }; + + constexpr std::size_t blocks = 8; + std::uint8_t state[blocks][16]{}; + std::uint8_t feed[blocks][16]{}; + + auto place_prefix = [&](std::uint8_t * dst) { + for (int i = 0; i < 8; ++i) + dst[i] = static_cast( + dst[i] ^ static_cast(prefix_share >> (8 * i))); + }; + + for (int owner = 0; owner < 2; ++owner) + { + const bool mine = (owner == Me); + for (int pos = 0; pos < 4; ++pos) + { + const std::size_t bi = static_cast(owner * 4 + pos); + if (mine) + { + auto bytes = m128_bytes(my_seed); + const std::uint64_t tag = 0x5600ull | (level & 0xffffu); + for (int i = 0; i < 8; ++i) + bytes[8 + i] = static_cast( + bytes[8 + i] + ^ static_cast(tag >> (8 * i))); + place_prefix(bytes.data()); + std::memcpy(feed[bi], bytes.data(), 16); + std::memcpy(state[bi], bytes.data(), 16); + } + else + { + std::uint8_t bytes[16]{}; + place_prefix(bytes); + std::memcpy(feed[bi], bytes, 16); + std::memcpy(state[bi], bytes, 16); + } + if constexpr (Me == 0) + { + auto key0 = rk(0); + key0[0] = static_cast( + key0[0] ^ static_cast(pos)); + key0[1] = static_cast( + key0[1] + ^ static_cast(static_cast(pos) >> 8)); + key0[2] = static_cast( + key0[2] + ^ static_cast( + static_cast(pos) >> 16)); + key0[3] = static_cast( + key0[3] + ^ static_cast( + static_cast(pos) >> 24)); + xor_bytes(state[bi], key0.data(), 16); + } + } + } + + auto all_bytes = [&]() -> std::uint8_t * { return &state[0][0]; }; + const bit_and_pad_msg * cursor = tape; + for (int round = 1; round <= 10; ++round) + { + sub_bytes_shared(net, all_bytes(), blocks * 16, cursor); + for (std::size_t b = 0; b < blocks; ++b) + shift_rows_bytes(state[b]); + if (round < 10) + { + for (std::size_t b = 0; b < blocks; ++b) + mix_columns_bytes(state[b]); + } + if constexpr (Me == 0) + { + const auto key = rk(round); + for (std::size_t b = 0; b < blocks; ++b) + xor_bytes(state[b], key.data(), 16); + } + } + if (cursor != tape + hash_level_and_count()) + throw std::runtime_error("oblivious hash consumed the wrong AND count"); + + for (std::size_t b = 0; b < blocks; ++b) + xor_bytes(state[b], feed[b], 16); + + cs_block mine{}; + for (int pos = 0; pos < 4; ++pos) + { + std::uint8_t mixed[16]{}; + xor_bytes(mixed, state[static_cast(pos)], 16); + xor_bytes(mixed, state[static_cast(4 + pos)], 16); + std::memcpy(&mine[static_cast(pos)], mixed, 16); + } + return open_cs(net, mine); +} + +/// @brief `oblivious_cs` with AND layers on a RoundSink; final open stays on trio. +template +cs_block oblivious_cs_on_sink(net::trio & net, dpf::net::RoundSink & sink, + std::uint16_t & round, std::size_t index, std::size_t level, + std::uint64_t prefix_share, simde__m128i my_seed, + const bit_and_pad_msg * tape) +{ + const auto schedule = prg::aes128_key(simde_mm_setzero_si128()); + const auto rk = [&](int r) { + return m128_bytes(schedule.rd_key[static_cast(r)]); + }; + + constexpr std::size_t blocks = 8; + std::uint8_t state[blocks][16]{}; + std::uint8_t feed[blocks][16]{}; + + auto place_prefix = [&](std::uint8_t * dst) { + for (int i = 0; i < 8; ++i) + dst[i] = static_cast( + dst[i] ^ static_cast(prefix_share >> (8 * i))); + }; + + for (int owner = 0; owner < 2; ++owner) + { + const bool mine = (owner == Me); + for (int pos = 0; pos < 4; ++pos) + { + const std::size_t bi = static_cast(owner * 4 + pos); + if (mine) + { + auto bytes = m128_bytes(my_seed); + const std::uint64_t tag = 0x5600ull | (level & 0xffffu); + for (int i = 0; i < 8; ++i) + bytes[8 + i] = static_cast( + bytes[8 + i] + ^ static_cast(tag >> (8 * i))); + place_prefix(bytes.data()); + std::memcpy(feed[bi], bytes.data(), 16); + std::memcpy(state[bi], bytes.data(), 16); + } + else + { + std::uint8_t bytes[16]{}; + place_prefix(bytes); + std::memcpy(feed[bi], bytes, 16); + std::memcpy(state[bi], bytes, 16); + } + if constexpr (Me == 0) + { + auto key0 = rk(0); + key0[0] = static_cast( + key0[0] ^ static_cast(pos)); + key0[1] = static_cast( + key0[1] + ^ static_cast(static_cast(pos) >> 8)); + key0[2] = static_cast( + key0[2] + ^ static_cast( + static_cast(pos) >> 16)); + key0[3] = static_cast( + key0[3] + ^ static_cast( + static_cast(pos) >> 24)); + xor_bytes(state[bi], key0.data(), 16); + } + } + } + + auto all_bytes = [&]() -> std::uint8_t * { return &state[0][0]; }; + const bit_and_pad_msg * cursor = tape; + for (int aes_round = 1; aes_round <= 10; ++aes_round) + { + sub_bytes_shared_on_sink( + sink, round, index, all_bytes(), blocks * 16, cursor); + for (std::size_t b = 0; b < blocks; ++b) + shift_rows_bytes(state[b]); + if (aes_round < 10) + { + for (std::size_t b = 0; b < blocks; ++b) + mix_columns_bytes(state[b]); + } + if constexpr (Me == 0) + { + const auto key = rk(aes_round); + for (std::size_t b = 0; b < blocks; ++b) + xor_bytes(state[b], key.data(), 16); + } + } + if (cursor != tape + hash_level_and_count()) + throw std::runtime_error("oblivious hash consumed the wrong AND count"); + + for (std::size_t b = 0; b < blocks; ++b) + xor_bytes(state[b], feed[b], 16); + + cs_block mine{}; + for (int pos = 0; pos < 4; ++pos) + { + std::uint8_t mixed[16]{}; + xor_bytes(mixed, state[static_cast(pos)], 16); + xor_bytes(mixed, state[static_cast(4 + pos)], 16); + std::memcpy(&mine[static_cast(pos)], mixed, 16); + } + return open_cs(net, mine); +} + +#endif diff --git a/party/oblivious_select.hpp b/party/oblivious_select.hpp new file mode 100644 index 0000000..ec174de --- /dev/null +++ b/party/oblivious_select.hpp @@ -0,0 +1,296 @@ +/// @file party/oblivious_select.hpp +/// @brief Shared-output muxes for the socket Doerner–Shelat walk. +/// @details Included from inside `dpf::party::dist`. Products stay shared. +/// The only opened values are public correction words. + +#ifndef LIBDPF_PARTY_OBLIVIOUS_SELECT_HPP__ +#define LIBDPF_PARTY_OBLIVIOUS_SELECT_HPP__ + +template +std::vector exch_vec(net::trio & net, const std::vector & mine) +{ + const role peer = Me == 0 ? role::p1 : role::p0; + if constexpr (Me == 0) + { + net.to(peer).send_vec(mine, net::msg::delta); + return net.to(peer).template recv_vec(net::msg::delta); + } + else + { + auto got = net.to(peer).template recv_vec(net::msg::delta); + net.to(peer).send_vec(mine, net::msg::delta); + return got; + } +} + +/// @brief This party's XOR share of `bit * block`. The product is not opened. +template +simde__m128i beaver_xor_share_bit(Exchange && exch, bool i_hold_block, + std::uint8_t bit_share, simde__m128i block, const and_share_msg & mine) +{ + and_round1_msg msg{}; + msg.d_bit = static_cast(bit_share ^ mine.a); + msg.b_bit = mine.b; + msg.a_m = mine.a; + msg.e_m = i_hold_block ? detail::ds_xor(block, mine.b) : mine.b; + const and_round1_msg peer = exch(msg); + const std::uint8_t d = static_cast(msg.d_bit ^ peer.d_bit); + const simde__m128i e = i_hold_block + ? detail::ds_xor(msg.e_m, peer.b_bit) + : detail::ds_xor(peer.e_m, mine.b); + simde__m128i z = detail::ds_xor( + detail::ds_xor(detail::ds_gate(d, mine.b), detail::ds_gate(mine.a, e)), + mine.c); + if (i_hold_block) + z = detail::ds_xor(z, detail::ds_gate(d, e)); + return z; +} + +/// @brief Additive leaf share of a XOR-shared block. Limb width matches `leaf_add`. +template +simde__m128i b2a_leaf(net::trio & net, simde__m128i xor_share, + const b2a_pad_msg * pads, std::size_t limb_bytes) +{ + std::uint8_t bytes[16]{}; + std::memcpy(bytes, &xor_share, 16); + std::vector masked(128); + for (int i = 0; i < 128; ++i) + { + const std::uint8_t bit = static_cast( + (bytes[i / 8] >> (i % 8)) & 1u); + masked[static_cast(i)] = static_cast( + bit ^ pads[i].r); + } + const auto peer = exch_vec(net, masked); + const std::size_t limb_bits = limb_bytes * 8; + const std::size_t nlimbs = 16 / limb_bytes; + const std::uint64_t limb_mask = limb_bits == 64 + ? ~std::uint64_t{0} + : ((std::uint64_t{1} << limb_bits) - 1); + std::uint64_t acc[16]{}; + for (int i = 0; i < 128; ++i) + { + const std::uint8_t c = static_cast( + masked[static_cast(i)] ^ peer[static_cast(i)]); + std::uint64_t s = pads[i].add; + if (c != 0) + s = Me == 0 ? (std::uint64_t{1} - pads[i].add) + : (std::uint64_t{0} - pads[i].add); + const std::size_t limb = static_cast(i) / limb_bits; + const unsigned shift = static_cast( + static_cast(i) % limb_bits); + acc[limb] += s << shift; + } + std::uint8_t outb[16]{}; + for (std::size_t k = 0; k < nlimbs; ++k) + { + const std::uint64_t v = acc[k] & limb_mask; + std::memcpy(outb + k * limb_bytes, &v, limb_bytes); + } + simde__m128i out{}; + std::memcpy(&out, outb, 16); + return out; +} + +template +Leaf open_leaf_sum(net::trio & net, Leaf mine) +{ + const role peer = Me == 0 ? role::p1 : role::p0; + const Leaf theirs = net.exchange_with(peer, mine, net::msg::ring_vector); + return leaf_add(mine, theirs); +} + +/// @brief Public leaf CW from a shared naked leaf and this party's mask. +template +Leaf cw_from_selected(net::trio & net, Leaf selected, Leaf mask, bool sign) +{ + constexpr bool char2 = utils::has_characteristic_two_v; + Leaf share{}; + if constexpr (char2) + { + share = leaf_add(selected, mask); + } + else if (sign) + { + if constexpr (Me == 0) + share = leaf_add(selected, mask); + else + share = dpf::subtract_leaf(selected, mask); + } + else if constexpr (Me == 0) + { + const Leaf neg = dpf::subtract_leaf(Leaf{}, selected); + share = dpf::subtract_leaf(neg, mask); + } + else + { + share = dpf::subtract_leaf(mask, selected); + } + return open_leaf_sum(net, share); +} + +/// @brief Share of the leaf selected by the low `lg` bits of the target. +/// @details Party 0's `make(i)` is the candidate. Party 1's is zero. Each mux +/// multiplies the selector by both parties' deltas and keeps the sum +/// shared, so neither party sees the lane. +template +Leaf mux_leaf_share(net::trio & net, Exchange && exch, std::size_t lg, + Make && make, BitAt && bit_at, const and_share_msg * ands, + const b2a_pad_msg * b2a) +{ + static_assert(sizeof(Leaf) == sizeof(simde__m128i), + "shared leaf mux covers a single AES block"); + constexpr bool char2 = utils::has_characteristic_two_v; + constexpr std::size_t limb = [] { + constexpr std::size_t s = sizeof(Concrete); + return (s == 1 || s == 2 || s == 4 || s == 8) ? s : std::size_t{8}; + }(); + std::vector cand(std::size_t{1} << lg); + for (std::size_t i = 0; i < cand.size(); ++i) + cand[i] = make(static_cast(i)); + std::size_t pad_i = 0; + std::size_t b2a_i = 0; + for (std::size_t b = 0; b < lg; ++b) + { + const std::uint8_t bit = bit_at(b); + std::vector next(cand.size() / 2); + for (std::size_t k = 0; k < next.size(); ++k) + { + const Leaf lo = cand[2 * k]; + const Leaf hi = cand[2 * k + 1]; + const Leaf delta = dpf::subtract_leaf(hi, lo); + simde__m128i dblock{}; + std::memcpy(&dblock, &delta, sizeof(dblock)); + const simde__m128i zero = simde_mm_setzero_si128(); + simde__m128i zx{}; + simde__m128i zy{}; + if constexpr (Me == 0) + { + zx = beaver_xor_share_bit(exch, true, bit, dblock, ands[pad_i++]); + zy = beaver_xor_share_bit(exch, false, bit, zero, ands[pad_i++]); + } + else + { + zx = beaver_xor_share_bit(exch, false, bit, zero, ands[pad_i++]); + zy = beaver_xor_share_bit(exch, true, bit, dblock, ands[pad_i++]); + } + Leaf prod{}; + if constexpr (char2) + { + const simde__m128i z = detail::ds_xor(zx, zy); + std::memcpy(&prod, &z, sizeof(prod)); + } + else + { + const simde__m128i ax = b2a_leaf(net, zx, b2a + b2a_i, limb); + b2a_i += 128; + const simde__m128i ay = b2a_leaf(net, zy, b2a + b2a_i, limb); + b2a_i += 128; + Leaf px{}; + Leaf py{}; + std::memcpy(&px, &ax, sizeof(px)); + std::memcpy(&py, &ay, sizeof(py)); + prod = leaf_add(px, py); + } + next[k] = leaf_add(lo, prod); + } + cand.swap(next); + } + return cand[0]; +} + +template +std::uint8_t and_bit_share(net::trio & net, std::uint8_t x, std::uint8_t y, + const bit_and_pad_msg & pad) +{ + const role peer = Me == 0 ? role::p1 : role::p0; + const bit_and_mask_msg mine{ + static_cast(x ^ pad.a), + static_cast(y ^ pad.b)}; + const bit_and_mask_msg got = net.exchange_with(peer, mine, net::msg::delta); + const std::uint8_t d = static_cast(mine.x ^ got.x); + const std::uint8_t e = static_cast(mine.y ^ got.y); + return detail::ds_bit_and_party(d, e, pad.a, pad.b, pad.c, Me == 0); +} + +template +std::uint64_t b2a_bit(net::trio & net, std::uint8_t bit, const b2a_pad_msg & pad) +{ + const role peer = Me == 0 ? role::p1 : role::p0; + const std::uint8_t masked = static_cast(bit ^ pad.r); + const std::uint8_t other = net.exchange_with(peer, masked, net::msg::delta); + const std::uint8_t c = static_cast(masked ^ other); + if (c == 0) + return pad.add; + if constexpr (Me == 0) + return std::uint64_t{1} - pad.add; + else + return std::uint64_t{0} - pad.add; +} + +/// @brief Additive share of `bit * word`. `word` is meaningful only for the holder. +template +std::uint64_t mul_known_word(net::trio & net, bool i_hold, std::uint64_t word, + std::uint8_t bit, const word_bit_pad * pads) +{ + std::vector mine(64); + for (int i = 0; i < 64; ++i) + { + const std::uint8_t wbit = i_hold + ? static_cast((word >> i) & 1u) : std::uint8_t{0}; + mine[static_cast(i)] = bit_and_mask_msg{ + static_cast(bit ^ pads[i].a), + static_cast(wbit ^ pads[i].b)}; + } + const auto peer = exch_vec(net, mine); + std::vector masked(64); + std::uint8_t prod[64]{}; + for (int i = 0; i < 64; ++i) + { + const auto & m = mine[static_cast(i)]; + const auto & g = peer[static_cast(i)]; + const std::uint8_t d = static_cast(m.x ^ g.x); + const std::uint8_t e = static_cast(m.y ^ g.y); + prod[i] = detail::ds_bit_and_party( + d, e, pads[i].a, pads[i].b, pads[i].c, Me == 0); + masked[static_cast(i)] = static_cast( + prod[i] ^ pads[i].r); + } + const auto opened = exch_vec(net, masked); + std::uint64_t acc = 0; + for (int i = 0; i < 64; ++i) + { + const std::uint8_t c = static_cast( + masked[static_cast(i)] ^ opened[static_cast(i)]); + std::uint64_t s = pads[i].add; + if (c != 0) + s = Me == 0 ? (std::uint64_t{1} - pads[i].add) + : (std::uint64_t{0} - pads[i].add); + acc += s << i; + } + return acc; +} + +/// @brief XOR-share of the AND of every bit in `bits`. `n == 0` returns 1 on p0. +template +std::uint8_t and_tree(net::trio & net, const std::uint8_t * bits, std::size_t n, + const bit_and_pad_msg * pads) +{ + if (n == 0) + return Me == 0 ? std::uint8_t{1} : std::uint8_t{0}; + std::uint8_t acc = bits[0]; + for (std::size_t i = 1; i < n; ++i) + acc = and_bit_share(net, acc, bits[i], pads[i - 1]); + return acc; +} + +template +std::uint8_t open_bit(net::trio & net, std::uint8_t mine) +{ + const role peer = Me == 0 ? role::p1 : role::p0; + const std::uint8_t other = net.exchange_with(peer, mine, net::msg::delta); + return static_cast(mine ^ other); +} + +#endif diff --git a/party/p0.cpp b/party/p0.cpp new file mode 100644 index 0000000..19c07fa --- /dev/null +++ b/party/p0.cpp @@ -0,0 +1,6 @@ +#include "cases.hpp" + +int main(int argc, char ** argv) +{ + return dpf::party::run(dpf::net::role::p0, argc, argv); +} diff --git a/party/p1.cpp b/party/p1.cpp new file mode 100644 index 0000000..a30bc70 --- /dev/null +++ b/party/p1.cpp @@ -0,0 +1,6 @@ +#include "cases.hpp" + +int main(int argc, char ** argv) +{ + return dpf::party::run(dpf::net::role::p1, argc, argv); +} diff --git a/party/p2.cpp b/party/p2.cpp new file mode 100644 index 0000000..b4de968 --- /dev/null +++ b/party/p2.cpp @@ -0,0 +1,6 @@ +#include "cases.hpp" + +int main(int argc, char ** argv) +{ + return dpf::party::run(dpf::net::role::p2, argc, argv); +} diff --git a/party/party_bench.cpp b/party/party_bench.cpp new file mode 100644 index 0000000..31c18d2 --- /dev/null +++ b/party/party_bench.cpp @@ -0,0 +1,173 @@ +/// @file party/party_bench.cpp +/// @brief Time specific (2+1) flows. Examples: +/// party_bench --list +/// party_bench --tag beaver,bench --repeat 20 --warmup 2 +/// party_bench --case beaver_dot_n32 --repeat 50 --warmup 5 +/// party_bench --tag iknp --repeat 1 --warmup 0 + +#include "cases.hpp" +#include "registry.hpp" +#include "spawn.hpp" + +#include +#include +#include +#include +#include + +int main(int argc, char ** argv) +{ + dpf::party::register_all_flows(); + + std::string tag; + std::string case_name; + std::uint64_t repeat = 10; + std::uint64_t warmup = 2; + bool list_only = false; + bool metrics = true; + + for (int i = 1; i < argc; ++i) + { + std::string a = argv[i]; + auto need = [&](const char * f) { + if (i + 1 >= argc) + { + std::cerr << "missing value for " << f << "\n"; + std::exit(2); + } + return std::string(argv[++i]); + }; + if (a == "--list") + list_only = true; + else if (a == "--tag") + tag = need("--tag"); + else if (a == "--case") + case_name = need("--case"); + else if (a == "--repeat") + repeat = std::stoull(need("--repeat")); + else if (a == "--warmup") + warmup = std::stoull(need("--warmup")); + else if (a == "--no-metrics") + metrics = false; + else if (a == "--help" || a == "-h") + { + std::cout + << "party_bench --list | --case NAME | --tag TAGS\n" + << " [--repeat N=10] [--warmup W=2] [--no-metrics]\n" + << "With metrics, each role also reports bytes_sent/recv and\n" + << "frames_sent/recv for the flow itself (not the repeat barrier).\n" + << "Tags are AND-matched (comma/space). Common tags:\n" + << " beaver product dot scale stream horner poly mux\n" + << " dpf wildcard geneval ds verifiable dcf grotto extreme bench smoke\n" + << " arith garble yao flute shuffle (word, stack, table, hidden column)\n" + << " iknp (two-party; spawned as p0/p1 only)\n"; + return 0; + } + } + + if (list_only) + { + dpf::party::list_flows(std::cout, tag.empty() ? case_name : tag); + return 0; + } + + std::vector flows; + if (!case_name.empty()) + { + auto * f = dpf::party::find_flow(case_name); + if (!f) + { + std::cerr << "unknown flow: " << case_name << "\n"; + return 2; + } + flows.push_back(f); + } + else + { + if (tag.empty()) + tag = "bench"; + flows = dpf::party::select_flows(tag); + if (flows.empty()) + { + std::cerr << "no flows match tag: " << tag << "\n"; + return 2; + } + } + + dpf::party::spawn_opts opts; + opts.repeat = repeat; + opts.warmup = warmup; + opts.metrics = metrics; + + auto pair_flow = [](const dpf::party::flow * f) { + return dpf::party::flow_is_pair(*f); + }; + + auto flow_of = [](const std::string & line) { + const auto p = line.find("flow="); + if (p == std::string::npos) + return std::string{}; + const auto e = line.find(' ', p + 5); + return line.substr(p + 5, e == std::string::npos ? std::string::npos : e - (p + 5)); + }; + auto avg_ns_of = [](const std::string & line) { + const auto p = line.find("avg_ns="); + if (p == std::string::npos) + return 0.0; + return std::stod(line.substr(p + 7)); + }; + + std::cout << "flow\twall_ms\tp0\tp1\tp2\trepeat\twarmup\n"; + int fails = 0; + bool mixed = false; + const bool first_pair = pair_flow(flows.front()); + for (const auto * f : flows) + mixed = mixed || (pair_flow(f) != first_pair); + + // One mesh for a homogeneous tag. wall_ms on each row is that flow's + // slowest role. The process startup is paid once, as suite_wall_ms. + if (case_name.empty() && !mixed && flows.size() > 1) + { + opts.by_tag = true; + auto r = first_pair ? dpf::party::spawn_pair_flow(tag, opts) + : dpf::party::spawn_trio_flow(tag, opts); + for (const auto * f : flows) + { + double slow = 0; + std::vector lines; + for (const auto & line : r.metrics_lines) + { + if (flow_of(line) != f->name) + continue; + lines.push_back(line); + slow = std::max(slow, avg_ns_of(line) / 1.0e6); + } + if (lines.empty()) + slow = r.wall_ms; + std::cout << f->name << '\t' << slow << '\t' + << r.rc[0] << '\t' << r.rc[1] << '\t' << r.rc[2] << '\t' + << repeat << '\t' << warmup << '\n'; + for (const auto & line : lines) + std::cout << " " << line << '\n'; + } + std::cout << "suite_wall_ms\t" << r.wall_ms << '\n'; + if (r.rc[0] || r.rc[1] || r.rc[2]) + ++fails; + } + else + { + for (const auto * f : flows) + { + auto r = pair_flow(f) ? dpf::party::spawn_pair_flow(f->name, opts) + : dpf::party::spawn_trio_flow(f->name, opts); + std::cout << f->name << '\t' << r.wall_ms << '\t' + << r.rc[0] << '\t' << r.rc[1] << '\t' << r.rc[2] << '\t' + << repeat << '\t' << warmup << '\n'; + for (const auto & line : r.metrics_lines) + std::cout << " " << line << '\n'; + if (r.rc[0] || r.rc[1] || r.rc[2]) + ++fails; + } + } + return fails ? 1 : 0; +} diff --git a/party/registry.cpp b/party/registry.cpp new file mode 100644 index 0000000..1021302 --- /dev/null +++ b/party/registry.cpp @@ -0,0 +1,136 @@ +/// @file party/registry.cpp +#include "registry.hpp" + +#include +#include +#include +#include + +namespace dpf +{ +namespace party +{ +namespace +{ + +std::vector & table() +{ + static std::vector t; + return t; +} + +std::vector split_csv(std::string_view s) +{ + std::vector out; + std::string cur; + for (char c : s) + { + if (c == ',' || c == ' ') + { + if (!cur.empty()) + { + out.push_back(cur); + cur.clear(); + } + } + else + cur.push_back(c); + } + if (!cur.empty()) + out.push_back(cur); + return out; +} + +} // namespace + +void register_flow(flow f) +{ + if (f.name == nullptr || f.run == nullptr) + throw std::invalid_argument("register_flow: null name or run"); + for (const auto & e : table()) + { + if (e.name == f.name || std::string_view(e.name) == f.name) + throw std::invalid_argument(std::string("duplicate flow: ") + f.name); + } + table().push_back(f); +} + +bool flow_has_tag(const flow & f, std::string_view tag) +{ + if (tag.empty()) + return true; + if (f.tags == nullptr) + return false; + std::string_view tags(f.tags); + std::size_t i = 0; + while (i < tags.size()) + { + while (i < tags.size() && tags[i] == ' ') + ++i; + std::size_t j = i; + while (j < tags.size() && tags[j] != ' ') + ++j; + if (j > i && tags.substr(i, j - i) == tag) + return true; + i = j; + } + return false; +} + +bool flow_is_pair(const flow & f) +{ + const std::string_view name = f.name ? f.name : ""; + if (name.size() >= 5 && name.substr(0, 5) == "iknp_") + return true; + return flow_has_tag(f, "iknp"); +} + +const flow * find_flow(std::string_view name) +{ + for (const auto & f : table()) + { + if (f.name == name) + return &f; + } + return nullptr; +} + +std::vector select_flows(std::string_view filter) +{ + std::vector out; + auto want = split_csv(filter); + for (const auto & f : table()) + { + bool ok = true; + for (const auto & t : want) + { + if (!flow_has_tag(f, t)) + { + ok = false; + break; + } + } + if (ok) + out.push_back(&f); + } + return out; +} + +void list_flows(std::ostream & os, std::string_view filter) +{ + auto sel = select_flows(filter); + for (const flow * f : sel) + { + os << f->name << '\t' << (f->tags ? f->tags : "") + << (f->bench ? "\tbench" : "\tsmoke") << '\n'; + } + os << "# " << sel.size() << " flows\n"; +} + +std::size_t flow_count() +{ + return table().size(); +} + +} // namespace party +} // namespace dpf diff --git a/party/registry.hpp b/party/registry.hpp new file mode 100644 index 0000000..8a817c4 --- /dev/null +++ b/party/registry.hpp @@ -0,0 +1,51 @@ +/// @file party/registry.hpp +/// @brief Named (2+1) party flows with tags for filtering and benchmarking. +#ifndef LIBDPF_PARTY_REGISTRY_HPP__ +#define LIBDPF_PARTY_REGISTRY_HPP__ + +#include +#include +#include +#include +#include + +#include "dpf/net/trio.hpp" + +namespace dpf +{ +namespace party +{ + +using flow_fn = int (*)(net::role self, net::trio & net); + +/// @brief One runnable flow. `tags` is a space-separated tag list. +struct flow +{ + const char * name = nullptr; + const char * tags = nullptr; + flow_fn run = nullptr; + /// @brief When false, skip under `--tag bench` (reject / handshake-only). + bool bench = true; +}; + +void register_flow(flow f); +void register_all_flows(); + +const flow * find_flow(std::string_view name); +bool flow_has_tag(const flow & f, std::string_view tag); + +/// @brief Two-party flow: spawn p0 and p1 only. IKNP has no dealer. +bool flow_is_pair(const flow & f); + +/// @brief All flows, or those matching every comma-separated tag in `filter`. +/// Empty filter returns every registered flow. +std::vector select_flows(std::string_view filter); + +void list_flows(std::ostream & os, std::string_view filter = {}); + +std::size_t flow_count(); + +} // namespace party +} // namespace dpf + +#endif // LIBDPF_PARTY_REGISTRY_HPP__ diff --git a/party/run.cpp b/party/run.cpp new file mode 100644 index 0000000..0d8b460 --- /dev/null +++ b/party/run.cpp @@ -0,0 +1,1518 @@ +/// @file party/run.cpp +/// @brief Shared (2+1) party case implementations. + +#include "cases.hpp" +#include "dist_ds.hpp" +#include "iknp_deal.hpp" +#include "flow_util.hpp" +#include "key_io.hpp" +#include "registry.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "asio.hpp" +#include "dpf.hpp" +#include "dpf/beaver.hpp" +#include "dpf/net/party_tape_io.hpp" +#include "dpf/net/trio.hpp" +#include "grotto/carry.hpp" + +bool do_quickack = false; + +namespace dpf +{ +namespace party +{ +namespace +{ + +using net::role; +using net::trio; +using u64 = std::uint64_t; +using util::evaluate_online; +using util::evaluate_online_auth; + +struct Counter +{ + int draws = 0; + u64 operator()() + { + ++draws; + return 0x9e3779b97f4a7c15ull * static_cast(draws); + } +}; + +std::pair split_u64(u64 secret, unsigned tag = 1) +{ + u64 p0 = 0x9e3779b97f4a7c15ull * (tag + 1u); + return {p0, secret - p0}; +} + +template +std::pair split_ring(Ring secret, unsigned tag = 1) +{ + using traits = beavers::ring_traits; + Ring p0 = Ring{static_cast(0x9e3779b97f4a7c15ull * (tag + 1u))}; + return {p0, traits::sub(secret, p0)}; +} + +void require(bool cond, const char * msg) +{ + if (!cond) + throw std::runtime_error(msg); +} + +template +Ring open_additive(trio & net, role self, Ring mine) +{ + role peer = self == role::p0 ? role::p1 : role::p0; + return net.open_with(peer, mine); +} + +template +T open_subtractive(trio & net, role self, T mine) +{ + role peer = self == role::p0 ? role::p1 : role::p0; + T theirs = net.exchange_with(peer, mine); + return self == role::p0 ? static_cast(mine - theirs) + : static_cast(theirs - mine); +} + +template +constexpr T share_bits(T s) noexcept +{ + return s; +} + +template +constexpr T share_bits(const secret_share & s) noexcept +{ + return s.raw(); +} + +template +void install_and_bind(beavers::session & s, trio & net, role self, + const std::vector::wire> & inputs, + const std::vector & secrets) +{ + auto tape = net::accept_session(net); + s.install_party(self == role::p0 ? 0u : 1u, tape); + for (std::size_t i = 0; i < inputs.size(); ++i) + { + auto [p0, p1] = split_ring(secrets[i], static_cast(i + 1)); + s.bind_party(inputs[i], self == role::p0 ? p0 : p1); + } +} + +void install_and_bind_u64(beavers::session & s, trio & net, role self, + const std::vector::wire> & inputs, + const std::vector & secrets) +{ + auto tape = net::accept_session(net); + s.install_party(self == role::p0 ? 0u : 1u, tape); + for (std::size_t i = 0; i < inputs.size(); ++i) + { + auto [p0, p1] = split_u64(secrets[i], static_cast(i + 1)); + s.bind_party(inputs[i], self == role::p0 ? p0 : p1); + } +} + +// --------------------------------------------------------------------------- +// Beaver +// --------------------------------------------------------------------------- + +int beaver_product_two(role self, trio & net) +{ + beavers::session s; + auto x = s.input(); + auto y = s.input(); + auto z = s(x * y); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + require(rng.draws == 5, "draws"); + require(s.preprocessing_count() == 3u, "prep"); + require(s.monomial({{x, 1u}, {y, 1u}}).open() + == s.lambda(x).open() * s.lambda(y).open(), + "mono"); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {x, y}, {7u, 9u}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == 63u, "product"); + return 0; +} + +int beaver_product_three_square(role self, trio & net) +{ + beavers::session s; + auto a = s.input(); + auto b = s.input(); + auto c = s.input(); + auto p = s.product(a, b, c); + auto sq = s(b * b); + if (self == role::p2) + { + require(s.monomial_count() == 5u, "monos"); + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {a, b, c}, {2u, 3u, 5u}); + evaluate_online(s, net, self); + auto op = open_additive(net, self, s.value_party(p)); + auto os = open_additive(net, self, s.value_party(sq)); + if (self == role::p0) + { + require(op == 30u, "p"); + require(os == 9u, "sq"); + } + return 0; +} + +int beaver_mul_square(role self, trio & net) +{ + beavers::session s; + auto a = s.input(); + auto x = s.input(); + auto z = s(a * x * x); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + require(s.round_of(z) == 1, "round"); + require(s.preprocessing_count() == 5u, "prep"); + require(rng.draws == 7, "draws"); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {a, x}, {4u, 5u}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == 100u, "mul_square"); + return 0; +} + +int beaver_chained_square(role self, trio & net) +{ + beavers::session s; + auto a = s.input(); + auto x = s.input(); + auto x2 = s(x * x); + auto z = s(a * x2); + if (self == role::p2) + { + require(s.round_of(x2) == 1 && s.round_of(z) == 2, "rounds"); + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {a, x}, {4u, 5u}); + evaluate_online(s, net, self); + auto o2 = open_additive(net, self, s.value_party(x2)); + auto oz = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + { + require(o2 == 25u, "x2"); + require(oz == 100u, "z"); + } + return 0; +} + +int beaver_dot(role self, trio & net) +{ + beavers::session s; + auto x0 = s.input(); + auto x1 = s.input(); + auto x2 = s.input(); + auto y0 = s.input(); + auto y1 = s.input(); + auto y2 = s.input(); + auto z = s.dot({x0, x1, x2}, {y0, y1, y2}); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + require(s.preprocessing_count() == 7u, "prep"); + require(rng.draws == 13, "draws"); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {x0, x1, x2, y0, y1, y2}, + {1u, 2u, 3u, 4u, 5u, 6u}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == 32u, "dot"); + return 0; +} + +int beaver_dot_reuse(role self, trio & net) +{ + beavers::session s; + auto a = s.input(); + auto b = s.input(); + auto z = s.dot({a, a}, {b, b}); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {a, b}, {3u, 4u}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == 24u, "dot_reuse"); + return 0; +} + +int beaver_inner_product(role self, trio & net) +{ + using wire = beavers::session::wire; + beavers::session s; + std::vector fx, fy; + for (int i = 0; i < 3; ++i) + { + fx.push_back(s.input()); + fy.push_back(s.input()); + } + auto z = s.dot(fx, fy); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + std::vector wires = fx; + wires.insert(wires.end(), fy.begin(), fy.end()); + install_and_bind_u64(s, net, self, wires, {0u, 2u, 5u, 4u, 0u, 7u}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == 35u, "inner"); + return 0; +} + +int beaver_scale(role self, trio & net) +{ + beavers::session s; + auto sc = s.input(); + auto l0 = s.input(); + auto l1 = s.input(); + auto l2 = s.input(); + auto out = s.scale(sc, {l0, l1, l2}); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {sc, l0, l1, l2}, {3u, 1u, 2u, 4u}); + evaluate_online(s, net, self); + const u64 expect[] = {3u, 6u, 12u}; + for (std::size_t i = 0; i < out.size(); ++i) + { + auto o = open_additive(net, self, s.value_party(out[i])); + if (self == role::p0) + require(o == expect[i], "scale"); + } + return 0; +} + +int beaver_bit_mul_mux(role self, trio & net) +{ + beavers::session s; + auto b = s.bit(); + auto x = s.input(); + auto y = s.input(); + auto bm = s.bit_mul(b, x); + auto mx = s.mux(b, x, y); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {b, x, y}, {1u, 10u, 3u}); + evaluate_online(s, net, self); + auto ob = open_additive(net, self, s.value_party(bm)); + auto om = open_additive(net, self, s.value_party(mx)); + if (self == role::p0) + { + require(ob == 10u, "bit_mul"); + require(om == 10u, "mux"); + } + return 0; +} + +int beaver_xor_mux(role self, trio & net) +{ + using ring = xor_wrapper; + beavers::session s; + auto b = s.bit(); + auto x = s.input(); + auto y = s.input(); + auto mx = s.mux(b, x, y); + if (self == role::p2) + { + struct XorCounter + { + Counter c; + ring operator()() { return ring{c()}; } + } rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind(s, net, self, {b, x, y}, + {ring{0}, ring{0xaaaau}, ring{0x1111u}}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(mx)); + if (self == role::p0) + require(o == ring{0x1111u}, "xor_mux"); + return 0; +} + +int beaver_modint_product(role self, trio & net) +{ + using ring = modint<61>; + beavers::session s; + auto x = s.input(); + auto y = s.input(); + auto z = s(x * y); + if (self == role::p2) + { + s.sample(); + net::deal_session(net, s); + return 0; + } + install_and_bind(s, net, self, {x, y}, {ring{7}, ring{9}}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == ring{63}, "modint"); + return 0; +} + +int beaver_oracle_stream(role self, trio & net) +{ + using block = prg::aes128::block_type; + block seed = simde_mm_set_epi64x(0x9, 0x9); + constexpr std::size_t n = 32; + if (self == role::p2) + { + beavers::oracle src(seed, 4); + beavers::beaver2 bulk[n]; + beavers::fill_beaver2(src, 0, bulk, n); + auto at31 = beavers::beaver2_at(src, 31); + require(bulk[31].a == at31.a && bulk[31].ab == at31.ab, "stream"); + require(bulk[0].ab.open() == bulk[0].a.open() * bulk[0].b.open(), "o0"); + std::vector p0, p1; + for (std::size_t i = 0; i < n; ++i) + { + p0.insert(p0.end(), + {bulk[i].a.p0, bulk[i].b.p0, bulk[i].ab.p0, bulk[i].out.p0}); + p1.insert(p1.end(), + {bulk[i].a.p1, bulk[i].b.p1, bulk[i].ab.p1, bulk[i].out.p1}); + } + net.to(role::p0).send_vec(p0); + net.to(role::p1).send_vec(p1); + return 0; + } + auto shares = net.to(role::p2).recv_vec(); + require(shares.size() == n * 4, "size"); + const std::size_t i = 7; + u64 a = shares[i * 4 + 0]; + u64 b = shares[i * 4 + 1]; + u64 ab = shares[i * 4 + 2]; + auto [x0, x1] = split_u64(6u, 1); + auto [y0, y1] = split_u64(7u, 2); + u64 xs = self == role::p0 ? x0 : x1; + u64 ys = self == role::p0 ? y0 : y1; + role peer = self == role::p0 ? role::p1 : role::p0; + u64 dx_mine = xs + a; + u64 dy_mine = ys + b; + u64 dx = dx_mine + net.exchange_with(peer, dx_mine); + u64 dy = dy_mine + net.exchange_with(peer, dy_mine); + u64 z = ab; + z -= dx * b; + z -= dy * a; + if (self == role::p0) + z += dx * dy; + auto open = open_additive(net, self, z); + if (self == role::p0) + require(open == 42u, "oracle online"); + return 0; +} + +int beaver_scheduled_replay(role self, trio & net) +{ + using block = prg::aes128::block_type; + block seed = simde_mm_set_epi64x(0x55, 0xaa); + beavers::session left; + auto x = left.input(); + auto y = left.input(); + auto z = left(3 * x * x + 2 * y + 5); + if (self == role::p2) + { + beavers::oracle src(seed, 4); + left.sample_from(src, 3); + beavers::session right; + auto rx = right.input(); + auto ry = right.input(); + (void)right(3 * rx * rx + 2 * ry + 5); + right.sample_from(src, 3); + require(left.lambda(x) == right.lambda(rx), "replay"); + net::deal_session(net, left); + return 0; + } + install_and_bind_u64(left, net, self, {x, y}, {4u, 6u}); + evaluate_online(left, net, self); + auto o = open_additive(net, self, left.value_party(z)); + if (self == role::p0) + require(o == 3u * 16u + 2u * 6u + 5u, "scheduled"); + return 0; +} + +int beaver_grotto_appendix_e(role self, trio & net) +{ + beavers::session linear; + auto x = linear.input(); + auto sgn = linear.input(); + auto a0 = linear.input(); + auto a1 = linear.input(); + auto lin = linear(sgn * (a1 * x + a0)); + if (self == role::p2) + { + require(linear.round_of(lin) == 2, "round"); + require(linear.preprocessing_count() == 6u, "prep"); + Counter rng; + linear.sample(rng); + net::deal_session(net, linear); + return 0; + } + install_and_bind_u64(linear, net, self, {x, sgn, a0, a1}, {2u, 3u, 4u, 5u}); + evaluate_online(linear, net, self); + auto o = open_additive(net, self, linear.value_party(lin)); + if (self == role::p0) + require(o == 3u * (5u * 2u + 4u), "grotto_e"); + return 0; +} + +int beaver_polynomial_share_powers(role self, trio & net) +{ + beavers::session s; + auto x = s.input(); + auto y = s.input(); + auto z = s(x * x * y + x * y); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {x, y}, {3u, 4u}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == 3u * 3u * 4u + 3u * 4u, "poly"); + return 0; +} + +int beaver_rejects_bad_use(role self, trio & net) +{ + if (self == role::p2) + { + bool threw = false; + try + { + beavers::session s; + auto x = s.input(); + auto y = s.input(); + (void)s.dot({x}, {y, y}); + } + catch (const std::invalid_argument &) + { + threw = true; + } + require(threw, "reject"); + net.to(role::p0).send(net::msg::case_ok, std::uint8_t{1}); + net.to(role::p1).send(net::msg::case_ok, std::uint8_t{1}); + return 0; + } + (void)net.to(role::p2).recv(net::msg::case_ok); + return 0; +} + +int beaver_one_shot_triples(role self, trio & net) +{ + if (self == role::p2) + { + Counter rng; + auto t2 = beavers::sample_beaver2(rng); + require(t2.ab.open() == t2.a.open() * t2.b.open(), "b2"); + auto t3 = beavers::sample_beaver3(rng); + require(t3.abc.open() == t3.a.open() * t3.b.open() * t3.c.open(), "b3"); + net.to(role::p0).send(net::msg::case_ok, std::uint8_t{1}); + net.to(role::p1).send(net::msg::case_ok, std::uint8_t{1}); + beavers::session s; + auto x = s.input(); + auto y = s.input(); + (void)s(x * y); + s.sample(rng); + net::deal_session(net, s); + return 0; + } + (void)net.to(role::p2).recv(net::msg::case_ok); + beavers::session s; + auto x = s.input(); + auto y = s.input(); + auto z = s(x * y); + install_and_bind_u64(s, net, self, {x, y}, {8u, 9u}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == 72u, "one_shot"); + return 0; +} + +int beaver_batch_one_round(role self, trio & net) +{ + beavers::session s; + auto a = s.input(); + auto b = s.input(); + auto c = s.input(); + auto p = s(a * b); + auto q = s(a * c); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {a, b, c}, {2u, 3u, 5u}); + evaluate_online(s, net, self); + auto op = open_additive(net, self, s.value_party(p)); + auto oq = open_additive(net, self, s.value_party(q)); + if (self == role::p0) + { + require(op == 6u && oq == 10u, "batch"); + } + return 0; +} + +int beaver_blind_survives(role self, trio & net) +{ + beavers::session s; + auto a = s.input(); + auto b = s.input(); + auto p = s(a * b); + auto q = s(p * a); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + auto lam = s.lambda(a); + net::deal_session(net, s); + require(s.lambda(a) == lam, "survived"); + return 0; + } + install_and_bind_u64(s, net, self, {a, b}, {3u, 4u}); + evaluate_online(s, net, self); + auto op = open_additive(net, self, s.value_party(p)); + auto oq = open_additive(net, self, s.value_party(q)); + if (self == role::p0) + require(op == 12u && oq == 36u, "blind"); + return 0; +} + +int beaver_sums_cancellations(role self, trio & net) +{ + beavers::session s; + auto x = s.input(); + auto y = s.input(); + auto z = s(x + y - x); + if (self == role::p2) + { + require(s.monomial_count() == 0u, "no products"); + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {x, y}, {11u, 22u}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == 22u, "sum"); + return 0; +} + +// --------------------------------------------------------------------------- +// Wildcard: parties assign over the p0–p1 link, then evaluate. +// --------------------------------------------------------------------------- + +template +void assign_wildcard_over_link(Key & key, Share my_share, trio & net, role self) +{ + role peer = self == role::p0 ? role::p1 : role::p0; + auto & wrap = std::get<0>(key.leaf_nodes); + if (wrap.is_ready()) + wrap.begin_update(); + auto blinded = wrap.compute_and_get_blinded_output_share(my_share); + auto peer_blinded = net.exchange_with(peer, blinded); + auto leaf = wrap.compute_and_get_leaf_share(peer_blinded); + auto peer_leaf = net.exchange_with(peer, leaf); + wrap.reconstruct_correction_word(peer_leaf); +} + +int wildcard_single_leaf(role self, trio & net) +{ + using input_type = std::uint8_t; + using concrete_type = std::uint32_t; + using output_type = wildcard_value; + input_type x = 0xAA; + input_type x0 = 0x31; + input_type x1 = static_cast(x ^ x0); + concrete_type y_exp = 0xAAAAAAAA; + concrete_type y_shr0 = 0x12345678; + concrete_type y_shr1 = y_exp - y_shr0; + + auto on = [&](auto key) { + const concrete_type my_share = + self == role::p0 ? y_shr0 : y_shr1; + assign_wildcard_over_link(key, my_share, net, self); + + auto y = *eval_point(key, x); + auto open = open_subtractive(net, self, share_bits(y)); + if (self == role::p0) + require(open == y_exp, "wildcard on"); + auto yz = *eval_point(key, static_cast(x ^ 1)); + auto oz = open_subtractive(net, self, share_bits(yz)); + if (self == role::p0) + require(oz == 0u, "wildcard off"); + }; + const auto encoded = encoded_xor_point(x0, x1); + require_tree_prefix( + dist_with_point_key( + net, self, x0, x1, output_type{}, on, on), + self, + verifiable_tree_prefix(x0, x1), + verifiable_lane(encoded)); + dist_with_point_key(net, self, x0, x1, output_type{}, on, on); + return 0; +} + +int wildcard_fail_before_assign(role self, trio & net) +{ + using input_type = std::uint8_t; + using output_type = wildcard_value; + const input_type alpha = 0xAA; + const input_type x0 = 0x31; + const input_type x1 = static_cast(alpha ^ x0); + auto on = [&](const auto & key) { + bool threw = false; + try + { + (void)eval_point(key, alpha); + } + catch (const std::runtime_error &) + { + threw = true; + } + require(threw, "fail before"); + }; + const auto encoded = encoded_xor_point(x0, x1); + require_tree_prefix( + dist_with_point_key( + net, self, x0, x1, output_type{}, on, on), + self, + verifiable_tree_prefix(x0, x1), + verifiable_lane(encoded)); + return 0; +} + +// --------------------------------------------------------------------------- +// Geneval / DS — p0 and p1 run Doerner–Shelat. p2 deals pads only. +// --------------------------------------------------------------------------- + +int geneval_point(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const std::uint64_t beta = 7; + require_tree_prefix(dist_with_point_key(net, self, x0, x1, beta, [&](const auto & key) { + const auto y = *eval_point(key, alpha); + const auto open = open_subtractive(net, self, share_bits(y)); + if (self == role::p0) + require(open == beta, "geneval"); + }, [&](const auto & key) { + const auto y = *eval_point(key, alpha); + (void)open_subtractive(net, self, share_bits(y)); + }), self, verifiable_tree_prefix(x0, x1)); + return 0; +} + +int geneval_arith_point(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha - x0); + const std::uint64_t beta = 11; + require_tree_prefix(dist_with_point_key( + net, self, x0, x1, beta, [&](const auto & key) { + const auto y = *eval_point(key, alpha); + const auto open = open_subtractive(net, self, share_bits(y)); + if (self == role::p0) + require(open == beta, "arith"); + }, [&](const auto & key) { + const auto y = *eval_point(key, alpha); + (void)open_subtractive(net, self, share_bits(y)); + }, false, true), self, + verifiable_tree_prefix( + alpha, Input{}, true)); + return 0; +} + +int ds_key_agrees(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x44; + const Input x0 = 0x12; + const Input x1 = static_cast(alpha ^ x0); + const std::uint64_t beta = 5; + require_tree_prefix(dist_with_point_key(net, self, x0, x1, beta, [&](const auto & key) { + const auto y = *eval_point(key, alpha); + const auto open = open_subtractive(net, self, share_bits(y)); + if (self == role::p0) + require(open == beta, "ds"); + }, [&](const auto & key) { + const auto y = *eval_point(key, alpha); + (void)open_subtractive(net, self, share_bits(y)); + }), self, verifiable_tree_prefix(x0, x1)); + return 0; +} + +// --------------------------------------------------------------------------- +// Verifiable +// --------------------------------------------------------------------------- + +int verifiable_honest_point(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const std::uint64_t beta = 7; + auto on = [&](const auto & key) { + proof_token pi{}; + auto y = *eval_point(key, alpha, prove(pi)); + role peer = self == role::p0 ? role::p1 : role::p0; + auto send_pi = [&](const proof_token & t) { + net.to(peer).send_bytes(net::msg::proof_token, + reinterpret_cast(&t), sizeof(t)); + }; + auto recv_pi = [&]() { + proof_token t{}; + auto b = net.to(peer).recv_bytes(net::msg::proof_token); + require(b.size() == sizeof(t), "pi size"); + std::memcpy(&t, b.data(), sizeof(t)); + return t; + }; + proof_token peer_pi{}; + if (self == role::p0) + { + send_pi(pi); + peer_pi = recv_pi(); + } + else + { + peer_pi = recv_pi(); + send_pi(pi); + } + bool ok = verify(pi, peer_pi); + auto open = open_subtractive(net, self, share_bits(y)); + if (self == role::p0) + { + require(ok, "verify"); + require(open == beta, "vpoint"); + } + }; + require_tree_prefix(dist_with_point_key( + net, self, x0, x1, beta, on, on), self, + verifiable_tree_prefix(x0, x1)); + return 0; +} + +int verifiable_tampered_rejects(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const std::uint64_t beta = 7; + auto on = [&](const auto & key) { + proof_token pi{}; + (void)*eval_point(key, alpha, prove(pi)); + if (self == role::p0) + pi[0] = simde_mm_xor_si128(pi[0], simde_mm_set1_epi8(0xff)); + role peer = self == role::p0 ? role::p1 : role::p0; + auto send_pi = [&](const proof_token & t) { + net.to(peer).send_bytes(net::msg::proof_token, + reinterpret_cast(&t), sizeof(t)); + }; + auto recv_pi = [&]() { + proof_token t{}; + auto b = net.to(peer).recv_bytes(net::msg::proof_token); + std::memcpy(&t, b.data(), sizeof(t)); + return t; + }; + proof_token peer_pi{}; + if (self == role::p0) + { + send_pi(pi); + peer_pi = recv_pi(); + } + else + { + peer_pi = recv_pi(); + send_pi(pi); + } + bool ok = verify(pi, peer_pi); + if (self == role::p0) + require(!ok, "tampered token"); + }; + require_tree_prefix(dist_with_point_key( + net, self, x0, x1, beta, on, on), self, + verifiable_tree_prefix(x0, x1)); + return 0; +} + +// --------------------------------------------------------------------------- +// Grotto / DCF +// --------------------------------------------------------------------------- + +int blocked_dcf_point(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x40; + const Input x0 = 0x14; + const Input x1 = static_cast(alpha ^ x0); + const std::uint64_t beta = 9; + auto on = [&](const auto & key) { + auto y = eval_point(cmp, key, static_cast(alpha - 1)); + auto open = + open_additive(net, self, share_bits(y)) & key.cmp().mask; + if (self == role::p0) + require(open == beta, "dcf lt"); + auto y2 = eval_point(cmp, key, alpha); + auto o2 = + open_additive(net, self, share_bits(y2)) & key.cmp().mask; + if (self == role::p0) + require(o2 == 0u, "dcf on"); + }; + require_opened(dist_with_cmp_key(net, self, x0, x1, lt(beta), on, on), + self, encoded_xor_point(x0, x1)); + return 0; +} + +int grotto_prefix_horner(role self, trio & net) +{ + beavers::session s; + auto x = s.input(); + auto z = s.horner(x, {u64{1}, u64{2}, u64{3}}); + if (self == role::p2) + { + Counter rng; + s.sample(rng); + net::deal_session(net, s); + return 0; + } + install_and_bind_u64(s, net, self, {x}, {5u}); + evaluate_online(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + if (self == role::p0) + require(o == 1u + 2u * 5u + 3u * 25u, "horner"); + return 0; +} + +/// @brief Opt-in MAC path: dealer sets Δ, parties open with auth openings. +int beaver_auth_horner(role self, trio & net) +{ + beavers::session s; + auto x = s.input(); + auto z = s.horner(x, {u64{1}, u64{2}, u64{3}}); + const u64 secret = 5u; + if (self == role::p2) + { + auto key = sample_mac_key(); + s.set_mac_key(key); + Counter rng; + s.sample(rng); + s.bind(x, secret, rng); + auto xv = s.value_auth(x); + net::deal_session(net, s); + net.to(role::p0).send(net::msg::mac_key, key.delta); + net.to(role::p1).send(net::msg::mac_key, key.delta); + net.to(role::p0).send(net::msg::mac_share, xv.party(0)); + net.to(role::p1).send(net::msg::mac_share, xv.party(1)); + return 0; + } + auto tape = net::accept_session(net); + s.install_party(self == role::p0 ? 0u : 1u, tape); + auto delta = net.to(role::p2).recv(net::msg::mac_key); + s.set_mac_key(mac_key{delta}); + auto xin = net.to(role::p2).recv>(net::msg::mac_share); + s.bind_party(x, xin); + evaluate_online_auth(s, net, self); + auto o = open_additive(net, self, s.value_party(z)); + require(s.verify_delta(x, mac_key{delta}), "auth delta x"); + if (self == role::p0) + require(o == 1u + 2u * 5u + 3u * 25u, "auth horner"); + return 0; +} + +/// @brief Carry with verifiable DCF tokens and an output MAC. +int carry_verifiable_mac(role self, trio & net) +{ + using Key0 = grotto::carry_detail::lt_v_pair::first_type; + using Key1 = grotto::carry_detail::lt_v_pair::second_type; + constexpr unsigned n = 8; + constexpr unsigned s = 3; + const std::uint64_t opened = 0x3cu; + if (self == role::p2) + { + grotto::carry_auth auth{}; + auth.verifiable = true; + auth.output_mac = true; + auto keys = grotto::make_carry_in_keys(n, s, auth); + require(keys.low_lt_v.has_value(), "carry lt v"); + require(keys.has_mac, "carry mac"); + auto send_one = [&](role r) { + send_key(net.to(r), keys.low_lt_v->first); + send_key(net.to(r), keys.low_lt_v->second); + net.to(r).send(net::msg::mac_key, keys.mac.delta); + net.to(r).send(net::msg::bytes, keys.rin); + net.to(r).send(net::msg::bytes, keys.rout0); + net.to(r).send(net::msg::bytes, keys.rout1); + }; + send_one(role::p0); + send_one(role::p1); + return 0; + } + auto k0 = recv_key(net.to(role::p2)); + auto k1 = recv_key(net.to(role::p2)); + auto delta = net.to(role::p2).recv(net::msg::mac_key); + auto rin = net.to(role::p2).recv(net::msg::bytes); + auto rout0 = net.to(role::p2).recv(net::msg::bytes); + auto rout1 = net.to(role::p2).recv(net::msg::bytes); + + grotto::carry_detail::carry_key_pair keys{}; + keys.recipe = grotto::plan_carry_in(n, s); + keys.auth.verifiable = true; + keys.auth.output_mac = true; + keys.rin = rin; + keys.rout0 = rout0; + keys.rout1 = rout1; + keys.low_lt_v.emplace(std::move(k0), std::move(k1)); + keys.mac = mac_key{delta}; + keys.has_mac = true; + + const unsigned party = self == role::p0 ? 0u : 1u; + dpf::proof_token toks[4]{}; + const auto nt = grotto::prove_carry_keys(keys, party, opened, toks, 4); + require(nt >= 1u, "carry tokens"); + + role peer = self == role::p0 ? role::p1 : role::p0; + auto send_pi = [&](const dpf::proof_token & t) { + net.to(peer).send_bytes(net::msg::proof_token, + reinterpret_cast(&t), sizeof(t)); + }; + auto recv_pi = [&]() { + dpf::proof_token t{}; + auto b = net.to(peer).recv_bytes(net::msg::proof_token); + require(b.size() == sizeof(t), "pi size"); + std::memcpy(&t, b.data(), sizeof(t)); + return t; + }; + std::vector mine(toks, toks + nt); + std::vector theirs(nt); + if (self == role::p0) + { + for (std::size_t i = 0; i < nt; ++i) + { + send_pi(mine[i]); + theirs[i] = recv_pi(); + } + } + else + { + for (std::size_t i = 0; i < nt; ++i) + { + theirs[i] = recv_pi(); + send_pi(mine[i]); + } + } + require(dpf::verify_batch(mine, theirs), "carry verify_batch"); + + auto y = grotto::eval_carry_in(keys, party, opened); + auto y_peer = open_additive(net, self, y.value); + // Reconstruct shares for MAC: party 0 holds y.value, peer opened sum is + // y0+y1; split as (y.value, sum - y.value) on p0 for the check. + std::uint64_t y0 = 0; + std::uint64_t y1 = 0; + if (self == role::p0) + { + y0 = y.value; + y1 = y_peer - y.value; + auto [m0, m1] = grotto::mac_carry_result(keys, y0, y1); + require(dpf::mac_verify(m0, m1, keys.mac, mine[0], theirs[0]), + "carry mac"); + require(!dpf::mac_verify(m0, m1, keys.mac, detail::vdpf::zero_proof(), + theirs[0]), "carry mac zero token"); + (void)m0; + (void)m1; + } + return 0; +} + +/// @brief Extractable sketch: fold opened payloads, exchange, verify. +int extractable_sketch_point(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const dpf::fp61 beta{7}; + auto on = [&](const auto & key) { + const std::array rs{dpf::fp61{3}}; + sketch_share local{}; + auto sk = sketch(local, rs); + (void)*eval_point(key, alpha, sk); + role peer = self == role::p0 ? role::p1 : role::p0; + sketch_share theirs = + net.exchange_with(peer, local, net::msg::sketch_share); + bool ok = self == role::p0 ? sketch_verify(local, theirs) + : sketch_verify(theirs, local); + if (self == role::p0) + require(ok, "extractable sketch"); + }; + dist_with_extractable_point_key( + net, self, x0, x1, beta, on, on); + return 0; +} + +/// @brief Two-party geneval point. Same check as `geneval_point`, pads from IKNP. +int iknp_geneval_point(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 7; + require_tree_prefix(dist_with_point_key_iknp( + net, self, x0, x1, beta, [&](const auto & key) { + const auto open = open_subtractive(net, self, share_bits(*eval_point(key, alpha))); + if (self == role::p0) + require(open == beta, "iknp geneval"); + }, [&](const auto & key) { + (void)open_subtractive(net, self, share_bits(*eval_point(key, alpha))); + }), self, verifiable_tree_prefix(x0, x1)); + return 0; +} + +/// @brief Two-party additive-share input. Same check as `geneval_arith_point`. +int iknp_arith_point(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha - x0); + const u64 beta = 11; + require_tree_prefix(dist_with_point_key_iknp( + net, self, x0, x1, beta, [&](const auto & key) { + const auto open = open_subtractive(net, self, share_bits(*eval_point(key, alpha))); + if (self == role::p0) + require(open == beta, "iknp arith"); + }, [&](const auto & key) { + (void)open_subtractive(net, self, share_bits(*eval_point(key, alpha))); + }, false, true), self, + verifiable_tree_prefix(alpha, Input{}, true)); + return 0; +} + +/// @brief Two-party wildcard: keygen hides the lane, then β is assigned on the link. +int iknp_wildcard_leaf(role self, trio & net) +{ + using input_type = std::uint8_t; + using concrete_type = std::uint32_t; + using output_type = wildcard_value; + const input_type x = 0xAA; + const input_type x0 = 0x31; + const input_type x1 = static_cast(x ^ x0); + const concrete_type y_exp = 0xAAAAAAAA; + const concrete_type y_shr0 = 0x12345678; + const concrete_type y_shr1 = y_exp - y_shr0; + auto on = [&](auto key) { + const concrete_type my_share = self == role::p0 ? y_shr0 : y_shr1; + assign_wildcard_over_link(key, my_share, net, self); + auto open = open_subtractive(net, self, share_bits(*eval_point(key, x))); + if (self == role::p0) + require(open == y_exp, "iknp wildcard on"); + auto oz = open_subtractive(net, self, + share_bits(*eval_point(key, static_cast(x ^ 1)))); + if (self == role::p0) + require(oz == 0u, "iknp wildcard off"); + }; + dist_with_point_key_iknp(net, self, x0, x1, output_type{}, on, on); + return 0; +} + +/// @brief Two-party extractable sketch. Same check as `extractable_sketch_point`. +int iknp_extractable_sketch(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const dpf::fp61 beta{7}; + auto on = [&](const auto & key) { + const std::array rs{dpf::fp61{3}}; + sketch_share local{}; + auto sk = sketch(local, rs); + (void)*eval_point(key, alpha, sk); + role peer = self == role::p0 ? role::p1 : role::p0; + sketch_share theirs = net.exchange_with(peer, local, net::msg::sketch_share); + bool ok = self == role::p0 ? sketch_verify(local, theirs) + : sketch_verify(theirs, local); + if (self == role::p0) + require(ok, "iknp extractable sketch"); + }; + dist_with_extractable_point_key_iknp(net, self, x0, x1, beta, on, on); + return 0; +} + +/// @brief Two-party comparison, point stays shared. +int iknp_cmp_oblivious(role self, trio & net) +{ + using Input = std::uint8_t; + const Input alpha = 0x40; + const Input x0 = 0x14; + const Input x1 = static_cast(alpha ^ x0); + const u64 beta = 9; + auto on = [&](const auto & key) { + const u64 mask = key.cmp().mask; + auto below = open_additive(net, self, share_bits(eval_point(cmp, key, + static_cast(alpha - 1)))) & mask; + auto at = open_additive(net, self, share_bits(eval_point(cmp, key, alpha))) & mask; + if (self == role::p0) + { + require(below == beta, "iknp cmp below"); + require(at == 0u, "iknp cmp at"); + } + }; + dist_with_cmp_key_iknp(net, self, x0, x1, lt(beta), on, on); + return 0; +} + +void register_core_flows_impl() +{ + register_flow({"beaver_product_two", "beaver product bench", beaver_product_two, true}); + register_flow({"beaver_product_three_square", "beaver product bench", beaver_product_three_square, true}); + register_flow({"beaver_mul_square", "beaver product bench", beaver_mul_square, true}); + register_flow({"beaver_chained_square", "beaver product bench", beaver_chained_square, true}); + register_flow({"beaver_dot", "beaver dot bench", beaver_dot, true}); + register_flow({"beaver_dot_reuse", "beaver dot bench", beaver_dot_reuse, true}); + register_flow({"beaver_inner_product", "beaver dot bench", beaver_inner_product, true}); + register_flow({"beaver_scale", "beaver scale bench", beaver_scale, true}); + register_flow({"beaver_bit_mul_mux", "beaver mux bench", beaver_bit_mul_mux, true}); + register_flow({"beaver_xor_mux", "beaver mux bench", beaver_xor_mux, true}); + register_flow({"beaver_modint_product", "beaver product bench", beaver_modint_product, true}); + register_flow({"beaver_oracle_stream", "beaver stream bench", beaver_oracle_stream, true}); + register_flow({"beaver_scheduled_replay", "beaver stream bench", beaver_scheduled_replay, true}); + register_flow({"beaver_grotto_appendix_e", "beaver grotto poly bench", beaver_grotto_appendix_e, true}); + register_flow({"beaver_polynomial_share_powers", "beaver poly bench", beaver_polynomial_share_powers, true}); + register_flow({"beaver_rejects_bad_use", "beaver smoke", beaver_rejects_bad_use, false}); + register_flow({"beaver_one_shot_triples", "beaver product bench", beaver_one_shot_triples, true}); + register_flow({"beaver_batch_one_round", "beaver product bench", beaver_batch_one_round, true}); + register_flow({"beaver_blind_survives", "beaver product bench", beaver_blind_survives, true}); + register_flow({"beaver_sums_cancellations", "beaver poly bench", beaver_sums_cancellations, true}); + register_flow({"wildcard_single_leaf", "wildcard dpf bench", wildcard_single_leaf, true}); + register_flow({"wildcard_fail_before_assign", "wildcard smoke", wildcard_fail_before_assign, false}); + register_flow({"geneval_point", "geneval dpf bench", geneval_point, true}); + register_flow({"geneval_arith_point", "geneval dpf bench", geneval_arith_point, true}); + register_flow({"ds_key_agrees", "ds geneval dpf bench", ds_key_agrees, true}); + register_flow({"verifiable_honest_point", "verifiable dpf bench", verifiable_honest_point, true}); + register_flow({"verifiable_tampered_rejects", "verifiable smoke", verifiable_tampered_rejects, false}); + register_flow({"blocked_dcf_point", "dcf grotto bench", blocked_dcf_point, true}); + register_flow({"grotto_prefix_horner", "beaver horner grotto bench", grotto_prefix_horner, true}); + register_flow({"beaver_auth_horner", "beaver auth mac", beaver_auth_horner, false}); + register_flow({"carry_verifiable_mac", "carry vdpf mac", carry_verifiable_mac, false}); + register_flow({"extractable_sketch_point", "extractable sketch", extractable_sketch_point, false}); + // Tag is `iknp`, not `bench`: party_bench spawns these with p0/p1 only. + register_flow({"iknp_geneval_point", "iknp geneval dpf", iknp_geneval_point, true}); + register_flow({"iknp_arith_point", "iknp geneval dpf", iknp_arith_point, true}); + register_flow({"iknp_wildcard_leaf", "iknp wildcard dpf", iknp_wildcard_leaf, true}); + register_flow({"iknp_extractable_sketch", "iknp extractable", iknp_extractable_sketch, true}); + register_flow({"iknp_cmp_oblivious", "iknp dcf", iknp_cmp_oblivious, true}); +} + +} // namespace + +void register_core_flows() +{ + register_core_flows_impl(); +} + +namespace +{ + +struct run_opts +{ + std::string dir; + std::string case_name; + std::string tag; + std::uint64_t repeat = 1; + std::uint64_t warmup = 0; + bool metrics = false; + bool list_only = false; + bool pair = false; +}; + +run_opts parse_opts(int argc, char ** argv) +{ + run_opts o; + for (int i = 1; i < argc; ++i) + { + std::string a = argv[i]; + auto need = [&](const char * flag) -> std::string { + if (i + 1 >= argc) + throw std::invalid_argument(std::string("missing value for ") + flag); + return argv[++i]; + }; + if (a == "--dir") + o.dir = need("--dir"); + else if (a == "--case") + o.case_name = need("--case"); + else if (a == "--tag") + o.tag = need("--tag"); + else if (a == "--repeat") + o.repeat = std::stoull(need("--repeat")); + else if (a == "--warmup") + o.warmup = std::stoull(need("--warmup")); + else if (a == "--metrics") + o.metrics = true; + else if (a == "--list") + o.list_only = true; + else if (a == "--pair") + o.pair = true; + } + return o; +} + +int run_one_flow(role self, const flow & f, trio & net, const run_opts & o) +{ + using clock = std::chrono::steady_clock; + std::uint64_t total_ns = 0; + std::uint64_t min_ns = ~std::uint64_t{0}; + std::uint64_t max_ns = 0; + std::uint64_t bytes_sent = 0; + std::uint64_t bytes_recv = 0; + std::uint64_t frames_sent = 0; + std::uint64_t frames_recv = 0; + std::uint64_t bytes_recv_from_p2 = 0; + std::uint64_t bytes_recv_from_peer = 0; + std::uint64_t bytes_sent_to_p2 = 0; + std::uint64_t bytes_sent_to_peer = 0; + std::uint64_t payload_sent = 0; + std::uint64_t payload_recv = 0; + std::uint64_t rounds = 0; + std::uint64_t prg_evals = 0; + const std::uint64_t iters = o.warmup + o.repeat; + for (std::uint64_t i = 0; i < iters; ++i) + { + // Align parties before each iteration (including first). + if (o.pair) + { + if (self == role::p2) + throw std::invalid_argument("pair flows have no p2"); + const role peer = self == role::p0 ? role::p1 : role::p0; + (void)net.exchange_with(peer, i, net::msg::case_ok); + } + else if (self == role::p2) + { + net.to(role::p0).send(net::msg::case_ok, i); + net.to(role::p1).send(net::msg::case_ok, i); + } + else + { + auto got = net.to(role::p2).recv(net::msg::case_ok); + if (got != i) + throw std::runtime_error("repeat barrier mismatch"); + } + + // The barrier is harness traffic. The tally below is the flow itself. + net.reset_tally(); + dpf::prg::reset_eval_count(); + const auto t0 = clock::now(); + int rc = f.run(self, net); + const auto t1 = clock::now(); + if (rc != 0) + return rc; + if (i < o.warmup) + continue; + const auto ns = static_cast( + std::chrono::duration_cast(t1 - t0).count()); + total_ns += ns; + min_ns = std::min(min_ns, ns); + max_ns = std::max(max_ns, ns); + const auto tally = net.tally(); + const auto from_p2 = net.tally_from_p2(); + const auto from_peer = net.tally_from_peer(); + bytes_sent += tally.bytes_sent; + bytes_recv += tally.bytes_recv; + frames_sent += tally.frames_sent; + frames_recv += tally.frames_recv; + bytes_recv_from_p2 += from_p2.bytes_recv; + bytes_recv_from_peer += from_peer.bytes_recv; + bytes_sent_to_p2 += from_p2.bytes_sent; + bytes_sent_to_peer += from_peer.bytes_sent; + payload_sent += tally.payload_sent; + payload_recv += tally.payload_recv; + rounds += tally.exchanges; + prg_evals += dpf::prg::eval_count(); + } + if (o.metrics) + { + const std::uint64_t reps = o.repeat == 0 ? 1 : o.repeat; + const std::uint64_t avg = total_ns / reps; + const std::uint64_t wire_overhead = + (bytes_sent + bytes_recv) - (payload_sent + payload_recv); + std::string path = o.dir + "/metrics." + role_name(self); + std::ofstream out(path, std::ios::app); + out << "flow=" << f.name + << " role=" << role_name(self) + << " repeat=" << o.repeat + << " warmup=" << o.warmup + << " avg_ns=" << avg + << " min_ns=" << (o.repeat ? min_ns : 0) + << " max_ns=" << max_ns + << " total_ns=" << total_ns + << " bytes_sent=" << bytes_sent + << " bytes_recv=" << bytes_recv + << " frames_sent=" << frames_sent + << " frames_recv=" << frames_recv + << " bytes_recv_from_p2=" << bytes_recv_from_p2 + << " bytes_recv_from_peer=" << bytes_recv_from_peer + << " bytes_sent_to_p2=" << bytes_sent_to_p2 + << " bytes_sent_to_peer=" << bytes_sent_to_peer + << " payload_sent=" << payload_sent + << " payload_recv=" << payload_recv + << " wire_overhead=" << wire_overhead + << " rounds=" << rounds + << " prg_evals=" << prg_evals + << " avg_bytes_sent=" << (bytes_sent / reps) + << " avg_bytes_recv=" << (bytes_recv / reps) + << " avg_frames_sent=" << (frames_sent / reps) + << " avg_frames_recv=" << (frames_recv / reps) + << '\n'; + } + return 0; +} + +} // namespace + +int run(role self, int argc, char ** argv) +{ + register_all_flows(); + try + { + auto o = parse_opts(argc, argv); + if (o.list_only) + { + if (self == role::p0) + list_flows(std::cout, o.tag); + return 0; + } + if (o.dir.empty()) + { + std::cerr << role_name(self) << ": need --dir\n"; + return 2; + } + if (o.case_name.empty() && o.tag.empty()) + { + std::cerr << role_name(self) << ": need --case or --tag\n"; + return 2; + } + if (o.repeat == 0) + o.repeat = 1; + + std::vector flows; + if (!o.case_name.empty()) + { + auto * f = find_flow(o.case_name); + if (!f) + throw std::invalid_argument("unknown flow: " + o.case_name); + flows.push_back(f); + } + else + { + flows = select_flows(o.tag); + if (flows.empty()) + throw std::invalid_argument("no flows match --tag " + o.tag); + } + + auto net = o.pair ? trio::connect_pair(self, o.dir) + : trio::connect_local(self, o.dir); + for (const flow * f : flows) + { + int rc = run_one_flow(self, *f, net, o); + if (rc != 0) + return rc; + } + return 0; + } + catch (const std::exception & ex) + { + std::cerr << role_name(self) << " failed: " << ex.what() << "\n"; + return 1; + } +} + +} // namespace party +} // namespace dpf + +// Amalgamate bulk + extreme flows into this TU: libdpf headers define +// non-inline symbols (utils/AES/SHA256), so a second party .cpp would ODR-collide. +#include "flows_bulk.cpp" +#include "flows_extreme.cpp" +#include "flows_recent.cpp" +#include "flows_coverage.cpp" +#include "flows_gadget.cpp" diff --git a/party/spawn.hpp b/party/spawn.hpp new file mode 100644 index 0000000..0cd641e --- /dev/null +++ b/party/spawn.hpp @@ -0,0 +1,219 @@ +/// @file party/spawn.hpp +/// @brief Spawn p0/p1/p2 for one flow (used by gtest and party_bench). +#ifndef LIBDPF_PARTY_SPAWN_HPP__ +#define LIBDPF_PARTY_SPAWN_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef LIBDPF_PARTY_BIN_DIR +#define LIBDPF_PARTY_BIN_DIR "." +#endif + +namespace dpf +{ +namespace party +{ + +inline std::string party_bin(const char * name) +{ + const char * env = std::getenv("LIBDPF_PARTY_BIN_DIR"); + std::string dir = env ? env : LIBDPF_PARTY_BIN_DIR; + return dir + "/" + name; +} + +struct spawn_result +{ + int rc[3] = {0, 0, 0}; + double wall_ms = 0; + /// @brief Per-role metric lines (from --metrics), ordered p0/p1/p2. + std::vector metrics_lines; +}; + +struct spawn_opts +{ + std::uint64_t repeat = 1; + std::uint64_t warmup = 0; + bool metrics = false; + /// @brief Pass `case_name` as `--tag` so one mesh runs every match. + bool by_tag = false; +}; + +inline spawn_result spawn_trio_flow(const std::string & case_name, + const spawn_opts & opts = {}) +{ + namespace fs = std::filesystem; + auto dir = fs::temp_directory_path() + / ("libdpf_party_" + std::to_string(::getpid()) + "_" + case_name); + fs::create_directories(dir); + + std::string rep = std::to_string(opts.repeat); + std::string warm = std::to_string(opts.warmup); + + const auto t0 = std::chrono::steady_clock::now(); + pid_t kids[3]; + const char * bins[3] = {"p0", "p1", "p2"}; + for (int i = 0; i < 3; ++i) + { + kids[i] = fork(); + if (kids[i] < 0) + { + fs::remove_all(dir); + throw std::runtime_error("fork failed"); + } + if (kids[i] == 0) + { + auto bin = party_bin(bins[i]); + const char * sel = opts.by_tag ? "--tag" : "--case"; + if (opts.metrics) + { + execl(bin.c_str(), bin.c_str(), + "--dir", dir.string().c_str(), + sel, case_name.c_str(), + "--repeat", rep.c_str(), + "--warmup", warm.c_str(), + "--metrics", + static_cast(nullptr)); + } + else + { + execl(bin.c_str(), bin.c_str(), + "--dir", dir.string().c_str(), + sel, case_name.c_str(), + "--repeat", rep.c_str(), + "--warmup", warm.c_str(), + static_cast(nullptr)); + } + _exit(126); + } + } + + spawn_result out; + for (int i = 0; i < 3; ++i) + { + int status = 0; + if (waitpid(kids[i], &status, 0) < 0) + out.rc[i] = 125; + else + out.rc[i] = WIFEXITED(status) ? WEXITSTATUS(status) : 124; + } + const auto t1 = std::chrono::steady_clock::now(); + out.wall_ms = std::chrono::duration(t1 - t0).count(); + + if (opts.metrics) + { + const char * roles[3] = {"p0", "p1", "p2"}; + for (const char * role : roles) + { + auto path = dir / (std::string("metrics.") + role); + std::ifstream in(path); + std::string line; + while (std::getline(in, line)) + { + if (!line.empty()) + out.metrics_lines.push_back(line); + } + } + } + + fs::remove_all(dir); + return out; +} + +/// @brief Spawn only p0 and p1 (no dealer). For IKNP / two-party flows. +inline spawn_result spawn_pair_flow(const std::string & case_name, + const spawn_opts & opts = {}) +{ + namespace fs = std::filesystem; + auto dir = fs::temp_directory_path() + / ("libdpf_pair_" + std::to_string(::getpid()) + "_" + case_name); + fs::create_directories(dir); + + std::string rep = std::to_string(opts.repeat); + std::string warm = std::to_string(opts.warmup); + + const auto t0 = std::chrono::steady_clock::now(); + pid_t kids[2]; + const char * bins[2] = {"p0", "p1"}; + for (int i = 0; i < 2; ++i) + { + kids[i] = fork(); + if (kids[i] < 0) + { + fs::remove_all(dir); + throw std::runtime_error("fork failed"); + } + if (kids[i] == 0) + { + auto bin = party_bin(bins[i]); + const char * sel = opts.by_tag ? "--tag" : "--case"; + if (opts.metrics) + { + execl(bin.c_str(), bin.c_str(), + "--dir", dir.string().c_str(), + sel, case_name.c_str(), + "--repeat", rep.c_str(), + "--warmup", warm.c_str(), + "--metrics", + "--pair", + static_cast(nullptr)); + } + else + { + execl(bin.c_str(), bin.c_str(), + "--dir", dir.string().c_str(), + sel, case_name.c_str(), + "--repeat", rep.c_str(), + "--warmup", warm.c_str(), + "--pair", + static_cast(nullptr)); + } + _exit(126); + } + } + + spawn_result out; + for (int i = 0; i < 2; ++i) + { + int status = 0; + if (waitpid(kids[i], &status, 0) < 0) + out.rc[i] = 125; + else + out.rc[i] = WIFEXITED(status) ? WEXITSTATUS(status) : 124; + } + out.rc[2] = 0; + const auto t1 = std::chrono::steady_clock::now(); + out.wall_ms = std::chrono::duration(t1 - t0).count(); + + if (opts.metrics) + { + const char * roles[2] = {"p0", "p1"}; + for (const char * role : roles) + { + auto path = dir / (std::string("metrics.") + role); + std::ifstream in(path); + std::string line; + while (std::getline(in, line)) + { + if (!line.empty()) + out.metrics_lines.push_back(line); + } + } + } + + fs::remove_all(dir); + return out; +} + +} // namespace party +} // namespace dpf + +#endif // LIBDPF_PARTY_SPAWN_HPP__ diff --git a/python/pydpf.cpp b/python/pydpf.cpp new file mode 100644 index 0000000..ebcf541 --- /dev/null +++ b/python/pydpf.cpp @@ -0,0 +1,109 @@ +#include +#include +#include +#include + +#include +#include + +#include "pydpf_types.hpp" +#include "pydpf_eval.hpp" + +// Header-only libdpf symbols are not `inline`; keep one TU. +#include "pydpf_eval.inc" + +namespace py = pybind11; + +PYBIND11_MODULE(pydpf, m) +{ + m.doc() = "libdpf bindings: point/interval/full/sequence/recipe, " + "multileaf, wildcards, eval_until, it_dpf3"; + + py::class_(m, "PointKeyPair"); + py::class_(m, "IdpfKeyPair"); + py::class_(m, "ItDpf3Keys"); + py::class_>(m, "IdpfEvalCtx0"); + py::class_>(m, "IdpfEvalCtx1"); + + m.def("make_dpf", [](std::uint8_t alpha, std::uint64_t beta) { + auto [a, b] = dpf::make_dpf(alpha, beta); + return pydpf_detail::PointKeyPair{std::move(a), std::move(b)}; + }, py::arg("alpha"), py::arg("beta")); + + m.def("eval_point", [](const pydpf_detail::PointKeyPair & keys, int party, + std::uint8_t x) { + pydpf_detail::require_party(party); + if (party == 0) + return pydpf_detail::share_limb(*dpf::eval_point(keys.k0, x)); + return pydpf_detail::share_limb(*dpf::eval_point(keys.k1, x)); + }, py::arg("keys"), py::arg("party"), py::arg("x")); + + m.def("reconstruct", [](std::uint64_t s0, std::uint64_t s1) { + return s0 - s1; + }, py::arg("share0"), py::arg("share1")); + + m.def("make_idpf16", [](std::uint16_t alpha) { + auto [a, b] = dpf::make_dpf(alpha, dpf::idpf_ones<16>()); + return pydpf_detail::IdpfKeyPair{std::move(a), std::move(b)}; + }, py::arg("alpha")); + + m.def("make_eval_ctx", [](const pydpf_detail::IdpfKeyPair & keys, int party) { + pydpf_detail::require_party(party); + if (party == 0) + return py::cast(dpf::idpf_eval_ctx(keys.k0)); + return py::cast(dpf::idpf_eval_ctx(keys.k1)); + }, py::arg("keys"), py::arg("party")); + + m.def("eval_until", [](py::object ctx, std::size_t level, + const std::vector & prefixes) { + if (py::isinstance>(ctx)) + { + auto & c = ctx.cast &>(); + auto shares = dpf::eval_until(c, level, prefixes); + std::vector out; + out.reserve(shares.size()); + for (auto & s : shares) + out.push_back(s.raw()); + return out; + } + if (py::isinstance>(ctx)) + { + auto & c = ctx.cast &>(); + auto shares = dpf::eval_until(c, level, prefixes); + std::vector out; + out.reserve(shares.size()); + for (auto & s : shares) + out.push_back(s.raw()); + return out; + } + throw std::invalid_argument("eval_until: unknown context type"); + }, py::arg("ctx"), py::arg("level"), py::arg("prefixes")); + + m.def("ctx_node_count", [](py::object ctx) { + if (py::isinstance>(ctx)) + return ctx.cast &>() + .node_count(); + if (py::isinstance>(ctx)) + return ctx.cast &>() + .node_count(); + throw std::invalid_argument("ctx_node_count: unknown context type"); + }, py::arg("ctx")); + + m.def("make_it_dpf3", [](std::uint8_t alpha, std::uint64_t beta) { + auto [a, b, c] = dpf::make_it_dpf3(alpha, beta); + return pydpf_detail::ItDpf3Keys{std::move(a), std::move(b), std::move(c)}; + }, py::arg("alpha"), py::arg("beta")); + + m.def("eval_it_dpf3", [](const pydpf_detail::ItDpf3Keys & keys, int party, + std::uint8_t x) { + if (party == 0) + return dpf::eval_it_dpf3(keys.k0, x); + if (party == 1) + return dpf::eval_it_dpf3(keys.k1, x); + if (party == 2) + return dpf::eval_it_dpf3(keys.k2, x); + throw std::invalid_argument("eval_it_dpf3: party must be 0, 1, or 2"); + }, py::arg("keys"), py::arg("party"), py::arg("x")); + + pydpf_detail::register_eval(m); +} diff --git a/python/pydpf_eval.hpp b/python/pydpf_eval.hpp new file mode 100644 index 0000000..44bc42a --- /dev/null +++ b/python/pydpf_eval.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace pydpf_detail +{ + +void register_eval(pybind11::module_ & m); + +} // namespace pydpf_detail diff --git a/python/pydpf_eval.inc b/python/pydpf_eval.inc new file mode 100644 index 0000000..0839caf --- /dev/null +++ b/python/pydpf_eval.inc @@ -0,0 +1,172 @@ +#include +#include +#include +#include + +#include +#include + +#include "pydpf_types.hpp" +#include "pydpf_eval.hpp" + +namespace py = pybind11; + +namespace pydpf_detail +{ + +namespace +{ + +template +std::vector eval_full_limbs(const Key & key) +{ + auto [buf, iter] = dpf::eval_full(key); + (void)buf; + return collect_limbs(iter); +} + +template +std::vector eval_interval_limbs(const Key & key, + std::uint8_t from, std::uint8_t to) +{ + if (to < from) + throw std::invalid_argument("eval_interval: to < from"); + auto [buf, iter] = dpf::eval_interval(key, from, to); + (void)buf; + return collect_limbs(iter); +} + +template +std::vector eval_sequence_limbs(const Key & key, + const std::vector & xs) +{ + require_sorted(xs); + auto [buf, iter] = dpf::eval_sequence(key, xs.begin(), xs.end()); + (void)buf; + return collect_limbs(iter); +} + +template +std::vector eval_recipe_limbs(const Key & key, + const std::vector & xs) +{ + require_sorted(xs); + auto recipe = dpf::make_sequence_recipe(key, xs.begin(), xs.end()); + auto [buf, iter] = dpf::eval_sequence(key, recipe); + (void)buf; + return collect_limbs(iter); +} + +} // namespace + +void register_eval(py::module_ & m) +{ + py::class_(m, "MultiKeyPair"); + py::class_(m, "WildcardKeyPair"); + + m.def("eval_full", [](const PointKeyPair & keys, int party) { + require_party(party); + return party == 0 ? eval_full_limbs(keys.k0) : eval_full_limbs(keys.k1); + }, py::arg("keys"), py::arg("party")); + + m.def("eval_interval", [](const PointKeyPair & keys, int party, + std::uint8_t from, std::uint8_t to) { + require_party(party); + return party == 0 ? eval_interval_limbs(keys.k0, from, to) + : eval_interval_limbs(keys.k1, from, to); + }, py::arg("keys"), py::arg("party"), py::arg("from"), py::arg("to")); + + m.def("eval_sequence", [](const PointKeyPair & keys, int party, + const std::vector & xs) { + require_party(party); + return party == 0 ? eval_sequence_limbs(keys.k0, xs) + : eval_sequence_limbs(keys.k1, xs); + }, py::arg("keys"), py::arg("party"), py::arg("points")); + + m.def("eval_sequence_recipe", [](const PointKeyPair & keys, int party, + const std::vector & xs) { + require_party(party); + return party == 0 ? eval_recipe_limbs(keys.k0, xs) + : eval_recipe_limbs(keys.k1, xs); + }, py::arg("keys"), py::arg("party"), py::arg("points")); + + m.def("make_dpf_multi", [](std::uint8_t alpha, std::uint64_t beta0, + std::uint64_t beta1) { + auto [a, b] = dpf::make_dpf(alpha, beta0, beta1); + return MultiKeyPair{std::move(a), std::move(b)}; + }, py::arg("alpha"), py::arg("beta0"), py::arg("beta1")); + + m.def("eval_point_leaf", [](const MultiKeyPair & keys, int party, int leaf, + std::uint8_t x) { + require_party(party); + if (leaf == 0) + { + if (party == 0) + return share_limb(*dpf::eval_point<0>(keys.k0, x)); + return share_limb(*dpf::eval_point<0>(keys.k1, x)); + } + if (leaf == 1) + { + if (party == 0) + return share_limb(*dpf::eval_point<1>(keys.k0, x)); + return share_limb(*dpf::eval_point<1>(keys.k1, x)); + } + throw std::invalid_argument("eval_point_leaf: leaf must be 0 or 1"); + }, py::arg("keys"), py::arg("party"), py::arg("leaf"), py::arg("x")); + + m.def("eval_full_leaf", [](const MultiKeyPair & keys, int party, int leaf) { + require_party(party); + if (leaf == 0) + { + if (party == 0) + { + auto [buf, iter] = dpf::eval_full<0>(keys.k0); + (void)buf; + return collect_limbs(iter); + } + auto [buf, iter] = dpf::eval_full<0>(keys.k1); + (void)buf; + return collect_limbs(iter); + } + if (leaf == 1) + { + if (party == 0) + { + auto [buf, iter] = dpf::eval_full<1>(keys.k0); + (void)buf; + return collect_limbs(iter); + } + auto [buf, iter] = dpf::eval_full<1>(keys.k1); + (void)buf; + return collect_limbs(iter); + } + throw std::invalid_argument("eval_full_leaf: leaf must be 0 or 1"); + }, py::arg("keys"), py::arg("party"), py::arg("leaf")); + + m.def("make_dpf_wildcard", [](std::uint8_t alpha) { + auto [a, b] = dpf::make_dpf(alpha, dpf::wildcard_value{}); + return WildcardKeyPair{std::move(a), std::move(b)}; + }, py::arg("alpha")); + + m.def("assign_wildcard", [](WildcardKeyPair & keys, std::uint64_t beta) { + // Beaver assign takes additive shares of β (same as wildcard_test). + const std::uint64_t shr0 = dpf::uniform_sample(); + const std::uint64_t shr1 = beta - shr0; + assign_leaf_local(keys.k0, keys.k1, shr0, shr1); + }, py::arg("keys"), py::arg("beta")); + + m.def("eval_point", [](const WildcardKeyPair & keys, int party, + std::uint8_t x) { + require_party(party); + if (party == 0) + return share_limb(*dpf::eval_point(keys.k0, x)); + return share_limb(*dpf::eval_point(keys.k1, x)); + }, py::arg("keys"), py::arg("party"), py::arg("x")); + + m.def("eval_full", [](const WildcardKeyPair & keys, int party) { + require_party(party); + return party == 0 ? eval_full_limbs(keys.k0) : eval_full_limbs(keys.k1); + }, py::arg("keys"), py::arg("party")); +} + +} // namespace pydpf_detail diff --git a/python/pydpf_types.hpp b/python/pydpf_types.hpp new file mode 100644 index 0000000..14cb6ee --- /dev/null +++ b/python/pydpf_types.hpp @@ -0,0 +1,125 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "dpf.hpp" + +namespace pydpf_detail +{ + +using point_key0 = decltype(dpf::make_dpf(std::uint8_t{0}, + std::uint64_t{0}).first); +using point_key1 = decltype(dpf::make_dpf(std::uint8_t{0}, + std::uint64_t{0}).second); + +using multi_key0 = decltype(dpf::make_dpf(std::uint8_t{0}, + std::uint64_t{0}, std::uint64_t{0}).first); +using multi_key1 = decltype(dpf::make_dpf(std::uint8_t{0}, + std::uint64_t{0}, std::uint64_t{0}).second); + +using wild_key0 = decltype(dpf::make_dpf(std::uint8_t{0}, + dpf::wildcard_value{}).first); +using wild_key1 = decltype(dpf::make_dpf(std::uint8_t{0}, + dpf::wildcard_value{}).second); + +using idpf_key0 = decltype(dpf::make_dpf(std::uint16_t{0}, + dpf::idpf_ones<16>()).first); +using idpf_key1 = decltype(dpf::make_dpf(std::uint16_t{0}, + dpf::idpf_ones<16>()).second); + +struct PointKeyPair +{ + point_key0 k0; + point_key1 k1; +}; + +struct MultiKeyPair +{ + multi_key0 k0; + multi_key1 k1; +}; + +struct WildcardKeyPair +{ + wild_key0 k0; + wild_key1 k1; +}; + +struct IdpfKeyPair +{ + idpf_key0 k0; + idpf_key1 k1; +}; + +struct ItDpf3Keys +{ + dpf::it_dpf3_key k0; + dpf::it_dpf3_key k1; + dpf::it_dpf3_key k2; +}; + +template +struct has_raw_member : std::false_type {}; +template +struct has_raw_member().raw())>> + : std::true_type {}; + +template +std::uint64_t share_limb(const Share & s) +{ + if constexpr (has_raw_member::value) + return static_cast(s.raw()); + else + return static_cast(s); +} + +template +std::vector collect_limbs(Iterable && iterable) +{ + std::vector out; + for (auto it = std::begin(iterable); it != std::end(iterable); ++it) + out.push_back(share_limb(*it)); + return out; +} + +/// In-process wildcard leaf assign (same messages as asio, no socket). +template +void assign_leaf_local(DpfKey0 & dpf0, DpfKey1 & dpf1, const ShareT & shr0, + const ShareT & shr1) +{ + auto & w0 = std::get(dpf0.leaf_nodes); + auto & w1 = std::get(dpf1.leaf_nodes); + if (w0.is_ready()) + w0.begin_update(); + if (w1.is_ready()) + w1.begin_update(); + const auto b0 = w0.compute_and_get_blinded_output_share(shr0); + const auto b1 = w1.compute_and_get_blinded_output_share(shr1); + const auto l0 = w0.compute_and_get_leaf_share(b1); + const auto l1 = w1.compute_and_get_leaf_share(b0); + w0.reconstruct_correction_word(l1); + w1.reconstruct_correction_word(l0); +} + +inline void require_party(int party) +{ + if (party != 0 && party != 1) + throw std::invalid_argument("party must be 0 or 1"); +} + +inline void require_sorted(const std::vector & xs) +{ + for (std::size_t i = 1; i < xs.size(); ++i) + { + if (xs[i] < xs[i - 1]) + throw std::invalid_argument("sequence points must be nondecreasing"); + } +} + +} // namespace pydpf_detail diff --git a/python/tests/__pycache__/test_pydpf.cpython-314.pyc b/python/tests/__pycache__/test_pydpf.cpython-314.pyc new file mode 100644 index 0000000..d21b9cc Binary files /dev/null and b/python/tests/__pycache__/test_pydpf.cpython-314.pyc differ diff --git a/python/tests/__pycache__/test_pydpf.cpython-37.pyc b/python/tests/__pycache__/test_pydpf.cpython-37.pyc new file mode 100644 index 0000000..9f25567 Binary files /dev/null and b/python/tests/__pycache__/test_pydpf.cpython-37.pyc differ diff --git a/python/tests/test_pydpf.py b/python/tests/test_pydpf.py new file mode 100644 index 0000000..9262894 --- /dev/null +++ b/python/tests/test_pydpf.py @@ -0,0 +1,159 @@ +"""Smoke tests for the optional pydpf module.""" + +import pydpf + + +def test_point_mass(): + keys = pydpf.make_dpf(7, 11) + on = pydpf.reconstruct( + pydpf.eval_point(keys, 0, 7), + pydpf.eval_point(keys, 1, 7), + ) + off = pydpf.reconstruct( + pydpf.eval_point(keys, 0, 8), + pydpf.eval_point(keys, 1, 8), + ) + assert on == 11 + assert off == 0 + + +def test_eval_until_prefix_resume(): + keys = pydpf.make_idpf16(0xBEEF) + ctx0 = pydpf.make_eval_ctx(keys, 0) + ctx1 = pydpf.make_eval_ctx(keys, 1) + # High bit of 0xBEEF is 1. + s0 = pydpf.eval_until(ctx0, 1, [0, 1]) + s1 = pydpf.eval_until(ctx1, 1, [0, 1]) + assert pydpf.ctx_node_count(ctx0) == 2 + assert pydpf.reconstruct(s0[0], s1[0]) == 0 + assert pydpf.reconstruct(s0[1], s1[1]) == 1 + + +def test_it_dpf3_reconstruction(): + keys = pydpf.make_it_dpf3(42, 7) + mask = (1 << 64) - 1 + on = ( + pydpf.eval_it_dpf3(keys, 0, 42) + + pydpf.eval_it_dpf3(keys, 1, 42) + + pydpf.eval_it_dpf3(keys, 2, 42) + ) & mask + off = ( + pydpf.eval_it_dpf3(keys, 0, 41) + + pydpf.eval_it_dpf3(keys, 1, 41) + + pydpf.eval_it_dpf3(keys, 2, 41) + ) & mask + assert on == 7 + assert off == 0 + + +def _open_vec(s0, s1): + return [pydpf.reconstruct(a, b) for a, b in zip(s0, s1)] + + +def test_eval_full(): + keys = pydpf.make_dpf(7, 11) + opened = _open_vec(pydpf.eval_full(keys, 0), pydpf.eval_full(keys, 1)) + assert len(opened) == 256 + assert opened[7] == 11 + assert all(v == 0 for i, v in enumerate(opened) if i != 7) + + +def test_eval_interval_matches_full_slice(): + keys = pydpf.make_dpf(40, 9) + full = _open_vec(pydpf.eval_full(keys, 0), pydpf.eval_full(keys, 1)) + lo, hi = 30, 50 + interval = _open_vec( + pydpf.eval_interval(keys, 0, lo, hi), + pydpf.eval_interval(keys, 1, lo, hi), + ) + assert interval == full[lo : hi + 1] + + +def test_eval_sequence_matches_point(): + keys = pydpf.make_dpf(5, 3) + points = [1, 5, 5, 200] + seq = _open_vec( + pydpf.eval_sequence(keys, 0, points), + pydpf.eval_sequence(keys, 1, points), + ) + for p, got in zip(points, seq): + expect = pydpf.reconstruct( + pydpf.eval_point(keys, 0, p), + pydpf.eval_point(keys, 1, p), + ) + assert got == expect + + +def test_eval_sequence_recipe(): + keys = pydpf.make_dpf(5, 3) + points = [1, 5, 200] + via_seq = _open_vec( + pydpf.eval_sequence(keys, 0, points), + pydpf.eval_sequence(keys, 1, points), + ) + via_recipe = _open_vec( + pydpf.eval_sequence_recipe(keys, 0, points), + pydpf.eval_sequence_recipe(keys, 1, points), + ) + assert via_seq == via_recipe + try: + pydpf.eval_sequence(keys, 0, [3, 1]) + assert False, "expected unsorted rejection" + except ValueError: + pass + + +def test_multileaf(): + keys = pydpf.make_dpf_multi(9, 100, 200) + assert pydpf.reconstruct( + pydpf.eval_point_leaf(keys, 0, 0, 9), + pydpf.eval_point_leaf(keys, 1, 0, 9), + ) == 100 + assert pydpf.reconstruct( + pydpf.eval_point_leaf(keys, 0, 1, 9), + pydpf.eval_point_leaf(keys, 1, 1, 9), + ) == 200 + assert pydpf.reconstruct( + pydpf.eval_point_leaf(keys, 0, 0, 8), + pydpf.eval_point_leaf(keys, 1, 0, 8), + ) == 0 + full0 = _open_vec( + pydpf.eval_full_leaf(keys, 0, 0), + pydpf.eval_full_leaf(keys, 1, 0), + ) + assert full0[9] == 100 + assert full0[0] == 0 + + +def test_wildcard(): + keys = pydpf.make_dpf_wildcard(12) + try: + pydpf.eval_point(keys, 0, 12) + assert False, "expected eval before assign to fail" + except RuntimeError: + pass + pydpf.assign_wildcard(keys, 77) + assert pydpf.reconstruct( + pydpf.eval_point(keys, 0, 12), + pydpf.eval_point(keys, 1, 12), + ) == 77 + assert pydpf.reconstruct( + pydpf.eval_point(keys, 0, 13), + pydpf.eval_point(keys, 1, 13), + ) == 0 + opened = _open_vec(pydpf.eval_full(keys, 0), pydpf.eval_full(keys, 1)) + assert opened[12] == 77 + assert opened[0] == 0 + + +if __name__ == "__main__": + test_point_mass() + test_eval_until_prefix_resume() + test_it_dpf3_reconstruction() + test_eval_full() + test_eval_interval_matches_full_slice() + test_eval_sequence_matches_point() + test_eval_sequence_recipe() + test_multileaf() + test_wildcard() + print("ok") diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5fb608c..6b4ae24 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,7 +11,51 @@ enable_testing() include_directories(../include ../thirdparty ../thirdparty/asio/asio/include) link_libraries(gtest_main bsd) +# The run log's `ev=build rev=` names the tree this build was configured from. +execute_process( + COMMAND git -C "${CMAKE_CURRENT_SOURCE_DIR}/.." describe --always --dirty --abbrev=12 + OUTPUT_VARIABLE LIBDPF_GIT_REV OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) +if(LIBDPF_GIT_REV) + add_compile_definitions(LIBDPF_GIT_REV="${LIBDPF_GIT_REV}") +endif() +# The async SCTP backend (dpf::net::async_sctp_stream_array) auto-enables on +# Linux when is present and needs libsctp (-lsctp). Most +# targets reach it through dpf.hpp, so link it everywhere; if the library is +# missing, force the header's stub path so the build still links. +if(UNIX AND NOT APPLE) + find_library(SCTP_LIB sctp) + if(SCTP_LIB) + link_libraries(${SCTP_LIB}) + else() + add_compile_definitions(DPF_HAS_LIBSCTP=0) + endif() +endif() +# Party and client links run TLS 1.3 through OpenSSL (dpf/net/tls.hpp). The +# headers auto-enable it when exists; without it, encrypted +# links fail at setup and `encryption=off` keeps plaintext links working. +find_package(OpenSSL) +if(OPENSSL_FOUND) + link_libraries(OpenSSL::SSL OpenSSL::Crypto) +else() + add_compile_definitions(DPF_HAS_OPENSSL=0) +endif() add_compile_options(-march=native) +add_compile_options(-Wall -Wextra -Wpedantic) +# `__int128` is the 128-bit limb. `-Wpedantic` reports that GNU extension +# at every use; the rest of `-Wall` and `-Wextra` stay on. +add_compile_options(-Wno-pedantic) +# `if constexpr` followed by a runtime `if`/`else` is the comparison-leaf +# dispatch. The `else` binds to the runtime `if`. +add_compile_options(-Wno-dangling-else) +# SIMD block types (`__m128i` / simde) carry alignment attributes that GCC +# cannot preserve on template arguments; the warning is noise for this codebase. +add_compile_options(-Wno-ignored-attributes) +# Third-party and leaf-lane memcpy patterns trigger GCC's false-positive +# stringop-overflow diagnostics under aggressive inlining. +add_compile_options(-Wno-stringop-overflow) +# `HEDLEY_WARN_UNUSED_RESULT` / `[[nodiscard]]` are not silenced by `(void)` +# casts on this GCC; tests intentionally discard values inside EXPECT_THROW. +add_compile_options(-Wno-unused-result) option(COVERAGE "Compile with coverage instrumentation" OFF) if(COVERAGE) @@ -19,6 +63,53 @@ if(COVERAGE) link_libraries(gcov) endif() +# Profile harnesses (profile_eval, profile_grotto, profile_party) and the +# party binaries that those harnesses execute. OFF leaves them as normal +# optimized drivers. generate instruments; use consumes the .gcda files. +set(LIBDPF_PGO "OFF" CACHE STRING + "PGO for profile harnesses and party binaries: OFF, generate, or use") +set_property(CACHE LIBDPF_PGO PROPERTY STRINGS OFF generate use) +set(LIBDPF_PGO_DIR "${CMAKE_BINARY_DIR}/pgo" CACHE PATH + "Directory for GCC .gcda profile data") +if(COVERAGE AND NOT LIBDPF_PGO STREQUAL "OFF") + message(FATAL_ERROR + "COVERAGE and LIBDPF_PGO cannot be combined; configure a separate build directory") +endif() +if(NOT LIBDPF_PGO STREQUAL "OFF" AND NOT LIBDPF_PGO STREQUAL "generate" AND NOT LIBDPF_PGO STREQUAL "use") + message(FATAL_ERROR "LIBDPF_PGO must be OFF, generate, or use (got '${LIBDPF_PGO}')") +endif() + +function(libdpf_apply_pgo target) + if(LIBDPF_PGO STREQUAL "OFF") + return() + endif() + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + file(MAKE_DIRECTORY "${LIBDPF_PGO_DIR}") + target_compile_options(${target} PRIVATE + -O3 -fno-omit-frame-pointer + "-fprofile-dir=${LIBDPF_PGO_DIR}") + get_target_property(_kind ${target} TYPE) + if(LIBDPF_PGO STREQUAL "generate") + target_compile_options(${target} PRIVATE -fprofile-generate) + if(_kind STREQUAL "EXECUTABLE") + target_link_options(${target} PRIVATE -fprofile-generate) + endif() + else() + target_compile_options(${target} PRIVATE + -fprofile-use -fprofile-correction -Wno-missing-profile) + if(_kind STREQUAL "EXECUTABLE") + target_link_options(${target} PRIVATE -fprofile-use -fprofile-correction) + endif() + endif() + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + message(FATAL_ERROR + "LIBDPF_PGO is implemented for GCC (-fprofile-generate/use). This compiler is ${CMAKE_CXX_COMPILER_ID}.") + else() + message(FATAL_ERROR + "LIBDPF_PGO is implemented for GCC. This compiler is ${CMAKE_CXX_COMPILER_ID}.") + endif() +endfunction() + add_executable(all_test tests/all_test.cpp) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") @@ -55,6 +146,7 @@ add_executable(keyword2_test tests/keyword2_test.cpp) target_compile_options(keyword2_test PRIVATE -fconstexpr-ops-limit=100000000) add_executable(types_test tests/types_test.cpp) add_executable(packed_lane_test tests/packed_lane_test.cpp) +add_executable(bitmore_mod_test tests/bitmore_mod_test.cpp) add_executable(lane_blast_test tests/lane_blast_test.cpp) add_executable(context_blast_test tests/context_blast_test.cpp) add_executable(random_test tests/random_test.cpp tests/random_odr_tu.cpp) @@ -67,23 +159,151 @@ add_executable(prg_aes_ccr_test tests/prg_aes_ccr_test.cpp) add_executable(half_tree_test tests/half_tree_test.cpp) add_executable(constrained_cmp_test tests/constrained_cmp_test.cpp) add_executable(fp61_test tests/fp61_test.cpp) +add_executable(field_output_test tests/field_output_test.cpp) +add_executable(gf2_test tests/gf2_test.cpp) +add_executable(gf2_adversarial_test tests/gf2_adversarial_test.cpp) add_executable(arith_payload_test tests/arith_payload_test.cpp) add_executable(verifiable_test tests/verifiable_test.cpp) +add_executable(vdpf_adversarial_test tests/vdpf_adversarial_test.cpp) +add_executable(shamir_adversarial_test tests/shamir_adversarial_test.cpp) +add_executable(vdpf_regression_test tests/vdpf_regression_test.cpp) +add_executable(opt_in_malicious_test tests/opt_in_malicious_test.cpp) add_executable(multipoint_test tests/multipoint_test.cpp) +add_executable(dpf3_test tests/dpf3_test.cpp) +add_executable(eval_inner_product_test tests/eval_inner_product_test.cpp) +add_executable(shared_and_test tests/shared_and_test.cpp) +target_include_directories(shared_and_test PRIVATE ../party) +add_executable(cohort_test tests/cohort_test.cpp) +add_executable(interleave_leaves_test tests/interleave_leaves_test.cpp) add_executable(secret_share_test tests/secret_share_test.cpp) add_executable(beaver_test tests/beaver_test.cpp) +add_executable(share_runtime_test tests/share_runtime_test.cpp) +add_executable(net_control_test tests/net_control_test.cpp) +add_executable(security_test tests/security_test.cpp) +add_executable(protocol_batch_test tests/protocol_batch_test.cpp) +target_include_directories(protocol_batch_test PRIVATE ../party) +add_executable(compose_test tests/compose_test.cpp) +target_include_directories(compose_test PRIVATE ../party) +add_executable(experiment_test tests/experiment_test.cpp) +add_executable(log_test tests/log_test.cpp) add_executable(constant_lut_test tests/constant_lut_test.cpp) add_executable(signed_prefix_test tests/signed_prefix_test.cpp) add_executable(easy_lut_test tests/easy_lut_test.cpp) add_executable(dyadic_lut_test tests/dyadic_lut_test.cpp) add_executable(nmod_test tests/nmod_test.cpp) +add_executable(exact_steps_test tests/exact_steps_test.cpp) +add_executable(closed_form_test tests/closed_form_test.cpp) add_executable(principal_lut_test tests/principal_lut_test.cpp) add_executable(range_lut_test tests/range_lut_test.cpp) add_executable(window_lut_test tests/window_lut_test.cpp) +add_executable(dwt_lut_test tests/dwt_lut_test.cpp) add_executable(offset_horner_test tests/offset_horner_test.cpp) +add_executable(offset_poly_test tests/offset_poly_test.cpp) +add_executable(lut_union_test tests/lut_union_test.cpp) +add_executable(offset_jet_test tests/offset_jet_test.cpp) +add_executable(offset_repr_test tests/offset_repr_test.cpp) +add_executable(offset_twist_test tests/offset_twist_test.cpp) +add_executable(ring_switch_test tests/ring_switch_test.cpp) add_executable(corner_gaps_test tests/corner_gaps_test.cpp) +add_executable(carry_test tests/carry_test.cpp) +add_executable(fixedpoint_beaver_test tests/fixedpoint_beaver_test.cpp) +add_executable(class_sweep_test tests/class_sweep_test.cpp) +add_executable(extractable_full_test tests/extractable_full_test.cpp) +add_executable(walk_helpers_test tests/walk_helpers_test.cpp) +add_executable(domain128_point_test tests/domain128_point_test.cpp) +add_executable(blob_leaf_test tests/blob_leaf_test.cpp) +add_executable(growing_idpf_test tests/growing_idpf_test.cpp) +add_executable(pprf_test tests/pprf_test.cpp) +add_executable(ppvc_test tests/ppvc_test.cpp) +add_executable(leaf_later_test tests/leaf_later_test.cpp) +add_executable(caller_fold_test tests/caller_fold_test.cpp) +add_executable(defer_eval_test tests/defer_eval_test.cpp) +add_executable(wrap_and_rotate_test tests/wrap_and_rotate_test.cpp) +add_executable(sfss_test tests/sfss_test.cpp) +add_executable(path_sketch_test tests/path_sketch_test.cpp) +add_executable(eval_until_test tests/eval_until_test.cpp) +add_executable(idpf_agg_test tests/idpf_agg_test.cpp) +add_executable(it_dpf3_test tests/it_dpf3_test.cpp) + +# (2+1) party processes over local sockets +add_library(party_flows STATIC + ../party/registry.cpp + ../party/run.cpp +) +# flows_bulk.cpp is #included from run.cpp (single TU; avoids dpf.hpp ODR). +target_include_directories(party_flows PUBLIC + ../include ../thirdparty ../thirdparty/asio/asio/include ../party + ../thirdparty/json/include) +target_compile_definitions(party_flows PUBLIC LIBDPF_HAS_ASIO LIBDPF_HAS_NLOHMANN_JSON) +target_link_libraries(party_flows PUBLIC bsd pthread) + +add_executable(p0 ../party/p0.cpp) +add_executable(p1 ../party/p1.cpp) +add_executable(p2 ../party/p2.cpp) +add_executable(party_bench ../party/party_bench.cpp) +foreach(party_target p0 p1 p2 party_bench) + target_link_libraries(${party_target} PRIVATE party_flows) + target_compile_definitions(${party_target} PRIVATE + "LIBDPF_PARTY_BIN_DIR=\"${CMAKE_BINARY_DIR}/bin\"") + set_target_properties(${party_target} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") +endforeach() +add_dependencies(party_bench p0 p1 p2) + +# In-process and (2+1) workloads for cost measurement and profile-guided +# optimization. Not gtest: run the binaries directly. See each file's header. +add_executable(profile_eval profile/eval_profile.cpp) +add_executable(profile_grotto profile/grotto_profile.cpp) +add_executable(profile_party profile/party_profile.cpp) +foreach(profile_target profile_eval profile_grotto profile_party) + target_compile_options(${profile_target} PRIVATE -O3 -fno-omit-frame-pointer) + set_target_properties(${profile_target} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") +endforeach() +target_link_libraries(profile_party PRIVATE party_flows) +target_compile_definitions(profile_party PRIVATE + "LIBDPF_PARTY_BIN_DIR=\"${CMAKE_BINARY_DIR}/bin\"") +add_dependencies(profile_party p0 p1 p2) +foreach(pgo_target profile_eval profile_grotto profile_party party_flows p0 p1 p2 party_bench) + libdpf_apply_pgo(${pgo_target}) +endforeach() +add_executable(yao_share_test tests/yao_share_test.cpp) + +add_executable(yao_test tests/yao_test.cpp) +add_executable(yao_stack_test tests/yao_stack_test.cpp) +add_executable(arith_garble_test tests/arith_garble_test.cpp) +add_executable(flute_test tests/flute_test.cpp) +add_executable(shuffle_hidden_test tests/shuffle_hidden_test.cpp) +add_executable(bench_cell_test tests/bench_cell_test.cpp) +target_link_libraries(bench_cell_test PRIVATE pthread) +target_include_directories(yao_test PRIVATE ../party) +target_link_libraries(yao_test PRIVATE pthread) +# Half-gates are fine at -O0. The session test's Chou–Orlandi base OT is not. +target_compile_options(yao_test PRIVATE -O2) + +add_executable(iknp_party_test tests/iknp_party_test.cpp) +target_include_directories(iknp_party_test PRIVATE ../party) +target_link_libraries(iknp_party_test PRIVATE pthread) +# Base OTs are P-256 scalar multiplications. The default test flags leave this +# TU unoptimized, which makes those scalars take minutes. +target_compile_options(iknp_party_test PRIVATE -O2) + +add_executable(beaver_party_test tests/beaver_party_test.cpp) +target_include_directories(beaver_party_test PRIVATE ../party) +target_compile_definitions(beaver_party_test PRIVATE + "LIBDPF_PARTY_BIN_DIR=\"${CMAKE_BINARY_DIR}/bin\"") +target_link_libraries(beaver_party_test PRIVATE party_flows) +add_dependencies(beaver_party_test p0 p1 p2) include(GoogleTest) +gtest_discover_tests(yao_share_test) +gtest_discover_tests(yao_test) +gtest_discover_tests(yao_stack_test) +gtest_discover_tests(arith_garble_test) +gtest_discover_tests(flute_test) +gtest_discover_tests(shuffle_hidden_test) +gtest_discover_tests(bench_cell_test) +gtest_discover_tests(iknp_party_test) gtest_discover_tests(dpf_key_test) gtest_discover_tests(wildcard_test) @@ -110,6 +330,7 @@ gtest_discover_tests(incremental_json_test) gtest_discover_tests(keyword2_test) gtest_discover_tests(types_test) gtest_discover_tests(packed_lane_test) +gtest_discover_tests(bitmore_mod_test) gtest_discover_tests(lane_blast_test) gtest_discover_tests(context_blast_test) gtest_discover_tests(random_test) @@ -119,24 +340,104 @@ gtest_discover_tests(prg_aes_ccr_test) gtest_discover_tests(half_tree_test) gtest_discover_tests(constrained_cmp_test) gtest_discover_tests(fp61_test) +gtest_discover_tests(field_output_test) +gtest_discover_tests(gf2_test) +gtest_discover_tests(gf2_adversarial_test) gtest_discover_tests(arith_payload_test) gtest_discover_tests(verifiable_test) +gtest_discover_tests(vdpf_adversarial_test) +gtest_discover_tests(shamir_adversarial_test) +gtest_discover_tests(vdpf_regression_test) +gtest_discover_tests(opt_in_malicious_test) gtest_discover_tests(multipoint_test) +gtest_discover_tests(dpf3_test) +gtest_discover_tests(eval_inner_product_test) +gtest_discover_tests(shared_and_test) +gtest_discover_tests(cohort_test) +gtest_discover_tests(interleave_leaves_test) gtest_discover_tests(secret_share_test) gtest_discover_tests(beaver_test) +gtest_discover_tests(share_runtime_test) +gtest_discover_tests(net_control_test) +gtest_discover_tests(security_test) +gtest_discover_tests(protocol_batch_test) +gtest_discover_tests(compose_test) +gtest_discover_tests(experiment_test) +gtest_discover_tests(log_test) +gtest_discover_tests(beaver_party_test) gtest_discover_tests(constant_lut_test) gtest_discover_tests(signed_prefix_test) gtest_discover_tests(easy_lut_test) gtest_discover_tests(dyadic_lut_test) gtest_discover_tests(nmod_test) +gtest_discover_tests(exact_steps_test) +gtest_discover_tests(closed_form_test) gtest_discover_tests(principal_lut_test) gtest_discover_tests(range_lut_test) gtest_discover_tests(window_lut_test) +gtest_discover_tests(dwt_lut_test) gtest_discover_tests(offset_horner_test) +gtest_discover_tests(offset_poly_test) +gtest_discover_tests(lut_union_test) +gtest_discover_tests(offset_jet_test) +gtest_discover_tests(offset_repr_test) +gtest_discover_tests(offset_twist_test) +gtest_discover_tests(ring_switch_test) add_executable(ic_test tests/ic_test.cpp) gtest_discover_tests(ic_test) add_executable(wide_payload_test tests/wide_payload_test.cpp) gtest_discover_tests(wide_payload_test) -add_executable(ppvc_test tests/ppvc_test.cpp) -gtest_discover_tests(ppvc_test) gtest_discover_tests(corner_gaps_test) +gtest_discover_tests(carry_test) +gtest_discover_tests(fixedpoint_beaver_test) +gtest_discover_tests(class_sweep_test) +gtest_discover_tests(extractable_full_test) +gtest_discover_tests(walk_helpers_test) +gtest_discover_tests(domain128_point_test) +gtest_discover_tests(blob_leaf_test) +gtest_discover_tests(growing_idpf_test) +gtest_discover_tests(pprf_test) +gtest_discover_tests(ppvc_test) +gtest_discover_tests(leaf_later_test) +gtest_discover_tests(caller_fold_test) +gtest_discover_tests(defer_eval_test) +gtest_discover_tests(wrap_and_rotate_test) +gtest_discover_tests(sfss_test) +gtest_discover_tests(path_sketch_test) +gtest_discover_tests(eval_until_test) +gtest_discover_tests(idpf_agg_test) +gtest_discover_tests(it_dpf3_test) + +# Optional Python module (keys stay opaque capsules). +option(LIBDPF_PYTHON "Build the optional pybind11 pydpf module" OFF) +if(LIBDPF_PYTHON) + set(PYBIND11_FINDPYTHON ON) + find_package(Python3 COMPONENTS Interpreter Development REQUIRED) + # Prefer the FindPython result over a stale classic PYTHON_EXECUTABLE + # (this tree previously cached 3.7). + set(PYTHON_EXECUTABLE "${Python3_EXECUTABLE}" CACHE FILEPATH + "Python interpreter for pybind11" FORCE) + include(FetchContent) + FetchContent_Declare( + pybind11 + GIT_REPOSITORY https://github.com/pybind/pybind11.git + GIT_TAG v2.13.6 + ) + FetchContent_MakeAvailable(pybind11) + pybind11_add_module(pydpf ../python/pydpf.cpp) + target_include_directories(pydpf PRIVATE ../include ../thirdparty ../python) + target_compile_options(pydpf PRIVATE -march=native -Wno-pedantic + -Wno-ignored-attributes -Wno-dangling-else) + target_link_libraries(pydpf PRIVATE bsd) + set_target_properties(pydpf PROPERTIES + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/python") + add_custom_target(pydpf_pytest + COMMAND ${CMAKE_COMMAND} -E env + "PYTHONPATH=${CMAKE_BINARY_DIR}/python" + ${Python3_EXECUTABLE} + "${CMAKE_CURRENT_SOURCE_DIR}/../python/tests/test_pydpf.py" + DEPENDS pydpf + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../python" + COMMENT "Run pydpf smoke tests") +endif() + diff --git a/test/build-asan/CMakeCache.txt b/test/build-asan/CMakeCache.txt new file mode 100644 index 0000000..7265944 --- /dev/null +++ b/test/build-asan/CMakeCache.txt @@ -0,0 +1,638 @@ +# This is the CMakeCache file. +# For build in directory: /home/cryptolicious/hushmap-specified/libdpf/test/build-asan +# It was generated by CMake: /usr/bin/cmake +# You can edit this file to change values found and used by cmake. +# If you do not want to change any of the values, simply exit the editor. +# If you do want to change a value, simply edit, save, and exit the editor. +# The syntax for the file is as follows: +# KEY:TYPE=VALUE +# KEY is the name of a variable in the cache. +# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!. +# VALUE is the current value for the KEY. + +######################## +# EXTERNAL cache entries +######################## + +//Builds the googlemock subproject +BUILD_GMOCK:BOOL=OFF + +//Path to a program. +CMAKE_ADDR2LINE:FILEPATH=/usr/bin/addr2line + +//Path to a program. +CMAKE_AR:FILEPATH=/usr/bin/ar + +//Choose the type of build, options are: None Debug Release RelWithDebInfo +// MinSizeRel ... +CMAKE_BUILD_TYPE:STRING=Debug + +//Enable/Disable color output during build. +CMAKE_COLOR_MAKEFILE:BOOL=ON + +//CXX compiler +CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++ + +//A wrapper around 'ar' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-15 + +//A wrapper around 'ranlib' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-15 + +//Flags used by the CXX compiler during all build types. +CMAKE_CXX_FLAGS:STRING=-fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 + +//Flags used by the CXX compiler during DEBUG builds. +CMAKE_CXX_FLAGS_DEBUG:STRING=-g + +//Flags used by the CXX compiler during MINSIZEREL builds. +CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG + +//Flags used by the CXX compiler during RELEASE builds. +CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG + +//Flags used by the CXX compiler during RELWITHDEBINFO builds. +CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG + +//C compiler +CMAKE_C_COMPILER:FILEPATH=/usr/bin/cc + +//A wrapper around 'ar' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-15 + +//A wrapper around 'ranlib' adding the appropriate '--plugin' option +// for the GCC compiler +CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-15 + +//Flags used by the C compiler during all build types. +CMAKE_C_FLAGS:STRING= + +//Flags used by the C compiler during DEBUG builds. +CMAKE_C_FLAGS_DEBUG:STRING=-g + +//Flags used by the C compiler during MINSIZEREL builds. +CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG + +//Flags used by the C compiler during RELEASE builds. +CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG + +//Flags used by the C compiler during RELWITHDEBINFO builds. +CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG + +//Path to a program. +CMAKE_DLLTOOL:FILEPATH=CMAKE_DLLTOOL-NOTFOUND + +//Flags used by the linker during all build types. +CMAKE_EXE_LINKER_FLAGS:STRING=-fsanitize=address,undefined + +//Flags used by the linker during DEBUG builds. +CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during MINSIZEREL builds. +CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during RELEASE builds. +CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during RELWITHDEBINFO builds. +CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Enable/Disable output of compile commands during generation. +CMAKE_EXPORT_COMPILE_COMMANDS:BOOL= + +//Value Computed by CMake. +CMAKE_FIND_PACKAGE_REDIRECTS_DIR:STATIC=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/pkgRedirects + +//User executables (bin) +CMAKE_INSTALL_BINDIR:PATH=bin + +//Read-only architecture-independent data (DATAROOTDIR) +CMAKE_INSTALL_DATADIR:PATH= + +//Read-only architecture-independent data root (share) +CMAKE_INSTALL_DATAROOTDIR:PATH=share + +//Documentation root (DATAROOTDIR/doc/PROJECT_NAME) +CMAKE_INSTALL_DOCDIR:PATH= + +//C header files (include) +CMAKE_INSTALL_INCLUDEDIR:PATH=include + +//Info documentation (DATAROOTDIR/info) +CMAKE_INSTALL_INFODIR:PATH= + +//Object code libraries (lib) +CMAKE_INSTALL_LIBDIR:PATH=lib + +//Program executables (libexec) +CMAKE_INSTALL_LIBEXECDIR:PATH=libexec + +//Locale-dependent data (DATAROOTDIR/locale) +CMAKE_INSTALL_LOCALEDIR:PATH= + +//Modifiable single-machine data (var) +CMAKE_INSTALL_LOCALSTATEDIR:PATH=var + +//Man documentation (DATAROOTDIR/man) +CMAKE_INSTALL_MANDIR:PATH= + +//C header files for non-gcc (/usr/include) +CMAKE_INSTALL_OLDINCLUDEDIR:PATH=/usr/include + +//Install path prefix, prepended onto install directories. +CMAKE_INSTALL_PREFIX:PATH=/usr/local + +//Run-time variable data (LOCALSTATEDIR/run) +CMAKE_INSTALL_RUNSTATEDIR:PATH= + +//System admin executables (sbin) +CMAKE_INSTALL_SBINDIR:PATH=sbin + +//Modifiable architecture-independent data (com) +CMAKE_INSTALL_SHAREDSTATEDIR:PATH=com + +//Read-only single-machine data (etc) +CMAKE_INSTALL_SYSCONFDIR:PATH=etc + +//Path to a program. +CMAKE_LINKER:FILEPATH=/usr/bin/ld + +//Path to a program. +CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/gmake + +//Flags used by the linker during the creation of modules during +// all build types. +CMAKE_MODULE_LINKER_FLAGS:STRING= + +//Flags used by the linker during the creation of modules during +// DEBUG builds. +CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during the creation of modules during +// MINSIZEREL builds. +CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during the creation of modules during +// RELEASE builds. +CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during the creation of modules during +// RELWITHDEBINFO builds. +CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Path to a program. +CMAKE_NM:FILEPATH=/usr/bin/nm + +//Path to a program. +CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy + +//Path to a program. +CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump + +//Value Computed by CMake +CMAKE_PROJECT_COMPAT_VERSION:STATIC= + +//Value Computed by CMake +CMAKE_PROJECT_DESCRIPTION:STATIC= + +//Value Computed by CMake +CMAKE_PROJECT_HOMEPAGE_URL:STATIC= + +//Value Computed by CMake +CMAKE_PROJECT_NAME:STATIC=libdpf_test + +//Value Computed by CMake +CMAKE_PROJECT_SPDX_LICENSE:STATIC= + +//Value Computed by CMake +CMAKE_PROJECT_VERSION:STATIC=1.18.0 + +//Value Computed by CMake +CMAKE_PROJECT_VERSION_MAJOR:STATIC=1 + +//Value Computed by CMake +CMAKE_PROJECT_VERSION_MINOR:STATIC=18 + +//Value Computed by CMake +CMAKE_PROJECT_VERSION_PATCH:STATIC=0 + +//Value Computed by CMake +CMAKE_PROJECT_VERSION_TWEAK:STATIC= + +//Path to a program. +CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib + +//Path to a program. +CMAKE_READELF:FILEPATH=/usr/bin/readelf + +//Flags used by the linker during the creation of shared libraries +// during all build types. +CMAKE_SHARED_LINKER_FLAGS:STRING= + +//Flags used by the linker during the creation of shared libraries +// during DEBUG builds. +CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the linker during the creation of shared libraries +// during MINSIZEREL builds. +CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the linker during the creation of shared libraries +// during RELEASE builds. +CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the linker during the creation of shared libraries +// during RELWITHDEBINFO builds. +CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//If set, runtime paths are not added when installing shared libraries, +// but are added when building. +CMAKE_SKIP_INSTALL_RPATH:BOOL=NO + +//If set, runtime paths are not added when using shared libraries. +CMAKE_SKIP_RPATH:BOOL=NO + +//Flags used by the archiver during the creation of static libraries +// during all build types. +CMAKE_STATIC_LINKER_FLAGS:STRING= + +//Flags used by the archiver during the creation of static libraries +// during DEBUG builds. +CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING= + +//Flags used by the archiver during the creation of static libraries +// during MINSIZEREL builds. +CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING= + +//Flags used by the archiver during the creation of static libraries +// during RELEASE builds. +CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING= + +//Flags used by the archiver during the creation of static libraries +// during RELWITHDEBINFO builds. +CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING= + +//Path to a program. +CMAKE_STRIP:FILEPATH=/usr/bin/strip + +//Path to a program. +CMAKE_TAPI:FILEPATH=CMAKE_TAPI-NOTFOUND + +//If this value is on, makefiles will be generated without the +// .SILENT directive, and all commands will be echoed to the console +// during the make. This is useful for debugging only. With Visual +// Studio IDE projects all commands are done without /nologo. +CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE + +//Compile with coverage instrumentation +COVERAGE:BOOL=OFF + +//Use Abseil and RE2. Requires Abseil and RE2 to be separately +// added to the build. +GTEST_HAS_ABSL:BOOL=OFF + +//Enable installation of googletest. (Projects embedding googletest +// may want to turn this OFF.) +INSTALL_GTEST:BOOL=OFF + +//PGO for profile harnesses and party binaries: OFF, generate, +// or use +LIBDPF_PGO:STRING=OFF + +//Directory for GCC .gcda profile data +LIBDPF_PGO_DIR:PATH=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/pgo + +//Build the optional pybind11 pydpf module +LIBDPF_PYTHON:BOOL=OFF + +//Path to a library. +OPENSSL_CRYPTO_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcrypto.so + +//Path to a file. +OPENSSL_INCLUDE_DIR:PATH=/usr/include + +//Path to a library. +OPENSSL_SSL_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libssl.so + +//Arguments to supply to pkg-config +PKG_CONFIG_ARGN:STRING= + +//pkg-config executable +PKG_CONFIG_EXECUTABLE:FILEPATH=/usr/bin/pkg-config + +//Path to a library. +SCTP_LIB:FILEPATH=/usr/lib/x86_64-linux-gnu/libsctp.so + +//Value Computed by CMake +googletest-distribution_BINARY_DIR:STATIC=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest + +//Value Computed by CMake +googletest-distribution_IS_TOP_LEVEL:STATIC=OFF + +//Value Computed by CMake +googletest-distribution_SOURCE_DIR:STATIC=/home/cryptolicious/hushmap-specified/libdpf/test/googletest + +//Value Computed by CMake +gtest_BINARY_DIR:STATIC=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest + +//Value Computed by CMake +gtest_IS_TOP_LEVEL:STATIC=OFF + +//Value Computed by CMake +gtest_SOURCE_DIR:STATIC=/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +//Build gtest's sample programs. +gtest_build_samples:BOOL=OFF + +//Build all of gtest's own tests. +gtest_build_tests:BOOL=OFF + +//Disable uses of pthreads in gtest. +gtest_disable_pthreads:BOOL=OFF + +//Use shared (DLL) run-time lib even when Google Test is built +// as static lib. +gtest_force_shared_crt:BOOL=OFF + +//Build gtest with internal symbols hidden in shared libraries. +gtest_hide_internal_symbols:BOOL=OFF + +//Value Computed by CMake +libdpf_test_BINARY_DIR:STATIC=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +//Value Computed by CMake +libdpf_test_IS_TOP_LEVEL:STATIC=ON + +//Value Computed by CMake +libdpf_test_SOURCE_DIR:STATIC=/home/cryptolicious/hushmap-specified/libdpf/test + +//Dependencies for the target +party_flows_LIB_DEPENDS:STATIC=general;gtest_main;general;bsd;general;/usr/lib/x86_64-linux-gnu/libsctp.so;general;OpenSSL::SSL;general;OpenSSL::Crypto;general;bsd;general;pthread; + +//Path to a library. +pkgcfg_lib__OPENSSL_crypto:FILEPATH=/usr/lib/x86_64-linux-gnu/libcrypto.so + +//Path to a library. +pkgcfg_lib__OPENSSL_ssl:FILEPATH=/usr/lib/x86_64-linux-gnu/libssl.so + + +######################## +# INTERNAL cache entries +######################## + +//ADVANCED property for variable: CMAKE_ADDR2LINE +CMAKE_ADDR2LINE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_AR +CMAKE_AR-ADVANCED:INTERNAL=1 +//This is the directory where this CMakeCache.txt was created +CMAKE_CACHEFILE_DIR:INTERNAL=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan +//Major version of cmake used to create the current loaded cache +CMAKE_CACHE_MAJOR_VERSION:INTERNAL=4 +//Minor version of cmake used to create the current loaded cache +CMAKE_CACHE_MINOR_VERSION:INTERNAL=2 +//Patch version of cmake used to create the current loaded cache +CMAKE_CACHE_PATCH_VERSION:INTERNAL=3 +//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE +CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1 +//Path to CMake executable. +CMAKE_COMMAND:INTERNAL=/usr/bin/cmake +//Path to cpack program executable. +CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack +//Path to ctest program executable. +CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest +//ADVANCED property for variable: CMAKE_CXX_COMPILER +CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR +CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB +CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS +CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG +CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL +CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE +CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO +CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER +CMAKE_C_COMPILER-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER_AR +CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB +CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS +CMAKE_C_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG +CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL +CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE +CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO +CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_DLLTOOL +CMAKE_DLLTOOL-ADVANCED:INTERNAL=1 +//Executable file format +CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS +CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG +CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL +CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE +CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS +CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1 +//Name of external makefile project generator. +CMAKE_EXTRA_GENERATOR:INTERNAL= +//Name of generator. +CMAKE_GENERATOR:INTERNAL=Unix Makefiles +//Generator instance identifier. +CMAKE_GENERATOR_INSTANCE:INTERNAL= +//Name of generator platform. +CMAKE_GENERATOR_PLATFORM:INTERNAL= +//Name of generator toolset. +CMAKE_GENERATOR_TOOLSET:INTERNAL= +//Test CMAKE_HAVE_LIBC_PTHREAD +CMAKE_HAVE_LIBC_PTHREAD:INTERNAL=1 +//Source directory with the top level CMakeLists.txt file for this +// project +CMAKE_HOME_DIRECTORY:INTERNAL=/home/cryptolicious/hushmap-specified/libdpf/test +//ADVANCED property for variable: CMAKE_INSTALL_BINDIR +CMAKE_INSTALL_BINDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_DATADIR +CMAKE_INSTALL_DATADIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_DATAROOTDIR +CMAKE_INSTALL_DATAROOTDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_DOCDIR +CMAKE_INSTALL_DOCDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_INCLUDEDIR +CMAKE_INSTALL_INCLUDEDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_INFODIR +CMAKE_INSTALL_INFODIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_LIBDIR +CMAKE_INSTALL_LIBDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_LIBEXECDIR +CMAKE_INSTALL_LIBEXECDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_LOCALEDIR +CMAKE_INSTALL_LOCALEDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_LOCALSTATEDIR +CMAKE_INSTALL_LOCALSTATEDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_MANDIR +CMAKE_INSTALL_MANDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_OLDINCLUDEDIR +CMAKE_INSTALL_OLDINCLUDEDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_RUNSTATEDIR +CMAKE_INSTALL_RUNSTATEDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_SBINDIR +CMAKE_INSTALL_SBINDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_SHAREDSTATEDIR +CMAKE_INSTALL_SHAREDSTATEDIR-ADVANCED:INTERNAL=1 +//Install .so files without execute permission. +CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1 +//ADVANCED property for variable: CMAKE_INSTALL_SYSCONFDIR +CMAKE_INSTALL_SYSCONFDIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_LINKER +CMAKE_LINKER-ADVANCED:INTERNAL=1 +//Name of CMakeLists files to read +CMAKE_LIST_FILE_NAME:INTERNAL=CMakeLists.txt +//ADVANCED property for variable: CMAKE_MAKE_PROGRAM +CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS +CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG +CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL +CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE +CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_NM +CMAKE_NM-ADVANCED:INTERNAL=1 +//number of local generators +CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=3 +//ADVANCED property for variable: CMAKE_OBJCOPY +CMAKE_OBJCOPY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_OBJDUMP +CMAKE_OBJDUMP-ADVANCED:INTERNAL=1 +//Platform information initialized +CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_RANLIB +CMAKE_RANLIB-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_READELF +CMAKE_READELF-ADVANCED:INTERNAL=1 +//Path to CMake installation. +CMAKE_ROOT:INTERNAL=/usr/share/cmake-4.2 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS +CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG +CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL +CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE +CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH +CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_SKIP_RPATH +CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS +CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG +CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL +CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE +CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO +CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_STRIP +CMAKE_STRIP-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: CMAKE_TAPI +CMAKE_TAPI-ADVANCED:INTERNAL=1 +//uname command +CMAKE_UNAME:INTERNAL=/usr/bin/uname +//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE +CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1 +//Details about finding OpenSSL +FIND_PACKAGE_MESSAGE_DETAILS_OpenSSL:INTERNAL=[/usr/lib/x86_64-linux-gnu/libcrypto.so][/usr/include][ ][v3.5.5()] +//Details about finding Threads +FIND_PACKAGE_MESSAGE_DETAILS_Threads:INTERNAL=[TRUE][v()] +//STRINGS property for variable: LIBDPF_PGO +LIBDPF_PGO-STRINGS:INTERNAL=OFF;generate;use +//ADVANCED property for variable: OPENSSL_CRYPTO_LIBRARY +OPENSSL_CRYPTO_LIBRARY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: OPENSSL_INCLUDE_DIR +OPENSSL_INCLUDE_DIR-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: OPENSSL_SSL_LIBRARY +OPENSSL_SSL_LIBRARY-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: PKG_CONFIG_ARGN +PKG_CONFIG_ARGN-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: PKG_CONFIG_EXECUTABLE +PKG_CONFIG_EXECUTABLE-ADVANCED:INTERNAL=1 +//CMAKE_INSTALL_PREFIX during last run +_GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX:INTERNAL=/usr/local +_OPENSSL_CFLAGS:INTERNAL=-I/usr/include +_OPENSSL_CFLAGS_I:INTERNAL= +_OPENSSL_CFLAGS_OTHER:INTERNAL= +_OPENSSL_FOUND:INTERNAL=1 +_OPENSSL_INCLUDEDIR:INTERNAL=/usr/include +_OPENSSL_INCLUDE_DIRS:INTERNAL=/usr/include +_OPENSSL_LDFLAGS:INTERNAL=-L/usr/lib/x86_64-linux-gnu;-lssl;-lcrypto +_OPENSSL_LDFLAGS_OTHER:INTERNAL= +_OPENSSL_LIBDIR:INTERNAL=/usr/lib/x86_64-linux-gnu +_OPENSSL_LIBRARIES:INTERNAL=ssl;crypto +_OPENSSL_LIBRARY_DIRS:INTERNAL=/usr/lib/x86_64-linux-gnu +_OPENSSL_LIBS:INTERNAL= +_OPENSSL_LIBS_L:INTERNAL= +_OPENSSL_LIBS_OTHER:INTERNAL= +_OPENSSL_LIBS_PATHS:INTERNAL= +_OPENSSL_MODULE_NAME:INTERNAL=openssl +_OPENSSL_PREFIX:INTERNAL=/usr +_OPENSSL_STATIC_CFLAGS:INTERNAL=-I/usr/include +_OPENSSL_STATIC_CFLAGS_I:INTERNAL= +_OPENSSL_STATIC_CFLAGS_OTHER:INTERNAL= +_OPENSSL_STATIC_INCLUDE_DIRS:INTERNAL=/usr/include +_OPENSSL_STATIC_LDFLAGS:INTERNAL=-L/usr/lib/x86_64-linux-gnu;-lssl;-lcrypto;-l:libjitterentropy.a;-lz;-lzstd;-ldl;-pthread +_OPENSSL_STATIC_LDFLAGS_OTHER:INTERNAL=-pthread +_OPENSSL_STATIC_LIBDIR:INTERNAL= +_OPENSSL_STATIC_LIBRARIES:INTERNAL=ssl;crypto;:libjitterentropy.a;z;zstd;dl +_OPENSSL_STATIC_LIBRARY_DIRS:INTERNAL=/usr/lib/x86_64-linux-gnu +_OPENSSL_STATIC_LIBS:INTERNAL= +_OPENSSL_STATIC_LIBS_L:INTERNAL= +_OPENSSL_STATIC_LIBS_OTHER:INTERNAL= +_OPENSSL_STATIC_LIBS_PATHS:INTERNAL= +_OPENSSL_VERSION:INTERNAL=3.5.5 +_OPENSSL_openssl_INCLUDEDIR:INTERNAL= +_OPENSSL_openssl_LIBDIR:INTERNAL= +_OPENSSL_openssl_PREFIX:INTERNAL= +_OPENSSL_openssl_VERSION:INTERNAL= +__pkg_config_arguments__OPENSSL:INTERNAL=QUIET;openssl +__pkg_config_checked__OPENSSL:INTERNAL=1 +cmake_package_name:INTERNAL=GTest +//ADVANCED property for variable: gtest_build_samples +gtest_build_samples-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: gtest_build_tests +gtest_build_tests-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: gtest_disable_pthreads +gtest_disable_pthreads-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: gtest_force_shared_crt +gtest_force_shared_crt-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: gtest_hide_internal_symbols +gtest_hide_internal_symbols-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: pkgcfg_lib__OPENSSL_crypto +pkgcfg_lib__OPENSSL_crypto-ADVANCED:INTERNAL=1 +//ADVANCED property for variable: pkgcfg_lib__OPENSSL_ssl +pkgcfg_lib__OPENSSL_ssl-ADVANCED:INTERNAL=1 +prefix_result:INTERNAL=/usr/lib/x86_64-linux-gnu + diff --git a/test/build-asan/CMakeFiles/4.2.3/CMakeCCompiler.cmake b/test/build-asan/CMakeFiles/4.2.3/CMakeCCompiler.cmake new file mode 100644 index 0000000..6f97c55 --- /dev/null +++ b/test/build-asan/CMakeFiles/4.2.3/CMakeCCompiler.cmake @@ -0,0 +1,84 @@ +set(CMAKE_C_COMPILER "/usr/bin/cc") +set(CMAKE_C_COMPILER_ARG1 "") +set(CMAKE_C_COMPILER_ID "GNU") +set(CMAKE_C_COMPILER_VERSION "15.2.0") +set(CMAKE_C_COMPILER_VERSION_INTERNAL "") +set(CMAKE_C_COMPILER_WRAPPER "") +set(CMAKE_C_STANDARD_COMPUTED_DEFAULT "23") +set(CMAKE_C_EXTENSIONS_COMPUTED_DEFAULT "ON") +set(CMAKE_C_STANDARD_LATEST "23") +set(CMAKE_C_COMPILE_FEATURES "c_std_90;c_function_prototypes;c_std_99;c_restrict;c_variadic_macros;c_std_11;c_static_assert;c_std_17;c_std_23") +set(CMAKE_C90_COMPILE_FEATURES "c_std_90;c_function_prototypes") +set(CMAKE_C99_COMPILE_FEATURES "c_std_99;c_restrict;c_variadic_macros") +set(CMAKE_C11_COMPILE_FEATURES "c_std_11;c_static_assert") +set(CMAKE_C17_COMPILE_FEATURES "c_std_17") +set(CMAKE_C23_COMPILE_FEATURES "c_std_23") + +set(CMAKE_C_PLATFORM_ID "Linux") +set(CMAKE_C_SIMULATE_ID "") +set(CMAKE_C_COMPILER_FRONTEND_VARIANT "GNU") +set(CMAKE_C_COMPILER_APPLE_SYSROOT "") +set(CMAKE_C_SIMULATE_VERSION "") +set(CMAKE_C_COMPILER_ARCHITECTURE_ID "x86_64") + + + +set(CMAKE_AR "/usr/bin/ar") +set(CMAKE_C_COMPILER_AR "/usr/bin/gcc-ar-15") +set(CMAKE_RANLIB "/usr/bin/ranlib") +set(CMAKE_C_COMPILER_RANLIB "/usr/bin/gcc-ranlib-15") +set(CMAKE_LINKER "/usr/bin/ld") +set(CMAKE_LINKER_LINK "") +set(CMAKE_LINKER_LLD "") +set(CMAKE_C_COMPILER_LINKER "/usr/bin/ld") +set(CMAKE_C_COMPILER_LINKER_ID "GNU") +set(CMAKE_C_COMPILER_LINKER_VERSION 2.46) +set(CMAKE_C_COMPILER_LINKER_FRONTEND_VARIANT GNU) +set(CMAKE_MT "") +set(CMAKE_TAPI "CMAKE_TAPI-NOTFOUND") +set(CMAKE_COMPILER_IS_GNUCC 1) +set(CMAKE_C_COMPILER_LOADED 1) +set(CMAKE_C_COMPILER_WORKS TRUE) +set(CMAKE_C_ABI_COMPILED TRUE) + +set(CMAKE_C_COMPILER_ENV_VAR "CC") + +set(CMAKE_C_COMPILER_ID_RUN 1) +set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m) +set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC) +set(CMAKE_C_LINKER_PREFERENCE 10) +set(CMAKE_C_LINKER_DEPFILE_SUPPORTED TRUE) +set(CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED TRUE) +set(CMAKE_C_LINKER_PUSHPOP_STATE_SUPPORTED TRUE) + +# Save compiler ABI information. +set(CMAKE_C_SIZEOF_DATA_PTR "8") +set(CMAKE_C_COMPILER_ABI "ELF") +set(CMAKE_C_BYTE_ORDER "LITTLE_ENDIAN") +set(CMAKE_C_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") + +if(CMAKE_C_SIZEOF_DATA_PTR) + set(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}") +endif() + +if(CMAKE_C_COMPILER_ABI) + set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}") +endif() + +if(CMAKE_C_LIBRARY_ARCHITECTURE) + set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") +endif() + +set(CMAKE_C_CL_SHOWINCLUDES_PREFIX "") +if(CMAKE_C_CL_SHOWINCLUDES_PREFIX) + set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_C_CL_SHOWINCLUDES_PREFIX}") +endif() + + + + + +set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/15/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include") +set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "asan;ubsan;gcc;gcc_s;c;gcc;gcc_s") +set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/15;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib") +set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") diff --git a/test/build-asan/CMakeFiles/4.2.3/CMakeCXXCompiler.cmake b/test/build-asan/CMakeFiles/4.2.3/CMakeCXXCompiler.cmake new file mode 100644 index 0000000..22478af --- /dev/null +++ b/test/build-asan/CMakeFiles/4.2.3/CMakeCXXCompiler.cmake @@ -0,0 +1,108 @@ +set(CMAKE_CXX_COMPILER "/usr/bin/c++") +set(CMAKE_CXX_COMPILER_ARG1 "") +set(CMAKE_CXX_COMPILER_ID "GNU") +set(CMAKE_CXX_COMPILER_VERSION "15.2.0") +set(CMAKE_CXX_COMPILER_VERSION_INTERNAL "") +set(CMAKE_CXX_COMPILER_WRAPPER "") +set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "17") +set(CMAKE_CXX_EXTENSIONS_COMPUTED_DEFAULT "ON") +set(CMAKE_CXX_STANDARD_LATEST "26") +set(CMAKE_CXX_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17;cxx_std_20;cxx_std_23;cxx_std_26") +set(CMAKE_CXX98_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters") +set(CMAKE_CXX11_COMPILE_FEATURES "cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates") +set(CMAKE_CXX14_COMPILE_FEATURES "cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates") +set(CMAKE_CXX17_COMPILE_FEATURES "cxx_std_17") +set(CMAKE_CXX20_COMPILE_FEATURES "cxx_std_20") +set(CMAKE_CXX23_COMPILE_FEATURES "cxx_std_23") +set(CMAKE_CXX26_COMPILE_FEATURES "cxx_std_26") + +set(CMAKE_CXX_PLATFORM_ID "Linux") +set(CMAKE_CXX_SIMULATE_ID "") +set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "GNU") +set(CMAKE_CXX_COMPILER_APPLE_SYSROOT "") +set(CMAKE_CXX_SIMULATE_VERSION "") +set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID "x86_64") + + + +set(CMAKE_AR "/usr/bin/ar") +set(CMAKE_CXX_COMPILER_AR "/usr/bin/gcc-ar-15") +set(CMAKE_RANLIB "/usr/bin/ranlib") +set(CMAKE_CXX_COMPILER_RANLIB "/usr/bin/gcc-ranlib-15") +set(CMAKE_LINKER "/usr/bin/ld") +set(CMAKE_LINKER_LINK "") +set(CMAKE_LINKER_LLD "") +set(CMAKE_CXX_COMPILER_LINKER "/usr/bin/ld") +set(CMAKE_CXX_COMPILER_LINKER_ID "GNU") +set(CMAKE_CXX_COMPILER_LINKER_VERSION 2.46) +set(CMAKE_CXX_COMPILER_LINKER_FRONTEND_VARIANT GNU) +set(CMAKE_MT "") +set(CMAKE_TAPI "CMAKE_TAPI-NOTFOUND") +set(CMAKE_COMPILER_IS_GNUCXX 1) +set(CMAKE_CXX_COMPILER_LOADED 1) +set(CMAKE_CXX_COMPILER_WORKS TRUE) +set(CMAKE_CXX_ABI_COMPILED TRUE) + +set(CMAKE_CXX_COMPILER_ENV_VAR "CXX") + +set(CMAKE_CXX_COMPILER_ID_RUN 1) +set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;mpp;CPP;ixx;cppm;ccm;cxxm;c++m) +set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC) + +foreach (lang IN ITEMS C OBJC OBJCXX) + if (CMAKE_${lang}_COMPILER_ID_RUN) + foreach(extension IN LISTS CMAKE_${lang}_SOURCE_FILE_EXTENSIONS) + list(REMOVE_ITEM CMAKE_CXX_SOURCE_FILE_EXTENSIONS ${extension}) + endforeach() + endif() +endforeach() + +set(CMAKE_CXX_LINKER_PREFERENCE 30) +set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1) +set(CMAKE_CXX_LINKER_DEPFILE_SUPPORTED TRUE) +set(CMAKE_LINKER_PUSHPOP_STATE_SUPPORTED TRUE) +set(CMAKE_CXX_LINKER_PUSHPOP_STATE_SUPPORTED TRUE) + +# Save compiler ABI information. +set(CMAKE_CXX_SIZEOF_DATA_PTR "8") +set(CMAKE_CXX_COMPILER_ABI "ELF") +set(CMAKE_CXX_BYTE_ORDER "LITTLE_ENDIAN") +set(CMAKE_CXX_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") + +if(CMAKE_CXX_SIZEOF_DATA_PTR) + set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}") +endif() + +if(CMAKE_CXX_COMPILER_ABI) + set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}") +endif() + +if(CMAKE_CXX_LIBRARY_ARCHITECTURE) + set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") +endif() + +set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "") +if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX) + set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}") +endif() + + + + + +set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include/c++/15;/usr/include/x86_64-linux-gnu/c++/15;/usr/include/c++/15/backward;/usr/lib/gcc/x86_64-linux-gnu/15/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include") +set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "asan;stdc++;m;ubsan;gcc_s;gcc;c;gcc_s;gcc") +set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/15;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib") +set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") +set(CMAKE_CXX_COMPILER_CLANG_RESOURCE_DIR "") + +set(CMAKE_CXX_COMPILER_IMPORT_STD "") +### Imported target for C++23 standard library +set(CMAKE_CXX23_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE "Unsupported generator: Unix Makefiles") + + +### Imported target for C++26 standard library +set(CMAKE_CXX26_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE "Unsupported generator: Unix Makefiles") + + + diff --git a/test/build-asan/CMakeFiles/4.2.3/CMakeDetermineCompilerABI_C.bin b/test/build-asan/CMakeFiles/4.2.3/CMakeDetermineCompilerABI_C.bin new file mode 100755 index 0000000..3edfc90 Binary files /dev/null and b/test/build-asan/CMakeFiles/4.2.3/CMakeDetermineCompilerABI_C.bin differ diff --git a/test/build-asan/CMakeFiles/4.2.3/CMakeDetermineCompilerABI_CXX.bin b/test/build-asan/CMakeFiles/4.2.3/CMakeDetermineCompilerABI_CXX.bin new file mode 100755 index 0000000..4d04bf9 Binary files /dev/null and b/test/build-asan/CMakeFiles/4.2.3/CMakeDetermineCompilerABI_CXX.bin differ diff --git a/test/build-asan/CMakeFiles/4.2.3/CMakeSystem.cmake b/test/build-asan/CMakeFiles/4.2.3/CMakeSystem.cmake new file mode 100644 index 0000000..e2dc0e4 --- /dev/null +++ b/test/build-asan/CMakeFiles/4.2.3/CMakeSystem.cmake @@ -0,0 +1,15 @@ +set(CMAKE_HOST_SYSTEM "Linux-7.0.0-29-generic") +set(CMAKE_HOST_SYSTEM_NAME "Linux") +set(CMAKE_HOST_SYSTEM_VERSION "7.0.0-29-generic") +set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64") + + + +set(CMAKE_SYSTEM "Linux-7.0.0-29-generic") +set(CMAKE_SYSTEM_NAME "Linux") +set(CMAKE_SYSTEM_VERSION "7.0.0-29-generic") +set(CMAKE_SYSTEM_PROCESSOR "x86_64") + +set(CMAKE_CROSSCOMPILING "FALSE") + +set(CMAKE_SYSTEM_LOADED 1) diff --git a/test/build-asan/CMakeFiles/4.2.3/CompilerIdC/CMakeCCompilerId.c b/test/build-asan/CMakeFiles/4.2.3/CompilerIdC/CMakeCCompilerId.c new file mode 100644 index 0000000..ab3c359 --- /dev/null +++ b/test/build-asan/CMakeFiles/4.2.3/CompilerIdC/CMakeCCompilerId.c @@ -0,0 +1,934 @@ +#ifdef __cplusplus +# error "A C++ compiler has been selected for C." +#endif + +#if defined(__18CXX) +# define ID_VOID_MAIN +#endif +#if defined(__CLASSIC_C__) +/* cv-qualifiers did not exist in K&R C */ +# define const +# define volatile +#endif + +#if !defined(__has_include) +/* If the compiler does not have __has_include, pretend the answer is + always no. */ +# define __has_include(x) 0 +#endif + + +/* Version number components: V=Version, R=Revision, P=Patch + Version date components: YYYY=Year, MM=Month, DD=Day */ + +#if defined(__INTEL_COMPILER) || defined(__ICC) +# define COMPILER_ID "Intel" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# if defined(__GNUC__) +# define SIMULATE_ID "GNU" +# endif + /* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later, + except that a few beta releases use the old format with V=2021. */ +# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111 +# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100) +# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10) +# if defined(__INTEL_COMPILER_UPDATE) +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE) +# else +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10) +# endif +# else +# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER) +# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE) + /* The third version component from --version is an update index, + but no macro is provided for it. */ +# define COMPILER_VERSION_PATCH DEC(0) +# endif +# if defined(__INTEL_COMPILER_BUILD_DATE) + /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */ +# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE) +# endif +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif +# if defined(__GNUC__) +# define SIMULATE_VERSION_MAJOR DEC(__GNUC__) +# elif defined(__GNUG__) +# define SIMULATE_VERSION_MAJOR DEC(__GNUG__) +# endif +# if defined(__GNUC_MINOR__) +# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__) +# endif +# if defined(__GNUC_PATCHLEVEL__) +# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif + +#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER) +# define COMPILER_ID "IntelLLVM" +#if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +#endif +#if defined(__GNUC__) +# define SIMULATE_ID "GNU" +#endif +/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and + * later. Look for 6 digit vs. 8 digit version number to decide encoding. + * VVVV is no smaller than the current year when a version is released. + */ +#if __INTEL_LLVM_COMPILER < 1000000L +# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100) +# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10) +#else +# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000) +# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100) +# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100) +#endif +#if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +#endif +#if defined(__GNUC__) +# define SIMULATE_VERSION_MAJOR DEC(__GNUC__) +#elif defined(__GNUG__) +# define SIMULATE_VERSION_MAJOR DEC(__GNUG__) +#endif +#if defined(__GNUC_MINOR__) +# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__) +#endif +#if defined(__GNUC_PATCHLEVEL__) +# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +#endif + +#elif defined(__PATHCC__) +# define COMPILER_ID "PathScale" +# define COMPILER_VERSION_MAJOR DEC(__PATHCC__) +# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__) +# if defined(__PATHCC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__) +# endif + +#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) +# define COMPILER_ID "Embarcadero" +# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF) +# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) +# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF) + +#elif defined(__BORLANDC__) +# define COMPILER_ID "Borland" + /* __BORLANDC__ = 0xVRR */ +# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8) +# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF) + +#elif defined(__WATCOMC__) && __WATCOMC__ < 1200 +# define COMPILER_ID "Watcom" + /* __WATCOMC__ = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100) +# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) +# if (__WATCOMC__ % 10) > 0 +# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) +# endif + +#elif defined(__WATCOMC__) +# define COMPILER_ID "OpenWatcom" + /* __WATCOMC__ = VVRP + 1100 */ +# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100) +# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) +# if (__WATCOMC__ % 10) > 0 +# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) +# endif + +#elif defined(__SUNPRO_C) +# define COMPILER_ID "SunPro" +# if __SUNPRO_C >= 0x5100 + /* __SUNPRO_C = 0xVRRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF) +# else + /* __SUNPRO_CC = 0xVRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF) +# endif + +#elif defined(__HP_cc) +# define COMPILER_ID "HP" + /* __HP_cc = VVRRPP */ +# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000) +# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100) +# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100) + +#elif defined(__DECC) +# define COMPILER_ID "Compaq" + /* __DECC_VER = VVRRTPPPP */ +# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000) +# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100) +# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000) + +#elif defined(__IBMC__) && defined(__COMPILER_VER__) +# define COMPILER_ID "zOS" + /* __IBMC__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) + +#elif defined(__open_xl__) && defined(__clang__) +# define COMPILER_ID "IBMClang" +# define COMPILER_VERSION_MAJOR DEC(__open_xl_version__) +# define COMPILER_VERSION_MINOR DEC(__open_xl_release__) +# define COMPILER_VERSION_PATCH DEC(__open_xl_modification__) +# define COMPILER_VERSION_TWEAK DEC(__open_xl_ptf_fix_level__) +# define COMPILER_VERSION_INTERNAL_STR __clang_version__ + + +#elif defined(__ibmxl__) && defined(__clang__) +# define COMPILER_ID "XLClang" +# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__) +# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__) +# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__) +# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__) + + +#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ >= 800 +# define COMPILER_ID "XL" + /* __IBMC__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) + +#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ < 800 +# define COMPILER_ID "VisualAge" + /* __IBMC__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) + +#elif defined(__NVCOMPILER) +# define COMPILER_ID "NVHPC" +# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__) +# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__) +# if defined(__NVCOMPILER_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__) +# endif + +#elif defined(__PGI) +# define COMPILER_ID "PGI" +# define COMPILER_VERSION_MAJOR DEC(__PGIC__) +# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) +# endif + +#elif defined(__clang__) && defined(__cray__) +# define COMPILER_ID "CrayClang" +# define COMPILER_VERSION_MAJOR DEC(__cray_major__) +# define COMPILER_VERSION_MINOR DEC(__cray_minor__) +# define COMPILER_VERSION_PATCH DEC(__cray_patchlevel__) +# define COMPILER_VERSION_INTERNAL_STR __clang_version__ + + +#elif defined(_CRAYC) +# define COMPILER_ID "Cray" +# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR) +# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR) + +#elif defined(__TI_COMPILER_VERSION__) +# define COMPILER_ID "TI" + /* __TI_COMPILER_VERSION__ = VVVRRRPPP */ +# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000) +# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000) +# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000) + +#elif defined(__CLANG_FUJITSU) +# define COMPILER_ID "FujitsuClang" +# define COMPILER_VERSION_MAJOR DEC(__FCC_major__) +# define COMPILER_VERSION_MINOR DEC(__FCC_minor__) +# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__) +# define COMPILER_VERSION_INTERNAL_STR __clang_version__ + + +#elif defined(__FUJITSU) +# define COMPILER_ID "Fujitsu" +# if defined(__FCC_version__) +# define COMPILER_VERSION __FCC_version__ +# elif defined(__FCC_major__) +# define COMPILER_VERSION_MAJOR DEC(__FCC_major__) +# define COMPILER_VERSION_MINOR DEC(__FCC_minor__) +# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__) +# endif +# if defined(__fcc_version) +# define COMPILER_VERSION_INTERNAL DEC(__fcc_version) +# elif defined(__FCC_VERSION) +# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION) +# endif + + +#elif defined(__ghs__) +# define COMPILER_ID "GHS" +/* __GHS_VERSION_NUMBER = VVVVRP */ +# ifdef __GHS_VERSION_NUMBER +# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100) +# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10) +# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10) +# endif + +#elif defined(__TASKING__) +# define COMPILER_ID "Tasking" + # define COMPILER_VERSION_MAJOR DEC(__VERSION__/1000) + # define COMPILER_VERSION_MINOR DEC(__VERSION__ % 100) +# define COMPILER_VERSION_INTERNAL DEC(__VERSION__) + +#elif defined(__ORANGEC__) +# define COMPILER_ID "OrangeC" +# define COMPILER_VERSION_MAJOR DEC(__ORANGEC_MAJOR__) +# define COMPILER_VERSION_MINOR DEC(__ORANGEC_MINOR__) +# define COMPILER_VERSION_PATCH DEC(__ORANGEC_PATCHLEVEL__) + +#elif defined(__RENESAS__) +# define COMPILER_ID "Renesas" +/* __RENESAS_VERSION__ = 0xVVRRPP00 */ +# define COMPILER_VERSION_MAJOR HEX(__RENESAS_VERSION__ >> 24 & 0xFF) +# define COMPILER_VERSION_MINOR HEX(__RENESAS_VERSION__ >> 16 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__RENESAS_VERSION__ >> 8 & 0xFF) + +#elif defined(__TINYC__) +# define COMPILER_ID "TinyCC" + +#elif defined(__BCC__) +# define COMPILER_ID "Bruce" + +#elif defined(__SCO_VERSION__) +# define COMPILER_ID "SCO" + +#elif defined(__ARMCC_VERSION) && !defined(__clang__) +# define COMPILER_ID "ARMCC" +#if __ARMCC_VERSION >= 1000000 + /* __ARMCC_VERSION = VRRPPPP */ + # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000) + # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100) + # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) +#else + /* __ARMCC_VERSION = VRPPPP */ + # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000) + # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10) + # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) +#endif + + +#elif defined(__clang__) && defined(__apple_build_version__) +# define COMPILER_ID "AppleClang" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# define COMPILER_VERSION_MAJOR DEC(__clang_major__) +# define COMPILER_VERSION_MINOR DEC(__clang_minor__) +# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif +# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__) + +#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION) +# define COMPILER_ID "ARMClang" + # define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000) + # define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100) + # define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION/100 % 100) +# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION) + +#elif defined(__clang__) && defined(__ti__) +# define COMPILER_ID "TIClang" + # define COMPILER_VERSION_MAJOR DEC(__ti_major__) + # define COMPILER_VERSION_MINOR DEC(__ti_minor__) + # define COMPILER_VERSION_PATCH DEC(__ti_patchlevel__) +# define COMPILER_VERSION_INTERNAL DEC(__ti_version__) + +#elif defined(__clang__) +# define COMPILER_ID "Clang" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# define COMPILER_VERSION_MAJOR DEC(__clang_major__) +# define COMPILER_VERSION_MINOR DEC(__clang_minor__) +# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif + +#elif defined(__LCC__) && (defined(__GNUC__) || defined(__GNUG__) || defined(__MCST__)) +# define COMPILER_ID "LCC" +# define COMPILER_VERSION_MAJOR DEC(__LCC__ / 100) +# define COMPILER_VERSION_MINOR DEC(__LCC__ % 100) +# if defined(__LCC_MINOR__) +# define COMPILER_VERSION_PATCH DEC(__LCC_MINOR__) +# endif +# if defined(__GNUC__) && defined(__GNUC_MINOR__) +# define SIMULATE_ID "GNU" +# define SIMULATE_VERSION_MAJOR DEC(__GNUC__) +# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__) +# if defined(__GNUC_PATCHLEVEL__) +# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif +# endif + +#elif defined(__GNUC__) +# define COMPILER_ID "GNU" +# define COMPILER_VERSION_MAJOR DEC(__GNUC__) +# if defined(__GNUC_MINOR__) +# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) +# endif +# if defined(__GNUC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif + +#elif defined(_MSC_VER) +# define COMPILER_ID "MSVC" + /* _MSC_VER = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100) +# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100) +# if defined(_MSC_FULL_VER) +# if _MSC_VER >= 1400 + /* _MSC_FULL_VER = VVRRPPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000) +# else + /* _MSC_FULL_VER = VVRRPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000) +# endif +# endif +# if defined(_MSC_BUILD) +# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD) +# endif + +#elif defined(_ADI_COMPILER) +# define COMPILER_ID "ADSP" +#if defined(__VERSIONNUM__) + /* __VERSIONNUM__ = 0xVVRRPPTT */ +# define COMPILER_VERSION_MAJOR DEC(__VERSIONNUM__ >> 24 & 0xFF) +# define COMPILER_VERSION_MINOR DEC(__VERSIONNUM__ >> 16 & 0xFF) +# define COMPILER_VERSION_PATCH DEC(__VERSIONNUM__ >> 8 & 0xFF) +# define COMPILER_VERSION_TWEAK DEC(__VERSIONNUM__ & 0xFF) +#endif + +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) +# define COMPILER_ID "IAR" +# if defined(__VER__) && defined(__ICCARM__) +# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000) +# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000) +# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000) +# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) +# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__)) +# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100) +# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100)) +# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__) +# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) +# endif + +#elif defined(__DCC__) && defined(_DIAB_TOOL) +# define COMPILER_ID "Diab" + # define COMPILER_VERSION_MAJOR DEC(__VERSION_MAJOR_NUMBER__) + # define COMPILER_VERSION_MINOR DEC(__VERSION_MINOR_NUMBER__) + # define COMPILER_VERSION_PATCH DEC(__VERSION_ARCH_FEATURE_NUMBER__) + # define COMPILER_VERSION_TWEAK DEC(__VERSION_BUG_FIX_NUMBER__) + + +#elif defined(__SDCC_VERSION_MAJOR) || defined(SDCC) +# define COMPILER_ID "SDCC" +# if defined(__SDCC_VERSION_MAJOR) +# define COMPILER_VERSION_MAJOR DEC(__SDCC_VERSION_MAJOR) +# define COMPILER_VERSION_MINOR DEC(__SDCC_VERSION_MINOR) +# define COMPILER_VERSION_PATCH DEC(__SDCC_VERSION_PATCH) +# else + /* SDCC = VRP */ +# define COMPILER_VERSION_MAJOR DEC(SDCC/100) +# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10) +# define COMPILER_VERSION_PATCH DEC(SDCC % 10) +# endif + + +/* These compilers are either not known or too old to define an + identification macro. Try to identify the platform and guess that + it is the native compiler. */ +#elif defined(__hpux) || defined(__hpua) +# define COMPILER_ID "HP" + +#else /* unknown compiler */ +# define COMPILER_ID "" +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; +#ifdef SIMULATE_ID +char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; +#endif + +#ifdef __QNXNTO__ +char const* qnxnto = "INFO" ":" "qnxnto[]"; +#endif + +#if defined(__CRAYXT_COMPUTE_LINUX_TARGET) +char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]"; +#endif + +#define STRINGIFY_HELPER(X) #X +#define STRINGIFY(X) STRINGIFY_HELPER(X) + +/* Identify known platforms by name. */ +#if defined(__linux) || defined(__linux__) || defined(linux) +# define PLATFORM_ID "Linux" + +#elif defined(__MSYS__) +# define PLATFORM_ID "MSYS" + +#elif defined(__CYGWIN__) +# define PLATFORM_ID "Cygwin" + +#elif defined(__MINGW32__) +# define PLATFORM_ID "MinGW" + +#elif defined(__APPLE__) +# define PLATFORM_ID "Darwin" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +# define PLATFORM_ID "Windows" + +#elif defined(__FreeBSD__) || defined(__FreeBSD) +# define PLATFORM_ID "FreeBSD" + +#elif defined(__NetBSD__) || defined(__NetBSD) +# define PLATFORM_ID "NetBSD" + +#elif defined(__OpenBSD__) || defined(__OPENBSD) +# define PLATFORM_ID "OpenBSD" + +#elif defined(__sun) || defined(sun) +# define PLATFORM_ID "SunOS" + +#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) +# define PLATFORM_ID "AIX" + +#elif defined(__hpux) || defined(__hpux__) +# define PLATFORM_ID "HP-UX" + +#elif defined(__HAIKU__) +# define PLATFORM_ID "Haiku" + +#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) +# define PLATFORM_ID "BeOS" + +#elif defined(__QNX__) || defined(__QNXNTO__) +# define PLATFORM_ID "QNX" + +#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) +# define PLATFORM_ID "Tru64" + +#elif defined(__riscos) || defined(__riscos__) +# define PLATFORM_ID "RISCos" + +#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) +# define PLATFORM_ID "SINIX" + +#elif defined(__UNIX_SV__) +# define PLATFORM_ID "UNIX_SV" + +#elif defined(__bsdos__) +# define PLATFORM_ID "BSDOS" + +#elif defined(_MPRAS) || defined(MPRAS) +# define PLATFORM_ID "MP-RAS" + +#elif defined(__osf) || defined(__osf__) +# define PLATFORM_ID "OSF1" + +#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) +# define PLATFORM_ID "SCO_SV" + +#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) +# define PLATFORM_ID "ULTRIX" + +#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) +# define PLATFORM_ID "Xenix" + +#elif defined(__WATCOMC__) +# if defined(__LINUX__) +# define PLATFORM_ID "Linux" + +# elif defined(__DOS__) +# define PLATFORM_ID "DOS" + +# elif defined(__OS2__) +# define PLATFORM_ID "OS2" + +# elif defined(__WINDOWS__) +# define PLATFORM_ID "Windows3x" + +# elif defined(__VXWORKS__) +# define PLATFORM_ID "VxWorks" + +# else /* unknown platform */ +# define PLATFORM_ID +# endif + +#elif defined(__INTEGRITY) +# if defined(INT_178B) +# define PLATFORM_ID "Integrity178" + +# else /* regular Integrity */ +# define PLATFORM_ID "Integrity" +# endif + +# elif defined(_ADI_COMPILER) +# define PLATFORM_ID "ADSP" + +#else /* unknown platform */ +# define PLATFORM_ID + +#endif + +/* For windows compilers MSVC and Intel we can determine + the architecture of the compiler being used. This is because + the compilers do not have flags that can change the architecture, + but rather depend on which compiler is being used +*/ +#if defined(_WIN32) && defined(_MSC_VER) +# if defined(_M_IA64) +# define ARCHITECTURE_ID "IA64" + +# elif defined(_M_ARM64EC) +# define ARCHITECTURE_ID "ARM64EC" + +# elif defined(_M_X64) || defined(_M_AMD64) +# define ARCHITECTURE_ID "x64" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# elif defined(_M_ARM64) +# define ARCHITECTURE_ID "ARM64" + +# elif defined(_M_ARM) +# if _M_ARM == 4 +# define ARCHITECTURE_ID "ARMV4I" +# elif _M_ARM == 5 +# define ARCHITECTURE_ID "ARMV5I" +# else +# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM) +# endif + +# elif defined(_M_MIPS) +# define ARCHITECTURE_ID "MIPS" + +# elif defined(_M_SH) +# define ARCHITECTURE_ID "SHx" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__WATCOMC__) +# if defined(_M_I86) +# define ARCHITECTURE_ID "I86" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) +# if defined(__ICCARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__ICCRX__) +# define ARCHITECTURE_ID "RX" + +# elif defined(__ICCRH850__) +# define ARCHITECTURE_ID "RH850" + +# elif defined(__ICCRL78__) +# define ARCHITECTURE_ID "RL78" + +# elif defined(__ICCRISCV__) +# define ARCHITECTURE_ID "RISCV" + +# elif defined(__ICCAVR__) +# define ARCHITECTURE_ID "AVR" + +# elif defined(__ICC430__) +# define ARCHITECTURE_ID "MSP430" + +# elif defined(__ICCV850__) +# define ARCHITECTURE_ID "V850" + +# elif defined(__ICC8051__) +# define ARCHITECTURE_ID "8051" + +# elif defined(__ICCSTM8__) +# define ARCHITECTURE_ID "STM8" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__ghs__) +# if defined(__PPC64__) +# define ARCHITECTURE_ID "PPC64" + +# elif defined(__ppc__) +# define ARCHITECTURE_ID "PPC" + +# elif defined(__ARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__x86_64__) +# define ARCHITECTURE_ID "x64" + +# elif defined(__i386__) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__clang__) && defined(__ti__) +# if defined(__ARM_ARCH) +# define ARCHITECTURE_ID "ARM" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__TI_COMPILER_VERSION__) +# if defined(__TI_ARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__MSP430__) +# define ARCHITECTURE_ID "MSP430" + +# elif defined(__TMS320C28XX__) +# define ARCHITECTURE_ID "TMS320C28x" + +# elif defined(__TMS320C6X__) || defined(_TMS320C6X) +# define ARCHITECTURE_ID "TMS320C6x" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +# elif defined(__ADSPSHARC__) +# define ARCHITECTURE_ID "SHARC" + +# elif defined(__ADSPBLACKFIN__) +# define ARCHITECTURE_ID "Blackfin" + +#elif defined(__TASKING__) + +# if defined(__CTC__) || defined(__CPTC__) +# define ARCHITECTURE_ID "TriCore" + +# elif defined(__CMCS__) +# define ARCHITECTURE_ID "MCS" + +# elif defined(__CARM__) || defined(__CPARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__CARC__) +# define ARCHITECTURE_ID "ARC" + +# elif defined(__C51__) +# define ARCHITECTURE_ID "8051" + +# elif defined(__CPCP__) +# define ARCHITECTURE_ID "PCP" + +# else +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__RENESAS__) +# if defined(__CCRX__) +# define ARCHITECTURE_ID "RX" + +# elif defined(__CCRL__) +# define ARCHITECTURE_ID "RL78" + +# elif defined(__CCRH__) +# define ARCHITECTURE_ID "RH850" + +# else +# define ARCHITECTURE_ID "" +# endif + +#else +# define ARCHITECTURE_ID +#endif + +/* Convert integer to decimal digit literals. */ +#define DEC(n) \ + ('0' + (((n) / 10000000)%10)), \ + ('0' + (((n) / 1000000)%10)), \ + ('0' + (((n) / 100000)%10)), \ + ('0' + (((n) / 10000)%10)), \ + ('0' + (((n) / 1000)%10)), \ + ('0' + (((n) / 100)%10)), \ + ('0' + (((n) / 10)%10)), \ + ('0' + ((n) % 10)) + +/* Convert integer to hex digit literals. */ +#define HEX(n) \ + ('0' + ((n)>>28 & 0xF)), \ + ('0' + ((n)>>24 & 0xF)), \ + ('0' + ((n)>>20 & 0xF)), \ + ('0' + ((n)>>16 & 0xF)), \ + ('0' + ((n)>>12 & 0xF)), \ + ('0' + ((n)>>8 & 0xF)), \ + ('0' + ((n)>>4 & 0xF)), \ + ('0' + ((n) & 0xF)) + +/* Construct a string literal encoding the version number. */ +#ifdef COMPILER_VERSION +char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]"; + +/* Construct a string literal encoding the version number components. */ +#elif defined(COMPILER_VERSION_MAJOR) +char const info_version[] = { + 'I', 'N', 'F', 'O', ':', + 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', + COMPILER_VERSION_MAJOR, +# ifdef COMPILER_VERSION_MINOR + '.', COMPILER_VERSION_MINOR, +# ifdef COMPILER_VERSION_PATCH + '.', COMPILER_VERSION_PATCH, +# ifdef COMPILER_VERSION_TWEAK + '.', COMPILER_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + +/* Construct a string literal encoding the internal version number. */ +#ifdef COMPILER_VERSION_INTERNAL +char const info_version_internal[] = { + 'I', 'N', 'F', 'O', ':', + 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_', + 'i','n','t','e','r','n','a','l','[', + COMPILER_VERSION_INTERNAL,']','\0'}; +#elif defined(COMPILER_VERSION_INTERNAL_STR) +char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]"; +#endif + +/* Construct a string literal encoding the version number components. */ +#ifdef SIMULATE_VERSION_MAJOR +char const info_simulate_version[] = { + 'I', 'N', 'F', 'O', ':', + 's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[', + SIMULATE_VERSION_MAJOR, +# ifdef SIMULATE_VERSION_MINOR + '.', SIMULATE_VERSION_MINOR, +# ifdef SIMULATE_VERSION_PATCH + '.', SIMULATE_VERSION_PATCH, +# ifdef SIMULATE_VERSION_TWEAK + '.', SIMULATE_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; +char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; + + + +#define C_STD_99 199901L +#define C_STD_11 201112L +#define C_STD_17 201710L +#define C_STD_23 202311L + +#ifdef __STDC_VERSION__ +# define C_STD __STDC_VERSION__ +#endif + +#if !defined(__STDC__) && !defined(__clang__) && !defined(__RENESAS__) +# if defined(_MSC_VER) || defined(__ibmxl__) || defined(__IBMC__) +# define C_VERSION "90" +# else +# define C_VERSION +# endif +#elif C_STD > C_STD_17 +# define C_VERSION "23" +#elif C_STD > C_STD_11 +# define C_VERSION "17" +#elif C_STD > C_STD_99 +# define C_VERSION "11" +#elif C_STD >= C_STD_99 +# define C_VERSION "99" +#else +# define C_VERSION "90" +#endif +const char* info_language_standard_default = + "INFO" ":" "standard_default[" C_VERSION "]"; + +const char* info_language_extensions_default = "INFO" ":" "extensions_default[" +#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \ + defined(__TI_COMPILER_VERSION__) || defined(__RENESAS__)) && \ + !defined(__STRICT_ANSI__) + "ON" +#else + "OFF" +#endif +"]"; + +/*--------------------------------------------------------------------------*/ + +#ifdef ID_VOID_MAIN +void main() {} +#else +# if defined(__CLASSIC_C__) +int main(argc, argv) int argc; char *argv[]; +# else +int main(int argc, char* argv[]) +# endif +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; + require += info_arch[argc]; +#ifdef COMPILER_VERSION_MAJOR + require += info_version[argc]; +#endif +#if defined(COMPILER_VERSION_INTERNAL) || defined(COMPILER_VERSION_INTERNAL_STR) + require += info_version_internal[argc]; +#endif +#ifdef SIMULATE_ID + require += info_simulate[argc]; +#endif +#ifdef SIMULATE_VERSION_MAJOR + require += info_simulate_version[argc]; +#endif +#if defined(__CRAYXT_COMPUTE_LINUX_TARGET) + require += info_cray[argc]; +#endif + require += info_language_standard_default[argc]; + require += info_language_extensions_default[argc]; + (void)argv; + return require; +} +#endif diff --git a/test/build-asan/CMakeFiles/4.2.3/CompilerIdCXX/CMakeCXXCompilerId.cpp b/test/build-asan/CMakeFiles/4.2.3/CompilerIdCXX/CMakeCXXCompilerId.cpp new file mode 100644 index 0000000..b35f567 --- /dev/null +++ b/test/build-asan/CMakeFiles/4.2.3/CompilerIdCXX/CMakeCXXCompilerId.cpp @@ -0,0 +1,949 @@ +/* This source file must have a .cpp extension so that all C++ compilers + recognize the extension without flags. Borland does not know .cxx for + example. */ +#ifndef __cplusplus +# error "A C compiler has been selected for C++." +#endif + +#if !defined(__has_include) +/* If the compiler does not have __has_include, pretend the answer is + always no. */ +# define __has_include(x) 0 +#endif + + +/* Version number components: V=Version, R=Revision, P=Patch + Version date components: YYYY=Year, MM=Month, DD=Day */ + +#if defined(__INTEL_COMPILER) || defined(__ICC) +# define COMPILER_ID "Intel" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# if defined(__GNUC__) +# define SIMULATE_ID "GNU" +# endif + /* __INTEL_COMPILER = VRP prior to 2021, and then VVVV for 2021 and later, + except that a few beta releases use the old format with V=2021. */ +# if __INTEL_COMPILER < 2021 || __INTEL_COMPILER == 202110 || __INTEL_COMPILER == 202111 +# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100) +# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10) +# if defined(__INTEL_COMPILER_UPDATE) +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE) +# else +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10) +# endif +# else +# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER) +# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER_UPDATE) + /* The third version component from --version is an update index, + but no macro is provided for it. */ +# define COMPILER_VERSION_PATCH DEC(0) +# endif +# if defined(__INTEL_COMPILER_BUILD_DATE) + /* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */ +# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE) +# endif +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif +# if defined(__GNUC__) +# define SIMULATE_VERSION_MAJOR DEC(__GNUC__) +# elif defined(__GNUG__) +# define SIMULATE_VERSION_MAJOR DEC(__GNUG__) +# endif +# if defined(__GNUC_MINOR__) +# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__) +# endif +# if defined(__GNUC_PATCHLEVEL__) +# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif + +#elif (defined(__clang__) && defined(__INTEL_CLANG_COMPILER)) || defined(__INTEL_LLVM_COMPILER) +# define COMPILER_ID "IntelLLVM" +#if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +#endif +#if defined(__GNUC__) +# define SIMULATE_ID "GNU" +#endif +/* __INTEL_LLVM_COMPILER = VVVVRP prior to 2021.2.0, VVVVRRPP for 2021.2.0 and + * later. Look for 6 digit vs. 8 digit version number to decide encoding. + * VVVV is no smaller than the current year when a version is released. + */ +#if __INTEL_LLVM_COMPILER < 1000000L +# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/100) +# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 10) +#else +# define COMPILER_VERSION_MAJOR DEC(__INTEL_LLVM_COMPILER/10000) +# define COMPILER_VERSION_MINOR DEC(__INTEL_LLVM_COMPILER/100 % 100) +# define COMPILER_VERSION_PATCH DEC(__INTEL_LLVM_COMPILER % 100) +#endif +#if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +#endif +#if defined(__GNUC__) +# define SIMULATE_VERSION_MAJOR DEC(__GNUC__) +#elif defined(__GNUG__) +# define SIMULATE_VERSION_MAJOR DEC(__GNUG__) +#endif +#if defined(__GNUC_MINOR__) +# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__) +#endif +#if defined(__GNUC_PATCHLEVEL__) +# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +#endif + +#elif defined(__PATHCC__) +# define COMPILER_ID "PathScale" +# define COMPILER_VERSION_MAJOR DEC(__PATHCC__) +# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__) +# if defined(__PATHCC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__) +# endif + +#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) +# define COMPILER_ID "Embarcadero" +# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF) +# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF) +# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF) + +#elif defined(__BORLANDC__) +# define COMPILER_ID "Borland" + /* __BORLANDC__ = 0xVRR */ +# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8) +# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF) + +#elif defined(__WATCOMC__) && __WATCOMC__ < 1200 +# define COMPILER_ID "Watcom" + /* __WATCOMC__ = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100) +# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) +# if (__WATCOMC__ % 10) > 0 +# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) +# endif + +#elif defined(__WATCOMC__) +# define COMPILER_ID "OpenWatcom" + /* __WATCOMC__ = VVRP + 1100 */ +# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100) +# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10) +# if (__WATCOMC__ % 10) > 0 +# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10) +# endif + +#elif defined(__SUNPRO_CC) +# define COMPILER_ID "SunPro" +# if __SUNPRO_CC >= 0x5100 + /* __SUNPRO_CC = 0xVRRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF) +# else + /* __SUNPRO_CC = 0xVRP */ +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF) +# endif + +#elif defined(__HP_aCC) +# define COMPILER_ID "HP" + /* __HP_aCC = VVRRPP */ +# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000) +# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100) +# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100) + +#elif defined(__DECCXX) +# define COMPILER_ID "Compaq" + /* __DECCXX_VER = VVRRTPPPP */ +# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000) +# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100) +# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000) + +#elif defined(__IBMCPP__) && defined(__COMPILER_VER__) +# define COMPILER_ID "zOS" + /* __IBMCPP__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) + +#elif defined(__open_xl__) && defined(__clang__) +# define COMPILER_ID "IBMClang" +# define COMPILER_VERSION_MAJOR DEC(__open_xl_version__) +# define COMPILER_VERSION_MINOR DEC(__open_xl_release__) +# define COMPILER_VERSION_PATCH DEC(__open_xl_modification__) +# define COMPILER_VERSION_TWEAK DEC(__open_xl_ptf_fix_level__) +# define COMPILER_VERSION_INTERNAL_STR __clang_version__ + + +#elif defined(__ibmxl__) && defined(__clang__) +# define COMPILER_ID "XLClang" +# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__) +# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__) +# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__) +# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__) + + +#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800 +# define COMPILER_ID "XL" + /* __IBMCPP__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) + +#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800 +# define COMPILER_ID "VisualAge" + /* __IBMCPP__ = VRP */ +# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10) + +#elif defined(__NVCOMPILER) +# define COMPILER_ID "NVHPC" +# define COMPILER_VERSION_MAJOR DEC(__NVCOMPILER_MAJOR__) +# define COMPILER_VERSION_MINOR DEC(__NVCOMPILER_MINOR__) +# if defined(__NVCOMPILER_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__NVCOMPILER_PATCHLEVEL__) +# endif + +#elif defined(__PGI) +# define COMPILER_ID "PGI" +# define COMPILER_VERSION_MAJOR DEC(__PGIC__) +# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) +# endif + +#elif defined(__clang__) && defined(__cray__) +# define COMPILER_ID "CrayClang" +# define COMPILER_VERSION_MAJOR DEC(__cray_major__) +# define COMPILER_VERSION_MINOR DEC(__cray_minor__) +# define COMPILER_VERSION_PATCH DEC(__cray_patchlevel__) +# define COMPILER_VERSION_INTERNAL_STR __clang_version__ + + +#elif defined(_CRAYC) +# define COMPILER_ID "Cray" +# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR) +# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR) + +#elif defined(__TI_COMPILER_VERSION__) +# define COMPILER_ID "TI" + /* __TI_COMPILER_VERSION__ = VVVRRRPPP */ +# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000) +# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000) +# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000) + +#elif defined(__CLANG_FUJITSU) +# define COMPILER_ID "FujitsuClang" +# define COMPILER_VERSION_MAJOR DEC(__FCC_major__) +# define COMPILER_VERSION_MINOR DEC(__FCC_minor__) +# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__) +# define COMPILER_VERSION_INTERNAL_STR __clang_version__ + + +#elif defined(__FUJITSU) +# define COMPILER_ID "Fujitsu" +# if defined(__FCC_version__) +# define COMPILER_VERSION __FCC_version__ +# elif defined(__FCC_major__) +# define COMPILER_VERSION_MAJOR DEC(__FCC_major__) +# define COMPILER_VERSION_MINOR DEC(__FCC_minor__) +# define COMPILER_VERSION_PATCH DEC(__FCC_patchlevel__) +# endif +# if defined(__fcc_version) +# define COMPILER_VERSION_INTERNAL DEC(__fcc_version) +# elif defined(__FCC_VERSION) +# define COMPILER_VERSION_INTERNAL DEC(__FCC_VERSION) +# endif + + +#elif defined(__ghs__) +# define COMPILER_ID "GHS" +/* __GHS_VERSION_NUMBER = VVVVRP */ +# ifdef __GHS_VERSION_NUMBER +# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100) +# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10) +# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10) +# endif + +#elif defined(__TASKING__) +# define COMPILER_ID "Tasking" + # define COMPILER_VERSION_MAJOR DEC(__VERSION__/1000) + # define COMPILER_VERSION_MINOR DEC(__VERSION__ % 100) +# define COMPILER_VERSION_INTERNAL DEC(__VERSION__) + +#elif defined(__ORANGEC__) +# define COMPILER_ID "OrangeC" +# define COMPILER_VERSION_MAJOR DEC(__ORANGEC_MAJOR__) +# define COMPILER_VERSION_MINOR DEC(__ORANGEC_MINOR__) +# define COMPILER_VERSION_PATCH DEC(__ORANGEC_PATCHLEVEL__) + +#elif defined(__RENESAS__) +# define COMPILER_ID "Renesas" +/* __RENESAS_VERSION__ = 0xVVRRPP00 */ +# define COMPILER_VERSION_MAJOR HEX(__RENESAS_VERSION__ >> 24 & 0xFF) +# define COMPILER_VERSION_MINOR HEX(__RENESAS_VERSION__ >> 16 & 0xFF) +# define COMPILER_VERSION_PATCH HEX(__RENESAS_VERSION__ >> 8 & 0xFF) + +#elif defined(__SCO_VERSION__) +# define COMPILER_ID "SCO" + +#elif defined(__ARMCC_VERSION) && !defined(__clang__) +# define COMPILER_ID "ARMCC" +#if __ARMCC_VERSION >= 1000000 + /* __ARMCC_VERSION = VRRPPPP */ + # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000) + # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100) + # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) +#else + /* __ARMCC_VERSION = VRPPPP */ + # define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000) + # define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10) + # define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000) +#endif + + +#elif defined(__clang__) && defined(__apple_build_version__) +# define COMPILER_ID "AppleClang" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# define COMPILER_VERSION_MAJOR DEC(__clang_major__) +# define COMPILER_VERSION_MINOR DEC(__clang_minor__) +# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif +# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__) + +#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION) +# define COMPILER_ID "ARMClang" + # define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000) + # define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100) + # define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION/100 % 100) +# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION) + +#elif defined(__clang__) && defined(__ti__) +# define COMPILER_ID "TIClang" + # define COMPILER_VERSION_MAJOR DEC(__ti_major__) + # define COMPILER_VERSION_MINOR DEC(__ti_minor__) + # define COMPILER_VERSION_PATCH DEC(__ti_patchlevel__) +# define COMPILER_VERSION_INTERNAL DEC(__ti_version__) + +#elif defined(__clang__) +# define COMPILER_ID "Clang" +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" +# endif +# define COMPILER_VERSION_MAJOR DEC(__clang_major__) +# define COMPILER_VERSION_MINOR DEC(__clang_minor__) +# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +# if defined(_MSC_VER) + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif + +#elif defined(__LCC__) && (defined(__GNUC__) || defined(__GNUG__) || defined(__MCST__)) +# define COMPILER_ID "LCC" +# define COMPILER_VERSION_MAJOR DEC(__LCC__ / 100) +# define COMPILER_VERSION_MINOR DEC(__LCC__ % 100) +# if defined(__LCC_MINOR__) +# define COMPILER_VERSION_PATCH DEC(__LCC_MINOR__) +# endif +# if defined(__GNUC__) && defined(__GNUC_MINOR__) +# define SIMULATE_ID "GNU" +# define SIMULATE_VERSION_MAJOR DEC(__GNUC__) +# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__) +# if defined(__GNUC_PATCHLEVEL__) +# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif +# endif + +#elif defined(__GNUC__) || defined(__GNUG__) +# define COMPILER_ID "GNU" +# if defined(__GNUC__) +# define COMPILER_VERSION_MAJOR DEC(__GNUC__) +# else +# define COMPILER_VERSION_MAJOR DEC(__GNUG__) +# endif +# if defined(__GNUC_MINOR__) +# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) +# endif +# if defined(__GNUC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif + +#elif defined(_MSC_VER) +# define COMPILER_ID "MSVC" + /* _MSC_VER = VVRR */ +# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100) +# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100) +# if defined(_MSC_FULL_VER) +# if _MSC_VER >= 1400 + /* _MSC_FULL_VER = VVRRPPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000) +# else + /* _MSC_FULL_VER = VVRRPPPP */ +# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000) +# endif +# endif +# if defined(_MSC_BUILD) +# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD) +# endif + +#elif defined(_ADI_COMPILER) +# define COMPILER_ID "ADSP" +#if defined(__VERSIONNUM__) + /* __VERSIONNUM__ = 0xVVRRPPTT */ +# define COMPILER_VERSION_MAJOR DEC(__VERSIONNUM__ >> 24 & 0xFF) +# define COMPILER_VERSION_MINOR DEC(__VERSIONNUM__ >> 16 & 0xFF) +# define COMPILER_VERSION_PATCH DEC(__VERSIONNUM__ >> 8 & 0xFF) +# define COMPILER_VERSION_TWEAK DEC(__VERSIONNUM__ & 0xFF) +#endif + +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) +# define COMPILER_ID "IAR" +# if defined(__VER__) && defined(__ICCARM__) +# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000) +# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000) +# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000) +# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) +# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__) || defined(__ICCSTM8__)) +# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100) +# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100)) +# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__) +# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__) +# endif + +#elif defined(__DCC__) && defined(_DIAB_TOOL) +# define COMPILER_ID "Diab" + # define COMPILER_VERSION_MAJOR DEC(__VERSION_MAJOR_NUMBER__) + # define COMPILER_VERSION_MINOR DEC(__VERSION_MINOR_NUMBER__) + # define COMPILER_VERSION_PATCH DEC(__VERSION_ARCH_FEATURE_NUMBER__) + # define COMPILER_VERSION_TWEAK DEC(__VERSION_BUG_FIX_NUMBER__) + + + +/* These compilers are either not known or too old to define an + identification macro. Try to identify the platform and guess that + it is the native compiler. */ +#elif defined(__hpux) || defined(__hpua) +# define COMPILER_ID "HP" + +#else /* unknown compiler */ +# define COMPILER_ID "" +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; +#ifdef SIMULATE_ID +char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; +#endif + +#ifdef __QNXNTO__ +char const* qnxnto = "INFO" ":" "qnxnto[]"; +#endif + +#if defined(__CRAYXT_COMPUTE_LINUX_TARGET) +char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]"; +#endif + +#define STRINGIFY_HELPER(X) #X +#define STRINGIFY(X) STRINGIFY_HELPER(X) + +/* Identify known platforms by name. */ +#if defined(__linux) || defined(__linux__) || defined(linux) +# define PLATFORM_ID "Linux" + +#elif defined(__MSYS__) +# define PLATFORM_ID "MSYS" + +#elif defined(__CYGWIN__) +# define PLATFORM_ID "Cygwin" + +#elif defined(__MINGW32__) +# define PLATFORM_ID "MinGW" + +#elif defined(__APPLE__) +# define PLATFORM_ID "Darwin" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +# define PLATFORM_ID "Windows" + +#elif defined(__FreeBSD__) || defined(__FreeBSD) +# define PLATFORM_ID "FreeBSD" + +#elif defined(__NetBSD__) || defined(__NetBSD) +# define PLATFORM_ID "NetBSD" + +#elif defined(__OpenBSD__) || defined(__OPENBSD) +# define PLATFORM_ID "OpenBSD" + +#elif defined(__sun) || defined(sun) +# define PLATFORM_ID "SunOS" + +#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__) +# define PLATFORM_ID "AIX" + +#elif defined(__hpux) || defined(__hpux__) +# define PLATFORM_ID "HP-UX" + +#elif defined(__HAIKU__) +# define PLATFORM_ID "Haiku" + +#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) +# define PLATFORM_ID "BeOS" + +#elif defined(__QNX__) || defined(__QNXNTO__) +# define PLATFORM_ID "QNX" + +#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__) +# define PLATFORM_ID "Tru64" + +#elif defined(__riscos) || defined(__riscos__) +# define PLATFORM_ID "RISCos" + +#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__) +# define PLATFORM_ID "SINIX" + +#elif defined(__UNIX_SV__) +# define PLATFORM_ID "UNIX_SV" + +#elif defined(__bsdos__) +# define PLATFORM_ID "BSDOS" + +#elif defined(_MPRAS) || defined(MPRAS) +# define PLATFORM_ID "MP-RAS" + +#elif defined(__osf) || defined(__osf__) +# define PLATFORM_ID "OSF1" + +#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv) +# define PLATFORM_ID "SCO_SV" + +#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX) +# define PLATFORM_ID "ULTRIX" + +#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX) +# define PLATFORM_ID "Xenix" + +#elif defined(__WATCOMC__) +# if defined(__LINUX__) +# define PLATFORM_ID "Linux" + +# elif defined(__DOS__) +# define PLATFORM_ID "DOS" + +# elif defined(__OS2__) +# define PLATFORM_ID "OS2" + +# elif defined(__WINDOWS__) +# define PLATFORM_ID "Windows3x" + +# elif defined(__VXWORKS__) +# define PLATFORM_ID "VxWorks" + +# else /* unknown platform */ +# define PLATFORM_ID +# endif + +#elif defined(__INTEGRITY) +# if defined(INT_178B) +# define PLATFORM_ID "Integrity178" + +# else /* regular Integrity */ +# define PLATFORM_ID "Integrity" +# endif + +# elif defined(_ADI_COMPILER) +# define PLATFORM_ID "ADSP" + +#else /* unknown platform */ +# define PLATFORM_ID + +#endif + +/* For windows compilers MSVC and Intel we can determine + the architecture of the compiler being used. This is because + the compilers do not have flags that can change the architecture, + but rather depend on which compiler is being used +*/ +#if defined(_WIN32) && defined(_MSC_VER) +# if defined(_M_IA64) +# define ARCHITECTURE_ID "IA64" + +# elif defined(_M_ARM64EC) +# define ARCHITECTURE_ID "ARM64EC" + +# elif defined(_M_X64) || defined(_M_AMD64) +# define ARCHITECTURE_ID "x64" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# elif defined(_M_ARM64) +# define ARCHITECTURE_ID "ARM64" + +# elif defined(_M_ARM) +# if _M_ARM == 4 +# define ARCHITECTURE_ID "ARMV4I" +# elif _M_ARM == 5 +# define ARCHITECTURE_ID "ARMV5I" +# else +# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM) +# endif + +# elif defined(_M_MIPS) +# define ARCHITECTURE_ID "MIPS" + +# elif defined(_M_SH) +# define ARCHITECTURE_ID "SHx" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__WATCOMC__) +# if defined(_M_I86) +# define ARCHITECTURE_ID "I86" + +# elif defined(_M_IX86) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC) +# if defined(__ICCARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__ICCRX__) +# define ARCHITECTURE_ID "RX" + +# elif defined(__ICCRH850__) +# define ARCHITECTURE_ID "RH850" + +# elif defined(__ICCRL78__) +# define ARCHITECTURE_ID "RL78" + +# elif defined(__ICCRISCV__) +# define ARCHITECTURE_ID "RISCV" + +# elif defined(__ICCAVR__) +# define ARCHITECTURE_ID "AVR" + +# elif defined(__ICC430__) +# define ARCHITECTURE_ID "MSP430" + +# elif defined(__ICCV850__) +# define ARCHITECTURE_ID "V850" + +# elif defined(__ICC8051__) +# define ARCHITECTURE_ID "8051" + +# elif defined(__ICCSTM8__) +# define ARCHITECTURE_ID "STM8" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__ghs__) +# if defined(__PPC64__) +# define ARCHITECTURE_ID "PPC64" + +# elif defined(__ppc__) +# define ARCHITECTURE_ID "PPC" + +# elif defined(__ARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__x86_64__) +# define ARCHITECTURE_ID "x64" + +# elif defined(__i386__) +# define ARCHITECTURE_ID "X86" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__clang__) && defined(__ti__) +# if defined(__ARM_ARCH) +# define ARCHITECTURE_ID "ARM" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__TI_COMPILER_VERSION__) +# if defined(__TI_ARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__MSP430__) +# define ARCHITECTURE_ID "MSP430" + +# elif defined(__TMS320C28XX__) +# define ARCHITECTURE_ID "TMS320C28x" + +# elif defined(__TMS320C6X__) || defined(_TMS320C6X) +# define ARCHITECTURE_ID "TMS320C6x" + +# else /* unknown architecture */ +# define ARCHITECTURE_ID "" +# endif + +# elif defined(__ADSPSHARC__) +# define ARCHITECTURE_ID "SHARC" + +# elif defined(__ADSPBLACKFIN__) +# define ARCHITECTURE_ID "Blackfin" + +#elif defined(__TASKING__) + +# if defined(__CTC__) || defined(__CPTC__) +# define ARCHITECTURE_ID "TriCore" + +# elif defined(__CMCS__) +# define ARCHITECTURE_ID "MCS" + +# elif defined(__CARM__) || defined(__CPARM__) +# define ARCHITECTURE_ID "ARM" + +# elif defined(__CARC__) +# define ARCHITECTURE_ID "ARC" + +# elif defined(__C51__) +# define ARCHITECTURE_ID "8051" + +# elif defined(__CPCP__) +# define ARCHITECTURE_ID "PCP" + +# else +# define ARCHITECTURE_ID "" +# endif + +#elif defined(__RENESAS__) +# if defined(__CCRX__) +# define ARCHITECTURE_ID "RX" + +# elif defined(__CCRL__) +# define ARCHITECTURE_ID "RL78" + +# elif defined(__CCRH__) +# define ARCHITECTURE_ID "RH850" + +# else +# define ARCHITECTURE_ID "" +# endif + +#else +# define ARCHITECTURE_ID +#endif + +/* Convert integer to decimal digit literals. */ +#define DEC(n) \ + ('0' + (((n) / 10000000)%10)), \ + ('0' + (((n) / 1000000)%10)), \ + ('0' + (((n) / 100000)%10)), \ + ('0' + (((n) / 10000)%10)), \ + ('0' + (((n) / 1000)%10)), \ + ('0' + (((n) / 100)%10)), \ + ('0' + (((n) / 10)%10)), \ + ('0' + ((n) % 10)) + +/* Convert integer to hex digit literals. */ +#define HEX(n) \ + ('0' + ((n)>>28 & 0xF)), \ + ('0' + ((n)>>24 & 0xF)), \ + ('0' + ((n)>>20 & 0xF)), \ + ('0' + ((n)>>16 & 0xF)), \ + ('0' + ((n)>>12 & 0xF)), \ + ('0' + ((n)>>8 & 0xF)), \ + ('0' + ((n)>>4 & 0xF)), \ + ('0' + ((n) & 0xF)) + +/* Construct a string literal encoding the version number. */ +#ifdef COMPILER_VERSION +char const* info_version = "INFO" ":" "compiler_version[" COMPILER_VERSION "]"; + +/* Construct a string literal encoding the version number components. */ +#elif defined(COMPILER_VERSION_MAJOR) +char const info_version[] = { + 'I', 'N', 'F', 'O', ':', + 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[', + COMPILER_VERSION_MAJOR, +# ifdef COMPILER_VERSION_MINOR + '.', COMPILER_VERSION_MINOR, +# ifdef COMPILER_VERSION_PATCH + '.', COMPILER_VERSION_PATCH, +# ifdef COMPILER_VERSION_TWEAK + '.', COMPILER_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + +/* Construct a string literal encoding the internal version number. */ +#ifdef COMPILER_VERSION_INTERNAL +char const info_version_internal[] = { + 'I', 'N', 'F', 'O', ':', + 'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_', + 'i','n','t','e','r','n','a','l','[', + COMPILER_VERSION_INTERNAL,']','\0'}; +#elif defined(COMPILER_VERSION_INTERNAL_STR) +char const* info_version_internal = "INFO" ":" "compiler_version_internal[" COMPILER_VERSION_INTERNAL_STR "]"; +#endif + +/* Construct a string literal encoding the version number components. */ +#ifdef SIMULATE_VERSION_MAJOR +char const info_simulate_version[] = { + 'I', 'N', 'F', 'O', ':', + 's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[', + SIMULATE_VERSION_MAJOR, +# ifdef SIMULATE_VERSION_MINOR + '.', SIMULATE_VERSION_MINOR, +# ifdef SIMULATE_VERSION_PATCH + '.', SIMULATE_VERSION_PATCH, +# ifdef SIMULATE_VERSION_TWEAK + '.', SIMULATE_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + +/* Construct the string literal in pieces to prevent the source from + getting matched. Store it in a pointer rather than an array + because some compilers will just produce instructions to fill the + array rather than assigning a pointer to a static array. */ +char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]"; +char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]"; + + + +#define CXX_STD_98 199711L +#define CXX_STD_11 201103L +#define CXX_STD_14 201402L +#define CXX_STD_17 201703L +#define CXX_STD_20 202002L +#define CXX_STD_23 202302L + +#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG) +# if _MSVC_LANG > CXX_STD_17 +# define CXX_STD _MSVC_LANG +# elif _MSVC_LANG == CXX_STD_17 && defined(__cpp_aggregate_paren_init) +# define CXX_STD CXX_STD_20 +# elif _MSVC_LANG > CXX_STD_14 && __cplusplus > CXX_STD_17 +# define CXX_STD CXX_STD_20 +# elif _MSVC_LANG > CXX_STD_14 +# define CXX_STD CXX_STD_17 +# elif defined(__INTEL_CXX11_MODE__) && defined(__cpp_aggregate_nsdmi) +# define CXX_STD CXX_STD_14 +# elif defined(__INTEL_CXX11_MODE__) +# define CXX_STD CXX_STD_11 +# else +# define CXX_STD CXX_STD_98 +# endif +#elif defined(_MSC_VER) && defined(_MSVC_LANG) +# if _MSVC_LANG > __cplusplus +# define CXX_STD _MSVC_LANG +# else +# define CXX_STD __cplusplus +# endif +#elif defined(__NVCOMPILER) +# if __cplusplus == CXX_STD_17 && defined(__cpp_aggregate_paren_init) +# define CXX_STD CXX_STD_20 +# else +# define CXX_STD __cplusplus +# endif +#elif defined(__INTEL_COMPILER) || defined(__PGI) +# if __cplusplus == CXX_STD_11 && defined(__cpp_namespace_attributes) +# define CXX_STD CXX_STD_17 +# elif __cplusplus == CXX_STD_11 && defined(__cpp_aggregate_nsdmi) +# define CXX_STD CXX_STD_14 +# else +# define CXX_STD __cplusplus +# endif +#elif (defined(__IBMCPP__) || defined(__ibmxl__)) && defined(__linux__) +# if __cplusplus == CXX_STD_11 && defined(__cpp_aggregate_nsdmi) +# define CXX_STD CXX_STD_14 +# else +# define CXX_STD __cplusplus +# endif +#elif __cplusplus == 1 && defined(__GXX_EXPERIMENTAL_CXX0X__) +# define CXX_STD CXX_STD_11 +#else +# define CXX_STD __cplusplus +#endif + +const char* info_language_standard_default = "INFO" ":" "standard_default[" +#if CXX_STD > CXX_STD_23 + "26" +#elif CXX_STD > CXX_STD_20 + "23" +#elif CXX_STD > CXX_STD_17 + "20" +#elif CXX_STD > CXX_STD_14 + "17" +#elif CXX_STD > CXX_STD_11 + "14" +#elif CXX_STD >= CXX_STD_11 + "11" +#else + "98" +#endif +"]"; + +const char* info_language_extensions_default = "INFO" ":" "extensions_default[" +#if (defined(__clang__) || defined(__GNUC__) || defined(__xlC__) || \ + defined(__TI_COMPILER_VERSION__) || defined(__RENESAS__)) && \ + !defined(__STRICT_ANSI__) + "ON" +#else + "OFF" +#endif +"]"; + +/*--------------------------------------------------------------------------*/ + +int main(int argc, char* argv[]) +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; + require += info_arch[argc]; +#ifdef COMPILER_VERSION_MAJOR + require += info_version[argc]; +#endif +#if defined(COMPILER_VERSION_INTERNAL) || defined(COMPILER_VERSION_INTERNAL_STR) + require += info_version_internal[argc]; +#endif +#ifdef SIMULATE_ID + require += info_simulate[argc]; +#endif +#ifdef SIMULATE_VERSION_MAJOR + require += info_simulate_version[argc]; +#endif +#if defined(__CRAYXT_COMPUTE_LINUX_TARGET) + require += info_cray[argc]; +#endif + require += info_language_standard_default[argc]; + require += info_language_extensions_default[argc]; + (void)argv; + return require; +} diff --git a/test/build-asan/CMakeFiles/CMakeConfigureLog.yaml b/test/build-asan/CMakeFiles/CMakeConfigureLog.yaml new file mode 100644 index 0000000..0d11199 --- /dev/null +++ b/test/build-asan/CMakeFiles/CMakeConfigureLog.yaml @@ -0,0 +1,2556 @@ + +--- +events: + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineSystem.cmake:12 (find_program)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_UNAME" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "uname" + candidate_directories: + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/usr/bin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + searched_directories: + - "/home/cryptolicious/.local/bin/uname" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/uname" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/uname" + - "/home/cryptolicious/.cargo/bin/uname" + - "/usr/local/sbin/uname" + - "/usr/local/bin/uname" + - "/usr/sbin/uname" + found: "/usr/bin/uname" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "message-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineSystem.cmake:212 (message)" + - "CMakeLists.txt:2 (project)" + message: | + The system is: Linux - 7.0.0-29-generic - x86_64 + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeUnixFindMake.cmake:5 (find_program)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_MAKE_PROGRAM" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "gmake" + - "make" + - "smake" + candidate_directories: + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/usr/bin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + searched_directories: + - "/home/cryptolicious/.local/bin/gmake" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/gmake" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/gmake" + - "/home/cryptolicious/.cargo/bin/gmake" + - "/usr/local/sbin/gmake" + - "/usr/local/bin/gmake" + - "/usr/sbin/gmake" + found: "/usr/bin/gmake" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompiler.cmake:73 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:64 (_cmake_find_compiler)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_C_COMPILER" + description: "C compiler" + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "cc" + - "gcc" + - "cl" + - "bcc" + - "xlc" + - "icx" + - "clang" + candidate_directories: + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/usr/bin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + searched_directories: + - "/home/cryptolicious/.local/bin/cc" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/cc" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/cc" + - "/home/cryptolicious/.cargo/bin/cc" + - "/usr/local/sbin/cc" + - "/usr/local/bin/cc" + - "/usr/sbin/cc" + found: "/usr/bin/cc" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake:462 (find_file)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake:500 (CMAKE_DETERMINE_COMPILER_ID_WRITE)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake:8 (CMAKE_DETERMINE_COMPILER_ID_BUILD)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake:64 (__determine_compiler_id_test)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:122 (CMAKE_DETERMINE_COMPILER_ID)" + - "CMakeLists.txt:2 (project)" + mode: "file" + variable: "src_in" + description: "Path to a file." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "CMakeCCompilerId.c.in" + candidate_directories: + - "/usr/share/cmake-4.2/Modules/" + found: "/usr/share/cmake-4.2/Modules/CMakeCCompilerId.c.in" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "message-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake:17 (message)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake:64 (__determine_compiler_id_test)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:122 (CMAKE_DETERMINE_COMPILER_ID)" + - "CMakeLists.txt:2 (project)" + message: | + Compiling the C compiler identification source file "CMakeCCompilerId.c" succeeded. + Compiler: /usr/bin/cc + Build flags: + Id flags: + + The output was: + 0 + + + Compilation of the C compiler identification source "CMakeCCompilerId.c" produced "a.out" + + The C compiler identification is GNU, found in: + /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/4.2.3/CompilerIdC/a.out + + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeFindBinUtils.cmake:243 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:200 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_AR" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "ar" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + found: "/usr/bin/ar" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeFindBinUtils.cmake:243 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:200 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_RANLIB" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "ranlib" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + found: "/usr/bin/ranlib" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeFindBinUtils.cmake:243 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:200 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_STRIP" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "strip" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + found: "/usr/bin/strip" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeFindBinUtils.cmake:243 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:200 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_LINKER" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "ld" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + found: "/usr/bin/ld" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeFindBinUtils.cmake:243 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:200 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_NM" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "nm" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + found: "/usr/bin/nm" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeFindBinUtils.cmake:243 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:200 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_OBJDUMP" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "objdump" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + found: "/usr/bin/objdump" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeFindBinUtils.cmake:243 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:200 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_OBJCOPY" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "objcopy" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + found: "/usr/bin/objcopy" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeFindBinUtils.cmake:243 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:200 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_READELF" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "readelf" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + found: "/usr/bin/readelf" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeFindBinUtils.cmake:243 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:200 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_DLLTOOL" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "dlltool" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + searched_directories: + - "/usr/bin/dlltool" + - "/home/cryptolicious/.local/bin/dlltool" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/dlltool" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/dlltool" + - "/home/cryptolicious/.cargo/bin/dlltool" + - "/usr/local/sbin/dlltool" + - "/usr/local/bin/dlltool" + - "/usr/sbin/dlltool" + - "/sbin/dlltool" + - "/bin/dlltool" + - "/usr/games/dlltool" + - "/usr/local/games/dlltool" + - "/snap/bin/dlltool" + found: false + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeFindBinUtils.cmake:243 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:200 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_ADDR2LINE" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "addr2line" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + found: "/usr/bin/addr2line" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeFindBinUtils.cmake:243 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:200 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_TAPI" + description: "Path to a program." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "tapi" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + searched_directories: + - "/usr/bin/tapi" + - "/home/cryptolicious/.local/bin/tapi" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/tapi" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/tapi" + - "/home/cryptolicious/.cargo/bin/tapi" + - "/usr/local/sbin/tapi" + - "/usr/local/bin/tapi" + - "/usr/sbin/tapi" + - "/sbin/tapi" + - "/bin/tapi" + - "/usr/games/tapi" + - "/usr/local/games/tapi" + - "/snap/bin/tapi" + found: false + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/Compiler/GNU-FindBinUtils.cmake:18 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:201 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_C_COMPILER_AR" + description: "A wrapper around 'ar' adding the appropriate '--plugin' option for the GCC compiler" + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "gcc-ar-15.2" + - "gcc-ar-15" + - "gcc-ar15" + - "gcc-ar" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + searched_directories: + - "/usr/bin/gcc-ar-15.2" + - "/home/cryptolicious/.local/bin/gcc-ar-15.2" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/gcc-ar-15.2" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/gcc-ar-15.2" + - "/home/cryptolicious/.cargo/bin/gcc-ar-15.2" + - "/usr/local/sbin/gcc-ar-15.2" + - "/usr/local/bin/gcc-ar-15.2" + - "/usr/sbin/gcc-ar-15.2" + - "/sbin/gcc-ar-15.2" + - "/bin/gcc-ar-15.2" + - "/usr/games/gcc-ar-15.2" + - "/usr/local/games/gcc-ar-15.2" + - "/snap/bin/gcc-ar-15.2" + found: "/usr/bin/gcc-ar-15" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/Compiler/GNU-FindBinUtils.cmake:30 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCCompiler.cmake:201 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_C_COMPILER_RANLIB" + description: "A wrapper around 'ranlib' adding the appropriate '--plugin' option for the GCC compiler" + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "gcc-ranlib-15.2" + - "gcc-ranlib-15" + - "gcc-ranlib15" + - "gcc-ranlib" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + searched_directories: + - "/usr/bin/gcc-ranlib-15.2" + - "/home/cryptolicious/.local/bin/gcc-ranlib-15.2" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/gcc-ranlib-15.2" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/gcc-ranlib-15.2" + - "/home/cryptolicious/.cargo/bin/gcc-ranlib-15.2" + - "/usr/local/sbin/gcc-ranlib-15.2" + - "/usr/local/bin/gcc-ranlib-15.2" + - "/usr/sbin/gcc-ranlib-15.2" + - "/sbin/gcc-ranlib-15.2" + - "/bin/gcc-ranlib-15.2" + - "/usr/games/gcc-ranlib-15.2" + - "/usr/local/games/gcc-ranlib-15.2" + - "/snap/bin/gcc-ranlib-15.2" + found: "/usr/bin/gcc-ranlib-15" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompiler.cmake:54 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCXXCompiler.cmake:69 (_cmake_find_compiler)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_CXX_COMPILER" + description: "CXX compiler" + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "c++" + - "CC" + - "g++" + - "aCC" + - "cl" + - "bcc" + - "xlC" + - "icpx" + - "icx" + - "clang++" + candidate_directories: + - "/usr/bin/" + found: "/usr/bin/c++" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake:462 (find_file)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake:500 (CMAKE_DETERMINE_COMPILER_ID_WRITE)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake:8 (CMAKE_DETERMINE_COMPILER_ID_BUILD)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake:64 (__determine_compiler_id_test)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCXXCompiler.cmake:125 (CMAKE_DETERMINE_COMPILER_ID)" + - "CMakeLists.txt:2 (project)" + mode: "file" + variable: "src_in" + description: "Path to a file." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "CMakeCXXCompilerId.cpp.in" + candidate_directories: + - "/usr/share/cmake-4.2/Modules/" + found: "/usr/share/cmake-4.2/Modules/CMakeCXXCompilerId.cpp.in" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "message-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake:17 (message)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerId.cmake:64 (__determine_compiler_id_test)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCXXCompiler.cmake:125 (CMAKE_DETERMINE_COMPILER_ID)" + - "CMakeLists.txt:2 (project)" + message: | + Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded. + Compiler: /usr/bin/c++ + Build flags: -fsanitize=address,undefined;-fno-omit-frame-pointer;-g;-O1 + Id flags: + + The output was: + 0 + + + Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out" + + The CXX compiler identification is GNU, found in: + /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/4.2.3/CompilerIdCXX/a.out + + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/Compiler/GNU-FindBinUtils.cmake:18 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCXXCompiler.cmake:207 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_CXX_COMPILER_AR" + description: "A wrapper around 'ar' adding the appropriate '--plugin' option for the GCC compiler" + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "gcc-ar-15.2" + - "gcc-ar-15" + - "gcc-ar15" + - "gcc-ar" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + searched_directories: + - "/usr/bin/gcc-ar-15.2" + - "/home/cryptolicious/.local/bin/gcc-ar-15.2" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/gcc-ar-15.2" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/gcc-ar-15.2" + - "/home/cryptolicious/.cargo/bin/gcc-ar-15.2" + - "/usr/local/sbin/gcc-ar-15.2" + - "/usr/local/bin/gcc-ar-15.2" + - "/usr/sbin/gcc-ar-15.2" + - "/sbin/gcc-ar-15.2" + - "/bin/gcc-ar-15.2" + - "/usr/games/gcc-ar-15.2" + - "/usr/local/games/gcc-ar-15.2" + - "/snap/bin/gcc-ar-15.2" + found: "/usr/bin/gcc-ar-15" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/Compiler/GNU-FindBinUtils.cmake:30 (find_program)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCXXCompiler.cmake:207 (include)" + - "CMakeLists.txt:2 (project)" + mode: "program" + variable: "CMAKE_CXX_COMPILER_RANLIB" + description: "A wrapper around 'ranlib' adding the appropriate '--plugin' option for the GCC compiler" + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: false + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: false + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "gcc-ranlib-15.2" + - "gcc-ranlib-15" + - "gcc-ranlib15" + - "gcc-ranlib" + candidate_directories: + - "/usr/bin/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + searched_directories: + - "/usr/bin/gcc-ranlib-15.2" + - "/home/cryptolicious/.local/bin/gcc-ranlib-15.2" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin/gcc-ranlib-15.2" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli/gcc-ranlib-15.2" + - "/home/cryptolicious/.cargo/bin/gcc-ranlib-15.2" + - "/usr/local/sbin/gcc-ranlib-15.2" + - "/usr/local/bin/gcc-ranlib-15.2" + - "/usr/sbin/gcc-ranlib-15.2" + - "/sbin/gcc-ranlib-15.2" + - "/bin/gcc-ranlib-15.2" + - "/usr/games/gcc-ranlib-15.2" + - "/usr/local/games/gcc-ranlib-15.2" + - "/snap/bin/gcc-ranlib-15.2" + found: "/usr/bin/gcc-ranlib-15" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/c4730f7d93d787d9ab120af715999f0345ee5bc0/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + - + kind: "try_compile-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerABI.cmake:83 (try_compile)" + - "/usr/share/cmake-4.2/Modules/CMakeTestCCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)" + - "CMakeLists.txt:2 (project)" + checks: + - "Detecting C compiler ABI info" + directories: + source: "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-H6zOSH" + binary: "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-H6zOSH" + cmakeVariables: + CMAKE_C_FLAGS: "" + CMAKE_C_FLAGS_DEBUG: "-g" + CMAKE_EXE_LINKER_FLAGS: "-fsanitize=address,undefined" + buildResult: + variable: "CMAKE_C_ABI_COMPILED" + cached: true + stdout: | + Change Dir: '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-H6zOSH' + + Run Build Command(s): /usr/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile cmTC_0acce/fast + /usr/bin/gmake -f CMakeFiles/cmTC_0acce.dir/build.make CMakeFiles/cmTC_0acce.dir/build + gmake[1]: Entering directory '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-H6zOSH' + Building C object CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o + /usr/bin/cc -v -o CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o -c /usr/share/cmake-4.2/Modules/CMakeCCompilerABI.c + Using built-in specs. + COLLECT_GCC=/usr/bin/cc + OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa + OFFLOAD_TARGET_DEFAULT=1 + Target: x86_64-linux-gnu + Configured with: ../src/configure -v --with-pkgversion='Ubuntu 15.2.0-16ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-15/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2,rust,cobol,algol68 --prefix=/usr --with-gcc-major-version-only --program-suffix=-15 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2 + Thread model: posix + Supported LTO compression algorithms: zlib zstd + gcc version 15.2.0 (Ubuntu 15.2.0-16ubuntu1) + COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_0acce.dir/' + /usr/libexec/gcc/x86_64-linux-gnu/15/cc1 -quiet -v -imultiarch x86_64-linux-gnu /usr/share/cmake-4.2/Modules/CMakeCCompilerABI.c -quiet -dumpdir CMakeFiles/cmTC_0acce.dir/ -dumpbase CMakeCCompilerABI.c.c -dumpbase-ext .c -mtune=generic -march=x86-64 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -fzero-init-padding-bits=all -Wbidi-chars=any -o /tmp/ccXSslO9.s + GNU C23 (Ubuntu 15.2.0-16ubuntu1) version 15.2.0 (x86_64-linux-gnu) + compiled by GNU C version 15.2.0, GMP version 6.3.0, MPFR version 4.2.2, MPC version 1.3.1, isl version isl-0.27-GMP + + warning: GMP header version 6.3.0 differs from library version 6.2.1. + GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 + ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" + ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/15/include-fixed/x86_64-linux-gnu" + ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/15/include-fixed" + ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include" + #include "..." search starts here: + #include <...> search starts here: + /usr/lib/gcc/x86_64-linux-gnu/15/include + /usr/local/include + /usr/include/x86_64-linux-gnu + /usr/include + End of search list. + Compiler executable checksum: edd70396dcc669433a92073f97309866 + COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_0acce.dir/' + /usr/bin/x86_64-linux-gnu-as -v --64 -o CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o /tmp/ccXSslO9.s + GNU assembler version 2.46 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.46 + COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/ + LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../:/lib/:/usr/lib/ + COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.' + Linking C executable cmTC_0acce + /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_0acce.dir/link.txt --verbose=1 + Using built-in specs. + COLLECT_GCC=/usr/bin/cc + COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper + OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa + OFFLOAD_TARGET_DEFAULT=1 + Target: x86_64-linux-gnu + Configured with: ../src/configure -v --with-pkgversion='Ubuntu 15.2.0-16ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-15/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2,rust,cobol,algol68 --prefix=/usr --with-gcc-major-version-only --program-suffix=-15 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2 + Thread model: posix + Supported LTO compression algorithms: zlib zstd + gcc version 15.2.0 (Ubuntu 15.2.0-16ubuntu1) + COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/ + LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../:/lib/:/usr/lib/ + COLLECT_GCC_OPTIONS='-fsanitize=address,undefined' '-v' '-o' 'cmTC_0acce' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_0acce.' + /usr/libexec/gcc/x86_64-linux-gnu/15/collect2 -plugin /usr/libexec/gcc/x86_64-linux-gnu/15/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper -plugin-opt=-fresolution=/tmp/ccVG4utd.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_0acce /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/15 -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/15/../../.. -L/lib -L/usr/lib /usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o --push-state --no-as-needed -lasan --pop-state -v CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o --push-state --no-as-needed -lubsan --pop-state -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o + collect2 version 15.2.0 + /usr/bin/ld -plugin /usr/libexec/gcc/x86_64-linux-gnu/15/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper -plugin-opt=-fresolution=/tmp/ccVG4utd.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_0acce /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/15 -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/15/../../.. -L/lib -L/usr/lib /usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o --push-state --no-as-needed -lasan --pop-state -v CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o --push-state --no-as-needed -lubsan --pop-state -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o + GNU ld (GNU Binutils for Ubuntu) 2.46 + COLLECT_GCC_OPTIONS='-fsanitize=address,undefined' '-v' '-o' 'cmTC_0acce' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_0acce.' + /usr/bin/cc -fsanitize=address,undefined -v -Wl,-v CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o -o cmTC_0acce + gmake[1]: Leaving directory '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-H6zOSH' + + exitCode: 0 + - + kind: "message-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerABI.cmake:217 (message)" + - "/usr/share/cmake-4.2/Modules/CMakeTestCCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)" + - "CMakeLists.txt:2 (project)" + message: | + Parsed C implicit include dir info: rv=done + found start of include info + found start of implicit include info + add: [/usr/lib/gcc/x86_64-linux-gnu/15/include] + add: [/usr/local/include] + add: [/usr/include/x86_64-linux-gnu] + add: [/usr/include] + end of search list found + collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/15/include] ==> [/usr/lib/gcc/x86_64-linux-gnu/15/include] + collapse include dir [/usr/local/include] ==> [/usr/local/include] + collapse include dir [/usr/include/x86_64-linux-gnu] ==> [/usr/include/x86_64-linux-gnu] + collapse include dir [/usr/include] ==> [/usr/include] + implicit include dirs: [/usr/lib/gcc/x86_64-linux-gnu/15/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include] + + + - + kind: "message-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerABI.cmake:253 (message)" + - "/usr/share/cmake-4.2/Modules/CMakeTestCCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)" + - "CMakeLists.txt:2 (project)" + message: | + Parsed C implicit link information: + link line regex: [^( *|.*[/\\])(ld[0-9]*(|\\.[a-rt-z][a-z]*|\\.s[a-np-z][a-z]*|\\.so[a-z]+)|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\\]+-)?ld|collect2)[^/\\]*( |$)] + linker tool regex: [^[ ]*(->|"|[0-9]+>[ -]*Build:[ 0-9]+ ms[ ]*)?[ ]*(([^"]*[/\\])?(ld[0-9]*(|\\.[a-rt-z][a-z]*|\\.s[a-np-z][a-z]*|\\.so[a-z]+)))("|,| |$)] + ignore line: [Change Dir: '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-H6zOSH'] + ignore line: [] + ignore line: [Run Build Command(s): /usr/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile cmTC_0acce/fast] + ignore line: [/usr/bin/gmake -f CMakeFiles/cmTC_0acce.dir/build.make CMakeFiles/cmTC_0acce.dir/build] + ignore line: [gmake[1]: Entering directory '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-H6zOSH'] + ignore line: [Building C object CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o] + ignore line: [/usr/bin/cc -v -o CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o -c /usr/share/cmake-4.2/Modules/CMakeCCompilerABI.c] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/cc] + ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa] + ignore line: [OFFLOAD_TARGET_DEFAULT=1] + ignore line: [Target: x86_64-linux-gnu] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 15.2.0-16ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-15/README.Bugs --enable-languages=c ada c++ go d fortran objc obj-c++ m2 rust cobol algol68 --prefix=/usr --with-gcc-major-version-only --program-suffix=-15 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-nvptx/usr amdgcn-amdhsa=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2] + ignore line: [Thread model: posix] + ignore line: [Supported LTO compression algorithms: zlib zstd] + ignore line: [gcc version 15.2.0 (Ubuntu 15.2.0-16ubuntu1) ] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_0acce.dir/'] + ignore line: [ /usr/libexec/gcc/x86_64-linux-gnu/15/cc1 -quiet -v -imultiarch x86_64-linux-gnu /usr/share/cmake-4.2/Modules/CMakeCCompilerABI.c -quiet -dumpdir CMakeFiles/cmTC_0acce.dir/ -dumpbase CMakeCCompilerABI.c.c -dumpbase-ext .c -mtune=generic -march=x86-64 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -fzero-init-padding-bits=all -Wbidi-chars=any -o /tmp/ccXSslO9.s] + ignore line: [GNU C23 (Ubuntu 15.2.0-16ubuntu1) version 15.2.0 (x86_64-linux-gnu)] + ignore line: [ compiled by GNU C version 15.2.0 GMP version 6.3.0 MPFR version 4.2.2 MPC version 1.3.1 isl version isl-0.27-GMP] + ignore line: [] + ignore line: [warning: GMP header version 6.3.0 differs from library version 6.2.1.] + ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072] + ignore line: [ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"] + ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/15/include-fixed/x86_64-linux-gnu"] + ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/15/include-fixed"] + ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include"] + ignore line: [#include "..." search starts here:] + ignore line: [#include <...> search starts here:] + ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/15/include] + ignore line: [ /usr/local/include] + ignore line: [ /usr/include/x86_64-linux-gnu] + ignore line: [ /usr/include] + ignore line: [End of search list.] + ignore line: [Compiler executable checksum: edd70396dcc669433a92073f97309866] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_0acce.dir/'] + ignore line: [ /usr/bin/x86_64-linux-gnu-as -v --64 -o CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o /tmp/ccXSslO9.s] + ignore line: [GNU assembler version 2.46 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.46] + ignore line: [COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/] + ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../:/lib/:/usr/lib/] + ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.'] + ignore line: [Linking C executable cmTC_0acce] + ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_0acce.dir/link.txt --verbose=1] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/cc] + ignore line: [COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper] + ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa] + ignore line: [OFFLOAD_TARGET_DEFAULT=1] + ignore line: [Target: x86_64-linux-gnu] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 15.2.0-16ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-15/README.Bugs --enable-languages=c ada c++ go d fortran objc obj-c++ m2 rust cobol algol68 --prefix=/usr --with-gcc-major-version-only --program-suffix=-15 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-nvptx/usr amdgcn-amdhsa=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2] + ignore line: [Thread model: posix] + ignore line: [Supported LTO compression algorithms: zlib zstd] + ignore line: [gcc version 15.2.0 (Ubuntu 15.2.0-16ubuntu1) ] + ignore line: [COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/] + ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../:/lib/:/usr/lib/] + ignore line: [COLLECT_GCC_OPTIONS='-fsanitize=address undefined' '-v' '-o' 'cmTC_0acce' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_0acce.'] + link line: [ /usr/libexec/gcc/x86_64-linux-gnu/15/collect2 -plugin /usr/libexec/gcc/x86_64-linux-gnu/15/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper -plugin-opt=-fresolution=/tmp/ccVG4utd.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_0acce /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/15 -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/15/../../.. -L/lib -L/usr/lib /usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o --push-state --no-as-needed -lasan --pop-state -v CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o --push-state --no-as-needed -lubsan --pop-state -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o] + arg [/usr/libexec/gcc/x86_64-linux-gnu/15/collect2] ==> ignore + arg [-plugin] ==> ignore + arg [/usr/libexec/gcc/x86_64-linux-gnu/15/liblto_plugin.so] ==> ignore + arg [-plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper] ==> ignore + arg [-plugin-opt=-fresolution=/tmp/ccVG4utd.res] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore + arg [-plugin-opt=-pass-through=-lc] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore + arg [--build-id] ==> ignore + arg [--eh-frame-hdr] ==> ignore + arg [-m] ==> ignore + arg [elf_x86_64] ==> ignore + arg [--hash-style=gnu] ==> ignore + arg [-dynamic-linker] ==> ignore + arg [/lib64/ld-linux-x86-64.so.2] ==> ignore + arg [-pie] ==> ignore + arg [-znow] ==> ignore + arg [-zrelro] ==> ignore + arg [-o] ==> ignore + arg [cmTC_0acce] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o] + arg [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o] + arg [/usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/15] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/15] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib] + arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu] + arg [-L/lib/../lib] ==> dir [/lib/../lib] + arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu] + arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/15/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/15/../../..] + arg [-L/lib] ==> dir [/lib] + arg [-L/usr/lib] ==> dir [/usr/lib] + arg [/usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o] + arg [--push-state] ==> ignore + arg [--no-as-needed] ==> ignore + arg [-lasan] ==> lib [asan] + arg [--pop-state] ==> ignore + arg [-v] ==> ignore + arg [CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o] ==> ignore + arg [--push-state] ==> ignore + arg [--no-as-needed] ==> ignore + arg [-lubsan] ==> lib [ubsan] + arg [--pop-state] ==> ignore + arg [-lgcc] ==> lib [gcc] + arg [--push-state] ==> ignore + arg [--as-needed] ==> ignore + arg [-lgcc_s] ==> lib [gcc_s] + arg [--pop-state] ==> ignore + arg [-lc] ==> lib [c] + arg [-lgcc] ==> lib [gcc] + arg [--push-state] ==> ignore + arg [--as-needed] ==> ignore + arg [-lgcc_s] ==> lib [gcc_s] + arg [--pop-state] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o] + arg [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o] + ignore line: [collect2 version 15.2.0] + ignore line: [/usr/bin/ld -plugin /usr/libexec/gcc/x86_64-linux-gnu/15/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper -plugin-opt=-fresolution=/tmp/ccVG4utd.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_0acce /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/15 -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/15/../../.. -L/lib -L/usr/lib /usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o --push-state --no-as-needed -lasan --pop-state -v CMakeFiles/cmTC_0acce.dir/CMakeCCompilerABI.c.o --push-state --no-as-needed -lubsan --pop-state -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o] + linker tool for 'C': /usr/bin/ld + collapse obj [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o] ==> [/usr/lib/x86_64-linux-gnu/Scrt1.o] + collapse obj [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o] ==> [/usr/lib/x86_64-linux-gnu/crti.o] + collapse obj [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o] ==> [/usr/lib/x86_64-linux-gnu/crtn.o] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/15] ==> [/usr/lib/gcc/x86_64-linux-gnu/15] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib] ==> [/usr/lib] + collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu] + collapse library dir [/lib/../lib] ==> [/lib] + collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse library dir [/usr/lib/../lib] ==> [/usr/lib] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/15/../../..] ==> [/usr/lib] + collapse library dir [/lib] ==> [/lib] + collapse library dir [/usr/lib] ==> [/usr/lib] + implicit libs: [asan;ubsan;gcc;gcc_s;c;gcc;gcc_s] + implicit objs: [/usr/lib/x86_64-linux-gnu/Scrt1.o;/usr/lib/x86_64-linux-gnu/crti.o;/usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o;/usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o;/usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o;/usr/lib/x86_64-linux-gnu/crtn.o] + implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/15;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib] + implicit fwks: [] + + + - + kind: "message-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/Internal/CMakeDetermineLinkerId.cmake:38 (message)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerABI.cmake:299 (cmake_determine_linker_id)" + - "/usr/share/cmake-4.2/Modules/CMakeTestCCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)" + - "CMakeLists.txt:2 (project)" + message: | + Running the C compiler's linker: "/usr/bin/ld" "-v" + GNU ld (GNU Binutils for Ubuntu) 2.46 + - + kind: "try_compile-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerABI.cmake:83 (try_compile)" + - "/usr/share/cmake-4.2/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)" + - "CMakeLists.txt:2 (project)" + checks: + - "Detecting CXX compiler ABI info" + directories: + source: "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-bD4Tip" + binary: "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-bD4Tip" + cmakeVariables: + CMAKE_CXX_FLAGS: "-fsanitize=address,undefined -fno-omit-frame-pointer -g -O1" + CMAKE_CXX_FLAGS_DEBUG: "-g" + CMAKE_CXX_SCAN_FOR_MODULES: "OFF" + CMAKE_EXE_LINKER_FLAGS: "-fsanitize=address,undefined" + buildResult: + variable: "CMAKE_CXX_ABI_COMPILED" + cached: true + stdout: | + Change Dir: '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-bD4Tip' + + Run Build Command(s): /usr/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile cmTC_b922a/fast + /usr/bin/gmake -f CMakeFiles/cmTC_b922a.dir/build.make CMakeFiles/cmTC_b922a.dir/build + gmake[1]: Entering directory '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-bD4Tip' + Building CXX object CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o + /usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -v -o CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-4.2/Modules/CMakeCXXCompilerABI.cpp + Using built-in specs. + COLLECT_GCC=/usr/bin/c++ + OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa + OFFLOAD_TARGET_DEFAULT=1 + Target: x86_64-linux-gnu + Configured with: ../src/configure -v --with-pkgversion='Ubuntu 15.2.0-16ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-15/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2,rust,cobol,algol68 --prefix=/usr --with-gcc-major-version-only --program-suffix=-15 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2 + Thread model: posix + Supported LTO compression algorithms: zlib zstd + gcc version 15.2.0 (Ubuntu 15.2.0-16ubuntu1) + COLLECT_GCC_OPTIONS='-fsanitize=address,undefined' '-fno-omit-frame-pointer' '-g' '-O1' '-v' '-o' 'CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_b922a.dir/' + /usr/libexec/gcc/x86_64-linux-gnu/15/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE /usr/share/cmake-4.2/Modules/CMakeCXXCompilerABI.cpp -D_FORTIFY_SOURCE=3 -quiet -dumpdir CMakeFiles/cmTC_b922a.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -g -O1 -version -fsanitize=address,undefined -fno-omit-frame-pointer -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -fzero-init-padding-bits=all -Wbidi-chars=any -o /tmp/ccPbWxKb.s + GNU C++17 (Ubuntu 15.2.0-16ubuntu1) version 15.2.0 (x86_64-linux-gnu) + compiled by GNU C version 15.2.0, GMP version 6.3.0, MPFR version 4.2.2, MPC version 1.3.1, isl version isl-0.27-GMP + + warning: GMP header version 6.3.0 differs from library version 6.2.1. + GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 + ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/15" + ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" + ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/15/include-fixed/x86_64-linux-gnu" + ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/15/include-fixed" + ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include" + #include "..." search starts here: + #include <...> search starts here: + /usr/include/c++/15 + /usr/include/x86_64-linux-gnu/c++/15 + /usr/include/c++/15/backward + /usr/lib/gcc/x86_64-linux-gnu/15/include + /usr/local/include + /usr/include/x86_64-linux-gnu + /usr/include + End of search list. + Compiler executable checksum: b661a74662ad7cf413c4193391ab5290 + COLLECT_GCC_OPTIONS='-fsanitize=address,undefined' '-fno-omit-frame-pointer' '-g' '-O1' '-v' '-o' 'CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_b922a.dir/' + /usr/bin/x86_64-linux-gnu-as -v --gdwarf-5 --64 -o CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccPbWxKb.s + GNU assembler version 2.46 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.46 + COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/ + LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../:/lib/:/usr/lib/ + COLLECT_GCC_OPTIONS='-fsanitize=address,undefined' '-fno-omit-frame-pointer' '-g' '-O1' '-v' '-o' 'CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.' + Linking CXX executable cmTC_b922a + /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_b922a.dir/link.txt --verbose=1 + Using built-in specs. + COLLECT_GCC=/usr/bin/c++ + COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper + OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa + OFFLOAD_TARGET_DEFAULT=1 + Target: x86_64-linux-gnu + Configured with: ../src/configure -v --with-pkgversion='Ubuntu 15.2.0-16ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-15/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2,rust,cobol,algol68 --prefix=/usr --with-gcc-major-version-only --program-suffix=-15 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2 + Thread model: posix + Supported LTO compression algorithms: zlib zstd + gcc version 15.2.0 (Ubuntu 15.2.0-16ubuntu1) + COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/ + LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../:/lib/:/usr/lib/ + COLLECT_GCC_OPTIONS='-fsanitize=address,undefined' '-fno-omit-frame-pointer' '-g' '-O1' '-fsanitize=address,undefined' '-v' '-o' 'cmTC_b922a' '-foffload-options=-l_GCC_stdc++' '-foffload-options=-l_GCC_m' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_b922a.' + /usr/libexec/gcc/x86_64-linux-gnu/15/collect2 -plugin /usr/libexec/gcc/x86_64-linux-gnu/15/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper -plugin-opt=-fresolution=/tmp/ccmbl5gW.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_b922a /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/15 -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/15/../../.. -L/lib -L/usr/lib /usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o --push-state --no-as-needed -lasan --pop-state -v CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm --push-state --no-as-needed -lubsan --pop-state -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o + collect2 version 15.2.0 + /usr/bin/ld -plugin /usr/libexec/gcc/x86_64-linux-gnu/15/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper -plugin-opt=-fresolution=/tmp/ccmbl5gW.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_b922a /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/15 -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/15/../../.. -L/lib -L/usr/lib /usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o --push-state --no-as-needed -lasan --pop-state -v CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm --push-state --no-as-needed -lubsan --pop-state -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o + GNU ld (GNU Binutils for Ubuntu) 2.46 + COLLECT_GCC_OPTIONS='-fsanitize=address,undefined' '-fno-omit-frame-pointer' '-g' '-O1' '-fsanitize=address,undefined' '-v' '-o' 'cmTC_b922a' '-foffload-options=-l_GCC_stdc++' '-foffload-options=-l_GCC_m' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_b922a.' + /usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -fsanitize=address,undefined -v -Wl,-v CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_b922a + gmake[1]: Leaving directory '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-bD4Tip' + + exitCode: 0 + - + kind: "message-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerABI.cmake:217 (message)" + - "/usr/share/cmake-4.2/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)" + - "CMakeLists.txt:2 (project)" + message: | + Parsed CXX implicit include dir info: rv=done + found start of include info + found start of implicit include info + add: [/usr/include/c++/15] + add: [/usr/include/x86_64-linux-gnu/c++/15] + add: [/usr/include/c++/15/backward] + add: [/usr/lib/gcc/x86_64-linux-gnu/15/include] + add: [/usr/local/include] + add: [/usr/include/x86_64-linux-gnu] + add: [/usr/include] + end of search list found + collapse include dir [/usr/include/c++/15] ==> [/usr/include/c++/15] + collapse include dir [/usr/include/x86_64-linux-gnu/c++/15] ==> [/usr/include/x86_64-linux-gnu/c++/15] + collapse include dir [/usr/include/c++/15/backward] ==> [/usr/include/c++/15/backward] + collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/15/include] ==> [/usr/lib/gcc/x86_64-linux-gnu/15/include] + collapse include dir [/usr/local/include] ==> [/usr/local/include] + collapse include dir [/usr/include/x86_64-linux-gnu] ==> [/usr/include/x86_64-linux-gnu] + collapse include dir [/usr/include] ==> [/usr/include] + implicit include dirs: [/usr/include/c++/15;/usr/include/x86_64-linux-gnu/c++/15;/usr/include/c++/15/backward;/usr/lib/gcc/x86_64-linux-gnu/15/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include] + + + - + kind: "message-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerABI.cmake:253 (message)" + - "/usr/share/cmake-4.2/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)" + - "CMakeLists.txt:2 (project)" + message: | + Parsed CXX implicit link information: + link line regex: [^( *|.*[/\\])(ld[0-9]*(|\\.[a-rt-z][a-z]*|\\.s[a-np-z][a-z]*|\\.so[a-z]+)|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\\]+-)?ld|collect2)[^/\\]*( |$)] + linker tool regex: [^[ ]*(->|"|[0-9]+>[ -]*Build:[ 0-9]+ ms[ ]*)?[ ]*(([^"]*[/\\])?(ld[0-9]*(|\\.[a-rt-z][a-z]*|\\.s[a-np-z][a-z]*|\\.so[a-z]+)))("|,| |$)] + ignore line: [Change Dir: '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-bD4Tip'] + ignore line: [] + ignore line: [Run Build Command(s): /usr/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile cmTC_b922a/fast] + ignore line: [/usr/bin/gmake -f CMakeFiles/cmTC_b922a.dir/build.make CMakeFiles/cmTC_b922a.dir/build] + ignore line: [gmake[1]: Entering directory '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-bD4Tip'] + ignore line: [Building CXX object CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o] + ignore line: [/usr/bin/c++ -fsanitize=address undefined -fno-omit-frame-pointer -g -O1 -v -o CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-4.2/Modules/CMakeCXXCompilerABI.cpp] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/c++] + ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa] + ignore line: [OFFLOAD_TARGET_DEFAULT=1] + ignore line: [Target: x86_64-linux-gnu] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 15.2.0-16ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-15/README.Bugs --enable-languages=c ada c++ go d fortran objc obj-c++ m2 rust cobol algol68 --prefix=/usr --with-gcc-major-version-only --program-suffix=-15 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-nvptx/usr amdgcn-amdhsa=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2] + ignore line: [Thread model: posix] + ignore line: [Supported LTO compression algorithms: zlib zstd] + ignore line: [gcc version 15.2.0 (Ubuntu 15.2.0-16ubuntu1) ] + ignore line: [COLLECT_GCC_OPTIONS='-fsanitize=address undefined' '-fno-omit-frame-pointer' '-g' '-O1' '-v' '-o' 'CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_b922a.dir/'] + ignore line: [ /usr/libexec/gcc/x86_64-linux-gnu/15/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE /usr/share/cmake-4.2/Modules/CMakeCXXCompilerABI.cpp -D_FORTIFY_SOURCE=3 -quiet -dumpdir CMakeFiles/cmTC_b922a.dir/ -dumpbase CMakeCXXCompilerABI.cpp.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -g -O1 -version -fsanitize=address undefined -fno-omit-frame-pointer -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -fzero-init-padding-bits=all -Wbidi-chars=any -o /tmp/ccPbWxKb.s] + ignore line: [GNU C++17 (Ubuntu 15.2.0-16ubuntu1) version 15.2.0 (x86_64-linux-gnu)] + ignore line: [ compiled by GNU C version 15.2.0 GMP version 6.3.0 MPFR version 4.2.2 MPC version 1.3.1 isl version isl-0.27-GMP] + ignore line: [] + ignore line: [warning: GMP header version 6.3.0 differs from library version 6.2.1.] + ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072] + ignore line: [ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/15"] + ignore line: [ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"] + ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/15/include-fixed/x86_64-linux-gnu"] + ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/15/include-fixed"] + ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include"] + ignore line: [#include "..." search starts here:] + ignore line: [#include <...> search starts here:] + ignore line: [ /usr/include/c++/15] + ignore line: [ /usr/include/x86_64-linux-gnu/c++/15] + ignore line: [ /usr/include/c++/15/backward] + ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/15/include] + ignore line: [ /usr/local/include] + ignore line: [ /usr/include/x86_64-linux-gnu] + ignore line: [ /usr/include] + ignore line: [End of search list.] + ignore line: [Compiler executable checksum: b661a74662ad7cf413c4193391ab5290] + ignore line: [COLLECT_GCC_OPTIONS='-fsanitize=address undefined' '-fno-omit-frame-pointer' '-g' '-O1' '-v' '-o' 'CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_b922a.dir/'] + ignore line: [ /usr/bin/x86_64-linux-gnu-as -v --gdwarf-5 --64 -o CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccPbWxKb.s] + ignore line: [GNU assembler version 2.46 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.46] + ignore line: [COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/] + ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../:/lib/:/usr/lib/] + ignore line: [COLLECT_GCC_OPTIONS='-fsanitize=address undefined' '-fno-omit-frame-pointer' '-g' '-O1' '-v' '-o' 'CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.'] + ignore line: [Linking CXX executable cmTC_b922a] + ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_b922a.dir/link.txt --verbose=1] + ignore line: [Using built-in specs.] + ignore line: [COLLECT_GCC=/usr/bin/c++] + ignore line: [COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper] + ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa] + ignore line: [OFFLOAD_TARGET_DEFAULT=1] + ignore line: [Target: x86_64-linux-gnu] + ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 15.2.0-16ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-15/README.Bugs --enable-languages=c ada c++ go d fortran objc obj-c++ m2 rust cobol algol68 --prefix=/usr --with-gcc-major-version-only --program-suffix=-15 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-nvptx/usr amdgcn-amdhsa=/build/gcc-15-j35TAX/gcc-15-15.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2] + ignore line: [Thread model: posix] + ignore line: [Supported LTO compression algorithms: zlib zstd] + ignore line: [gcc version 15.2.0 (Ubuntu 15.2.0-16ubuntu1) ] + ignore line: [COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/15/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/] + ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/15/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/15/../../../:/lib/:/usr/lib/] + ignore line: [COLLECT_GCC_OPTIONS='-fsanitize=address undefined' '-fno-omit-frame-pointer' '-g' '-O1' '-fsanitize=address undefined' '-v' '-o' 'cmTC_b922a' '-foffload-options=-l_GCC_stdc++' '-foffload-options=-l_GCC_m' '-shared-libgcc' '-mtune=generic' '-march=x86-64' '-dumpdir' 'cmTC_b922a.'] + link line: [ /usr/libexec/gcc/x86_64-linux-gnu/15/collect2 -plugin /usr/libexec/gcc/x86_64-linux-gnu/15/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper -plugin-opt=-fresolution=/tmp/ccmbl5gW.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_b922a /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/15 -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/15/../../.. -L/lib -L/usr/lib /usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o --push-state --no-as-needed -lasan --pop-state -v CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm --push-state --no-as-needed -lubsan --pop-state -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o] + arg [/usr/libexec/gcc/x86_64-linux-gnu/15/collect2] ==> ignore + arg [-plugin] ==> ignore + arg [/usr/libexec/gcc/x86_64-linux-gnu/15/liblto_plugin.so] ==> ignore + arg [-plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper] ==> ignore + arg [-plugin-opt=-fresolution=/tmp/ccmbl5gW.res] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc] ==> ignore + arg [-plugin-opt=-pass-through=-lc] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore + arg [-plugin-opt=-pass-through=-lgcc] ==> ignore + arg [--build-id] ==> ignore + arg [--eh-frame-hdr] ==> ignore + arg [-m] ==> ignore + arg [elf_x86_64] ==> ignore + arg [--hash-style=gnu] ==> ignore + arg [-dynamic-linker] ==> ignore + arg [/lib64/ld-linux-x86-64.so.2] ==> ignore + arg [-pie] ==> ignore + arg [-znow] ==> ignore + arg [-zrelro] ==> ignore + arg [-o] ==> ignore + arg [cmTC_b922a] ==> ignore + arg [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o] + arg [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o] + arg [/usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/15] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/15] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib] + arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu] + arg [-L/lib/../lib] ==> dir [/lib/../lib] + arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu] + arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib] + arg [-L/usr/lib/gcc/x86_64-linux-gnu/15/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/15/../../..] + arg [-L/lib] ==> dir [/lib] + arg [-L/usr/lib] ==> dir [/usr/lib] + arg [/usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o] + arg [--push-state] ==> ignore + arg [--no-as-needed] ==> ignore + arg [-lasan] ==> lib [asan] + arg [--pop-state] ==> ignore + arg [-v] ==> ignore + arg [CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore + arg [-lstdc++] ==> lib [stdc++] + arg [-lm] ==> lib [m] + arg [--push-state] ==> ignore + arg [--no-as-needed] ==> ignore + arg [-lubsan] ==> lib [ubsan] + arg [--pop-state] ==> ignore + arg [-lgcc_s] ==> lib [gcc_s] + arg [-lgcc] ==> lib [gcc] + arg [-lc] ==> lib [c] + arg [-lgcc_s] ==> lib [gcc_s] + arg [-lgcc] ==> lib [gcc] + arg [/usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o] + arg [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o] ==> obj [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o] + ignore line: [collect2 version 15.2.0] + ignore line: [/usr/bin/ld -plugin /usr/libexec/gcc/x86_64-linux-gnu/15/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper -plugin-opt=-fresolution=/tmp/ccmbl5gW.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_b922a /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/15 -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/15/../../.. -L/lib -L/usr/lib /usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o --push-state --no-as-needed -lasan --pop-state -v CMakeFiles/cmTC_b922a.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm --push-state --no-as-needed -lubsan --pop-state -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o] + linker tool for 'CXX': /usr/bin/ld + collapse obj [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/Scrt1.o] ==> [/usr/lib/x86_64-linux-gnu/Scrt1.o] + collapse obj [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crti.o] ==> [/usr/lib/x86_64-linux-gnu/crti.o] + collapse obj [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu/crtn.o] ==> [/usr/lib/x86_64-linux-gnu/crtn.o] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/15] ==> [/usr/lib/gcc/x86_64-linux-gnu/15] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/15/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/15/../../../../lib] ==> [/usr/lib] + collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu] + collapse library dir [/lib/../lib] ==> [/lib] + collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu] + collapse library dir [/usr/lib/../lib] ==> [/usr/lib] + collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/15/../../..] ==> [/usr/lib] + collapse library dir [/lib] ==> [/lib] + collapse library dir [/usr/lib] ==> [/usr/lib] + implicit libs: [asan;stdc++;m;ubsan;gcc_s;gcc;c;gcc_s;gcc] + implicit objs: [/usr/lib/x86_64-linux-gnu/Scrt1.o;/usr/lib/x86_64-linux-gnu/crti.o;/usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o;/usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o;/usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o;/usr/lib/x86_64-linux-gnu/crtn.o] + implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/15;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib] + implicit fwks: [] + + + - + kind: "message-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/Internal/CMakeDetermineLinkerId.cmake:38 (message)" + - "/usr/share/cmake-4.2/Modules/CMakeDetermineCompilerABI.cmake:299 (cmake_determine_linker_id)" + - "/usr/share/cmake-4.2/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)" + - "CMakeLists.txt:2 (project)" + message: | + Running the CXX compiler's linker: "/usr/bin/ld" "-v" + GNU ld (GNU Binutils for Ubuntu) 2.46 + - + kind: "try_compile-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/Internal/CheckSourceCompiles.cmake:104 (try_compile)" + - "/usr/share/cmake-4.2/Modules/CheckCSourceCompiles.cmake:103 (cmake_check_source_compiles)" + - "/usr/share/cmake-4.2/Modules/FindThreads.cmake:160 (check_c_source_compiles)" + - "/usr/share/cmake-4.2/Modules/FindThreads.cmake:226 (_threads_check_libc)" + - "googletest/googletest/cmake/internal_utils.cmake:58 (find_package)" + - "googletest/googletest/CMakeLists.txt:83 (config_compiler_and_linker)" + checks: + - "Performing Test CMAKE_HAVE_LIBC_PTHREAD" + directories: + source: "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-jm7nNb" + binary: "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-jm7nNb" + cmakeVariables: + CMAKE_C_FLAGS: "" + CMAKE_C_FLAGS_DEBUG: "-g" + CMAKE_EXE_LINKER_FLAGS: "-fsanitize=address,undefined" + buildResult: + variable: "CMAKE_HAVE_LIBC_PTHREAD" + cached: true + stdout: | + Change Dir: '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-jm7nNb' + + Run Build Command(s): /usr/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile cmTC_c551f/fast + /usr/bin/gmake -f CMakeFiles/cmTC_c551f.dir/build.make CMakeFiles/cmTC_c551f.dir/build + gmake[1]: Entering directory '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-jm7nNb' + Building C object CMakeFiles/cmTC_c551f.dir/src.c.o + /usr/bin/cc -DCMAKE_HAVE_LIBC_PTHREAD -o CMakeFiles/cmTC_c551f.dir/src.c.o -c /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-jm7nNb/src.c + Linking C executable cmTC_c551f + /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_c551f.dir/link.txt --verbose=1 + /usr/bin/cc -fsanitize=address,undefined CMakeFiles/cmTC_c551f.dir/src.c.o -o cmTC_c551f + gmake[1]: Leaving directory '/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/CMakeScratch/TryCompile-jm7nNb' + + exitCode: 0 +... + +--- +events: + - + kind: "find-v1" + backtrace: + - "CMakeLists.txt:163 (find_library)" + mode: "library" + variable: "SCTP_LIB" + description: "Path to a library." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "sctp" + candidate_directories: + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/usr/bin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + - "/usr/local/lib/x86_64-linux-gnu/" + - "/usr/local/lib/" + - "/usr/local/" + - "/usr/lib/x86_64-linux-gnu/" + - "/usr/lib/" + - "/usr/" + - "/lib/x86_64-linux-gnu/" + - "/lib/" + - "/usr/X11R6/lib/x86_64-linux-gnu/" + - "/usr/X11R6/lib/" + - "/usr/X11R6/" + - "/usr/pkg/lib/x86_64-linux-gnu/" + - "/usr/pkg/lib/" + - "/usr/pkg/" + - "/opt/lib/x86_64-linux-gnu/" + - "/opt/lib/" + - "/opt/" + - "/usr/lib/X11/" + searched_directories: + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/usr/bin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + - "/usr/local/lib/x86_64-linux-gnu/" + - "/usr/local/lib/" + - "/usr/local/" + found: "/usr/lib/x86_64-linux-gnu/libsctp.so" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + CMAKE_INSTALL_PREFIX: "/usr/local" + CMAKE_SYSTEM_PREFIX_PATH: + - "/usr/local" + - "/usr" + - "/" + - "/usr" + - "/usr/local" + - "/usr/X11R6" + - "/usr/pkg" + - "/opt" + CMAKE_SYSTEM_LIBRARY_PATH: + - "/usr/lib/X11" +... + +--- +events: + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/FindPkgConfig.cmake:517 (find_program)" + - "/usr/share/cmake-4.2/Modules/FindOpenSSL.cmake:295 (find_package)" + - "CMakeLists.txt:36 (find_package)" + mode: "program" + variable: "PKG_CONFIG_EXECUTABLE" + description: "pkg-config executable" + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "pkg-config" + - "pkgconf" + candidate_directories: + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/" + - "/usr/local/bin/" + - "/usr/sbin/" + - "/usr/bin/" + - "/sbin/" + - "/bin/" + - "/usr/games/" + - "/usr/local/games/" + - "/snap/bin/" + - "/usr/local/bin/" + - "/usr/local/sbin/" + - "/usr/local/" + - "/usr/bin/" + - "/usr/sbin/" + - "/usr/" + - "/bin/" + - "/sbin/" + - "/usr/X11R6/bin/" + - "/usr/X11R6/sbin/" + - "/usr/X11R6/" + - "/usr/pkg/bin/" + - "/usr/pkg/sbin/" + - "/usr/pkg/" + - "/opt/bin/" + - "/opt/sbin/" + - "/opt/" + searched_directories: + - "/home/cryptolicious/.local/bin/pkg-config" + - "/home/cryptolicious/.local/bin/pkgconf" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/pkg-config" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/pkgconf" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/pkg-config" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/pkgconf" + - "/home/cryptolicious/.cargo/bin/pkg-config" + - "/home/cryptolicious/.cargo/bin/pkgconf" + - "/usr/local/sbin/pkg-config" + - "/usr/local/sbin/pkgconf" + - "/usr/local/bin/pkg-config" + - "/usr/local/bin/pkgconf" + - "/usr/sbin/pkg-config" + - "/usr/sbin/pkgconf" + found: "/usr/bin/pkg-config" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + CMAKE_INSTALL_PREFIX: "/usr/local" + CMAKE_SYSTEM_PREFIX_PATH: + - "/usr/local" + - "/usr" + - "/" + - "/usr" + - "/usr/local" + - "/usr/X11R6" + - "/usr/pkg" + - "/opt" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/FindPkgConfig.cmake:761 (find_library)" + - "/usr/share/cmake-4.2/Modules/FindPkgConfig.cmake:811 (_pkg_find_libs)" + - "/usr/share/cmake-4.2/Modules/FindPkgConfig.cmake:1149 (_pkg_recalculate)" + - "/usr/share/cmake-4.2/Modules/FindPkgConfig.cmake:1166 (_pkg_check_modules_internal)" + - "/usr/share/cmake-4.2/Modules/FindOpenSSL.cmake:297 (pkg_check_modules)" + - "CMakeLists.txt:36 (find_package)" + mode: "library" + variable: "pkgcfg_lib__OPENSSL_ssl" + description: "Path to a library." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "ssl" + candidate_directories: + - "/usr/lib/x86_64-linux-gnu/" + found: "/usr/lib/x86_64-linux-gnu/libssl.so" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + CMAKE_INSTALL_PREFIX: "/usr/local" + CMAKE_SYSTEM_PREFIX_PATH: + - "/usr/local" + - "/usr" + - "/" + - "/usr" + - "/usr/local" + - "/usr/X11R6" + - "/usr/pkg" + - "/opt" + CMAKE_SYSTEM_LIBRARY_PATH: + - "/usr/lib/X11" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/FindPkgConfig.cmake:761 (find_library)" + - "/usr/share/cmake-4.2/Modules/FindPkgConfig.cmake:811 (_pkg_find_libs)" + - "/usr/share/cmake-4.2/Modules/FindPkgConfig.cmake:1149 (_pkg_recalculate)" + - "/usr/share/cmake-4.2/Modules/FindPkgConfig.cmake:1166 (_pkg_check_modules_internal)" + - "/usr/share/cmake-4.2/Modules/FindOpenSSL.cmake:297 (pkg_check_modules)" + - "CMakeLists.txt:36 (find_package)" + mode: "library" + variable: "pkgcfg_lib__OPENSSL_crypto" + description: "Path to a library." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "crypto" + candidate_directories: + - "/usr/lib/x86_64-linux-gnu/" + found: "/usr/lib/x86_64-linux-gnu/libcrypto.so" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + CMAKE_INSTALL_PREFIX: "/usr/local" + CMAKE_SYSTEM_PREFIX_PATH: + - "/usr/local" + - "/usr" + - "/" + - "/usr" + - "/usr/local" + - "/usr/X11R6" + - "/usr/pkg" + - "/opt" + CMAKE_SYSTEM_LIBRARY_PATH: + - "/usr/lib/X11" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/FindOpenSSL.cmake:370 (find_path)" + - "CMakeLists.txt:36 (find_package)" + mode: "path" + variable: "OPENSSL_INCLUDE_DIR" + description: "Path to a file." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "openssl/ssl.h" + candidate_directories: + - "/usr/include/include/" + - "/usr/include/" + - "/home/cryptolicious/.local/bin/include/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/include/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/include/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/include/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/include/" + - "/usr/local/sbin/" + - "/usr/local/bin/include/" + - "/usr/local/bin/" + - "/usr/sbin/include/" + - "/usr/sbin/" + - "/usr/bin/include/" + - "/usr/bin/" + - "/sbin/include/" + - "/sbin/" + - "/bin/include/" + - "/bin/" + - "/usr/games/include/" + - "/usr/games/" + - "/usr/local/games/include/" + - "/usr/local/games/" + - "/snap/bin/include/" + - "/snap/bin/" + - "/usr/local/include/x86_64-linux-gnu/include/" + - "/usr/local/include/x86_64-linux-gnu/" + - "/usr/local/include/include/" + - "/usr/local/include/" + - "/usr/local/include/" + - "/usr/local/" + - "/usr/include/x86_64-linux-gnu/include/" + - "/usr/include/x86_64-linux-gnu/" + - "/usr/include/include/" + - "/usr/include/" + - "/usr/include/" + - "/usr/" + - "/include/x86_64-linux-gnu/include/" + - "/include/x86_64-linux-gnu/" + - "/include/include/" + - "/include/" + - "/usr/X11R6/include/x86_64-linux-gnu/include/" + - "/usr/X11R6/include/x86_64-linux-gnu/" + - "/usr/X11R6/include/include/" + - "/usr/X11R6/include/" + - "/usr/X11R6/include/" + - "/usr/X11R6/" + - "/usr/pkg/include/x86_64-linux-gnu/include/" + - "/usr/pkg/include/x86_64-linux-gnu/" + - "/usr/pkg/include/include/" + - "/usr/pkg/include/" + - "/usr/pkg/include/" + - "/usr/pkg/" + - "/opt/include/x86_64-linux-gnu/include/" + - "/opt/include/x86_64-linux-gnu/" + - "/opt/include/include/" + - "/opt/include/" + - "/opt/include/" + - "/opt/" + - "/usr/include/X11/include/" + - "/usr/include/X11/" + searched_directories: + - "/usr/include/include/openssl/ssl.h" + found: "/usr/include/" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + CMAKE_INSTALL_PREFIX: "/usr/local" + CMAKE_SYSTEM_PREFIX_PATH: + - "/usr/local" + - "/usr" + - "/" + - "/usr" + - "/usr/local" + - "/usr/X11R6" + - "/usr/pkg" + - "/opt" + CMAKE_SYSTEM_INCLUDE_PATH: + - "/usr/include/X11" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/FindOpenSSL.cmake:628 (find_library)" + - "CMakeLists.txt:36 (find_package)" + mode: "library" + variable: "OPENSSL_SSL_LIBRARY" + description: "Path to a library." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "ssl" + - "ssleay32" + - "ssleay32MD" + candidate_directories: + - "/usr/lib/x86_64-linux-gnu/lib/" + - "/usr/lib/x86_64-linux-gnu/lib64/" + - "/usr/lib/x86_64-linux-gnu/" + - "/home/cryptolicious/.local/bin/lib/" + - "/home/cryptolicious/.local/bin/lib64/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/lib/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/lib64/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/lib/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/lib64/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/lib/" + - "/home/cryptolicious/.cargo/bin/lib64/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/lib/" + - "/usr/local/sbin/lib64/" + - "/usr/local/sbin/" + - "/usr/local/bin/lib/" + - "/usr/local/bin/lib64/" + - "/usr/local/bin/" + - "/usr/sbin/lib/" + - "/usr/sbin/lib64/" + - "/usr/sbin/" + - "/usr/bin/lib/" + - "/usr/bin/lib64/" + - "/usr/bin/" + - "/sbin/lib/" + - "/sbin/lib64/" + - "/sbin/" + - "/bin/lib/" + - "/bin/lib64/" + - "/bin/" + - "/usr/games/lib/" + - "/usr/games/lib64/" + - "/usr/games/" + - "/usr/local/games/lib/" + - "/usr/local/games/lib64/" + - "/usr/local/games/" + - "/snap/bin/lib/" + - "/snap/bin/lib64/" + - "/snap/bin/" + - "/usr/local/lib/x86_64-linux-gnu/lib/" + - "/usr/local/lib/x86_64-linux-gnu/lib64/" + - "/usr/local/lib/x86_64-linux-gnu/" + - "/usr/local/lib/lib/" + - "/usr/local/lib/lib64/" + - "/usr/local/lib/" + - "/usr/local/lib/" + - "/usr/local/lib64/" + - "/usr/local/" + - "/usr/lib/x86_64-linux-gnu/lib/" + - "/usr/lib/x86_64-linux-gnu/lib64/" + - "/usr/lib/x86_64-linux-gnu/" + - "/usr/lib/lib/" + - "/usr/lib/lib64/" + - "/usr/lib/" + - "/usr/lib/" + - "/usr/lib64/" + - "/usr/" + - "/lib/x86_64-linux-gnu/lib/" + - "/lib/x86_64-linux-gnu/lib64/" + - "/lib/x86_64-linux-gnu/" + - "/lib/lib/" + - "/lib/lib64/" + - "/lib/" + - "/usr/X11R6/lib/x86_64-linux-gnu/lib/" + - "/usr/X11R6/lib/x86_64-linux-gnu/lib64/" + - "/usr/X11R6/lib/x86_64-linux-gnu/" + - "/usr/X11R6/lib/lib/" + - "/usr/X11R6/lib/lib64/" + - "/usr/X11R6/lib/" + - "/usr/X11R6/lib/" + - "/usr/X11R6/lib64/" + - "/usr/X11R6/" + - "/usr/pkg/lib/x86_64-linux-gnu/lib/" + - "/usr/pkg/lib/x86_64-linux-gnu/lib64/" + - "/usr/pkg/lib/x86_64-linux-gnu/" + - "/usr/pkg/lib/lib/" + - "/usr/pkg/lib/lib64/" + - "/usr/pkg/lib/" + - "/usr/pkg/lib/" + - "/usr/pkg/lib64/" + - "/usr/pkg/" + - "/opt/lib/x86_64-linux-gnu/lib/" + - "/opt/lib/x86_64-linux-gnu/lib64/" + - "/opt/lib/x86_64-linux-gnu/" + - "/opt/lib/lib/" + - "/opt/lib/lib64/" + - "/opt/lib/" + - "/opt/lib/" + - "/opt/lib64/" + - "/opt/" + - "/usr/lib/X11/lib/" + - "/usr/lib/X11/lib64/" + - "/usr/lib/X11/" + searched_directories: + - "/usr/lib/x86_64-linux-gnu/lib/" + - "/usr/lib/x86_64-linux-gnu/lib/" + - "/usr/lib/x86_64-linux-gnu/lib/" + - "/usr/lib/x86_64-linux-gnu/lib64/" + - "/usr/lib/x86_64-linux-gnu/lib64/" + - "/usr/lib/x86_64-linux-gnu/lib64/" + found: "/usr/lib/x86_64-linux-gnu/libssl.so" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + CMAKE_INSTALL_PREFIX: "/usr/local" + CMAKE_SYSTEM_PREFIX_PATH: + - "/usr/local" + - "/usr" + - "/" + - "/usr" + - "/usr/local" + - "/usr/X11R6" + - "/usr/pkg" + - "/opt" + CMAKE_SYSTEM_LIBRARY_PATH: + - "/usr/lib/X11" + - + kind: "find-v1" + backtrace: + - "/usr/share/cmake-4.2/Modules/FindOpenSSL.cmake:642 (find_library)" + - "CMakeLists.txt:36 (find_package)" + mode: "library" + variable: "OPENSSL_CRYPTO_LIBRARY" + description: "Path to a library." + settings: + SearchFramework: "NEVER" + SearchAppBundle: "NEVER" + CMAKE_FIND_USE_CMAKE_PATH: true + CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true + CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true + CMAKE_FIND_USE_INSTALL_PREFIX: true + names: + - "crypto" + candidate_directories: + - "/usr/lib/x86_64-linux-gnu/lib/" + - "/usr/lib/x86_64-linux-gnu/lib64/" + - "/usr/lib/x86_64-linux-gnu/" + - "/home/cryptolicious/.local/bin/lib/" + - "/home/cryptolicious/.local/bin/lib64/" + - "/home/cryptolicious/.local/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/lib/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/lib64/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/lib/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/lib64/" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli/" + - "/home/cryptolicious/.cargo/bin/lib/" + - "/home/cryptolicious/.cargo/bin/lib64/" + - "/home/cryptolicious/.cargo/bin/" + - "/usr/local/sbin/lib/" + - "/usr/local/sbin/lib64/" + - "/usr/local/sbin/" + - "/usr/local/bin/lib/" + - "/usr/local/bin/lib64/" + - "/usr/local/bin/" + - "/usr/sbin/lib/" + - "/usr/sbin/lib64/" + - "/usr/sbin/" + - "/usr/bin/lib/" + - "/usr/bin/lib64/" + - "/usr/bin/" + - "/sbin/lib/" + - "/sbin/lib64/" + - "/sbin/" + - "/bin/lib/" + - "/bin/lib64/" + - "/bin/" + - "/usr/games/lib/" + - "/usr/games/lib64/" + - "/usr/games/" + - "/usr/local/games/lib/" + - "/usr/local/games/lib64/" + - "/usr/local/games/" + - "/snap/bin/lib/" + - "/snap/bin/lib64/" + - "/snap/bin/" + - "/usr/local/lib/x86_64-linux-gnu/lib/" + - "/usr/local/lib/x86_64-linux-gnu/lib64/" + - "/usr/local/lib/x86_64-linux-gnu/" + - "/usr/local/lib/lib/" + - "/usr/local/lib/lib64/" + - "/usr/local/lib/" + - "/usr/local/lib/" + - "/usr/local/lib64/" + - "/usr/local/" + - "/usr/lib/x86_64-linux-gnu/lib/" + - "/usr/lib/x86_64-linux-gnu/lib64/" + - "/usr/lib/x86_64-linux-gnu/" + - "/usr/lib/lib/" + - "/usr/lib/lib64/" + - "/usr/lib/" + - "/usr/lib/" + - "/usr/lib64/" + - "/usr/" + - "/lib/x86_64-linux-gnu/lib/" + - "/lib/x86_64-linux-gnu/lib64/" + - "/lib/x86_64-linux-gnu/" + - "/lib/lib/" + - "/lib/lib64/" + - "/lib/" + - "/usr/X11R6/lib/x86_64-linux-gnu/lib/" + - "/usr/X11R6/lib/x86_64-linux-gnu/lib64/" + - "/usr/X11R6/lib/x86_64-linux-gnu/" + - "/usr/X11R6/lib/lib/" + - "/usr/X11R6/lib/lib64/" + - "/usr/X11R6/lib/" + - "/usr/X11R6/lib/" + - "/usr/X11R6/lib64/" + - "/usr/X11R6/" + - "/usr/pkg/lib/x86_64-linux-gnu/lib/" + - "/usr/pkg/lib/x86_64-linux-gnu/lib64/" + - "/usr/pkg/lib/x86_64-linux-gnu/" + - "/usr/pkg/lib/lib/" + - "/usr/pkg/lib/lib64/" + - "/usr/pkg/lib/" + - "/usr/pkg/lib/" + - "/usr/pkg/lib64/" + - "/usr/pkg/" + - "/opt/lib/x86_64-linux-gnu/lib/" + - "/opt/lib/x86_64-linux-gnu/lib64/" + - "/opt/lib/x86_64-linux-gnu/" + - "/opt/lib/lib/" + - "/opt/lib/lib64/" + - "/opt/lib/" + - "/opt/lib/" + - "/opt/lib64/" + - "/opt/" + - "/usr/lib/X11/lib/" + - "/usr/lib/X11/lib64/" + - "/usr/lib/X11/" + searched_directories: + - "/usr/lib/x86_64-linux-gnu/lib/" + - "/usr/lib/x86_64-linux-gnu/lib64/" + found: "/usr/lib/x86_64-linux-gnu/libcrypto.so" + search_context: + ENV{PATH}: + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/node_modules/@vscode/ripgrep/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.local/bin" + - "/home/cryptolicious/.cursor-server/bin/linux-x64/37076c6c3f9e253c0fa2305197e45befd13a2260/bin/remote-cli" + - "/home/cryptolicious/.cargo/bin" + - "/home/cryptolicious/.local/bin" + - "/usr/local/sbin" + - "/usr/local/bin" + - "/usr/sbin" + - "/usr/bin" + - "/sbin" + - "/bin" + - "/usr/games" + - "/usr/local/games" + - "/snap/bin" + CMAKE_INSTALL_PREFIX: "/usr/local" + CMAKE_SYSTEM_PREFIX_PATH: + - "/usr/local" + - "/usr" + - "/" + - "/usr" + - "/usr/local" + - "/usr/X11R6" + - "/usr/pkg" + - "/opt" + CMAKE_SYSTEM_LIBRARY_PATH: + - "/usr/lib/X11" +... diff --git a/test/build-asan/CMakeFiles/CMakeDirectoryInformation.cmake b/test/build-asan/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..f27a407 --- /dev/null +++ b/test/build-asan/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,16 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Relative path conversion top directories. +set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/cryptolicious/hushmap-specified/libdpf/test") +set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan") + +# Force unix paths in dependencies. +set(CMAKE_FORCE_UNIX_PATHS 1) + + +# The C and CXX include file regular expressions for this directory. +set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/test/build-asan/CMakeFiles/InstallScripts.json b/test/build-asan/CMakeFiles/InstallScripts.json new file mode 100644 index 0000000..2892816 --- /dev/null +++ b/test/build-asan/CMakeFiles/InstallScripts.json @@ -0,0 +1,9 @@ +{ + "InstallScripts" : + [ + "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/cmake_install.cmake", + "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/cmake_install.cmake", + "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest/cmake_install.cmake" + ], + "Parallel" : false +} diff --git a/test/build-asan/CMakeFiles/Makefile.cmake b/test/build-asan/CMakeFiles/Makefile.cmake new file mode 100644 index 0000000..95f3034 --- /dev/null +++ b/test/build-asan/CMakeFiles/Makefile.cmake @@ -0,0 +1,191 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# The generator used is: +set(CMAKE_DEPENDS_GENERATOR "Unix Makefiles") + +# The top level Makefile was generated from the following files: +set(CMAKE_MAKEFILE_DEPENDS + "CMakeCache.txt" + "/home/cryptolicious/hushmap-specified/libdpf/test/CMakeLists.txt" + "CMakeFiles/4.2.3/CMakeCCompiler.cmake" + "CMakeFiles/4.2.3/CMakeCXXCompiler.cmake" + "CMakeFiles/4.2.3/CMakeSystem.cmake" + "/home/cryptolicious/hushmap-specified/libdpf/test/googletest/CMakeLists.txt" + "/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/CMakeLists.txt" + "/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/cmake/internal_utils.cmake" + "/usr/share/cmake-4.2/Modules/CMakeCInformation.cmake" + "/usr/share/cmake-4.2/Modules/CMakeCXXInformation.cmake" + "/usr/share/cmake-4.2/Modules/CMakeCommonLanguageInclude.cmake" + "/usr/share/cmake-4.2/Modules/CMakeDependentOption.cmake" + "/usr/share/cmake-4.2/Modules/CMakeGenericSystem.cmake" + "/usr/share/cmake-4.2/Modules/CMakeInitializeConfigs.cmake" + "/usr/share/cmake-4.2/Modules/CMakeLanguageInformation.cmake" + "/usr/share/cmake-4.2/Modules/CMakeSystemSpecificInformation.cmake" + "/usr/share/cmake-4.2/Modules/CMakeSystemSpecificInitialize.cmake" + "/usr/share/cmake-4.2/Modules/CheckCSourceCompiles.cmake" + "/usr/share/cmake-4.2/Modules/CheckIncludeFile.cmake" + "/usr/share/cmake-4.2/Modules/CheckLibraryExists.cmake" + "/usr/share/cmake-4.2/Modules/Compiler/CMakeCommonCompilerMacros.cmake" + "/usr/share/cmake-4.2/Modules/Compiler/GNU-C.cmake" + "/usr/share/cmake-4.2/Modules/Compiler/GNU-CXX.cmake" + "/usr/share/cmake-4.2/Modules/Compiler/GNU.cmake" + "/usr/share/cmake-4.2/Modules/FindOpenSSL.cmake" + "/usr/share/cmake-4.2/Modules/FindPackageHandleStandardArgs.cmake" + "/usr/share/cmake-4.2/Modules/FindPackageMessage.cmake" + "/usr/share/cmake-4.2/Modules/FindPkgConfig.cmake" + "/usr/share/cmake-4.2/Modules/FindThreads.cmake" + "/usr/share/cmake-4.2/Modules/GNUInstallDirs.cmake" + "/usr/share/cmake-4.2/Modules/GoogleTest.cmake" + "/usr/share/cmake-4.2/Modules/Internal/CMakeCLinkerInformation.cmake" + "/usr/share/cmake-4.2/Modules/Internal/CMakeCXXLinkerInformation.cmake" + "/usr/share/cmake-4.2/Modules/Internal/CMakeCommonLinkerInformation.cmake" + "/usr/share/cmake-4.2/Modules/Internal/CheckSourceCompiles.cmake" + "/usr/share/cmake-4.2/Modules/Linker/GNU-C.cmake" + "/usr/share/cmake-4.2/Modules/Linker/GNU-CXX.cmake" + "/usr/share/cmake-4.2/Modules/Linker/GNU.cmake" + "/usr/share/cmake-4.2/Modules/Platform/Linker/GNU.cmake" + "/usr/share/cmake-4.2/Modules/Platform/Linker/Linux-GNU-C.cmake" + "/usr/share/cmake-4.2/Modules/Platform/Linker/Linux-GNU-CXX.cmake" + "/usr/share/cmake-4.2/Modules/Platform/Linker/Linux-GNU.cmake" + "/usr/share/cmake-4.2/Modules/Platform/Linux-GNU-C.cmake" + "/usr/share/cmake-4.2/Modules/Platform/Linux-GNU-CXX.cmake" + "/usr/share/cmake-4.2/Modules/Platform/Linux-GNU.cmake" + "/usr/share/cmake-4.2/Modules/Platform/Linux-Initialize.cmake" + "/usr/share/cmake-4.2/Modules/Platform/Linux.cmake" + "/usr/share/cmake-4.2/Modules/Platform/UnixPaths.cmake" + ) + +# The corresponding makefile is: +set(CMAKE_MAKEFILE_OUTPUTS + "Makefile" + "CMakeFiles/cmake.check_cache" + ) + +# Byproducts of CMake generate step: +set(CMAKE_MAKEFILE_PRODUCTS + "CMakeFiles/CMakeDirectoryInformation.cmake" + "googletest/CMakeFiles/CMakeDirectoryInformation.cmake" + "googletest/googletest/CMakeFiles/CMakeDirectoryInformation.cmake" + ) + +# Dependency information for all targets: +set(CMAKE_DEPEND_INFO_FILES + "CMakeFiles/all_test.dir/DependInfo.cmake" + "CMakeFiles/dpf_key_test.dir/DependInfo.cmake" + "CMakeFiles/wildcard_test.dir/DependInfo.cmake" + "CMakeFiles/eval_point_test.dir/DependInfo.cmake" + "CMakeFiles/eval_interval_test.dir/DependInfo.cmake" + "CMakeFiles/eval_full_test.dir/DependInfo.cmake" + "CMakeFiles/eval_sequence_test.dir/DependInfo.cmake" + "CMakeFiles/eval_point_multi_test.dir/DependInfo.cmake" + "CMakeFiles/eval_interval_multi_test.dir/DependInfo.cmake" + "CMakeFiles/eval_full_multi_test.dir/DependInfo.cmake" + "CMakeFiles/eval_sequence_multi_test.dir/DependInfo.cmake" + "CMakeFiles/advice_bit_iterable_test.dir/DependInfo.cmake" + "CMakeFiles/bit_array_test.dir/DependInfo.cmake" + "CMakeFiles/parallel_bit_iterable_test.dir/DependInfo.cmake" + "CMakeFiles/setbit_index_iterable_test.dir/DependInfo.cmake" + "CMakeFiles/incremental_test.dir/DependInfo.cmake" + "CMakeFiles/path_recipe_test.dir/DependInfo.cmake" + "CMakeFiles/blocked_dcf_test.dir/DependInfo.cmake" + "CMakeFiles/geneval_test.dir/DependInfo.cmake" + "CMakeFiles/stress_scenarios_test.dir/DependInfo.cmake" + "CMakeFiles/incremental_json_test.dir/DependInfo.cmake" + "CMakeFiles/keyword2_test.dir/DependInfo.cmake" + "CMakeFiles/types_test.dir/DependInfo.cmake" + "CMakeFiles/packed_lane_test.dir/DependInfo.cmake" + "CMakeFiles/bitmore_mod_test.dir/DependInfo.cmake" + "CMakeFiles/lane_blast_test.dir/DependInfo.cmake" + "CMakeFiles/context_blast_test.dir/DependInfo.cmake" + "CMakeFiles/random_test.dir/DependInfo.cmake" + "CMakeFiles/prg_lowmc_test.dir/DependInfo.cmake" + "CMakeFiles/prg_chacha_test.dir/DependInfo.cmake" + "CMakeFiles/prg_aes_ccr_test.dir/DependInfo.cmake" + "CMakeFiles/half_tree_test.dir/DependInfo.cmake" + "CMakeFiles/constrained_cmp_test.dir/DependInfo.cmake" + "CMakeFiles/fp61_test.dir/DependInfo.cmake" + "CMakeFiles/field_output_test.dir/DependInfo.cmake" + "CMakeFiles/gf2_test.dir/DependInfo.cmake" + "CMakeFiles/gf2_adversarial_test.dir/DependInfo.cmake" + "CMakeFiles/arith_payload_test.dir/DependInfo.cmake" + "CMakeFiles/verifiable_test.dir/DependInfo.cmake" + "CMakeFiles/vdpf_adversarial_test.dir/DependInfo.cmake" + "CMakeFiles/shamir_adversarial_test.dir/DependInfo.cmake" + "CMakeFiles/vdpf_regression_test.dir/DependInfo.cmake" + "CMakeFiles/opt_in_malicious_test.dir/DependInfo.cmake" + "CMakeFiles/multipoint_test.dir/DependInfo.cmake" + "CMakeFiles/dpf3_test.dir/DependInfo.cmake" + "CMakeFiles/eval_inner_product_test.dir/DependInfo.cmake" + "CMakeFiles/shared_and_test.dir/DependInfo.cmake" + "CMakeFiles/cohort_test.dir/DependInfo.cmake" + "CMakeFiles/interleave_leaves_test.dir/DependInfo.cmake" + "CMakeFiles/secret_share_test.dir/DependInfo.cmake" + "CMakeFiles/beaver_test.dir/DependInfo.cmake" + "CMakeFiles/share_runtime_test.dir/DependInfo.cmake" + "CMakeFiles/net_control_test.dir/DependInfo.cmake" + "CMakeFiles/security_test.dir/DependInfo.cmake" + "CMakeFiles/protocol_batch_test.dir/DependInfo.cmake" + "CMakeFiles/compose_test.dir/DependInfo.cmake" + "CMakeFiles/experiment_test.dir/DependInfo.cmake" + "CMakeFiles/log_test.dir/DependInfo.cmake" + "CMakeFiles/constant_lut_test.dir/DependInfo.cmake" + "CMakeFiles/signed_prefix_test.dir/DependInfo.cmake" + "CMakeFiles/easy_lut_test.dir/DependInfo.cmake" + "CMakeFiles/dyadic_lut_test.dir/DependInfo.cmake" + "CMakeFiles/nmod_test.dir/DependInfo.cmake" + "CMakeFiles/exact_steps_test.dir/DependInfo.cmake" + "CMakeFiles/closed_form_test.dir/DependInfo.cmake" + "CMakeFiles/principal_lut_test.dir/DependInfo.cmake" + "CMakeFiles/range_lut_test.dir/DependInfo.cmake" + "CMakeFiles/window_lut_test.dir/DependInfo.cmake" + "CMakeFiles/dwt_lut_test.dir/DependInfo.cmake" + "CMakeFiles/offset_horner_test.dir/DependInfo.cmake" + "CMakeFiles/offset_poly_test.dir/DependInfo.cmake" + "CMakeFiles/lut_union_test.dir/DependInfo.cmake" + "CMakeFiles/offset_jet_test.dir/DependInfo.cmake" + "CMakeFiles/offset_repr_test.dir/DependInfo.cmake" + "CMakeFiles/offset_twist_test.dir/DependInfo.cmake" + "CMakeFiles/ring_switch_test.dir/DependInfo.cmake" + "CMakeFiles/corner_gaps_test.dir/DependInfo.cmake" + "CMakeFiles/carry_test.dir/DependInfo.cmake" + "CMakeFiles/fixedpoint_beaver_test.dir/DependInfo.cmake" + "CMakeFiles/class_sweep_test.dir/DependInfo.cmake" + "CMakeFiles/extractable_full_test.dir/DependInfo.cmake" + "CMakeFiles/walk_helpers_test.dir/DependInfo.cmake" + "CMakeFiles/domain128_point_test.dir/DependInfo.cmake" + "CMakeFiles/blob_leaf_test.dir/DependInfo.cmake" + "CMakeFiles/growing_idpf_test.dir/DependInfo.cmake" + "CMakeFiles/pprf_test.dir/DependInfo.cmake" + "CMakeFiles/ppvc_test.dir/DependInfo.cmake" + "CMakeFiles/leaf_later_test.dir/DependInfo.cmake" + "CMakeFiles/caller_fold_test.dir/DependInfo.cmake" + "CMakeFiles/defer_eval_test.dir/DependInfo.cmake" + "CMakeFiles/wrap_and_rotate_test.dir/DependInfo.cmake" + "CMakeFiles/sfss_test.dir/DependInfo.cmake" + "CMakeFiles/path_sketch_test.dir/DependInfo.cmake" + "CMakeFiles/eval_until_test.dir/DependInfo.cmake" + "CMakeFiles/idpf_agg_test.dir/DependInfo.cmake" + "CMakeFiles/it_dpf3_test.dir/DependInfo.cmake" + "CMakeFiles/party_flows.dir/DependInfo.cmake" + "CMakeFiles/p0.dir/DependInfo.cmake" + "CMakeFiles/p1.dir/DependInfo.cmake" + "CMakeFiles/p2.dir/DependInfo.cmake" + "CMakeFiles/party_bench.dir/DependInfo.cmake" + "CMakeFiles/profile_eval.dir/DependInfo.cmake" + "CMakeFiles/profile_grotto.dir/DependInfo.cmake" + "CMakeFiles/profile_party.dir/DependInfo.cmake" + "CMakeFiles/yao_share_test.dir/DependInfo.cmake" + "CMakeFiles/yao_test.dir/DependInfo.cmake" + "CMakeFiles/yao_stack_test.dir/DependInfo.cmake" + "CMakeFiles/arith_garble_test.dir/DependInfo.cmake" + "CMakeFiles/flute_test.dir/DependInfo.cmake" + "CMakeFiles/shuffle_hidden_test.dir/DependInfo.cmake" + "CMakeFiles/bench_cell_test.dir/DependInfo.cmake" + "CMakeFiles/iknp_party_test.dir/DependInfo.cmake" + "CMakeFiles/beaver_party_test.dir/DependInfo.cmake" + "CMakeFiles/ic_test.dir/DependInfo.cmake" + "CMakeFiles/wide_payload_test.dir/DependInfo.cmake" + "googletest/googletest/CMakeFiles/gtest.dir/DependInfo.cmake" + "googletest/googletest/CMakeFiles/gtest_main.dir/DependInfo.cmake" + ) diff --git a/test/build-asan/CMakeFiles/Makefile2 b/test/build-asan/CMakeFiles/Makefile2 new file mode 100644 index 0000000..37b3a96 --- /dev/null +++ b/test/build-asan/CMakeFiles/Makefile2 @@ -0,0 +1,4356 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +#============================================================================= +# Directory level rules for the build root directory + +# The main recursive "all" target. +all: CMakeFiles/all_test.dir/all +all: CMakeFiles/dpf_key_test.dir/all +all: CMakeFiles/wildcard_test.dir/all +all: CMakeFiles/eval_point_test.dir/all +all: CMakeFiles/eval_interval_test.dir/all +all: CMakeFiles/eval_full_test.dir/all +all: CMakeFiles/eval_sequence_test.dir/all +all: CMakeFiles/eval_point_multi_test.dir/all +all: CMakeFiles/eval_interval_multi_test.dir/all +all: CMakeFiles/eval_full_multi_test.dir/all +all: CMakeFiles/eval_sequence_multi_test.dir/all +all: CMakeFiles/advice_bit_iterable_test.dir/all +all: CMakeFiles/bit_array_test.dir/all +all: CMakeFiles/parallel_bit_iterable_test.dir/all +all: CMakeFiles/setbit_index_iterable_test.dir/all +all: CMakeFiles/incremental_test.dir/all +all: CMakeFiles/path_recipe_test.dir/all +all: CMakeFiles/blocked_dcf_test.dir/all +all: CMakeFiles/geneval_test.dir/all +all: CMakeFiles/stress_scenarios_test.dir/all +all: CMakeFiles/incremental_json_test.dir/all +all: CMakeFiles/keyword2_test.dir/all +all: CMakeFiles/types_test.dir/all +all: CMakeFiles/packed_lane_test.dir/all +all: CMakeFiles/bitmore_mod_test.dir/all +all: CMakeFiles/lane_blast_test.dir/all +all: CMakeFiles/context_blast_test.dir/all +all: CMakeFiles/random_test.dir/all +all: CMakeFiles/prg_lowmc_test.dir/all +all: CMakeFiles/prg_chacha_test.dir/all +all: CMakeFiles/prg_aes_ccr_test.dir/all +all: CMakeFiles/half_tree_test.dir/all +all: CMakeFiles/constrained_cmp_test.dir/all +all: CMakeFiles/fp61_test.dir/all +all: CMakeFiles/field_output_test.dir/all +all: CMakeFiles/gf2_test.dir/all +all: CMakeFiles/gf2_adversarial_test.dir/all +all: CMakeFiles/arith_payload_test.dir/all +all: CMakeFiles/verifiable_test.dir/all +all: CMakeFiles/vdpf_adversarial_test.dir/all +all: CMakeFiles/shamir_adversarial_test.dir/all +all: CMakeFiles/vdpf_regression_test.dir/all +all: CMakeFiles/opt_in_malicious_test.dir/all +all: CMakeFiles/multipoint_test.dir/all +all: CMakeFiles/dpf3_test.dir/all +all: CMakeFiles/eval_inner_product_test.dir/all +all: CMakeFiles/shared_and_test.dir/all +all: CMakeFiles/cohort_test.dir/all +all: CMakeFiles/interleave_leaves_test.dir/all +all: CMakeFiles/secret_share_test.dir/all +all: CMakeFiles/beaver_test.dir/all +all: CMakeFiles/share_runtime_test.dir/all +all: CMakeFiles/net_control_test.dir/all +all: CMakeFiles/security_test.dir/all +all: CMakeFiles/protocol_batch_test.dir/all +all: CMakeFiles/compose_test.dir/all +all: CMakeFiles/experiment_test.dir/all +all: CMakeFiles/log_test.dir/all +all: CMakeFiles/constant_lut_test.dir/all +all: CMakeFiles/signed_prefix_test.dir/all +all: CMakeFiles/easy_lut_test.dir/all +all: CMakeFiles/dyadic_lut_test.dir/all +all: CMakeFiles/nmod_test.dir/all +all: CMakeFiles/exact_steps_test.dir/all +all: CMakeFiles/closed_form_test.dir/all +all: CMakeFiles/principal_lut_test.dir/all +all: CMakeFiles/range_lut_test.dir/all +all: CMakeFiles/window_lut_test.dir/all +all: CMakeFiles/dwt_lut_test.dir/all +all: CMakeFiles/offset_horner_test.dir/all +all: CMakeFiles/offset_poly_test.dir/all +all: CMakeFiles/lut_union_test.dir/all +all: CMakeFiles/offset_jet_test.dir/all +all: CMakeFiles/offset_repr_test.dir/all +all: CMakeFiles/offset_twist_test.dir/all +all: CMakeFiles/ring_switch_test.dir/all +all: CMakeFiles/corner_gaps_test.dir/all +all: CMakeFiles/carry_test.dir/all +all: CMakeFiles/fixedpoint_beaver_test.dir/all +all: CMakeFiles/class_sweep_test.dir/all +all: CMakeFiles/extractable_full_test.dir/all +all: CMakeFiles/walk_helpers_test.dir/all +all: CMakeFiles/domain128_point_test.dir/all +all: CMakeFiles/blob_leaf_test.dir/all +all: CMakeFiles/growing_idpf_test.dir/all +all: CMakeFiles/pprf_test.dir/all +all: CMakeFiles/ppvc_test.dir/all +all: CMakeFiles/leaf_later_test.dir/all +all: CMakeFiles/caller_fold_test.dir/all +all: CMakeFiles/defer_eval_test.dir/all +all: CMakeFiles/wrap_and_rotate_test.dir/all +all: CMakeFiles/sfss_test.dir/all +all: CMakeFiles/path_sketch_test.dir/all +all: CMakeFiles/eval_until_test.dir/all +all: CMakeFiles/idpf_agg_test.dir/all +all: CMakeFiles/it_dpf3_test.dir/all +all: CMakeFiles/party_flows.dir/all +all: CMakeFiles/p0.dir/all +all: CMakeFiles/p1.dir/all +all: CMakeFiles/p2.dir/all +all: CMakeFiles/party_bench.dir/all +all: CMakeFiles/profile_eval.dir/all +all: CMakeFiles/profile_grotto.dir/all +all: CMakeFiles/profile_party.dir/all +all: CMakeFiles/yao_share_test.dir/all +all: CMakeFiles/yao_test.dir/all +all: CMakeFiles/yao_stack_test.dir/all +all: CMakeFiles/arith_garble_test.dir/all +all: CMakeFiles/flute_test.dir/all +all: CMakeFiles/shuffle_hidden_test.dir/all +all: CMakeFiles/bench_cell_test.dir/all +all: CMakeFiles/iknp_party_test.dir/all +all: CMakeFiles/beaver_party_test.dir/all +all: CMakeFiles/ic_test.dir/all +all: CMakeFiles/wide_payload_test.dir/all +all: googletest/all +.PHONY : all + +# The main recursive "codegen" target. +codegen: CMakeFiles/all_test.dir/codegen +codegen: CMakeFiles/dpf_key_test.dir/codegen +codegen: CMakeFiles/wildcard_test.dir/codegen +codegen: CMakeFiles/eval_point_test.dir/codegen +codegen: CMakeFiles/eval_interval_test.dir/codegen +codegen: CMakeFiles/eval_full_test.dir/codegen +codegen: CMakeFiles/eval_sequence_test.dir/codegen +codegen: CMakeFiles/eval_point_multi_test.dir/codegen +codegen: CMakeFiles/eval_interval_multi_test.dir/codegen +codegen: CMakeFiles/eval_full_multi_test.dir/codegen +codegen: CMakeFiles/eval_sequence_multi_test.dir/codegen +codegen: CMakeFiles/advice_bit_iterable_test.dir/codegen +codegen: CMakeFiles/bit_array_test.dir/codegen +codegen: CMakeFiles/parallel_bit_iterable_test.dir/codegen +codegen: CMakeFiles/setbit_index_iterable_test.dir/codegen +codegen: CMakeFiles/incremental_test.dir/codegen +codegen: CMakeFiles/path_recipe_test.dir/codegen +codegen: CMakeFiles/blocked_dcf_test.dir/codegen +codegen: CMakeFiles/geneval_test.dir/codegen +codegen: CMakeFiles/stress_scenarios_test.dir/codegen +codegen: CMakeFiles/incremental_json_test.dir/codegen +codegen: CMakeFiles/keyword2_test.dir/codegen +codegen: CMakeFiles/types_test.dir/codegen +codegen: CMakeFiles/packed_lane_test.dir/codegen +codegen: CMakeFiles/bitmore_mod_test.dir/codegen +codegen: CMakeFiles/lane_blast_test.dir/codegen +codegen: CMakeFiles/context_blast_test.dir/codegen +codegen: CMakeFiles/random_test.dir/codegen +codegen: CMakeFiles/prg_lowmc_test.dir/codegen +codegen: CMakeFiles/prg_chacha_test.dir/codegen +codegen: CMakeFiles/prg_aes_ccr_test.dir/codegen +codegen: CMakeFiles/half_tree_test.dir/codegen +codegen: CMakeFiles/constrained_cmp_test.dir/codegen +codegen: CMakeFiles/fp61_test.dir/codegen +codegen: CMakeFiles/field_output_test.dir/codegen +codegen: CMakeFiles/gf2_test.dir/codegen +codegen: CMakeFiles/gf2_adversarial_test.dir/codegen +codegen: CMakeFiles/arith_payload_test.dir/codegen +codegen: CMakeFiles/verifiable_test.dir/codegen +codegen: CMakeFiles/vdpf_adversarial_test.dir/codegen +codegen: CMakeFiles/shamir_adversarial_test.dir/codegen +codegen: CMakeFiles/vdpf_regression_test.dir/codegen +codegen: CMakeFiles/opt_in_malicious_test.dir/codegen +codegen: CMakeFiles/multipoint_test.dir/codegen +codegen: CMakeFiles/dpf3_test.dir/codegen +codegen: CMakeFiles/eval_inner_product_test.dir/codegen +codegen: CMakeFiles/shared_and_test.dir/codegen +codegen: CMakeFiles/cohort_test.dir/codegen +codegen: CMakeFiles/interleave_leaves_test.dir/codegen +codegen: CMakeFiles/secret_share_test.dir/codegen +codegen: CMakeFiles/beaver_test.dir/codegen +codegen: CMakeFiles/share_runtime_test.dir/codegen +codegen: CMakeFiles/net_control_test.dir/codegen +codegen: CMakeFiles/security_test.dir/codegen +codegen: CMakeFiles/protocol_batch_test.dir/codegen +codegen: CMakeFiles/compose_test.dir/codegen +codegen: CMakeFiles/experiment_test.dir/codegen +codegen: CMakeFiles/log_test.dir/codegen +codegen: CMakeFiles/constant_lut_test.dir/codegen +codegen: CMakeFiles/signed_prefix_test.dir/codegen +codegen: CMakeFiles/easy_lut_test.dir/codegen +codegen: CMakeFiles/dyadic_lut_test.dir/codegen +codegen: CMakeFiles/nmod_test.dir/codegen +codegen: CMakeFiles/exact_steps_test.dir/codegen +codegen: CMakeFiles/closed_form_test.dir/codegen +codegen: CMakeFiles/principal_lut_test.dir/codegen +codegen: CMakeFiles/range_lut_test.dir/codegen +codegen: CMakeFiles/window_lut_test.dir/codegen +codegen: CMakeFiles/dwt_lut_test.dir/codegen +codegen: CMakeFiles/offset_horner_test.dir/codegen +codegen: CMakeFiles/offset_poly_test.dir/codegen +codegen: CMakeFiles/lut_union_test.dir/codegen +codegen: CMakeFiles/offset_jet_test.dir/codegen +codegen: CMakeFiles/offset_repr_test.dir/codegen +codegen: CMakeFiles/offset_twist_test.dir/codegen +codegen: CMakeFiles/ring_switch_test.dir/codegen +codegen: CMakeFiles/corner_gaps_test.dir/codegen +codegen: CMakeFiles/carry_test.dir/codegen +codegen: CMakeFiles/fixedpoint_beaver_test.dir/codegen +codegen: CMakeFiles/class_sweep_test.dir/codegen +codegen: CMakeFiles/extractable_full_test.dir/codegen +codegen: CMakeFiles/walk_helpers_test.dir/codegen +codegen: CMakeFiles/domain128_point_test.dir/codegen +codegen: CMakeFiles/blob_leaf_test.dir/codegen +codegen: CMakeFiles/growing_idpf_test.dir/codegen +codegen: CMakeFiles/pprf_test.dir/codegen +codegen: CMakeFiles/ppvc_test.dir/codegen +codegen: CMakeFiles/leaf_later_test.dir/codegen +codegen: CMakeFiles/caller_fold_test.dir/codegen +codegen: CMakeFiles/defer_eval_test.dir/codegen +codegen: CMakeFiles/wrap_and_rotate_test.dir/codegen +codegen: CMakeFiles/sfss_test.dir/codegen +codegen: CMakeFiles/path_sketch_test.dir/codegen +codegen: CMakeFiles/eval_until_test.dir/codegen +codegen: CMakeFiles/idpf_agg_test.dir/codegen +codegen: CMakeFiles/it_dpf3_test.dir/codegen +codegen: CMakeFiles/party_flows.dir/codegen +codegen: CMakeFiles/p0.dir/codegen +codegen: CMakeFiles/p1.dir/codegen +codegen: CMakeFiles/p2.dir/codegen +codegen: CMakeFiles/party_bench.dir/codegen +codegen: CMakeFiles/profile_eval.dir/codegen +codegen: CMakeFiles/profile_grotto.dir/codegen +codegen: CMakeFiles/profile_party.dir/codegen +codegen: CMakeFiles/yao_share_test.dir/codegen +codegen: CMakeFiles/yao_test.dir/codegen +codegen: CMakeFiles/yao_stack_test.dir/codegen +codegen: CMakeFiles/arith_garble_test.dir/codegen +codegen: CMakeFiles/flute_test.dir/codegen +codegen: CMakeFiles/shuffle_hidden_test.dir/codegen +codegen: CMakeFiles/bench_cell_test.dir/codegen +codegen: CMakeFiles/iknp_party_test.dir/codegen +codegen: CMakeFiles/beaver_party_test.dir/codegen +codegen: CMakeFiles/ic_test.dir/codegen +codegen: CMakeFiles/wide_payload_test.dir/codegen +codegen: googletest/codegen +.PHONY : codegen + +# The main recursive "preinstall" target. +preinstall: googletest/preinstall +.PHONY : preinstall + +# The main recursive "clean" target. +clean: CMakeFiles/all_test.dir/clean +clean: CMakeFiles/dpf_key_test.dir/clean +clean: CMakeFiles/wildcard_test.dir/clean +clean: CMakeFiles/eval_point_test.dir/clean +clean: CMakeFiles/eval_interval_test.dir/clean +clean: CMakeFiles/eval_full_test.dir/clean +clean: CMakeFiles/eval_sequence_test.dir/clean +clean: CMakeFiles/eval_point_multi_test.dir/clean +clean: CMakeFiles/eval_interval_multi_test.dir/clean +clean: CMakeFiles/eval_full_multi_test.dir/clean +clean: CMakeFiles/eval_sequence_multi_test.dir/clean +clean: CMakeFiles/advice_bit_iterable_test.dir/clean +clean: CMakeFiles/bit_array_test.dir/clean +clean: CMakeFiles/parallel_bit_iterable_test.dir/clean +clean: CMakeFiles/setbit_index_iterable_test.dir/clean +clean: CMakeFiles/incremental_test.dir/clean +clean: CMakeFiles/path_recipe_test.dir/clean +clean: CMakeFiles/blocked_dcf_test.dir/clean +clean: CMakeFiles/geneval_test.dir/clean +clean: CMakeFiles/stress_scenarios_test.dir/clean +clean: CMakeFiles/incremental_json_test.dir/clean +clean: CMakeFiles/keyword2_test.dir/clean +clean: CMakeFiles/types_test.dir/clean +clean: CMakeFiles/packed_lane_test.dir/clean +clean: CMakeFiles/bitmore_mod_test.dir/clean +clean: CMakeFiles/lane_blast_test.dir/clean +clean: CMakeFiles/context_blast_test.dir/clean +clean: CMakeFiles/random_test.dir/clean +clean: CMakeFiles/prg_lowmc_test.dir/clean +clean: CMakeFiles/prg_chacha_test.dir/clean +clean: CMakeFiles/prg_aes_ccr_test.dir/clean +clean: CMakeFiles/half_tree_test.dir/clean +clean: CMakeFiles/constrained_cmp_test.dir/clean +clean: CMakeFiles/fp61_test.dir/clean +clean: CMakeFiles/field_output_test.dir/clean +clean: CMakeFiles/gf2_test.dir/clean +clean: CMakeFiles/gf2_adversarial_test.dir/clean +clean: CMakeFiles/arith_payload_test.dir/clean +clean: CMakeFiles/verifiable_test.dir/clean +clean: CMakeFiles/vdpf_adversarial_test.dir/clean +clean: CMakeFiles/shamir_adversarial_test.dir/clean +clean: CMakeFiles/vdpf_regression_test.dir/clean +clean: CMakeFiles/opt_in_malicious_test.dir/clean +clean: CMakeFiles/multipoint_test.dir/clean +clean: CMakeFiles/dpf3_test.dir/clean +clean: CMakeFiles/eval_inner_product_test.dir/clean +clean: CMakeFiles/shared_and_test.dir/clean +clean: CMakeFiles/cohort_test.dir/clean +clean: CMakeFiles/interleave_leaves_test.dir/clean +clean: CMakeFiles/secret_share_test.dir/clean +clean: CMakeFiles/beaver_test.dir/clean +clean: CMakeFiles/share_runtime_test.dir/clean +clean: CMakeFiles/net_control_test.dir/clean +clean: CMakeFiles/security_test.dir/clean +clean: CMakeFiles/protocol_batch_test.dir/clean +clean: CMakeFiles/compose_test.dir/clean +clean: CMakeFiles/experiment_test.dir/clean +clean: CMakeFiles/log_test.dir/clean +clean: CMakeFiles/constant_lut_test.dir/clean +clean: CMakeFiles/signed_prefix_test.dir/clean +clean: CMakeFiles/easy_lut_test.dir/clean +clean: CMakeFiles/dyadic_lut_test.dir/clean +clean: CMakeFiles/nmod_test.dir/clean +clean: CMakeFiles/exact_steps_test.dir/clean +clean: CMakeFiles/closed_form_test.dir/clean +clean: CMakeFiles/principal_lut_test.dir/clean +clean: CMakeFiles/range_lut_test.dir/clean +clean: CMakeFiles/window_lut_test.dir/clean +clean: CMakeFiles/dwt_lut_test.dir/clean +clean: CMakeFiles/offset_horner_test.dir/clean +clean: CMakeFiles/offset_poly_test.dir/clean +clean: CMakeFiles/lut_union_test.dir/clean +clean: CMakeFiles/offset_jet_test.dir/clean +clean: CMakeFiles/offset_repr_test.dir/clean +clean: CMakeFiles/offset_twist_test.dir/clean +clean: CMakeFiles/ring_switch_test.dir/clean +clean: CMakeFiles/corner_gaps_test.dir/clean +clean: CMakeFiles/carry_test.dir/clean +clean: CMakeFiles/fixedpoint_beaver_test.dir/clean +clean: CMakeFiles/class_sweep_test.dir/clean +clean: CMakeFiles/extractable_full_test.dir/clean +clean: CMakeFiles/walk_helpers_test.dir/clean +clean: CMakeFiles/domain128_point_test.dir/clean +clean: CMakeFiles/blob_leaf_test.dir/clean +clean: CMakeFiles/growing_idpf_test.dir/clean +clean: CMakeFiles/pprf_test.dir/clean +clean: CMakeFiles/ppvc_test.dir/clean +clean: CMakeFiles/leaf_later_test.dir/clean +clean: CMakeFiles/caller_fold_test.dir/clean +clean: CMakeFiles/defer_eval_test.dir/clean +clean: CMakeFiles/wrap_and_rotate_test.dir/clean +clean: CMakeFiles/sfss_test.dir/clean +clean: CMakeFiles/path_sketch_test.dir/clean +clean: CMakeFiles/eval_until_test.dir/clean +clean: CMakeFiles/idpf_agg_test.dir/clean +clean: CMakeFiles/it_dpf3_test.dir/clean +clean: CMakeFiles/party_flows.dir/clean +clean: CMakeFiles/p0.dir/clean +clean: CMakeFiles/p1.dir/clean +clean: CMakeFiles/p2.dir/clean +clean: CMakeFiles/party_bench.dir/clean +clean: CMakeFiles/profile_eval.dir/clean +clean: CMakeFiles/profile_grotto.dir/clean +clean: CMakeFiles/profile_party.dir/clean +clean: CMakeFiles/yao_share_test.dir/clean +clean: CMakeFiles/yao_test.dir/clean +clean: CMakeFiles/yao_stack_test.dir/clean +clean: CMakeFiles/arith_garble_test.dir/clean +clean: CMakeFiles/flute_test.dir/clean +clean: CMakeFiles/shuffle_hidden_test.dir/clean +clean: CMakeFiles/bench_cell_test.dir/clean +clean: CMakeFiles/iknp_party_test.dir/clean +clean: CMakeFiles/beaver_party_test.dir/clean +clean: CMakeFiles/ic_test.dir/clean +clean: CMakeFiles/wide_payload_test.dir/clean +clean: googletest/clean +.PHONY : clean + +#============================================================================= +# Directory level rules for directory googletest + +# Recursive "all" directory target. +googletest/all: googletest/googletest/all +.PHONY : googletest/all + +# Recursive "codegen" directory target. +googletest/codegen: googletest/googletest/codegen +.PHONY : googletest/codegen + +# Recursive "preinstall" directory target. +googletest/preinstall: googletest/googletest/preinstall +.PHONY : googletest/preinstall + +# Recursive "clean" directory target. +googletest/clean: googletest/googletest/clean +.PHONY : googletest/clean + +#============================================================================= +# Directory level rules for directory googletest/googletest + +# Recursive "all" directory target. +googletest/googletest/all: googletest/googletest/CMakeFiles/gtest.dir/all +googletest/googletest/all: googletest/googletest/CMakeFiles/gtest_main.dir/all +.PHONY : googletest/googletest/all + +# Recursive "codegen" directory target. +googletest/googletest/codegen: googletest/googletest/CMakeFiles/gtest.dir/codegen +googletest/googletest/codegen: googletest/googletest/CMakeFiles/gtest_main.dir/codegen +.PHONY : googletest/googletest/codegen + +# Recursive "preinstall" directory target. +googletest/googletest/preinstall: +.PHONY : googletest/googletest/preinstall + +# Recursive "clean" directory target. +googletest/googletest/clean: googletest/googletest/CMakeFiles/gtest.dir/clean +googletest/googletest/clean: googletest/googletest/CMakeFiles/gtest_main.dir/clean +.PHONY : googletest/googletest/clean + +#============================================================================= +# Target rules for target CMakeFiles/all_test.dir + +# All Build rule for target. +CMakeFiles/all_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/all_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/all_test.dir/build.make CMakeFiles/all_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/all_test.dir/build.make CMakeFiles/all_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=1 "Built target all_test" +.PHONY : CMakeFiles/all_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/all_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/all_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/all_test.dir/rule + +# Convenience name for target. +all_test: CMakeFiles/all_test.dir/rule +.PHONY : all_test + +# codegen rule for target. +CMakeFiles/all_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/all_test.dir/build.make CMakeFiles/all_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=1 "Finished codegen for target all_test" +.PHONY : CMakeFiles/all_test.dir/codegen + +# clean rule for target. +CMakeFiles/all_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/all_test.dir/build.make CMakeFiles/all_test.dir/clean +.PHONY : CMakeFiles/all_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/dpf_key_test.dir + +# All Build rule for target. +CMakeFiles/dpf_key_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/dpf_key_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf_key_test.dir/build.make CMakeFiles/dpf_key_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf_key_test.dir/build.make CMakeFiles/dpf_key_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=21 "Built target dpf_key_test" +.PHONY : CMakeFiles/dpf_key_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/dpf_key_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/dpf_key_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/dpf_key_test.dir/rule + +# Convenience name for target. +dpf_key_test: CMakeFiles/dpf_key_test.dir/rule +.PHONY : dpf_key_test + +# codegen rule for target. +CMakeFiles/dpf_key_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf_key_test.dir/build.make CMakeFiles/dpf_key_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=21 "Finished codegen for target dpf_key_test" +.PHONY : CMakeFiles/dpf_key_test.dir/codegen + +# clean rule for target. +CMakeFiles/dpf_key_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf_key_test.dir/build.make CMakeFiles/dpf_key_test.dir/clean +.PHONY : CMakeFiles/dpf_key_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/wildcard_test.dir + +# All Build rule for target. +CMakeFiles/wildcard_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/wildcard_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/wildcard_test.dir/build.make CMakeFiles/wildcard_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/wildcard_test.dir/build.make CMakeFiles/wildcard_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=95 "Built target wildcard_test" +.PHONY : CMakeFiles/wildcard_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/wildcard_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/wildcard_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/wildcard_test.dir/rule + +# Convenience name for target. +wildcard_test: CMakeFiles/wildcard_test.dir/rule +.PHONY : wildcard_test + +# codegen rule for target. +CMakeFiles/wildcard_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wildcard_test.dir/build.make CMakeFiles/wildcard_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=95 "Finished codegen for target wildcard_test" +.PHONY : CMakeFiles/wildcard_test.dir/codegen + +# clean rule for target. +CMakeFiles/wildcard_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wildcard_test.dir/build.make CMakeFiles/wildcard_test.dir/clean +.PHONY : CMakeFiles/wildcard_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/eval_point_test.dir + +# All Build rule for target. +CMakeFiles/eval_point_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/eval_point_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_test.dir/build.make CMakeFiles/eval_point_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_test.dir/build.make CMakeFiles/eval_point_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=29 "Built target eval_point_test" +.PHONY : CMakeFiles/eval_point_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/eval_point_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/eval_point_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/eval_point_test.dir/rule + +# Convenience name for target. +eval_point_test: CMakeFiles/eval_point_test.dir/rule +.PHONY : eval_point_test + +# codegen rule for target. +CMakeFiles/eval_point_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_test.dir/build.make CMakeFiles/eval_point_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=29 "Finished codegen for target eval_point_test" +.PHONY : CMakeFiles/eval_point_test.dir/codegen + +# clean rule for target. +CMakeFiles/eval_point_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_test.dir/build.make CMakeFiles/eval_point_test.dir/clean +.PHONY : CMakeFiles/eval_point_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/eval_interval_test.dir + +# All Build rule for target. +CMakeFiles/eval_interval_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/eval_interval_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_test.dir/build.make CMakeFiles/eval_interval_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_test.dir/build.make CMakeFiles/eval_interval_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target eval_interval_test" +.PHONY : CMakeFiles/eval_interval_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/eval_interval_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/eval_interval_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/eval_interval_test.dir/rule + +# Convenience name for target. +eval_interval_test: CMakeFiles/eval_interval_test.dir/rule +.PHONY : eval_interval_test + +# codegen rule for target. +CMakeFiles/eval_interval_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_test.dir/build.make CMakeFiles/eval_interval_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target eval_interval_test" +.PHONY : CMakeFiles/eval_interval_test.dir/codegen + +# clean rule for target. +CMakeFiles/eval_interval_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_test.dir/build.make CMakeFiles/eval_interval_test.dir/clean +.PHONY : CMakeFiles/eval_interval_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/eval_full_test.dir + +# All Build rule for target. +CMakeFiles/eval_full_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/eval_full_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_test.dir/build.make CMakeFiles/eval_full_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_test.dir/build.make CMakeFiles/eval_full_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=25 "Built target eval_full_test" +.PHONY : CMakeFiles/eval_full_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/eval_full_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/eval_full_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/eval_full_test.dir/rule + +# Convenience name for target. +eval_full_test: CMakeFiles/eval_full_test.dir/rule +.PHONY : eval_full_test + +# codegen rule for target. +CMakeFiles/eval_full_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_test.dir/build.make CMakeFiles/eval_full_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=25 "Finished codegen for target eval_full_test" +.PHONY : CMakeFiles/eval_full_test.dir/codegen + +# clean rule for target. +CMakeFiles/eval_full_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_test.dir/build.make CMakeFiles/eval_full_test.dir/clean +.PHONY : CMakeFiles/eval_full_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/eval_sequence_test.dir + +# All Build rule for target. +CMakeFiles/eval_sequence_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/eval_sequence_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_test.dir/build.make CMakeFiles/eval_sequence_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_test.dir/build.make CMakeFiles/eval_sequence_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=31 "Built target eval_sequence_test" +.PHONY : CMakeFiles/eval_sequence_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/eval_sequence_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/eval_sequence_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/eval_sequence_test.dir/rule + +# Convenience name for target. +eval_sequence_test: CMakeFiles/eval_sequence_test.dir/rule +.PHONY : eval_sequence_test + +# codegen rule for target. +CMakeFiles/eval_sequence_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_test.dir/build.make CMakeFiles/eval_sequence_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=31 "Finished codegen for target eval_sequence_test" +.PHONY : CMakeFiles/eval_sequence_test.dir/codegen + +# clean rule for target. +CMakeFiles/eval_sequence_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_test.dir/build.make CMakeFiles/eval_sequence_test.dir/clean +.PHONY : CMakeFiles/eval_sequence_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/eval_point_multi_test.dir + +# All Build rule for target. +CMakeFiles/eval_point_multi_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/eval_point_multi_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_multi_test.dir/build.make CMakeFiles/eval_point_multi_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_multi_test.dir/build.make CMakeFiles/eval_point_multi_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=28 "Built target eval_point_multi_test" +.PHONY : CMakeFiles/eval_point_multi_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/eval_point_multi_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/eval_point_multi_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/eval_point_multi_test.dir/rule + +# Convenience name for target. +eval_point_multi_test: CMakeFiles/eval_point_multi_test.dir/rule +.PHONY : eval_point_multi_test + +# codegen rule for target. +CMakeFiles/eval_point_multi_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_multi_test.dir/build.make CMakeFiles/eval_point_multi_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=28 "Finished codegen for target eval_point_multi_test" +.PHONY : CMakeFiles/eval_point_multi_test.dir/codegen + +# clean rule for target. +CMakeFiles/eval_point_multi_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_multi_test.dir/build.make CMakeFiles/eval_point_multi_test.dir/clean +.PHONY : CMakeFiles/eval_point_multi_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/eval_interval_multi_test.dir + +# All Build rule for target. +CMakeFiles/eval_interval_multi_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/eval_interval_multi_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_multi_test.dir/build.make CMakeFiles/eval_interval_multi_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_multi_test.dir/build.make CMakeFiles/eval_interval_multi_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=27 "Built target eval_interval_multi_test" +.PHONY : CMakeFiles/eval_interval_multi_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/eval_interval_multi_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/eval_interval_multi_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/eval_interval_multi_test.dir/rule + +# Convenience name for target. +eval_interval_multi_test: CMakeFiles/eval_interval_multi_test.dir/rule +.PHONY : eval_interval_multi_test + +# codegen rule for target. +CMakeFiles/eval_interval_multi_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_multi_test.dir/build.make CMakeFiles/eval_interval_multi_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=27 "Finished codegen for target eval_interval_multi_test" +.PHONY : CMakeFiles/eval_interval_multi_test.dir/codegen + +# clean rule for target. +CMakeFiles/eval_interval_multi_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_multi_test.dir/build.make CMakeFiles/eval_interval_multi_test.dir/clean +.PHONY : CMakeFiles/eval_interval_multi_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/eval_full_multi_test.dir + +# All Build rule for target. +CMakeFiles/eval_full_multi_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/eval_full_multi_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_multi_test.dir/build.make CMakeFiles/eval_full_multi_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_multi_test.dir/build.make CMakeFiles/eval_full_multi_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=24 "Built target eval_full_multi_test" +.PHONY : CMakeFiles/eval_full_multi_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/eval_full_multi_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/eval_full_multi_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/eval_full_multi_test.dir/rule + +# Convenience name for target. +eval_full_multi_test: CMakeFiles/eval_full_multi_test.dir/rule +.PHONY : eval_full_multi_test + +# codegen rule for target. +CMakeFiles/eval_full_multi_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_multi_test.dir/build.make CMakeFiles/eval_full_multi_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=24 "Finished codegen for target eval_full_multi_test" +.PHONY : CMakeFiles/eval_full_multi_test.dir/codegen + +# clean rule for target. +CMakeFiles/eval_full_multi_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_multi_test.dir/build.make CMakeFiles/eval_full_multi_test.dir/clean +.PHONY : CMakeFiles/eval_full_multi_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/eval_sequence_multi_test.dir + +# All Build rule for target. +CMakeFiles/eval_sequence_multi_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/eval_sequence_multi_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_multi_test.dir/build.make CMakeFiles/eval_sequence_multi_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_multi_test.dir/build.make CMakeFiles/eval_sequence_multi_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=30 "Built target eval_sequence_multi_test" +.PHONY : CMakeFiles/eval_sequence_multi_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/eval_sequence_multi_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/eval_sequence_multi_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/eval_sequence_multi_test.dir/rule + +# Convenience name for target. +eval_sequence_multi_test: CMakeFiles/eval_sequence_multi_test.dir/rule +.PHONY : eval_sequence_multi_test + +# codegen rule for target. +CMakeFiles/eval_sequence_multi_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_multi_test.dir/build.make CMakeFiles/eval_sequence_multi_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=30 "Finished codegen for target eval_sequence_multi_test" +.PHONY : CMakeFiles/eval_sequence_multi_test.dir/codegen + +# clean rule for target. +CMakeFiles/eval_sequence_multi_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_multi_test.dir/build.make CMakeFiles/eval_sequence_multi_test.dir/clean +.PHONY : CMakeFiles/eval_sequence_multi_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/advice_bit_iterable_test.dir + +# All Build rule for target. +CMakeFiles/advice_bit_iterable_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/advice_bit_iterable_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/advice_bit_iterable_test.dir/build.make CMakeFiles/advice_bit_iterable_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/advice_bit_iterable_test.dir/build.make CMakeFiles/advice_bit_iterable_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target advice_bit_iterable_test" +.PHONY : CMakeFiles/advice_bit_iterable_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/advice_bit_iterable_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/advice_bit_iterable_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/advice_bit_iterable_test.dir/rule + +# Convenience name for target. +advice_bit_iterable_test: CMakeFiles/advice_bit_iterable_test.dir/rule +.PHONY : advice_bit_iterable_test + +# codegen rule for target. +CMakeFiles/advice_bit_iterable_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/advice_bit_iterable_test.dir/build.make CMakeFiles/advice_bit_iterable_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target advice_bit_iterable_test" +.PHONY : CMakeFiles/advice_bit_iterable_test.dir/codegen + +# clean rule for target. +CMakeFiles/advice_bit_iterable_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/advice_bit_iterable_test.dir/build.make CMakeFiles/advice_bit_iterable_test.dir/clean +.PHONY : CMakeFiles/advice_bit_iterable_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/bit_array_test.dir + +# All Build rule for target. +CMakeFiles/bit_array_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/bit_array_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/bit_array_test.dir/build.make CMakeFiles/bit_array_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/bit_array_test.dir/build.make CMakeFiles/bit_array_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=6 "Built target bit_array_test" +.PHONY : CMakeFiles/bit_array_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/bit_array_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/bit_array_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/bit_array_test.dir/rule + +# Convenience name for target. +bit_array_test: CMakeFiles/bit_array_test.dir/rule +.PHONY : bit_array_test + +# codegen rule for target. +CMakeFiles/bit_array_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bit_array_test.dir/build.make CMakeFiles/bit_array_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=6 "Finished codegen for target bit_array_test" +.PHONY : CMakeFiles/bit_array_test.dir/codegen + +# clean rule for target. +CMakeFiles/bit_array_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bit_array_test.dir/build.make CMakeFiles/bit_array_test.dir/clean +.PHONY : CMakeFiles/bit_array_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/parallel_bit_iterable_test.dir + +# All Build rule for target. +CMakeFiles/parallel_bit_iterable_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/parallel_bit_iterable_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/parallel_bit_iterable_test.dir/build.make CMakeFiles/parallel_bit_iterable_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/parallel_bit_iterable_test.dir/build.make CMakeFiles/parallel_bit_iterable_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=66 "Built target parallel_bit_iterable_test" +.PHONY : CMakeFiles/parallel_bit_iterable_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/parallel_bit_iterable_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/parallel_bit_iterable_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/parallel_bit_iterable_test.dir/rule + +# Convenience name for target. +parallel_bit_iterable_test: CMakeFiles/parallel_bit_iterable_test.dir/rule +.PHONY : parallel_bit_iterable_test + +# codegen rule for target. +CMakeFiles/parallel_bit_iterable_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/parallel_bit_iterable_test.dir/build.make CMakeFiles/parallel_bit_iterable_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=66 "Finished codegen for target parallel_bit_iterable_test" +.PHONY : CMakeFiles/parallel_bit_iterable_test.dir/codegen + +# clean rule for target. +CMakeFiles/parallel_bit_iterable_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/parallel_bit_iterable_test.dir/build.make CMakeFiles/parallel_bit_iterable_test.dir/clean +.PHONY : CMakeFiles/parallel_bit_iterable_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/setbit_index_iterable_test.dir + +# All Build rule for target. +CMakeFiles/setbit_index_iterable_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/setbit_index_iterable_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/setbit_index_iterable_test.dir/build.make CMakeFiles/setbit_index_iterable_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/setbit_index_iterable_test.dir/build.make CMakeFiles/setbit_index_iterable_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target setbit_index_iterable_test" +.PHONY : CMakeFiles/setbit_index_iterable_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/setbit_index_iterable_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/setbit_index_iterable_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/setbit_index_iterable_test.dir/rule + +# Convenience name for target. +setbit_index_iterable_test: CMakeFiles/setbit_index_iterable_test.dir/rule +.PHONY : setbit_index_iterable_test + +# codegen rule for target. +CMakeFiles/setbit_index_iterable_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/setbit_index_iterable_test.dir/build.make CMakeFiles/setbit_index_iterable_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target setbit_index_iterable_test" +.PHONY : CMakeFiles/setbit_index_iterable_test.dir/codegen + +# clean rule for target. +CMakeFiles/setbit_index_iterable_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/setbit_index_iterable_test.dir/build.make CMakeFiles/setbit_index_iterable_test.dir/clean +.PHONY : CMakeFiles/setbit_index_iterable_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/incremental_test.dir + +# All Build rule for target. +CMakeFiles/incremental_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/incremental_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_test.dir/build.make CMakeFiles/incremental_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_test.dir/build.make CMakeFiles/incremental_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=48 "Built target incremental_test" +.PHONY : CMakeFiles/incremental_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/incremental_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/incremental_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/incremental_test.dir/rule + +# Convenience name for target. +incremental_test: CMakeFiles/incremental_test.dir/rule +.PHONY : incremental_test + +# codegen rule for target. +CMakeFiles/incremental_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_test.dir/build.make CMakeFiles/incremental_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=48 "Finished codegen for target incremental_test" +.PHONY : CMakeFiles/incremental_test.dir/codegen + +# clean rule for target. +CMakeFiles/incremental_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_test.dir/build.make CMakeFiles/incremental_test.dir/clean +.PHONY : CMakeFiles/incremental_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/path_recipe_test.dir + +# All Build rule for target. +CMakeFiles/path_recipe_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/path_recipe_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_recipe_test.dir/build.make CMakeFiles/path_recipe_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_recipe_test.dir/build.make CMakeFiles/path_recipe_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=69 "Built target path_recipe_test" +.PHONY : CMakeFiles/path_recipe_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/path_recipe_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/path_recipe_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/path_recipe_test.dir/rule + +# Convenience name for target. +path_recipe_test: CMakeFiles/path_recipe_test.dir/rule +.PHONY : path_recipe_test + +# codegen rule for target. +CMakeFiles/path_recipe_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_recipe_test.dir/build.make CMakeFiles/path_recipe_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=69 "Finished codegen for target path_recipe_test" +.PHONY : CMakeFiles/path_recipe_test.dir/codegen + +# clean rule for target. +CMakeFiles/path_recipe_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_recipe_test.dir/build.make CMakeFiles/path_recipe_test.dir/clean +.PHONY : CMakeFiles/path_recipe_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/blocked_dcf_test.dir + +# All Build rule for target. +CMakeFiles/blocked_dcf_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/blocked_dcf_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/blocked_dcf_test.dir/build.make CMakeFiles/blocked_dcf_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/blocked_dcf_test.dir/build.make CMakeFiles/blocked_dcf_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=9 "Built target blocked_dcf_test" +.PHONY : CMakeFiles/blocked_dcf_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/blocked_dcf_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/blocked_dcf_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/blocked_dcf_test.dir/rule + +# Convenience name for target. +blocked_dcf_test: CMakeFiles/blocked_dcf_test.dir/rule +.PHONY : blocked_dcf_test + +# codegen rule for target. +CMakeFiles/blocked_dcf_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/blocked_dcf_test.dir/build.make CMakeFiles/blocked_dcf_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=9 "Finished codegen for target blocked_dcf_test" +.PHONY : CMakeFiles/blocked_dcf_test.dir/codegen + +# clean rule for target. +CMakeFiles/blocked_dcf_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/blocked_dcf_test.dir/build.make CMakeFiles/blocked_dcf_test.dir/clean +.PHONY : CMakeFiles/blocked_dcf_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/geneval_test.dir + +# All Build rule for target. +CMakeFiles/geneval_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/geneval_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/geneval_test.dir/build.make CMakeFiles/geneval_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/geneval_test.dir/build.make CMakeFiles/geneval_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target geneval_test" +.PHONY : CMakeFiles/geneval_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/geneval_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/geneval_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/geneval_test.dir/rule + +# Convenience name for target. +geneval_test: CMakeFiles/geneval_test.dir/rule +.PHONY : geneval_test + +# codegen rule for target. +CMakeFiles/geneval_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/geneval_test.dir/build.make CMakeFiles/geneval_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target geneval_test" +.PHONY : CMakeFiles/geneval_test.dir/codegen + +# clean rule for target. +CMakeFiles/geneval_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/geneval_test.dir/build.make CMakeFiles/geneval_test.dir/clean +.PHONY : CMakeFiles/geneval_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/stress_scenarios_test.dir + +# All Build rule for target. +CMakeFiles/stress_scenarios_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/stress_scenarios_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/stress_scenarios_test.dir/build.make CMakeFiles/stress_scenarios_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/stress_scenarios_test.dir/build.make CMakeFiles/stress_scenarios_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=89 "Built target stress_scenarios_test" +.PHONY : CMakeFiles/stress_scenarios_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/stress_scenarios_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/stress_scenarios_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/stress_scenarios_test.dir/rule + +# Convenience name for target. +stress_scenarios_test: CMakeFiles/stress_scenarios_test.dir/rule +.PHONY : stress_scenarios_test + +# codegen rule for target. +CMakeFiles/stress_scenarios_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/stress_scenarios_test.dir/build.make CMakeFiles/stress_scenarios_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=89 "Finished codegen for target stress_scenarios_test" +.PHONY : CMakeFiles/stress_scenarios_test.dir/codegen + +# clean rule for target. +CMakeFiles/stress_scenarios_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/stress_scenarios_test.dir/build.make CMakeFiles/stress_scenarios_test.dir/clean +.PHONY : CMakeFiles/stress_scenarios_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/incremental_json_test.dir + +# All Build rule for target. +CMakeFiles/incremental_json_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/incremental_json_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_json_test.dir/build.make CMakeFiles/incremental_json_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_json_test.dir/build.make CMakeFiles/incremental_json_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=47 "Built target incremental_json_test" +.PHONY : CMakeFiles/incremental_json_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/incremental_json_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/incremental_json_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/incremental_json_test.dir/rule + +# Convenience name for target. +incremental_json_test: CMakeFiles/incremental_json_test.dir/rule +.PHONY : incremental_json_test + +# codegen rule for target. +CMakeFiles/incremental_json_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_json_test.dir/build.make CMakeFiles/incremental_json_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=47 "Finished codegen for target incremental_json_test" +.PHONY : CMakeFiles/incremental_json_test.dir/codegen + +# clean rule for target. +CMakeFiles/incremental_json_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_json_test.dir/build.make CMakeFiles/incremental_json_test.dir/clean +.PHONY : CMakeFiles/incremental_json_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/keyword2_test.dir + +# All Build rule for target. +CMakeFiles/keyword2_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/keyword2_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/keyword2_test.dir/build.make CMakeFiles/keyword2_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/keyword2_test.dir/build.make CMakeFiles/keyword2_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target keyword2_test" +.PHONY : CMakeFiles/keyword2_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/keyword2_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/keyword2_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/keyword2_test.dir/rule + +# Convenience name for target. +keyword2_test: CMakeFiles/keyword2_test.dir/rule +.PHONY : keyword2_test + +# codegen rule for target. +CMakeFiles/keyword2_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/keyword2_test.dir/build.make CMakeFiles/keyword2_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target keyword2_test" +.PHONY : CMakeFiles/keyword2_test.dir/codegen + +# clean rule for target. +CMakeFiles/keyword2_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/keyword2_test.dir/build.make CMakeFiles/keyword2_test.dir/clean +.PHONY : CMakeFiles/keyword2_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/types_test.dir + +# All Build rule for target. +CMakeFiles/types_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/types_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/types_test.dir/build.make CMakeFiles/types_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/types_test.dir/build.make CMakeFiles/types_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=90 "Built target types_test" +.PHONY : CMakeFiles/types_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/types_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/types_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/types_test.dir/rule + +# Convenience name for target. +types_test: CMakeFiles/types_test.dir/rule +.PHONY : types_test + +# codegen rule for target. +CMakeFiles/types_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/types_test.dir/build.make CMakeFiles/types_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=90 "Finished codegen for target types_test" +.PHONY : CMakeFiles/types_test.dir/codegen + +# clean rule for target. +CMakeFiles/types_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/types_test.dir/build.make CMakeFiles/types_test.dir/clean +.PHONY : CMakeFiles/types_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/packed_lane_test.dir + +# All Build rule for target. +CMakeFiles/packed_lane_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/packed_lane_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/packed_lane_test.dir/build.make CMakeFiles/packed_lane_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/packed_lane_test.dir/build.make CMakeFiles/packed_lane_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=65 "Built target packed_lane_test" +.PHONY : CMakeFiles/packed_lane_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/packed_lane_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/packed_lane_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/packed_lane_test.dir/rule + +# Convenience name for target. +packed_lane_test: CMakeFiles/packed_lane_test.dir/rule +.PHONY : packed_lane_test + +# codegen rule for target. +CMakeFiles/packed_lane_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/packed_lane_test.dir/build.make CMakeFiles/packed_lane_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=65 "Finished codegen for target packed_lane_test" +.PHONY : CMakeFiles/packed_lane_test.dir/codegen + +# clean rule for target. +CMakeFiles/packed_lane_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/packed_lane_test.dir/build.make CMakeFiles/packed_lane_test.dir/clean +.PHONY : CMakeFiles/packed_lane_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/bitmore_mod_test.dir + +# All Build rule for target. +CMakeFiles/bitmore_mod_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/bitmore_mod_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/bitmore_mod_test.dir/build.make CMakeFiles/bitmore_mod_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/bitmore_mod_test.dir/build.make CMakeFiles/bitmore_mod_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=7 "Built target bitmore_mod_test" +.PHONY : CMakeFiles/bitmore_mod_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/bitmore_mod_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/bitmore_mod_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/bitmore_mod_test.dir/rule + +# Convenience name for target. +bitmore_mod_test: CMakeFiles/bitmore_mod_test.dir/rule +.PHONY : bitmore_mod_test + +# codegen rule for target. +CMakeFiles/bitmore_mod_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bitmore_mod_test.dir/build.make CMakeFiles/bitmore_mod_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=7 "Finished codegen for target bitmore_mod_test" +.PHONY : CMakeFiles/bitmore_mod_test.dir/codegen + +# clean rule for target. +CMakeFiles/bitmore_mod_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bitmore_mod_test.dir/build.make CMakeFiles/bitmore_mod_test.dir/clean +.PHONY : CMakeFiles/bitmore_mod_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/lane_blast_test.dir + +# All Build rule for target. +CMakeFiles/lane_blast_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/lane_blast_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/lane_blast_test.dir/build.make CMakeFiles/lane_blast_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/lane_blast_test.dir/build.make CMakeFiles/lane_blast_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=51 "Built target lane_blast_test" +.PHONY : CMakeFiles/lane_blast_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/lane_blast_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/lane_blast_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/lane_blast_test.dir/rule + +# Convenience name for target. +lane_blast_test: CMakeFiles/lane_blast_test.dir/rule +.PHONY : lane_blast_test + +# codegen rule for target. +CMakeFiles/lane_blast_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/lane_blast_test.dir/build.make CMakeFiles/lane_blast_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=51 "Finished codegen for target lane_blast_test" +.PHONY : CMakeFiles/lane_blast_test.dir/codegen + +# clean rule for target. +CMakeFiles/lane_blast_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/lane_blast_test.dir/build.make CMakeFiles/lane_blast_test.dir/clean +.PHONY : CMakeFiles/lane_blast_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/context_blast_test.dir + +# All Build rule for target. +CMakeFiles/context_blast_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/context_blast_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/context_blast_test.dir/build.make CMakeFiles/context_blast_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/context_blast_test.dir/build.make CMakeFiles/context_blast_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target context_blast_test" +.PHONY : CMakeFiles/context_blast_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/context_blast_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/context_blast_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/context_blast_test.dir/rule + +# Convenience name for target. +context_blast_test: CMakeFiles/context_blast_test.dir/rule +.PHONY : context_blast_test + +# codegen rule for target. +CMakeFiles/context_blast_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/context_blast_test.dir/build.make CMakeFiles/context_blast_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target context_blast_test" +.PHONY : CMakeFiles/context_blast_test.dir/codegen + +# clean rule for target. +CMakeFiles/context_blast_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/context_blast_test.dir/build.make CMakeFiles/context_blast_test.dir/clean +.PHONY : CMakeFiles/context_blast_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/random_test.dir + +# All Build rule for target. +CMakeFiles/random_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/random_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/random_test.dir/build.make CMakeFiles/random_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/random_test.dir/build.make CMakeFiles/random_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=79 "Built target random_test" +.PHONY : CMakeFiles/random_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/random_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/random_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/random_test.dir/rule + +# Convenience name for target. +random_test: CMakeFiles/random_test.dir/rule +.PHONY : random_test + +# codegen rule for target. +CMakeFiles/random_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/random_test.dir/build.make CMakeFiles/random_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=79 "Finished codegen for target random_test" +.PHONY : CMakeFiles/random_test.dir/codegen + +# clean rule for target. +CMakeFiles/random_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/random_test.dir/build.make CMakeFiles/random_test.dir/clean +.PHONY : CMakeFiles/random_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/prg_lowmc_test.dir + +# All Build rule for target. +CMakeFiles/prg_lowmc_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/prg_lowmc_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_lowmc_test.dir/build.make CMakeFiles/prg_lowmc_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_lowmc_test.dir/build.make CMakeFiles/prg_lowmc_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=74 "Built target prg_lowmc_test" +.PHONY : CMakeFiles/prg_lowmc_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/prg_lowmc_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/prg_lowmc_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/prg_lowmc_test.dir/rule + +# Convenience name for target. +prg_lowmc_test: CMakeFiles/prg_lowmc_test.dir/rule +.PHONY : prg_lowmc_test + +# codegen rule for target. +CMakeFiles/prg_lowmc_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_lowmc_test.dir/build.make CMakeFiles/prg_lowmc_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=74 "Finished codegen for target prg_lowmc_test" +.PHONY : CMakeFiles/prg_lowmc_test.dir/codegen + +# clean rule for target. +CMakeFiles/prg_lowmc_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_lowmc_test.dir/build.make CMakeFiles/prg_lowmc_test.dir/clean +.PHONY : CMakeFiles/prg_lowmc_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/prg_chacha_test.dir + +# All Build rule for target. +CMakeFiles/prg_chacha_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/prg_chacha_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_chacha_test.dir/build.make CMakeFiles/prg_chacha_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_chacha_test.dir/build.make CMakeFiles/prg_chacha_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=73 "Built target prg_chacha_test" +.PHONY : CMakeFiles/prg_chacha_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/prg_chacha_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/prg_chacha_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/prg_chacha_test.dir/rule + +# Convenience name for target. +prg_chacha_test: CMakeFiles/prg_chacha_test.dir/rule +.PHONY : prg_chacha_test + +# codegen rule for target. +CMakeFiles/prg_chacha_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_chacha_test.dir/build.make CMakeFiles/prg_chacha_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=73 "Finished codegen for target prg_chacha_test" +.PHONY : CMakeFiles/prg_chacha_test.dir/codegen + +# clean rule for target. +CMakeFiles/prg_chacha_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_chacha_test.dir/build.make CMakeFiles/prg_chacha_test.dir/clean +.PHONY : CMakeFiles/prg_chacha_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/prg_aes_ccr_test.dir + +# All Build rule for target. +CMakeFiles/prg_aes_ccr_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/prg_aes_ccr_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_aes_ccr_test.dir/build.make CMakeFiles/prg_aes_ccr_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_aes_ccr_test.dir/build.make CMakeFiles/prg_aes_ccr_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=72 "Built target prg_aes_ccr_test" +.PHONY : CMakeFiles/prg_aes_ccr_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/prg_aes_ccr_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/prg_aes_ccr_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/prg_aes_ccr_test.dir/rule + +# Convenience name for target. +prg_aes_ccr_test: CMakeFiles/prg_aes_ccr_test.dir/rule +.PHONY : prg_aes_ccr_test + +# codegen rule for target. +CMakeFiles/prg_aes_ccr_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_aes_ccr_test.dir/build.make CMakeFiles/prg_aes_ccr_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=72 "Finished codegen for target prg_aes_ccr_test" +.PHONY : CMakeFiles/prg_aes_ccr_test.dir/codegen + +# clean rule for target. +CMakeFiles/prg_aes_ccr_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_aes_ccr_test.dir/build.make CMakeFiles/prg_aes_ccr_test.dir/clean +.PHONY : CMakeFiles/prg_aes_ccr_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/half_tree_test.dir + +# All Build rule for target. +CMakeFiles/half_tree_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/half_tree_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/half_tree_test.dir/build.make CMakeFiles/half_tree_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/half_tree_test.dir/build.make CMakeFiles/half_tree_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=44 "Built target half_tree_test" +.PHONY : CMakeFiles/half_tree_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/half_tree_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/half_tree_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/half_tree_test.dir/rule + +# Convenience name for target. +half_tree_test: CMakeFiles/half_tree_test.dir/rule +.PHONY : half_tree_test + +# codegen rule for target. +CMakeFiles/half_tree_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/half_tree_test.dir/build.make CMakeFiles/half_tree_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=44 "Finished codegen for target half_tree_test" +.PHONY : CMakeFiles/half_tree_test.dir/codegen + +# clean rule for target. +CMakeFiles/half_tree_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/half_tree_test.dir/build.make CMakeFiles/half_tree_test.dir/clean +.PHONY : CMakeFiles/half_tree_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/constrained_cmp_test.dir + +# All Build rule for target. +CMakeFiles/constrained_cmp_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/constrained_cmp_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/constrained_cmp_test.dir/build.make CMakeFiles/constrained_cmp_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/constrained_cmp_test.dir/build.make CMakeFiles/constrained_cmp_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=16 "Built target constrained_cmp_test" +.PHONY : CMakeFiles/constrained_cmp_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/constrained_cmp_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/constrained_cmp_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/constrained_cmp_test.dir/rule + +# Convenience name for target. +constrained_cmp_test: CMakeFiles/constrained_cmp_test.dir/rule +.PHONY : constrained_cmp_test + +# codegen rule for target. +CMakeFiles/constrained_cmp_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/constrained_cmp_test.dir/build.make CMakeFiles/constrained_cmp_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=16 "Finished codegen for target constrained_cmp_test" +.PHONY : CMakeFiles/constrained_cmp_test.dir/codegen + +# clean rule for target. +CMakeFiles/constrained_cmp_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/constrained_cmp_test.dir/build.make CMakeFiles/constrained_cmp_test.dir/clean +.PHONY : CMakeFiles/constrained_cmp_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/fp61_test.dir + +# All Build rule for target. +CMakeFiles/fp61_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/fp61_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/fp61_test.dir/build.make CMakeFiles/fp61_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/fp61_test.dir/build.make CMakeFiles/fp61_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=38 "Built target fp61_test" +.PHONY : CMakeFiles/fp61_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/fp61_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/fp61_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/fp61_test.dir/rule + +# Convenience name for target. +fp61_test: CMakeFiles/fp61_test.dir/rule +.PHONY : fp61_test + +# codegen rule for target. +CMakeFiles/fp61_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/fp61_test.dir/build.make CMakeFiles/fp61_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=38 "Finished codegen for target fp61_test" +.PHONY : CMakeFiles/fp61_test.dir/codegen + +# clean rule for target. +CMakeFiles/fp61_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/fp61_test.dir/build.make CMakeFiles/fp61_test.dir/clean +.PHONY : CMakeFiles/fp61_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/field_output_test.dir + +# All Build rule for target. +CMakeFiles/field_output_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/field_output_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/field_output_test.dir/build.make CMakeFiles/field_output_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/field_output_test.dir/build.make CMakeFiles/field_output_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=35 "Built target field_output_test" +.PHONY : CMakeFiles/field_output_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/field_output_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/field_output_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/field_output_test.dir/rule + +# Convenience name for target. +field_output_test: CMakeFiles/field_output_test.dir/rule +.PHONY : field_output_test + +# codegen rule for target. +CMakeFiles/field_output_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/field_output_test.dir/build.make CMakeFiles/field_output_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=35 "Finished codegen for target field_output_test" +.PHONY : CMakeFiles/field_output_test.dir/codegen + +# clean rule for target. +CMakeFiles/field_output_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/field_output_test.dir/build.make CMakeFiles/field_output_test.dir/clean +.PHONY : CMakeFiles/field_output_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/gf2_test.dir + +# All Build rule for target. +CMakeFiles/gf2_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/gf2_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_test.dir/build.make CMakeFiles/gf2_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_test.dir/build.make CMakeFiles/gf2_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=40 "Built target gf2_test" +.PHONY : CMakeFiles/gf2_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/gf2_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/gf2_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/gf2_test.dir/rule + +# Convenience name for target. +gf2_test: CMakeFiles/gf2_test.dir/rule +.PHONY : gf2_test + +# codegen rule for target. +CMakeFiles/gf2_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_test.dir/build.make CMakeFiles/gf2_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=40 "Finished codegen for target gf2_test" +.PHONY : CMakeFiles/gf2_test.dir/codegen + +# clean rule for target. +CMakeFiles/gf2_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_test.dir/build.make CMakeFiles/gf2_test.dir/clean +.PHONY : CMakeFiles/gf2_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/gf2_adversarial_test.dir + +# All Build rule for target. +CMakeFiles/gf2_adversarial_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/gf2_adversarial_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_adversarial_test.dir/build.make CMakeFiles/gf2_adversarial_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_adversarial_test.dir/build.make CMakeFiles/gf2_adversarial_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=39 "Built target gf2_adversarial_test" +.PHONY : CMakeFiles/gf2_adversarial_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/gf2_adversarial_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/gf2_adversarial_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/gf2_adversarial_test.dir/rule + +# Convenience name for target. +gf2_adversarial_test: CMakeFiles/gf2_adversarial_test.dir/rule +.PHONY : gf2_adversarial_test + +# codegen rule for target. +CMakeFiles/gf2_adversarial_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_adversarial_test.dir/build.make CMakeFiles/gf2_adversarial_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=39 "Finished codegen for target gf2_adversarial_test" +.PHONY : CMakeFiles/gf2_adversarial_test.dir/codegen + +# clean rule for target. +CMakeFiles/gf2_adversarial_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_adversarial_test.dir/build.make CMakeFiles/gf2_adversarial_test.dir/clean +.PHONY : CMakeFiles/gf2_adversarial_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/arith_payload_test.dir + +# All Build rule for target. +CMakeFiles/arith_payload_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/arith_payload_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_payload_test.dir/build.make CMakeFiles/arith_payload_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_payload_test.dir/build.make CMakeFiles/arith_payload_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=3 "Built target arith_payload_test" +.PHONY : CMakeFiles/arith_payload_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/arith_payload_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/arith_payload_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/arith_payload_test.dir/rule + +# Convenience name for target. +arith_payload_test: CMakeFiles/arith_payload_test.dir/rule +.PHONY : arith_payload_test + +# codegen rule for target. +CMakeFiles/arith_payload_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_payload_test.dir/build.make CMakeFiles/arith_payload_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=3 "Finished codegen for target arith_payload_test" +.PHONY : CMakeFiles/arith_payload_test.dir/codegen + +# clean rule for target. +CMakeFiles/arith_payload_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_payload_test.dir/build.make CMakeFiles/arith_payload_test.dir/clean +.PHONY : CMakeFiles/arith_payload_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/verifiable_test.dir + +# All Build rule for target. +CMakeFiles/verifiable_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/verifiable_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/verifiable_test.dir/build.make CMakeFiles/verifiable_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/verifiable_test.dir/build.make CMakeFiles/verifiable_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=93 "Built target verifiable_test" +.PHONY : CMakeFiles/verifiable_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/verifiable_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/verifiable_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/verifiable_test.dir/rule + +# Convenience name for target. +verifiable_test: CMakeFiles/verifiable_test.dir/rule +.PHONY : verifiable_test + +# codegen rule for target. +CMakeFiles/verifiable_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/verifiable_test.dir/build.make CMakeFiles/verifiable_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=93 "Finished codegen for target verifiable_test" +.PHONY : CMakeFiles/verifiable_test.dir/codegen + +# clean rule for target. +CMakeFiles/verifiable_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/verifiable_test.dir/build.make CMakeFiles/verifiable_test.dir/clean +.PHONY : CMakeFiles/verifiable_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/vdpf_adversarial_test.dir + +# All Build rule for target. +CMakeFiles/vdpf_adversarial_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/vdpf_adversarial_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_adversarial_test.dir/build.make CMakeFiles/vdpf_adversarial_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_adversarial_test.dir/build.make CMakeFiles/vdpf_adversarial_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=91 "Built target vdpf_adversarial_test" +.PHONY : CMakeFiles/vdpf_adversarial_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/vdpf_adversarial_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/vdpf_adversarial_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/vdpf_adversarial_test.dir/rule + +# Convenience name for target. +vdpf_adversarial_test: CMakeFiles/vdpf_adversarial_test.dir/rule +.PHONY : vdpf_adversarial_test + +# codegen rule for target. +CMakeFiles/vdpf_adversarial_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_adversarial_test.dir/build.make CMakeFiles/vdpf_adversarial_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=91 "Finished codegen for target vdpf_adversarial_test" +.PHONY : CMakeFiles/vdpf_adversarial_test.dir/codegen + +# clean rule for target. +CMakeFiles/vdpf_adversarial_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_adversarial_test.dir/build.make CMakeFiles/vdpf_adversarial_test.dir/clean +.PHONY : CMakeFiles/vdpf_adversarial_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/shamir_adversarial_test.dir + +# All Build rule for target. +CMakeFiles/shamir_adversarial_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/shamir_adversarial_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/shamir_adversarial_test.dir/build.make CMakeFiles/shamir_adversarial_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/shamir_adversarial_test.dir/build.make CMakeFiles/shamir_adversarial_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=85 "Built target shamir_adversarial_test" +.PHONY : CMakeFiles/shamir_adversarial_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/shamir_adversarial_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/shamir_adversarial_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/shamir_adversarial_test.dir/rule + +# Convenience name for target. +shamir_adversarial_test: CMakeFiles/shamir_adversarial_test.dir/rule +.PHONY : shamir_adversarial_test + +# codegen rule for target. +CMakeFiles/shamir_adversarial_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shamir_adversarial_test.dir/build.make CMakeFiles/shamir_adversarial_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=85 "Finished codegen for target shamir_adversarial_test" +.PHONY : CMakeFiles/shamir_adversarial_test.dir/codegen + +# clean rule for target. +CMakeFiles/shamir_adversarial_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shamir_adversarial_test.dir/build.make CMakeFiles/shamir_adversarial_test.dir/clean +.PHONY : CMakeFiles/shamir_adversarial_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/vdpf_regression_test.dir + +# All Build rule for target. +CMakeFiles/vdpf_regression_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/vdpf_regression_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_regression_test.dir/build.make CMakeFiles/vdpf_regression_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_regression_test.dir/build.make CMakeFiles/vdpf_regression_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=92 "Built target vdpf_regression_test" +.PHONY : CMakeFiles/vdpf_regression_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/vdpf_regression_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/vdpf_regression_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/vdpf_regression_test.dir/rule + +# Convenience name for target. +vdpf_regression_test: CMakeFiles/vdpf_regression_test.dir/rule +.PHONY : vdpf_regression_test + +# codegen rule for target. +CMakeFiles/vdpf_regression_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_regression_test.dir/build.make CMakeFiles/vdpf_regression_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=92 "Finished codegen for target vdpf_regression_test" +.PHONY : CMakeFiles/vdpf_regression_test.dir/codegen + +# clean rule for target. +CMakeFiles/vdpf_regression_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_regression_test.dir/build.make CMakeFiles/vdpf_regression_test.dir/clean +.PHONY : CMakeFiles/vdpf_regression_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/opt_in_malicious_test.dir + +# All Build rule for target. +CMakeFiles/opt_in_malicious_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/opt_in_malicious_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/opt_in_malicious_test.dir/build.make CMakeFiles/opt_in_malicious_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/opt_in_malicious_test.dir/build.make CMakeFiles/opt_in_malicious_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target opt_in_malicious_test" +.PHONY : CMakeFiles/opt_in_malicious_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/opt_in_malicious_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/opt_in_malicious_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/opt_in_malicious_test.dir/rule + +# Convenience name for target. +opt_in_malicious_test: CMakeFiles/opt_in_malicious_test.dir/rule +.PHONY : opt_in_malicious_test + +# codegen rule for target. +CMakeFiles/opt_in_malicious_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/opt_in_malicious_test.dir/build.make CMakeFiles/opt_in_malicious_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target opt_in_malicious_test" +.PHONY : CMakeFiles/opt_in_malicious_test.dir/codegen + +# clean rule for target. +CMakeFiles/opt_in_malicious_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/opt_in_malicious_test.dir/build.make CMakeFiles/opt_in_malicious_test.dir/clean +.PHONY : CMakeFiles/opt_in_malicious_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/multipoint_test.dir + +# All Build rule for target. +CMakeFiles/multipoint_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/multipoint_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/multipoint_test.dir/build.make CMakeFiles/multipoint_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/multipoint_test.dir/build.make CMakeFiles/multipoint_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=55 "Built target multipoint_test" +.PHONY : CMakeFiles/multipoint_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/multipoint_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/multipoint_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/multipoint_test.dir/rule + +# Convenience name for target. +multipoint_test: CMakeFiles/multipoint_test.dir/rule +.PHONY : multipoint_test + +# codegen rule for target. +CMakeFiles/multipoint_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/multipoint_test.dir/build.make CMakeFiles/multipoint_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=55 "Finished codegen for target multipoint_test" +.PHONY : CMakeFiles/multipoint_test.dir/codegen + +# clean rule for target. +CMakeFiles/multipoint_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/multipoint_test.dir/build.make CMakeFiles/multipoint_test.dir/clean +.PHONY : CMakeFiles/multipoint_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/dpf3_test.dir + +# All Build rule for target. +CMakeFiles/dpf3_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/dpf3_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf3_test.dir/build.make CMakeFiles/dpf3_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf3_test.dir/build.make CMakeFiles/dpf3_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=20 "Built target dpf3_test" +.PHONY : CMakeFiles/dpf3_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/dpf3_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/dpf3_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/dpf3_test.dir/rule + +# Convenience name for target. +dpf3_test: CMakeFiles/dpf3_test.dir/rule +.PHONY : dpf3_test + +# codegen rule for target. +CMakeFiles/dpf3_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf3_test.dir/build.make CMakeFiles/dpf3_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=20 "Finished codegen for target dpf3_test" +.PHONY : CMakeFiles/dpf3_test.dir/codegen + +# clean rule for target. +CMakeFiles/dpf3_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf3_test.dir/build.make CMakeFiles/dpf3_test.dir/clean +.PHONY : CMakeFiles/dpf3_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/eval_inner_product_test.dir + +# All Build rule for target. +CMakeFiles/eval_inner_product_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/eval_inner_product_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_inner_product_test.dir/build.make CMakeFiles/eval_inner_product_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_inner_product_test.dir/build.make CMakeFiles/eval_inner_product_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=26 "Built target eval_inner_product_test" +.PHONY : CMakeFiles/eval_inner_product_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/eval_inner_product_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/eval_inner_product_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/eval_inner_product_test.dir/rule + +# Convenience name for target. +eval_inner_product_test: CMakeFiles/eval_inner_product_test.dir/rule +.PHONY : eval_inner_product_test + +# codegen rule for target. +CMakeFiles/eval_inner_product_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_inner_product_test.dir/build.make CMakeFiles/eval_inner_product_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=26 "Finished codegen for target eval_inner_product_test" +.PHONY : CMakeFiles/eval_inner_product_test.dir/codegen + +# clean rule for target. +CMakeFiles/eval_inner_product_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_inner_product_test.dir/build.make CMakeFiles/eval_inner_product_test.dir/clean +.PHONY : CMakeFiles/eval_inner_product_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/shared_and_test.dir + +# All Build rule for target. +CMakeFiles/shared_and_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/shared_and_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/shared_and_test.dir/build.make CMakeFiles/shared_and_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/shared_and_test.dir/build.make CMakeFiles/shared_and_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=87 "Built target shared_and_test" +.PHONY : CMakeFiles/shared_and_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/shared_and_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/shared_and_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/shared_and_test.dir/rule + +# Convenience name for target. +shared_and_test: CMakeFiles/shared_and_test.dir/rule +.PHONY : shared_and_test + +# codegen rule for target. +CMakeFiles/shared_and_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shared_and_test.dir/build.make CMakeFiles/shared_and_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=87 "Finished codegen for target shared_and_test" +.PHONY : CMakeFiles/shared_and_test.dir/codegen + +# clean rule for target. +CMakeFiles/shared_and_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shared_and_test.dir/build.make CMakeFiles/shared_and_test.dir/clean +.PHONY : CMakeFiles/shared_and_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/cohort_test.dir + +# All Build rule for target. +CMakeFiles/cohort_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/cohort_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/cohort_test.dir/build.make CMakeFiles/cohort_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/cohort_test.dir/build.make CMakeFiles/cohort_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=13 "Built target cohort_test" +.PHONY : CMakeFiles/cohort_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/cohort_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/cohort_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/cohort_test.dir/rule + +# Convenience name for target. +cohort_test: CMakeFiles/cohort_test.dir/rule +.PHONY : cohort_test + +# codegen rule for target. +CMakeFiles/cohort_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cohort_test.dir/build.make CMakeFiles/cohort_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=13 "Finished codegen for target cohort_test" +.PHONY : CMakeFiles/cohort_test.dir/codegen + +# clean rule for target. +CMakeFiles/cohort_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cohort_test.dir/build.make CMakeFiles/cohort_test.dir/clean +.PHONY : CMakeFiles/cohort_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/interleave_leaves_test.dir + +# All Build rule for target. +CMakeFiles/interleave_leaves_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/interleave_leaves_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/interleave_leaves_test.dir/build.make CMakeFiles/interleave_leaves_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/interleave_leaves_test.dir/build.make CMakeFiles/interleave_leaves_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=49 "Built target interleave_leaves_test" +.PHONY : CMakeFiles/interleave_leaves_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/interleave_leaves_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/interleave_leaves_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/interleave_leaves_test.dir/rule + +# Convenience name for target. +interleave_leaves_test: CMakeFiles/interleave_leaves_test.dir/rule +.PHONY : interleave_leaves_test + +# codegen rule for target. +CMakeFiles/interleave_leaves_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/interleave_leaves_test.dir/build.make CMakeFiles/interleave_leaves_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=49 "Finished codegen for target interleave_leaves_test" +.PHONY : CMakeFiles/interleave_leaves_test.dir/codegen + +# clean rule for target. +CMakeFiles/interleave_leaves_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/interleave_leaves_test.dir/build.make CMakeFiles/interleave_leaves_test.dir/clean +.PHONY : CMakeFiles/interleave_leaves_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/secret_share_test.dir + +# All Build rule for target. +CMakeFiles/secret_share_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/secret_share_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/secret_share_test.dir/build.make CMakeFiles/secret_share_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/secret_share_test.dir/build.make CMakeFiles/secret_share_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=82 "Built target secret_share_test" +.PHONY : CMakeFiles/secret_share_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/secret_share_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/secret_share_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/secret_share_test.dir/rule + +# Convenience name for target. +secret_share_test: CMakeFiles/secret_share_test.dir/rule +.PHONY : secret_share_test + +# codegen rule for target. +CMakeFiles/secret_share_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/secret_share_test.dir/build.make CMakeFiles/secret_share_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=82 "Finished codegen for target secret_share_test" +.PHONY : CMakeFiles/secret_share_test.dir/codegen + +# clean rule for target. +CMakeFiles/secret_share_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/secret_share_test.dir/build.make CMakeFiles/secret_share_test.dir/clean +.PHONY : CMakeFiles/secret_share_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/beaver_test.dir + +# All Build rule for target. +CMakeFiles/beaver_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/beaver_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_test.dir/build.make CMakeFiles/beaver_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_test.dir/build.make CMakeFiles/beaver_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=5 "Built target beaver_test" +.PHONY : CMakeFiles/beaver_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/beaver_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/beaver_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/beaver_test.dir/rule + +# Convenience name for target. +beaver_test: CMakeFiles/beaver_test.dir/rule +.PHONY : beaver_test + +# codegen rule for target. +CMakeFiles/beaver_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_test.dir/build.make CMakeFiles/beaver_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=5 "Finished codegen for target beaver_test" +.PHONY : CMakeFiles/beaver_test.dir/codegen + +# clean rule for target. +CMakeFiles/beaver_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_test.dir/build.make CMakeFiles/beaver_test.dir/clean +.PHONY : CMakeFiles/beaver_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/share_runtime_test.dir + +# All Build rule for target. +CMakeFiles/share_runtime_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/share_runtime_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/share_runtime_test.dir/build.make CMakeFiles/share_runtime_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/share_runtime_test.dir/build.make CMakeFiles/share_runtime_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=86 "Built target share_runtime_test" +.PHONY : CMakeFiles/share_runtime_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/share_runtime_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/share_runtime_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/share_runtime_test.dir/rule + +# Convenience name for target. +share_runtime_test: CMakeFiles/share_runtime_test.dir/rule +.PHONY : share_runtime_test + +# codegen rule for target. +CMakeFiles/share_runtime_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/share_runtime_test.dir/build.make CMakeFiles/share_runtime_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=86 "Finished codegen for target share_runtime_test" +.PHONY : CMakeFiles/share_runtime_test.dir/codegen + +# clean rule for target. +CMakeFiles/share_runtime_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/share_runtime_test.dir/build.make CMakeFiles/share_runtime_test.dir/clean +.PHONY : CMakeFiles/share_runtime_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/net_control_test.dir + +# All Build rule for target. +CMakeFiles/net_control_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/net_control_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/net_control_test.dir/build.make CMakeFiles/net_control_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/net_control_test.dir/build.make CMakeFiles/net_control_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target net_control_test" +.PHONY : CMakeFiles/net_control_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/net_control_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/net_control_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/net_control_test.dir/rule + +# Convenience name for target. +net_control_test: CMakeFiles/net_control_test.dir/rule +.PHONY : net_control_test + +# codegen rule for target. +CMakeFiles/net_control_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/net_control_test.dir/build.make CMakeFiles/net_control_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target net_control_test" +.PHONY : CMakeFiles/net_control_test.dir/codegen + +# clean rule for target. +CMakeFiles/net_control_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/net_control_test.dir/build.make CMakeFiles/net_control_test.dir/clean +.PHONY : CMakeFiles/net_control_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/security_test.dir + +# All Build rule for target. +CMakeFiles/security_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/security_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/security_test.dir/build.make CMakeFiles/security_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/security_test.dir/build.make CMakeFiles/security_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=83 "Built target security_test" +.PHONY : CMakeFiles/security_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/security_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/security_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/security_test.dir/rule + +# Convenience name for target. +security_test: CMakeFiles/security_test.dir/rule +.PHONY : security_test + +# codegen rule for target. +CMakeFiles/security_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/security_test.dir/build.make CMakeFiles/security_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=83 "Finished codegen for target security_test" +.PHONY : CMakeFiles/security_test.dir/codegen + +# clean rule for target. +CMakeFiles/security_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/security_test.dir/build.make CMakeFiles/security_test.dir/clean +.PHONY : CMakeFiles/security_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/protocol_batch_test.dir + +# All Build rule for target. +CMakeFiles/protocol_batch_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/protocol_batch_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/protocol_batch_test.dir/build.make CMakeFiles/protocol_batch_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/protocol_batch_test.dir/build.make CMakeFiles/protocol_batch_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=78 "Built target protocol_batch_test" +.PHONY : CMakeFiles/protocol_batch_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/protocol_batch_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/protocol_batch_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/protocol_batch_test.dir/rule + +# Convenience name for target. +protocol_batch_test: CMakeFiles/protocol_batch_test.dir/rule +.PHONY : protocol_batch_test + +# codegen rule for target. +CMakeFiles/protocol_batch_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/protocol_batch_test.dir/build.make CMakeFiles/protocol_batch_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=78 "Finished codegen for target protocol_batch_test" +.PHONY : CMakeFiles/protocol_batch_test.dir/codegen + +# clean rule for target. +CMakeFiles/protocol_batch_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/protocol_batch_test.dir/build.make CMakeFiles/protocol_batch_test.dir/clean +.PHONY : CMakeFiles/protocol_batch_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/compose_test.dir + +# All Build rule for target. +CMakeFiles/compose_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/compose_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/compose_test.dir/build.make CMakeFiles/compose_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/compose_test.dir/build.make CMakeFiles/compose_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=14 "Built target compose_test" +.PHONY : CMakeFiles/compose_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/compose_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/compose_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/compose_test.dir/rule + +# Convenience name for target. +compose_test: CMakeFiles/compose_test.dir/rule +.PHONY : compose_test + +# codegen rule for target. +CMakeFiles/compose_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/compose_test.dir/build.make CMakeFiles/compose_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=14 "Finished codegen for target compose_test" +.PHONY : CMakeFiles/compose_test.dir/codegen + +# clean rule for target. +CMakeFiles/compose_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/compose_test.dir/build.make CMakeFiles/compose_test.dir/clean +.PHONY : CMakeFiles/compose_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/experiment_test.dir + +# All Build rule for target. +CMakeFiles/experiment_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/experiment_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/experiment_test.dir/build.make CMakeFiles/experiment_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/experiment_test.dir/build.make CMakeFiles/experiment_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target experiment_test" +.PHONY : CMakeFiles/experiment_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/experiment_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/experiment_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/experiment_test.dir/rule + +# Convenience name for target. +experiment_test: CMakeFiles/experiment_test.dir/rule +.PHONY : experiment_test + +# codegen rule for target. +CMakeFiles/experiment_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/experiment_test.dir/build.make CMakeFiles/experiment_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target experiment_test" +.PHONY : CMakeFiles/experiment_test.dir/codegen + +# clean rule for target. +CMakeFiles/experiment_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/experiment_test.dir/build.make CMakeFiles/experiment_test.dir/clean +.PHONY : CMakeFiles/experiment_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/log_test.dir + +# All Build rule for target. +CMakeFiles/log_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/log_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/log_test.dir/build.make CMakeFiles/log_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/log_test.dir/build.make CMakeFiles/log_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=53 "Built target log_test" +.PHONY : CMakeFiles/log_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/log_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/log_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/log_test.dir/rule + +# Convenience name for target. +log_test: CMakeFiles/log_test.dir/rule +.PHONY : log_test + +# codegen rule for target. +CMakeFiles/log_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/log_test.dir/build.make CMakeFiles/log_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=53 "Finished codegen for target log_test" +.PHONY : CMakeFiles/log_test.dir/codegen + +# clean rule for target. +CMakeFiles/log_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/log_test.dir/build.make CMakeFiles/log_test.dir/clean +.PHONY : CMakeFiles/log_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/constant_lut_test.dir + +# All Build rule for target. +CMakeFiles/constant_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/constant_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/constant_lut_test.dir/build.make CMakeFiles/constant_lut_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/constant_lut_test.dir/build.make CMakeFiles/constant_lut_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=15 "Built target constant_lut_test" +.PHONY : CMakeFiles/constant_lut_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/constant_lut_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/constant_lut_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/constant_lut_test.dir/rule + +# Convenience name for target. +constant_lut_test: CMakeFiles/constant_lut_test.dir/rule +.PHONY : constant_lut_test + +# codegen rule for target. +CMakeFiles/constant_lut_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/constant_lut_test.dir/build.make CMakeFiles/constant_lut_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=15 "Finished codegen for target constant_lut_test" +.PHONY : CMakeFiles/constant_lut_test.dir/codegen + +# clean rule for target. +CMakeFiles/constant_lut_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/constant_lut_test.dir/build.make CMakeFiles/constant_lut_test.dir/clean +.PHONY : CMakeFiles/constant_lut_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/signed_prefix_test.dir + +# All Build rule for target. +CMakeFiles/signed_prefix_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/signed_prefix_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/signed_prefix_test.dir/build.make CMakeFiles/signed_prefix_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/signed_prefix_test.dir/build.make CMakeFiles/signed_prefix_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target signed_prefix_test" +.PHONY : CMakeFiles/signed_prefix_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/signed_prefix_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/signed_prefix_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/signed_prefix_test.dir/rule + +# Convenience name for target. +signed_prefix_test: CMakeFiles/signed_prefix_test.dir/rule +.PHONY : signed_prefix_test + +# codegen rule for target. +CMakeFiles/signed_prefix_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/signed_prefix_test.dir/build.make CMakeFiles/signed_prefix_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target signed_prefix_test" +.PHONY : CMakeFiles/signed_prefix_test.dir/codegen + +# clean rule for target. +CMakeFiles/signed_prefix_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/signed_prefix_test.dir/build.make CMakeFiles/signed_prefix_test.dir/clean +.PHONY : CMakeFiles/signed_prefix_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/easy_lut_test.dir + +# All Build rule for target. +CMakeFiles/easy_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/easy_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/easy_lut_test.dir/build.make CMakeFiles/easy_lut_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/easy_lut_test.dir/build.make CMakeFiles/easy_lut_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=23 "Built target easy_lut_test" +.PHONY : CMakeFiles/easy_lut_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/easy_lut_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/easy_lut_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/easy_lut_test.dir/rule + +# Convenience name for target. +easy_lut_test: CMakeFiles/easy_lut_test.dir/rule +.PHONY : easy_lut_test + +# codegen rule for target. +CMakeFiles/easy_lut_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/easy_lut_test.dir/build.make CMakeFiles/easy_lut_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=23 "Finished codegen for target easy_lut_test" +.PHONY : CMakeFiles/easy_lut_test.dir/codegen + +# clean rule for target. +CMakeFiles/easy_lut_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/easy_lut_test.dir/build.make CMakeFiles/easy_lut_test.dir/clean +.PHONY : CMakeFiles/easy_lut_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/dyadic_lut_test.dir + +# All Build rule for target. +CMakeFiles/dyadic_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/dyadic_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/dyadic_lut_test.dir/build.make CMakeFiles/dyadic_lut_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/dyadic_lut_test.dir/build.make CMakeFiles/dyadic_lut_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target dyadic_lut_test" +.PHONY : CMakeFiles/dyadic_lut_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/dyadic_lut_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/dyadic_lut_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/dyadic_lut_test.dir/rule + +# Convenience name for target. +dyadic_lut_test: CMakeFiles/dyadic_lut_test.dir/rule +.PHONY : dyadic_lut_test + +# codegen rule for target. +CMakeFiles/dyadic_lut_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dyadic_lut_test.dir/build.make CMakeFiles/dyadic_lut_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target dyadic_lut_test" +.PHONY : CMakeFiles/dyadic_lut_test.dir/codegen + +# clean rule for target. +CMakeFiles/dyadic_lut_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dyadic_lut_test.dir/build.make CMakeFiles/dyadic_lut_test.dir/clean +.PHONY : CMakeFiles/dyadic_lut_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/nmod_test.dir + +# All Build rule for target. +CMakeFiles/nmod_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/nmod_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/nmod_test.dir/build.make CMakeFiles/nmod_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/nmod_test.dir/build.make CMakeFiles/nmod_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=56 "Built target nmod_test" +.PHONY : CMakeFiles/nmod_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/nmod_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/nmod_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/nmod_test.dir/rule + +# Convenience name for target. +nmod_test: CMakeFiles/nmod_test.dir/rule +.PHONY : nmod_test + +# codegen rule for target. +CMakeFiles/nmod_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/nmod_test.dir/build.make CMakeFiles/nmod_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=56 "Finished codegen for target nmod_test" +.PHONY : CMakeFiles/nmod_test.dir/codegen + +# clean rule for target. +CMakeFiles/nmod_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/nmod_test.dir/build.make CMakeFiles/nmod_test.dir/clean +.PHONY : CMakeFiles/nmod_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/exact_steps_test.dir + +# All Build rule for target. +CMakeFiles/exact_steps_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/exact_steps_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/exact_steps_test.dir/build.make CMakeFiles/exact_steps_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/exact_steps_test.dir/build.make CMakeFiles/exact_steps_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=33 "Built target exact_steps_test" +.PHONY : CMakeFiles/exact_steps_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/exact_steps_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/exact_steps_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/exact_steps_test.dir/rule + +# Convenience name for target. +exact_steps_test: CMakeFiles/exact_steps_test.dir/rule +.PHONY : exact_steps_test + +# codegen rule for target. +CMakeFiles/exact_steps_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/exact_steps_test.dir/build.make CMakeFiles/exact_steps_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=33 "Finished codegen for target exact_steps_test" +.PHONY : CMakeFiles/exact_steps_test.dir/codegen + +# clean rule for target. +CMakeFiles/exact_steps_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/exact_steps_test.dir/build.make CMakeFiles/exact_steps_test.dir/clean +.PHONY : CMakeFiles/exact_steps_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/closed_form_test.dir + +# All Build rule for target. +CMakeFiles/closed_form_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/closed_form_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/closed_form_test.dir/build.make CMakeFiles/closed_form_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/closed_form_test.dir/build.make CMakeFiles/closed_form_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=12 "Built target closed_form_test" +.PHONY : CMakeFiles/closed_form_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/closed_form_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/closed_form_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/closed_form_test.dir/rule + +# Convenience name for target. +closed_form_test: CMakeFiles/closed_form_test.dir/rule +.PHONY : closed_form_test + +# codegen rule for target. +CMakeFiles/closed_form_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/closed_form_test.dir/build.make CMakeFiles/closed_form_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=12 "Finished codegen for target closed_form_test" +.PHONY : CMakeFiles/closed_form_test.dir/codegen + +# clean rule for target. +CMakeFiles/closed_form_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/closed_form_test.dir/build.make CMakeFiles/closed_form_test.dir/clean +.PHONY : CMakeFiles/closed_form_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/principal_lut_test.dir + +# All Build rule for target. +CMakeFiles/principal_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/principal_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/principal_lut_test.dir/build.make CMakeFiles/principal_lut_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/principal_lut_test.dir/build.make CMakeFiles/principal_lut_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=75 "Built target principal_lut_test" +.PHONY : CMakeFiles/principal_lut_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/principal_lut_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/principal_lut_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/principal_lut_test.dir/rule + +# Convenience name for target. +principal_lut_test: CMakeFiles/principal_lut_test.dir/rule +.PHONY : principal_lut_test + +# codegen rule for target. +CMakeFiles/principal_lut_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/principal_lut_test.dir/build.make CMakeFiles/principal_lut_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=75 "Finished codegen for target principal_lut_test" +.PHONY : CMakeFiles/principal_lut_test.dir/codegen + +# clean rule for target. +CMakeFiles/principal_lut_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/principal_lut_test.dir/build.make CMakeFiles/principal_lut_test.dir/clean +.PHONY : CMakeFiles/principal_lut_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/range_lut_test.dir + +# All Build rule for target. +CMakeFiles/range_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/range_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/range_lut_test.dir/build.make CMakeFiles/range_lut_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/range_lut_test.dir/build.make CMakeFiles/range_lut_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=80 "Built target range_lut_test" +.PHONY : CMakeFiles/range_lut_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/range_lut_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/range_lut_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/range_lut_test.dir/rule + +# Convenience name for target. +range_lut_test: CMakeFiles/range_lut_test.dir/rule +.PHONY : range_lut_test + +# codegen rule for target. +CMakeFiles/range_lut_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/range_lut_test.dir/build.make CMakeFiles/range_lut_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=80 "Finished codegen for target range_lut_test" +.PHONY : CMakeFiles/range_lut_test.dir/codegen + +# clean rule for target. +CMakeFiles/range_lut_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/range_lut_test.dir/build.make CMakeFiles/range_lut_test.dir/clean +.PHONY : CMakeFiles/range_lut_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/window_lut_test.dir + +# All Build rule for target. +CMakeFiles/window_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/window_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/window_lut_test.dir/build.make CMakeFiles/window_lut_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/window_lut_test.dir/build.make CMakeFiles/window_lut_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=96 "Built target window_lut_test" +.PHONY : CMakeFiles/window_lut_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/window_lut_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/window_lut_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/window_lut_test.dir/rule + +# Convenience name for target. +window_lut_test: CMakeFiles/window_lut_test.dir/rule +.PHONY : window_lut_test + +# codegen rule for target. +CMakeFiles/window_lut_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/window_lut_test.dir/build.make CMakeFiles/window_lut_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=96 "Finished codegen for target window_lut_test" +.PHONY : CMakeFiles/window_lut_test.dir/codegen + +# clean rule for target. +CMakeFiles/window_lut_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/window_lut_test.dir/build.make CMakeFiles/window_lut_test.dir/clean +.PHONY : CMakeFiles/window_lut_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/dwt_lut_test.dir + +# All Build rule for target. +CMakeFiles/dwt_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/dwt_lut_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/dwt_lut_test.dir/build.make CMakeFiles/dwt_lut_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/dwt_lut_test.dir/build.make CMakeFiles/dwt_lut_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=22 "Built target dwt_lut_test" +.PHONY : CMakeFiles/dwt_lut_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/dwt_lut_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/dwt_lut_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/dwt_lut_test.dir/rule + +# Convenience name for target. +dwt_lut_test: CMakeFiles/dwt_lut_test.dir/rule +.PHONY : dwt_lut_test + +# codegen rule for target. +CMakeFiles/dwt_lut_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dwt_lut_test.dir/build.make CMakeFiles/dwt_lut_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=22 "Finished codegen for target dwt_lut_test" +.PHONY : CMakeFiles/dwt_lut_test.dir/codegen + +# clean rule for target. +CMakeFiles/dwt_lut_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dwt_lut_test.dir/build.make CMakeFiles/dwt_lut_test.dir/clean +.PHONY : CMakeFiles/dwt_lut_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/offset_horner_test.dir + +# All Build rule for target. +CMakeFiles/offset_horner_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/offset_horner_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_horner_test.dir/build.make CMakeFiles/offset_horner_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_horner_test.dir/build.make CMakeFiles/offset_horner_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=57 "Built target offset_horner_test" +.PHONY : CMakeFiles/offset_horner_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/offset_horner_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/offset_horner_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/offset_horner_test.dir/rule + +# Convenience name for target. +offset_horner_test: CMakeFiles/offset_horner_test.dir/rule +.PHONY : offset_horner_test + +# codegen rule for target. +CMakeFiles/offset_horner_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_horner_test.dir/build.make CMakeFiles/offset_horner_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=57 "Finished codegen for target offset_horner_test" +.PHONY : CMakeFiles/offset_horner_test.dir/codegen + +# clean rule for target. +CMakeFiles/offset_horner_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_horner_test.dir/build.make CMakeFiles/offset_horner_test.dir/clean +.PHONY : CMakeFiles/offset_horner_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/offset_poly_test.dir + +# All Build rule for target. +CMakeFiles/offset_poly_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/offset_poly_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_poly_test.dir/build.make CMakeFiles/offset_poly_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_poly_test.dir/build.make CMakeFiles/offset_poly_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=59 "Built target offset_poly_test" +.PHONY : CMakeFiles/offset_poly_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/offset_poly_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/offset_poly_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/offset_poly_test.dir/rule + +# Convenience name for target. +offset_poly_test: CMakeFiles/offset_poly_test.dir/rule +.PHONY : offset_poly_test + +# codegen rule for target. +CMakeFiles/offset_poly_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_poly_test.dir/build.make CMakeFiles/offset_poly_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=59 "Finished codegen for target offset_poly_test" +.PHONY : CMakeFiles/offset_poly_test.dir/codegen + +# clean rule for target. +CMakeFiles/offset_poly_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_poly_test.dir/build.make CMakeFiles/offset_poly_test.dir/clean +.PHONY : CMakeFiles/offset_poly_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/lut_union_test.dir + +# All Build rule for target. +CMakeFiles/lut_union_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/lut_union_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/lut_union_test.dir/build.make CMakeFiles/lut_union_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/lut_union_test.dir/build.make CMakeFiles/lut_union_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=54 "Built target lut_union_test" +.PHONY : CMakeFiles/lut_union_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/lut_union_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/lut_union_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/lut_union_test.dir/rule + +# Convenience name for target. +lut_union_test: CMakeFiles/lut_union_test.dir/rule +.PHONY : lut_union_test + +# codegen rule for target. +CMakeFiles/lut_union_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/lut_union_test.dir/build.make CMakeFiles/lut_union_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=54 "Finished codegen for target lut_union_test" +.PHONY : CMakeFiles/lut_union_test.dir/codegen + +# clean rule for target. +CMakeFiles/lut_union_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/lut_union_test.dir/build.make CMakeFiles/lut_union_test.dir/clean +.PHONY : CMakeFiles/lut_union_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/offset_jet_test.dir + +# All Build rule for target. +CMakeFiles/offset_jet_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/offset_jet_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_jet_test.dir/build.make CMakeFiles/offset_jet_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_jet_test.dir/build.make CMakeFiles/offset_jet_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=58 "Built target offset_jet_test" +.PHONY : CMakeFiles/offset_jet_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/offset_jet_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/offset_jet_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/offset_jet_test.dir/rule + +# Convenience name for target. +offset_jet_test: CMakeFiles/offset_jet_test.dir/rule +.PHONY : offset_jet_test + +# codegen rule for target. +CMakeFiles/offset_jet_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_jet_test.dir/build.make CMakeFiles/offset_jet_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=58 "Finished codegen for target offset_jet_test" +.PHONY : CMakeFiles/offset_jet_test.dir/codegen + +# clean rule for target. +CMakeFiles/offset_jet_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_jet_test.dir/build.make CMakeFiles/offset_jet_test.dir/clean +.PHONY : CMakeFiles/offset_jet_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/offset_repr_test.dir + +# All Build rule for target. +CMakeFiles/offset_repr_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/offset_repr_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_repr_test.dir/build.make CMakeFiles/offset_repr_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_repr_test.dir/build.make CMakeFiles/offset_repr_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=60 "Built target offset_repr_test" +.PHONY : CMakeFiles/offset_repr_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/offset_repr_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/offset_repr_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/offset_repr_test.dir/rule + +# Convenience name for target. +offset_repr_test: CMakeFiles/offset_repr_test.dir/rule +.PHONY : offset_repr_test + +# codegen rule for target. +CMakeFiles/offset_repr_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_repr_test.dir/build.make CMakeFiles/offset_repr_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=60 "Finished codegen for target offset_repr_test" +.PHONY : CMakeFiles/offset_repr_test.dir/codegen + +# clean rule for target. +CMakeFiles/offset_repr_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_repr_test.dir/build.make CMakeFiles/offset_repr_test.dir/clean +.PHONY : CMakeFiles/offset_repr_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/offset_twist_test.dir + +# All Build rule for target. +CMakeFiles/offset_twist_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/offset_twist_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_twist_test.dir/build.make CMakeFiles/offset_twist_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_twist_test.dir/build.make CMakeFiles/offset_twist_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=61 "Built target offset_twist_test" +.PHONY : CMakeFiles/offset_twist_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/offset_twist_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/offset_twist_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/offset_twist_test.dir/rule + +# Convenience name for target. +offset_twist_test: CMakeFiles/offset_twist_test.dir/rule +.PHONY : offset_twist_test + +# codegen rule for target. +CMakeFiles/offset_twist_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_twist_test.dir/build.make CMakeFiles/offset_twist_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=61 "Finished codegen for target offset_twist_test" +.PHONY : CMakeFiles/offset_twist_test.dir/codegen + +# clean rule for target. +CMakeFiles/offset_twist_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_twist_test.dir/build.make CMakeFiles/offset_twist_test.dir/clean +.PHONY : CMakeFiles/offset_twist_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/ring_switch_test.dir + +# All Build rule for target. +CMakeFiles/ring_switch_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/ring_switch_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/ring_switch_test.dir/build.make CMakeFiles/ring_switch_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/ring_switch_test.dir/build.make CMakeFiles/ring_switch_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=81 "Built target ring_switch_test" +.PHONY : CMakeFiles/ring_switch_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/ring_switch_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ring_switch_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/ring_switch_test.dir/rule + +# Convenience name for target. +ring_switch_test: CMakeFiles/ring_switch_test.dir/rule +.PHONY : ring_switch_test + +# codegen rule for target. +CMakeFiles/ring_switch_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ring_switch_test.dir/build.make CMakeFiles/ring_switch_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=81 "Finished codegen for target ring_switch_test" +.PHONY : CMakeFiles/ring_switch_test.dir/codegen + +# clean rule for target. +CMakeFiles/ring_switch_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ring_switch_test.dir/build.make CMakeFiles/ring_switch_test.dir/clean +.PHONY : CMakeFiles/ring_switch_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/corner_gaps_test.dir + +# All Build rule for target. +CMakeFiles/corner_gaps_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/corner_gaps_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/corner_gaps_test.dir/build.make CMakeFiles/corner_gaps_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/corner_gaps_test.dir/build.make CMakeFiles/corner_gaps_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=17 "Built target corner_gaps_test" +.PHONY : CMakeFiles/corner_gaps_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/corner_gaps_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/corner_gaps_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/corner_gaps_test.dir/rule + +# Convenience name for target. +corner_gaps_test: CMakeFiles/corner_gaps_test.dir/rule +.PHONY : corner_gaps_test + +# codegen rule for target. +CMakeFiles/corner_gaps_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/corner_gaps_test.dir/build.make CMakeFiles/corner_gaps_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=17 "Finished codegen for target corner_gaps_test" +.PHONY : CMakeFiles/corner_gaps_test.dir/codegen + +# clean rule for target. +CMakeFiles/corner_gaps_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/corner_gaps_test.dir/build.make CMakeFiles/corner_gaps_test.dir/clean +.PHONY : CMakeFiles/corner_gaps_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/carry_test.dir + +# All Build rule for target. +CMakeFiles/carry_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/carry_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/carry_test.dir/build.make CMakeFiles/carry_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/carry_test.dir/build.make CMakeFiles/carry_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=11 "Built target carry_test" +.PHONY : CMakeFiles/carry_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/carry_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/carry_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/carry_test.dir/rule + +# Convenience name for target. +carry_test: CMakeFiles/carry_test.dir/rule +.PHONY : carry_test + +# codegen rule for target. +CMakeFiles/carry_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/carry_test.dir/build.make CMakeFiles/carry_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=11 "Finished codegen for target carry_test" +.PHONY : CMakeFiles/carry_test.dir/codegen + +# clean rule for target. +CMakeFiles/carry_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/carry_test.dir/build.make CMakeFiles/carry_test.dir/clean +.PHONY : CMakeFiles/carry_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/fixedpoint_beaver_test.dir + +# All Build rule for target. +CMakeFiles/fixedpoint_beaver_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/fixedpoint_beaver_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/fixedpoint_beaver_test.dir/build.make CMakeFiles/fixedpoint_beaver_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/fixedpoint_beaver_test.dir/build.make CMakeFiles/fixedpoint_beaver_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=36 "Built target fixedpoint_beaver_test" +.PHONY : CMakeFiles/fixedpoint_beaver_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/fixedpoint_beaver_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/fixedpoint_beaver_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/fixedpoint_beaver_test.dir/rule + +# Convenience name for target. +fixedpoint_beaver_test: CMakeFiles/fixedpoint_beaver_test.dir/rule +.PHONY : fixedpoint_beaver_test + +# codegen rule for target. +CMakeFiles/fixedpoint_beaver_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/fixedpoint_beaver_test.dir/build.make CMakeFiles/fixedpoint_beaver_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=36 "Finished codegen for target fixedpoint_beaver_test" +.PHONY : CMakeFiles/fixedpoint_beaver_test.dir/codegen + +# clean rule for target. +CMakeFiles/fixedpoint_beaver_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/fixedpoint_beaver_test.dir/build.make CMakeFiles/fixedpoint_beaver_test.dir/clean +.PHONY : CMakeFiles/fixedpoint_beaver_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/class_sweep_test.dir + +# All Build rule for target. +CMakeFiles/class_sweep_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/class_sweep_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/class_sweep_test.dir/build.make CMakeFiles/class_sweep_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/class_sweep_test.dir/build.make CMakeFiles/class_sweep_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target class_sweep_test" +.PHONY : CMakeFiles/class_sweep_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/class_sweep_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/class_sweep_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/class_sweep_test.dir/rule + +# Convenience name for target. +class_sweep_test: CMakeFiles/class_sweep_test.dir/rule +.PHONY : class_sweep_test + +# codegen rule for target. +CMakeFiles/class_sweep_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/class_sweep_test.dir/build.make CMakeFiles/class_sweep_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target class_sweep_test" +.PHONY : CMakeFiles/class_sweep_test.dir/codegen + +# clean rule for target. +CMakeFiles/class_sweep_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/class_sweep_test.dir/build.make CMakeFiles/class_sweep_test.dir/clean +.PHONY : CMakeFiles/class_sweep_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/extractable_full_test.dir + +# All Build rule for target. +CMakeFiles/extractable_full_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/extractable_full_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/extractable_full_test.dir/build.make CMakeFiles/extractable_full_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/extractable_full_test.dir/build.make CMakeFiles/extractable_full_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=34 "Built target extractable_full_test" +.PHONY : CMakeFiles/extractable_full_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/extractable_full_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/extractable_full_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/extractable_full_test.dir/rule + +# Convenience name for target. +extractable_full_test: CMakeFiles/extractable_full_test.dir/rule +.PHONY : extractable_full_test + +# codegen rule for target. +CMakeFiles/extractable_full_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/extractable_full_test.dir/build.make CMakeFiles/extractable_full_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=34 "Finished codegen for target extractable_full_test" +.PHONY : CMakeFiles/extractable_full_test.dir/codegen + +# clean rule for target. +CMakeFiles/extractable_full_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/extractable_full_test.dir/build.make CMakeFiles/extractable_full_test.dir/clean +.PHONY : CMakeFiles/extractable_full_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/walk_helpers_test.dir + +# All Build rule for target. +CMakeFiles/walk_helpers_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/walk_helpers_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/walk_helpers_test.dir/build.make CMakeFiles/walk_helpers_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/walk_helpers_test.dir/build.make CMakeFiles/walk_helpers_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=94 "Built target walk_helpers_test" +.PHONY : CMakeFiles/walk_helpers_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/walk_helpers_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/walk_helpers_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/walk_helpers_test.dir/rule + +# Convenience name for target. +walk_helpers_test: CMakeFiles/walk_helpers_test.dir/rule +.PHONY : walk_helpers_test + +# codegen rule for target. +CMakeFiles/walk_helpers_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/walk_helpers_test.dir/build.make CMakeFiles/walk_helpers_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=94 "Finished codegen for target walk_helpers_test" +.PHONY : CMakeFiles/walk_helpers_test.dir/codegen + +# clean rule for target. +CMakeFiles/walk_helpers_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/walk_helpers_test.dir/build.make CMakeFiles/walk_helpers_test.dir/clean +.PHONY : CMakeFiles/walk_helpers_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/domain128_point_test.dir + +# All Build rule for target. +CMakeFiles/domain128_point_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/domain128_point_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/domain128_point_test.dir/build.make CMakeFiles/domain128_point_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/domain128_point_test.dir/build.make CMakeFiles/domain128_point_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=19 "Built target domain128_point_test" +.PHONY : CMakeFiles/domain128_point_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/domain128_point_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/domain128_point_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/domain128_point_test.dir/rule + +# Convenience name for target. +domain128_point_test: CMakeFiles/domain128_point_test.dir/rule +.PHONY : domain128_point_test + +# codegen rule for target. +CMakeFiles/domain128_point_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/domain128_point_test.dir/build.make CMakeFiles/domain128_point_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=19 "Finished codegen for target domain128_point_test" +.PHONY : CMakeFiles/domain128_point_test.dir/codegen + +# clean rule for target. +CMakeFiles/domain128_point_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/domain128_point_test.dir/build.make CMakeFiles/domain128_point_test.dir/clean +.PHONY : CMakeFiles/domain128_point_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/blob_leaf_test.dir + +# All Build rule for target. +CMakeFiles/blob_leaf_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/blob_leaf_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/blob_leaf_test.dir/build.make CMakeFiles/blob_leaf_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/blob_leaf_test.dir/build.make CMakeFiles/blob_leaf_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=8 "Built target blob_leaf_test" +.PHONY : CMakeFiles/blob_leaf_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/blob_leaf_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/blob_leaf_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/blob_leaf_test.dir/rule + +# Convenience name for target. +blob_leaf_test: CMakeFiles/blob_leaf_test.dir/rule +.PHONY : blob_leaf_test + +# codegen rule for target. +CMakeFiles/blob_leaf_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/blob_leaf_test.dir/build.make CMakeFiles/blob_leaf_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=8 "Finished codegen for target blob_leaf_test" +.PHONY : CMakeFiles/blob_leaf_test.dir/codegen + +# clean rule for target. +CMakeFiles/blob_leaf_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/blob_leaf_test.dir/build.make CMakeFiles/blob_leaf_test.dir/clean +.PHONY : CMakeFiles/blob_leaf_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/growing_idpf_test.dir + +# All Build rule for target. +CMakeFiles/growing_idpf_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/growing_idpf_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/growing_idpf_test.dir/build.make CMakeFiles/growing_idpf_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/growing_idpf_test.dir/build.make CMakeFiles/growing_idpf_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=41 "Built target growing_idpf_test" +.PHONY : CMakeFiles/growing_idpf_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/growing_idpf_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/growing_idpf_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/growing_idpf_test.dir/rule + +# Convenience name for target. +growing_idpf_test: CMakeFiles/growing_idpf_test.dir/rule +.PHONY : growing_idpf_test + +# codegen rule for target. +CMakeFiles/growing_idpf_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/growing_idpf_test.dir/build.make CMakeFiles/growing_idpf_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=41 "Finished codegen for target growing_idpf_test" +.PHONY : CMakeFiles/growing_idpf_test.dir/codegen + +# clean rule for target. +CMakeFiles/growing_idpf_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/growing_idpf_test.dir/build.make CMakeFiles/growing_idpf_test.dir/clean +.PHONY : CMakeFiles/growing_idpf_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/pprf_test.dir + +# All Build rule for target. +CMakeFiles/pprf_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/pprf_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/pprf_test.dir/build.make CMakeFiles/pprf_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/pprf_test.dir/build.make CMakeFiles/pprf_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=70 "Built target pprf_test" +.PHONY : CMakeFiles/pprf_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/pprf_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/pprf_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/pprf_test.dir/rule + +# Convenience name for target. +pprf_test: CMakeFiles/pprf_test.dir/rule +.PHONY : pprf_test + +# codegen rule for target. +CMakeFiles/pprf_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pprf_test.dir/build.make CMakeFiles/pprf_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=70 "Finished codegen for target pprf_test" +.PHONY : CMakeFiles/pprf_test.dir/codegen + +# clean rule for target. +CMakeFiles/pprf_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pprf_test.dir/build.make CMakeFiles/pprf_test.dir/clean +.PHONY : CMakeFiles/pprf_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/ppvc_test.dir + +# All Build rule for target. +CMakeFiles/ppvc_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/ppvc_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/ppvc_test.dir/build.make CMakeFiles/ppvc_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/ppvc_test.dir/build.make CMakeFiles/ppvc_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=71 "Built target ppvc_test" +.PHONY : CMakeFiles/ppvc_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/ppvc_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ppvc_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/ppvc_test.dir/rule + +# Convenience name for target. +ppvc_test: CMakeFiles/ppvc_test.dir/rule +.PHONY : ppvc_test + +# codegen rule for target. +CMakeFiles/ppvc_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ppvc_test.dir/build.make CMakeFiles/ppvc_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=71 "Finished codegen for target ppvc_test" +.PHONY : CMakeFiles/ppvc_test.dir/codegen + +# clean rule for target. +CMakeFiles/ppvc_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ppvc_test.dir/build.make CMakeFiles/ppvc_test.dir/clean +.PHONY : CMakeFiles/ppvc_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/leaf_later_test.dir + +# All Build rule for target. +CMakeFiles/leaf_later_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/leaf_later_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/leaf_later_test.dir/build.make CMakeFiles/leaf_later_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/leaf_later_test.dir/build.make CMakeFiles/leaf_later_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=52 "Built target leaf_later_test" +.PHONY : CMakeFiles/leaf_later_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/leaf_later_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/leaf_later_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/leaf_later_test.dir/rule + +# Convenience name for target. +leaf_later_test: CMakeFiles/leaf_later_test.dir/rule +.PHONY : leaf_later_test + +# codegen rule for target. +CMakeFiles/leaf_later_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/leaf_later_test.dir/build.make CMakeFiles/leaf_later_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=52 "Finished codegen for target leaf_later_test" +.PHONY : CMakeFiles/leaf_later_test.dir/codegen + +# clean rule for target. +CMakeFiles/leaf_later_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/leaf_later_test.dir/build.make CMakeFiles/leaf_later_test.dir/clean +.PHONY : CMakeFiles/leaf_later_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/caller_fold_test.dir + +# All Build rule for target. +CMakeFiles/caller_fold_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/caller_fold_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/caller_fold_test.dir/build.make CMakeFiles/caller_fold_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/caller_fold_test.dir/build.make CMakeFiles/caller_fold_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=10 "Built target caller_fold_test" +.PHONY : CMakeFiles/caller_fold_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/caller_fold_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/caller_fold_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/caller_fold_test.dir/rule + +# Convenience name for target. +caller_fold_test: CMakeFiles/caller_fold_test.dir/rule +.PHONY : caller_fold_test + +# codegen rule for target. +CMakeFiles/caller_fold_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/caller_fold_test.dir/build.make CMakeFiles/caller_fold_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=10 "Finished codegen for target caller_fold_test" +.PHONY : CMakeFiles/caller_fold_test.dir/codegen + +# clean rule for target. +CMakeFiles/caller_fold_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/caller_fold_test.dir/build.make CMakeFiles/caller_fold_test.dir/clean +.PHONY : CMakeFiles/caller_fold_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/defer_eval_test.dir + +# All Build rule for target. +CMakeFiles/defer_eval_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/defer_eval_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/defer_eval_test.dir/build.make CMakeFiles/defer_eval_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/defer_eval_test.dir/build.make CMakeFiles/defer_eval_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=18 "Built target defer_eval_test" +.PHONY : CMakeFiles/defer_eval_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/defer_eval_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/defer_eval_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/defer_eval_test.dir/rule + +# Convenience name for target. +defer_eval_test: CMakeFiles/defer_eval_test.dir/rule +.PHONY : defer_eval_test + +# codegen rule for target. +CMakeFiles/defer_eval_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/defer_eval_test.dir/build.make CMakeFiles/defer_eval_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=18 "Finished codegen for target defer_eval_test" +.PHONY : CMakeFiles/defer_eval_test.dir/codegen + +# clean rule for target. +CMakeFiles/defer_eval_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/defer_eval_test.dir/build.make CMakeFiles/defer_eval_test.dir/clean +.PHONY : CMakeFiles/defer_eval_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/wrap_and_rotate_test.dir + +# All Build rule for target. +CMakeFiles/wrap_and_rotate_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/wrap_and_rotate_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/wrap_and_rotate_test.dir/build.make CMakeFiles/wrap_and_rotate_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/wrap_and_rotate_test.dir/build.make CMakeFiles/wrap_and_rotate_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=97 "Built target wrap_and_rotate_test" +.PHONY : CMakeFiles/wrap_and_rotate_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/wrap_and_rotate_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/wrap_and_rotate_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/wrap_and_rotate_test.dir/rule + +# Convenience name for target. +wrap_and_rotate_test: CMakeFiles/wrap_and_rotate_test.dir/rule +.PHONY : wrap_and_rotate_test + +# codegen rule for target. +CMakeFiles/wrap_and_rotate_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wrap_and_rotate_test.dir/build.make CMakeFiles/wrap_and_rotate_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=97 "Finished codegen for target wrap_and_rotate_test" +.PHONY : CMakeFiles/wrap_and_rotate_test.dir/codegen + +# clean rule for target. +CMakeFiles/wrap_and_rotate_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wrap_and_rotate_test.dir/build.make CMakeFiles/wrap_and_rotate_test.dir/clean +.PHONY : CMakeFiles/wrap_and_rotate_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/sfss_test.dir + +# All Build rule for target. +CMakeFiles/sfss_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/sfss_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/sfss_test.dir/build.make CMakeFiles/sfss_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/sfss_test.dir/build.make CMakeFiles/sfss_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=84 "Built target sfss_test" +.PHONY : CMakeFiles/sfss_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/sfss_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/sfss_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/sfss_test.dir/rule + +# Convenience name for target. +sfss_test: CMakeFiles/sfss_test.dir/rule +.PHONY : sfss_test + +# codegen rule for target. +CMakeFiles/sfss_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/sfss_test.dir/build.make CMakeFiles/sfss_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=84 "Finished codegen for target sfss_test" +.PHONY : CMakeFiles/sfss_test.dir/codegen + +# clean rule for target. +CMakeFiles/sfss_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/sfss_test.dir/build.make CMakeFiles/sfss_test.dir/clean +.PHONY : CMakeFiles/sfss_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/path_sketch_test.dir + +# All Build rule for target. +CMakeFiles/path_sketch_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/path_sketch_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_sketch_test.dir/build.make CMakeFiles/path_sketch_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_sketch_test.dir/build.make CMakeFiles/path_sketch_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target path_sketch_test" +.PHONY : CMakeFiles/path_sketch_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/path_sketch_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/path_sketch_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/path_sketch_test.dir/rule + +# Convenience name for target. +path_sketch_test: CMakeFiles/path_sketch_test.dir/rule +.PHONY : path_sketch_test + +# codegen rule for target. +CMakeFiles/path_sketch_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_sketch_test.dir/build.make CMakeFiles/path_sketch_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target path_sketch_test" +.PHONY : CMakeFiles/path_sketch_test.dir/codegen + +# clean rule for target. +CMakeFiles/path_sketch_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_sketch_test.dir/build.make CMakeFiles/path_sketch_test.dir/clean +.PHONY : CMakeFiles/path_sketch_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/eval_until_test.dir + +# All Build rule for target. +CMakeFiles/eval_until_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/eval_until_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_until_test.dir/build.make CMakeFiles/eval_until_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_until_test.dir/build.make CMakeFiles/eval_until_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=32 "Built target eval_until_test" +.PHONY : CMakeFiles/eval_until_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/eval_until_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/eval_until_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/eval_until_test.dir/rule + +# Convenience name for target. +eval_until_test: CMakeFiles/eval_until_test.dir/rule +.PHONY : eval_until_test + +# codegen rule for target. +CMakeFiles/eval_until_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_until_test.dir/build.make CMakeFiles/eval_until_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=32 "Finished codegen for target eval_until_test" +.PHONY : CMakeFiles/eval_until_test.dir/codegen + +# clean rule for target. +CMakeFiles/eval_until_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_until_test.dir/build.make CMakeFiles/eval_until_test.dir/clean +.PHONY : CMakeFiles/eval_until_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/idpf_agg_test.dir + +# All Build rule for target. +CMakeFiles/idpf_agg_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/idpf_agg_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/idpf_agg_test.dir/build.make CMakeFiles/idpf_agg_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/idpf_agg_test.dir/build.make CMakeFiles/idpf_agg_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=45 "Built target idpf_agg_test" +.PHONY : CMakeFiles/idpf_agg_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/idpf_agg_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/idpf_agg_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/idpf_agg_test.dir/rule + +# Convenience name for target. +idpf_agg_test: CMakeFiles/idpf_agg_test.dir/rule +.PHONY : idpf_agg_test + +# codegen rule for target. +CMakeFiles/idpf_agg_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/idpf_agg_test.dir/build.make CMakeFiles/idpf_agg_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=45 "Finished codegen for target idpf_agg_test" +.PHONY : CMakeFiles/idpf_agg_test.dir/codegen + +# clean rule for target. +CMakeFiles/idpf_agg_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/idpf_agg_test.dir/build.make CMakeFiles/idpf_agg_test.dir/clean +.PHONY : CMakeFiles/idpf_agg_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/it_dpf3_test.dir + +# All Build rule for target. +CMakeFiles/it_dpf3_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/it_dpf3_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/it_dpf3_test.dir/build.make CMakeFiles/it_dpf3_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/it_dpf3_test.dir/build.make CMakeFiles/it_dpf3_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=50 "Built target it_dpf3_test" +.PHONY : CMakeFiles/it_dpf3_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/it_dpf3_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/it_dpf3_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/it_dpf3_test.dir/rule + +# Convenience name for target. +it_dpf3_test: CMakeFiles/it_dpf3_test.dir/rule +.PHONY : it_dpf3_test + +# codegen rule for target. +CMakeFiles/it_dpf3_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/it_dpf3_test.dir/build.make CMakeFiles/it_dpf3_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=50 "Finished codegen for target it_dpf3_test" +.PHONY : CMakeFiles/it_dpf3_test.dir/codegen + +# clean rule for target. +CMakeFiles/it_dpf3_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/it_dpf3_test.dir/build.make CMakeFiles/it_dpf3_test.dir/clean +.PHONY : CMakeFiles/it_dpf3_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/party_flows.dir + +# All Build rule for target. +CMakeFiles/party_flows.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/party_flows.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_flows.dir/build.make CMakeFiles/party_flows.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_flows.dir/build.make CMakeFiles/party_flows.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=67,68 "Built target party_flows" +.PHONY : CMakeFiles/party_flows.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/party_flows.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 4 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/party_flows.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/party_flows.dir/rule + +# Convenience name for target. +party_flows: CMakeFiles/party_flows.dir/rule +.PHONY : party_flows + +# codegen rule for target. +CMakeFiles/party_flows.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_flows.dir/build.make CMakeFiles/party_flows.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=67,68 "Finished codegen for target party_flows" +.PHONY : CMakeFiles/party_flows.dir/codegen + +# clean rule for target. +CMakeFiles/party_flows.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_flows.dir/build.make CMakeFiles/party_flows.dir/clean +.PHONY : CMakeFiles/party_flows.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/p0.dir + +# All Build rule for target. +CMakeFiles/p0.dir/all: CMakeFiles/party_flows.dir/all +CMakeFiles/p0.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/p0.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/p0.dir/build.make CMakeFiles/p0.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/p0.dir/build.make CMakeFiles/p0.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=62 "Built target p0" +.PHONY : CMakeFiles/p0.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/p0.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 5 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/p0.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/p0.dir/rule + +# Convenience name for target. +p0: CMakeFiles/p0.dir/rule +.PHONY : p0 + +# codegen rule for target. +CMakeFiles/p0.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p0.dir/build.make CMakeFiles/p0.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=62 "Finished codegen for target p0" +.PHONY : CMakeFiles/p0.dir/codegen + +# clean rule for target. +CMakeFiles/p0.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p0.dir/build.make CMakeFiles/p0.dir/clean +.PHONY : CMakeFiles/p0.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/p1.dir + +# All Build rule for target. +CMakeFiles/p1.dir/all: CMakeFiles/party_flows.dir/all +CMakeFiles/p1.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/p1.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/p1.dir/build.make CMakeFiles/p1.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/p1.dir/build.make CMakeFiles/p1.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=63 "Built target p1" +.PHONY : CMakeFiles/p1.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/p1.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 5 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/p1.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/p1.dir/rule + +# Convenience name for target. +p1: CMakeFiles/p1.dir/rule +.PHONY : p1 + +# codegen rule for target. +CMakeFiles/p1.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p1.dir/build.make CMakeFiles/p1.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=63 "Finished codegen for target p1" +.PHONY : CMakeFiles/p1.dir/codegen + +# clean rule for target. +CMakeFiles/p1.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p1.dir/build.make CMakeFiles/p1.dir/clean +.PHONY : CMakeFiles/p1.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/p2.dir + +# All Build rule for target. +CMakeFiles/p2.dir/all: CMakeFiles/party_flows.dir/all +CMakeFiles/p2.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/p2.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/p2.dir/build.make CMakeFiles/p2.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/p2.dir/build.make CMakeFiles/p2.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=64 "Built target p2" +.PHONY : CMakeFiles/p2.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/p2.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 5 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/p2.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/p2.dir/rule + +# Convenience name for target. +p2: CMakeFiles/p2.dir/rule +.PHONY : p2 + +# codegen rule for target. +CMakeFiles/p2.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p2.dir/build.make CMakeFiles/p2.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=64 "Finished codegen for target p2" +.PHONY : CMakeFiles/p2.dir/codegen + +# clean rule for target. +CMakeFiles/p2.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p2.dir/build.make CMakeFiles/p2.dir/clean +.PHONY : CMakeFiles/p2.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/party_bench.dir + +# All Build rule for target. +CMakeFiles/party_bench.dir/all: CMakeFiles/party_flows.dir/all +CMakeFiles/party_bench.dir/all: CMakeFiles/p0.dir/all +CMakeFiles/party_bench.dir/all: CMakeFiles/p1.dir/all +CMakeFiles/party_bench.dir/all: CMakeFiles/p2.dir/all +CMakeFiles/party_bench.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/party_bench.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_bench.dir/build.make CMakeFiles/party_bench.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_bench.dir/build.make CMakeFiles/party_bench.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target party_bench" +.PHONY : CMakeFiles/party_bench.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/party_bench.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 7 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/party_bench.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/party_bench.dir/rule + +# Convenience name for target. +party_bench: CMakeFiles/party_bench.dir/rule +.PHONY : party_bench + +# codegen rule for target. +CMakeFiles/party_bench.dir/codegen: CMakeFiles/p0.dir/all +CMakeFiles/party_bench.dir/codegen: CMakeFiles/p1.dir/all +CMakeFiles/party_bench.dir/codegen: CMakeFiles/p2.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_bench.dir/build.make CMakeFiles/party_bench.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target party_bench" +.PHONY : CMakeFiles/party_bench.dir/codegen + +# clean rule for target. +CMakeFiles/party_bench.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_bench.dir/build.make CMakeFiles/party_bench.dir/clean +.PHONY : CMakeFiles/party_bench.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/profile_eval.dir + +# All Build rule for target. +CMakeFiles/profile_eval.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/profile_eval.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_eval.dir/build.make CMakeFiles/profile_eval.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_eval.dir/build.make CMakeFiles/profile_eval.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target profile_eval" +.PHONY : CMakeFiles/profile_eval.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/profile_eval.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/profile_eval.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/profile_eval.dir/rule + +# Convenience name for target. +profile_eval: CMakeFiles/profile_eval.dir/rule +.PHONY : profile_eval + +# codegen rule for target. +CMakeFiles/profile_eval.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_eval.dir/build.make CMakeFiles/profile_eval.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target profile_eval" +.PHONY : CMakeFiles/profile_eval.dir/codegen + +# clean rule for target. +CMakeFiles/profile_eval.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_eval.dir/build.make CMakeFiles/profile_eval.dir/clean +.PHONY : CMakeFiles/profile_eval.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/profile_grotto.dir + +# All Build rule for target. +CMakeFiles/profile_grotto.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/profile_grotto.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_grotto.dir/build.make CMakeFiles/profile_grotto.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_grotto.dir/build.make CMakeFiles/profile_grotto.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=76 "Built target profile_grotto" +.PHONY : CMakeFiles/profile_grotto.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/profile_grotto.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/profile_grotto.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/profile_grotto.dir/rule + +# Convenience name for target. +profile_grotto: CMakeFiles/profile_grotto.dir/rule +.PHONY : profile_grotto + +# codegen rule for target. +CMakeFiles/profile_grotto.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_grotto.dir/build.make CMakeFiles/profile_grotto.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=76 "Finished codegen for target profile_grotto" +.PHONY : CMakeFiles/profile_grotto.dir/codegen + +# clean rule for target. +CMakeFiles/profile_grotto.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_grotto.dir/build.make CMakeFiles/profile_grotto.dir/clean +.PHONY : CMakeFiles/profile_grotto.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/profile_party.dir + +# All Build rule for target. +CMakeFiles/profile_party.dir/all: CMakeFiles/party_flows.dir/all +CMakeFiles/profile_party.dir/all: CMakeFiles/p0.dir/all +CMakeFiles/profile_party.dir/all: CMakeFiles/p1.dir/all +CMakeFiles/profile_party.dir/all: CMakeFiles/p2.dir/all +CMakeFiles/profile_party.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/profile_party.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_party.dir/build.make CMakeFiles/profile_party.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_party.dir/build.make CMakeFiles/profile_party.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=77 "Built target profile_party" +.PHONY : CMakeFiles/profile_party.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/profile_party.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 8 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/profile_party.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/profile_party.dir/rule + +# Convenience name for target. +profile_party: CMakeFiles/profile_party.dir/rule +.PHONY : profile_party + +# codegen rule for target. +CMakeFiles/profile_party.dir/codegen: CMakeFiles/p0.dir/all +CMakeFiles/profile_party.dir/codegen: CMakeFiles/p1.dir/all +CMakeFiles/profile_party.dir/codegen: CMakeFiles/p2.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_party.dir/build.make CMakeFiles/profile_party.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=77 "Finished codegen for target profile_party" +.PHONY : CMakeFiles/profile_party.dir/codegen + +# clean rule for target. +CMakeFiles/profile_party.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_party.dir/build.make CMakeFiles/profile_party.dir/clean +.PHONY : CMakeFiles/profile_party.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/yao_share_test.dir + +# All Build rule for target. +CMakeFiles/yao_share_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/yao_share_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_share_test.dir/build.make CMakeFiles/yao_share_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_share_test.dir/build.make CMakeFiles/yao_share_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=98 "Built target yao_share_test" +.PHONY : CMakeFiles/yao_share_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/yao_share_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/yao_share_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/yao_share_test.dir/rule + +# Convenience name for target. +yao_share_test: CMakeFiles/yao_share_test.dir/rule +.PHONY : yao_share_test + +# codegen rule for target. +CMakeFiles/yao_share_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_share_test.dir/build.make CMakeFiles/yao_share_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=98 "Finished codegen for target yao_share_test" +.PHONY : CMakeFiles/yao_share_test.dir/codegen + +# clean rule for target. +CMakeFiles/yao_share_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_share_test.dir/build.make CMakeFiles/yao_share_test.dir/clean +.PHONY : CMakeFiles/yao_share_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/yao_test.dir + +# All Build rule for target. +CMakeFiles/yao_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/yao_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_test.dir/build.make CMakeFiles/yao_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_test.dir/build.make CMakeFiles/yao_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=100 "Built target yao_test" +.PHONY : CMakeFiles/yao_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/yao_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/yao_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/yao_test.dir/rule + +# Convenience name for target. +yao_test: CMakeFiles/yao_test.dir/rule +.PHONY : yao_test + +# codegen rule for target. +CMakeFiles/yao_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_test.dir/build.make CMakeFiles/yao_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=100 "Finished codegen for target yao_test" +.PHONY : CMakeFiles/yao_test.dir/codegen + +# clean rule for target. +CMakeFiles/yao_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_test.dir/build.make CMakeFiles/yao_test.dir/clean +.PHONY : CMakeFiles/yao_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/yao_stack_test.dir + +# All Build rule for target. +CMakeFiles/yao_stack_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/yao_stack_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_stack_test.dir/build.make CMakeFiles/yao_stack_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_stack_test.dir/build.make CMakeFiles/yao_stack_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=99 "Built target yao_stack_test" +.PHONY : CMakeFiles/yao_stack_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/yao_stack_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/yao_stack_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/yao_stack_test.dir/rule + +# Convenience name for target. +yao_stack_test: CMakeFiles/yao_stack_test.dir/rule +.PHONY : yao_stack_test + +# codegen rule for target. +CMakeFiles/yao_stack_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_stack_test.dir/build.make CMakeFiles/yao_stack_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=99 "Finished codegen for target yao_stack_test" +.PHONY : CMakeFiles/yao_stack_test.dir/codegen + +# clean rule for target. +CMakeFiles/yao_stack_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_stack_test.dir/build.make CMakeFiles/yao_stack_test.dir/clean +.PHONY : CMakeFiles/yao_stack_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/arith_garble_test.dir + +# All Build rule for target. +CMakeFiles/arith_garble_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/arith_garble_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_garble_test.dir/build.make CMakeFiles/arith_garble_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_garble_test.dir/build.make CMakeFiles/arith_garble_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=2 "Built target arith_garble_test" +.PHONY : CMakeFiles/arith_garble_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/arith_garble_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/arith_garble_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/arith_garble_test.dir/rule + +# Convenience name for target. +arith_garble_test: CMakeFiles/arith_garble_test.dir/rule +.PHONY : arith_garble_test + +# codegen rule for target. +CMakeFiles/arith_garble_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_garble_test.dir/build.make CMakeFiles/arith_garble_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=2 "Finished codegen for target arith_garble_test" +.PHONY : CMakeFiles/arith_garble_test.dir/codegen + +# clean rule for target. +CMakeFiles/arith_garble_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_garble_test.dir/build.make CMakeFiles/arith_garble_test.dir/clean +.PHONY : CMakeFiles/arith_garble_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/flute_test.dir + +# All Build rule for target. +CMakeFiles/flute_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/flute_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/flute_test.dir/build.make CMakeFiles/flute_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/flute_test.dir/build.make CMakeFiles/flute_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=37 "Built target flute_test" +.PHONY : CMakeFiles/flute_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/flute_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/flute_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/flute_test.dir/rule + +# Convenience name for target. +flute_test: CMakeFiles/flute_test.dir/rule +.PHONY : flute_test + +# codegen rule for target. +CMakeFiles/flute_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/flute_test.dir/build.make CMakeFiles/flute_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=37 "Finished codegen for target flute_test" +.PHONY : CMakeFiles/flute_test.dir/codegen + +# clean rule for target. +CMakeFiles/flute_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/flute_test.dir/build.make CMakeFiles/flute_test.dir/clean +.PHONY : CMakeFiles/flute_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/shuffle_hidden_test.dir + +# All Build rule for target. +CMakeFiles/shuffle_hidden_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/shuffle_hidden_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/shuffle_hidden_test.dir/build.make CMakeFiles/shuffle_hidden_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/shuffle_hidden_test.dir/build.make CMakeFiles/shuffle_hidden_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=88 "Built target shuffle_hidden_test" +.PHONY : CMakeFiles/shuffle_hidden_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/shuffle_hidden_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/shuffle_hidden_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/shuffle_hidden_test.dir/rule + +# Convenience name for target. +shuffle_hidden_test: CMakeFiles/shuffle_hidden_test.dir/rule +.PHONY : shuffle_hidden_test + +# codegen rule for target. +CMakeFiles/shuffle_hidden_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shuffle_hidden_test.dir/build.make CMakeFiles/shuffle_hidden_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=88 "Finished codegen for target shuffle_hidden_test" +.PHONY : CMakeFiles/shuffle_hidden_test.dir/codegen + +# clean rule for target. +CMakeFiles/shuffle_hidden_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shuffle_hidden_test.dir/build.make CMakeFiles/shuffle_hidden_test.dir/clean +.PHONY : CMakeFiles/shuffle_hidden_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/bench_cell_test.dir + +# All Build rule for target. +CMakeFiles/bench_cell_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/bench_cell_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/bench_cell_test.dir/build.make CMakeFiles/bench_cell_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/bench_cell_test.dir/build.make CMakeFiles/bench_cell_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target bench_cell_test" +.PHONY : CMakeFiles/bench_cell_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/bench_cell_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/bench_cell_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/bench_cell_test.dir/rule + +# Convenience name for target. +bench_cell_test: CMakeFiles/bench_cell_test.dir/rule +.PHONY : bench_cell_test + +# codegen rule for target. +CMakeFiles/bench_cell_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bench_cell_test.dir/build.make CMakeFiles/bench_cell_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target bench_cell_test" +.PHONY : CMakeFiles/bench_cell_test.dir/codegen + +# clean rule for target. +CMakeFiles/bench_cell_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bench_cell_test.dir/build.make CMakeFiles/bench_cell_test.dir/clean +.PHONY : CMakeFiles/bench_cell_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/iknp_party_test.dir + +# All Build rule for target. +CMakeFiles/iknp_party_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/iknp_party_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/iknp_party_test.dir/build.make CMakeFiles/iknp_party_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/iknp_party_test.dir/build.make CMakeFiles/iknp_party_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=46 "Built target iknp_party_test" +.PHONY : CMakeFiles/iknp_party_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/iknp_party_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 3 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/iknp_party_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/iknp_party_test.dir/rule + +# Convenience name for target. +iknp_party_test: CMakeFiles/iknp_party_test.dir/rule +.PHONY : iknp_party_test + +# codegen rule for target. +CMakeFiles/iknp_party_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/iknp_party_test.dir/build.make CMakeFiles/iknp_party_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=46 "Finished codegen for target iknp_party_test" +.PHONY : CMakeFiles/iknp_party_test.dir/codegen + +# clean rule for target. +CMakeFiles/iknp_party_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/iknp_party_test.dir/build.make CMakeFiles/iknp_party_test.dir/clean +.PHONY : CMakeFiles/iknp_party_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/beaver_party_test.dir + +# All Build rule for target. +CMakeFiles/beaver_party_test.dir/all: CMakeFiles/party_flows.dir/all +CMakeFiles/beaver_party_test.dir/all: CMakeFiles/p0.dir/all +CMakeFiles/beaver_party_test.dir/all: CMakeFiles/p1.dir/all +CMakeFiles/beaver_party_test.dir/all: CMakeFiles/p2.dir/all +CMakeFiles/beaver_party_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/beaver_party_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_party_test.dir/build.make CMakeFiles/beaver_party_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_party_test.dir/build.make CMakeFiles/beaver_party_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=4 "Built target beaver_party_test" +.PHONY : CMakeFiles/beaver_party_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/beaver_party_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 8 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/beaver_party_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/beaver_party_test.dir/rule + +# Convenience name for target. +beaver_party_test: CMakeFiles/beaver_party_test.dir/rule +.PHONY : beaver_party_test + +# codegen rule for target. +CMakeFiles/beaver_party_test.dir/codegen: CMakeFiles/p0.dir/all +CMakeFiles/beaver_party_test.dir/codegen: CMakeFiles/p1.dir/all +CMakeFiles/beaver_party_test.dir/codegen: CMakeFiles/p2.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_party_test.dir/build.make CMakeFiles/beaver_party_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=4 "Finished codegen for target beaver_party_test" +.PHONY : CMakeFiles/beaver_party_test.dir/codegen + +# clean rule for target. +CMakeFiles/beaver_party_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_party_test.dir/build.make CMakeFiles/beaver_party_test.dir/clean +.PHONY : CMakeFiles/beaver_party_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/ic_test.dir + +# All Build rule for target. +CMakeFiles/ic_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/ic_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/ic_test.dir/build.make CMakeFiles/ic_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/ic_test.dir/build.make CMakeFiles/ic_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target ic_test" +.PHONY : CMakeFiles/ic_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/ic_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/ic_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/ic_test.dir/rule + +# Convenience name for target. +ic_test: CMakeFiles/ic_test.dir/rule +.PHONY : ic_test + +# codegen rule for target. +CMakeFiles/ic_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ic_test.dir/build.make CMakeFiles/ic_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target ic_test" +.PHONY : CMakeFiles/ic_test.dir/codegen + +# clean rule for target. +CMakeFiles/ic_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ic_test.dir/build.make CMakeFiles/ic_test.dir/clean +.PHONY : CMakeFiles/ic_test.dir/clean + +#============================================================================= +# Target rules for target CMakeFiles/wide_payload_test.dir + +# All Build rule for target. +CMakeFiles/wide_payload_test.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all +CMakeFiles/wide_payload_test.dir/all: googletest/googletest/CMakeFiles/gtest_main.dir/all + $(MAKE) $(MAKESILENT) -f CMakeFiles/wide_payload_test.dir/build.make CMakeFiles/wide_payload_test.dir/depend + $(MAKE) $(MAKESILENT) -f CMakeFiles/wide_payload_test.dir/build.make CMakeFiles/wide_payload_test.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Built target wide_payload_test" +.PHONY : CMakeFiles/wide_payload_test.dir/all + +# Build rule for subdir invocation for target. +CMakeFiles/wide_payload_test.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 CMakeFiles/wide_payload_test.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : CMakeFiles/wide_payload_test.dir/rule + +# Convenience name for target. +wide_payload_test: CMakeFiles/wide_payload_test.dir/rule +.PHONY : wide_payload_test + +# codegen rule for target. +CMakeFiles/wide_payload_test.dir/codegen: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wide_payload_test.dir/build.make CMakeFiles/wide_payload_test.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num= "Finished codegen for target wide_payload_test" +.PHONY : CMakeFiles/wide_payload_test.dir/codegen + +# clean rule for target. +CMakeFiles/wide_payload_test.dir/clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wide_payload_test.dir/build.make CMakeFiles/wide_payload_test.dir/clean +.PHONY : CMakeFiles/wide_payload_test.dir/clean + +#============================================================================= +# Target rules for target googletest/googletest/CMakeFiles/gtest.dir + +# All Build rule for target. +googletest/googletest/CMakeFiles/gtest.dir/all: + $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest.dir/build.make googletest/googletest/CMakeFiles/gtest.dir/depend + $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest.dir/build.make googletest/googletest/CMakeFiles/gtest.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=42 "Built target gtest" +.PHONY : googletest/googletest/CMakeFiles/gtest.dir/all + +# Build rule for subdir invocation for target. +googletest/googletest/CMakeFiles/gtest.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 1 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 googletest/googletest/CMakeFiles/gtest.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : googletest/googletest/CMakeFiles/gtest.dir/rule + +# Convenience name for target. +gtest: googletest/googletest/CMakeFiles/gtest.dir/rule +.PHONY : gtest + +# codegen rule for target. +googletest/googletest/CMakeFiles/gtest.dir/codegen: + $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest.dir/build.make googletest/googletest/CMakeFiles/gtest.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=42 "Finished codegen for target gtest" +.PHONY : googletest/googletest/CMakeFiles/gtest.dir/codegen + +# clean rule for target. +googletest/googletest/CMakeFiles/gtest.dir/clean: + $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest.dir/build.make googletest/googletest/CMakeFiles/gtest.dir/clean +.PHONY : googletest/googletest/CMakeFiles/gtest.dir/clean + +#============================================================================= +# Target rules for target googletest/googletest/CMakeFiles/gtest_main.dir + +# All Build rule for target. +googletest/googletest/CMakeFiles/gtest_main.dir/all: googletest/googletest/CMakeFiles/gtest.dir/all + $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest_main.dir/build.make googletest/googletest/CMakeFiles/gtest_main.dir/depend + $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest_main.dir/build.make googletest/googletest/CMakeFiles/gtest_main.dir/build + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=43 "Built target gtest_main" +.PHONY : googletest/googletest/CMakeFiles/gtest_main.dir/all + +# Build rule for subdir invocation for target. +googletest/googletest/CMakeFiles/gtest_main.dir/rule: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 2 + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 googletest/googletest/CMakeFiles/gtest_main.dir/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : googletest/googletest/CMakeFiles/gtest_main.dir/rule + +# Convenience name for target. +gtest_main: googletest/googletest/CMakeFiles/gtest_main.dir/rule +.PHONY : gtest_main + +# codegen rule for target. +googletest/googletest/CMakeFiles/gtest_main.dir/codegen: + $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest_main.dir/build.make googletest/googletest/CMakeFiles/gtest_main.dir/codegen + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=43 "Finished codegen for target gtest_main" +.PHONY : googletest/googletest/CMakeFiles/gtest_main.dir/codegen + +# clean rule for target. +googletest/googletest/CMakeFiles/gtest_main.dir/clean: + $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest_main.dir/build.make googletest/googletest/CMakeFiles/gtest_main.dir/clean +.PHONY : googletest/googletest/CMakeFiles/gtest_main.dir/clean + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/test/build-asan/CMakeFiles/TargetDirectories.txt b/test/build-asan/CMakeFiles/TargetDirectories.txt new file mode 100644 index 0000000..71bc790 --- /dev/null +++ b/test/build-asan/CMakeFiles/TargetDirectories.txt @@ -0,0 +1,126 @@ +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/all_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/dpf_key_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/wildcard_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_point_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_interval_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_full_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_sequence_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_point_multi_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_interval_multi_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_full_multi_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/bit_array_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/incremental_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/path_recipe_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/blocked_dcf_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/geneval_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/stress_scenarios_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/incremental_json_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/keyword2_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/types_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/packed_lane_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/bitmore_mod_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/lane_blast_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/context_blast_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/random_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/prg_lowmc_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/prg_chacha_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/half_tree_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/constrained_cmp_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/fp61_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/field_output_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/gf2_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/gf2_adversarial_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/arith_payload_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/verifiable_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/shamir_adversarial_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/vdpf_regression_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/opt_in_malicious_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/multipoint_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/dpf3_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_inner_product_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/shared_and_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/cohort_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/interleave_leaves_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/secret_share_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/beaver_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/share_runtime_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/net_control_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/security_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/protocol_batch_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/compose_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/experiment_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/log_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/constant_lut_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/signed_prefix_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/easy_lut_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/dyadic_lut_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/nmod_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/exact_steps_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/closed_form_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/principal_lut_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/range_lut_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/window_lut_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/dwt_lut_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/offset_horner_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/offset_poly_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/lut_union_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/offset_jet_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/offset_repr_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/offset_twist_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/ring_switch_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/corner_gaps_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/carry_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/class_sweep_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/extractable_full_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/walk_helpers_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/domain128_point_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/blob_leaf_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/growing_idpf_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/pprf_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/ppvc_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/leaf_later_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/caller_fold_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/defer_eval_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/sfss_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/path_sketch_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_until_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/idpf_agg_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/it_dpf3_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/party_flows.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/p0.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/p1.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/p2.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/party_bench.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/profile_eval.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/profile_grotto.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/profile_party.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/yao_share_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/yao_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/yao_stack_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/arith_garble_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/flute_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/shuffle_hidden_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/bench_cell_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/iknp_party_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/beaver_party_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/ic_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/wide_payload_test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/edit_cache.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/rebuild_cache.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/CMakeFiles/test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/CMakeFiles/edit_cache.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/CMakeFiles/rebuild_cache.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest/CMakeFiles/test.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest/CMakeFiles/edit_cache.dir +/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest/CMakeFiles/rebuild_cache.dir diff --git a/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/DependInfo.cmake new file mode 100644 index 0000000..4a46b83 --- /dev/null +++ b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/advice_bit_iterable_test.cpp" "CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o" "gcc" "CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o.d" + "" "bin/advice_bit_iterable_test" "gcc" "CMakeFiles/advice_bit_iterable_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/build.make b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/build.make new file mode 100644 index 0000000..bf724bf --- /dev/null +++ b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/advice_bit_iterable_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/advice_bit_iterable_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/advice_bit_iterable_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/advice_bit_iterable_test.dir/flags.make + +CMakeFiles/advice_bit_iterable_test.dir/codegen: +.PHONY : CMakeFiles/advice_bit_iterable_test.dir/codegen + +CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o: CMakeFiles/advice_bit_iterable_test.dir/flags.make +CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/advice_bit_iterable_test.cpp +CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o: CMakeFiles/advice_bit_iterable_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o -MF CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o.d -o CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/advice_bit_iterable_test.cpp + +CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/advice_bit_iterable_test.cpp > CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.i + +CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/advice_bit_iterable_test.cpp -o CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.s + +# Object files for target advice_bit_iterable_test +advice_bit_iterable_test_OBJECTS = \ +"CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o" + +# External object files for target advice_bit_iterable_test +advice_bit_iterable_test_EXTERNAL_OBJECTS = + +bin/advice_bit_iterable_test: CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o +bin/advice_bit_iterable_test: CMakeFiles/advice_bit_iterable_test.dir/build.make +bin/advice_bit_iterable_test: CMakeFiles/advice_bit_iterable_test.dir/compiler_depend.ts +bin/advice_bit_iterable_test: lib/libgtest_main.a +bin/advice_bit_iterable_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/advice_bit_iterable_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/advice_bit_iterable_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/advice_bit_iterable_test: lib/libgtest.a +bin/advice_bit_iterable_test: CMakeFiles/advice_bit_iterable_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/advice_bit_iterable_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/advice_bit_iterable_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=advice_bit_iterable_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/advice_bit_iterable_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=advice_bit_iterable_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/advice_bit_iterable_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/advice_bit_iterable_test.dir/build: bin/advice_bit_iterable_test +.PHONY : CMakeFiles/advice_bit_iterable_test.dir/build + +CMakeFiles/advice_bit_iterable_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/advice_bit_iterable_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/advice_bit_iterable_test.dir/clean + +CMakeFiles/advice_bit_iterable_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/DependInfo.cmake "--color=$(COLOR)" advice_bit_iterable_test +.PHONY : CMakeFiles/advice_bit_iterable_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..92e8bb1 --- /dev/null +++ b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/advice_bit_iterable_test.dir/link.d" + "CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o" + "CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o.d" + "advice_bit_iterable_test[1]_tests.cmake" + "bin/advice_bit_iterable_test" + "bin/advice_bit_iterable_test.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/advice_bit_iterable_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/compiler_depend.make new file mode 100644 index 0000000..23f3e4a --- /dev/null +++ b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for advice_bit_iterable_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/compiler_depend.ts new file mode 100644 index 0000000..daeb455 --- /dev/null +++ b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for advice_bit_iterable_test. diff --git a/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/depend.make b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/depend.make new file mode 100644 index 0000000..8f79070 --- /dev/null +++ b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for advice_bit_iterable_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/flags.make b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/link.txt b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/link.txt new file mode 100644 index 0000000..64d3037 --- /dev/null +++ b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/advice_bit_iterable_test.dir/link.d CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o -o bin/advice_bit_iterable_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/progress.make b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/advice_bit_iterable_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/all_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/all_test.dir/DependInfo.cmake new file mode 100644 index 0000000..0c51436 --- /dev/null +++ b/test/build-asan/CMakeFiles/all_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/all_test.cpp" "CMakeFiles/all_test.dir/tests/all_test.cpp.o" "gcc" "CMakeFiles/all_test.dir/tests/all_test.cpp.o.d" + "" "all_test" "gcc" "CMakeFiles/all_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/all_test.dir/build.make b/test/build-asan/CMakeFiles/all_test.dir/build.make new file mode 100644 index 0000000..1c7f1d6 --- /dev/null +++ b/test/build-asan/CMakeFiles/all_test.dir/build.make @@ -0,0 +1,119 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/all_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/all_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/all_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/all_test.dir/flags.make + +CMakeFiles/all_test.dir/codegen: +.PHONY : CMakeFiles/all_test.dir/codegen + +CMakeFiles/all_test.dir/tests/all_test.cpp.o: CMakeFiles/all_test.dir/flags.make +CMakeFiles/all_test.dir/tests/all_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/all_test.cpp +CMakeFiles/all_test.dir/tests/all_test.cpp.o: CMakeFiles/all_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/all_test.dir/tests/all_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/all_test.dir/tests/all_test.cpp.o -MF CMakeFiles/all_test.dir/tests/all_test.cpp.o.d -o CMakeFiles/all_test.dir/tests/all_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/all_test.cpp + +CMakeFiles/all_test.dir/tests/all_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/all_test.dir/tests/all_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/all_test.cpp > CMakeFiles/all_test.dir/tests/all_test.cpp.i + +CMakeFiles/all_test.dir/tests/all_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/all_test.dir/tests/all_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/all_test.cpp -o CMakeFiles/all_test.dir/tests/all_test.cpp.s + +# Object files for target all_test +all_test_OBJECTS = \ +"CMakeFiles/all_test.dir/tests/all_test.cpp.o" + +# External object files for target all_test +all_test_EXTERNAL_OBJECTS = + +all_test: CMakeFiles/all_test.dir/tests/all_test.cpp.o +all_test: CMakeFiles/all_test.dir/build.make +all_test: CMakeFiles/all_test.dir/compiler_depend.ts +all_test: lib/libgtest_main.a +all_test: /usr/lib/x86_64-linux-gnu/libsctp.so +all_test: /usr/lib/x86_64-linux-gnu/libssl.so +all_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +all_test: lib/libgtest.a +all_test: CMakeFiles/all_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable all_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/all_test.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +CMakeFiles/all_test.dir/build: all_test +.PHONY : CMakeFiles/all_test.dir/build + +CMakeFiles/all_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/all_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/all_test.dir/clean + +CMakeFiles/all_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/all_test.dir/DependInfo.cmake "--color=$(COLOR)" all_test +.PHONY : CMakeFiles/all_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/all_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/all_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..06efbad --- /dev/null +++ b/test/build-asan/CMakeFiles/all_test.dir/cmake_clean.cmake @@ -0,0 +1,12 @@ +file(REMOVE_RECURSE + "CMakeFiles/all_test.dir/link.d" + "CMakeFiles/all_test.dir/tests/all_test.cpp.o" + "CMakeFiles/all_test.dir/tests/all_test.cpp.o.d" + "all_test" + "all_test.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/all_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/all_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/all_test.dir/compiler_depend.make new file mode 100644 index 0000000..b86044a --- /dev/null +++ b/test/build-asan/CMakeFiles/all_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for all_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/all_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/all_test.dir/compiler_depend.ts new file mode 100644 index 0000000..f693d94 --- /dev/null +++ b/test/build-asan/CMakeFiles/all_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for all_test. diff --git a/test/build-asan/CMakeFiles/all_test.dir/depend.make b/test/build-asan/CMakeFiles/all_test.dir/depend.make new file mode 100644 index 0000000..aa4db8b --- /dev/null +++ b/test/build-asan/CMakeFiles/all_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for all_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/all_test.dir/flags.make b/test/build-asan/CMakeFiles/all_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/all_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/all_test.dir/link.txt b/test/build-asan/CMakeFiles/all_test.dir/link.txt new file mode 100644 index 0000000..0470504 --- /dev/null +++ b/test/build-asan/CMakeFiles/all_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/all_test.dir/link.d CMakeFiles/all_test.dir/tests/all_test.cpp.o -o all_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/all_test.dir/progress.make b/test/build-asan/CMakeFiles/all_test.dir/progress.make new file mode 100644 index 0000000..b8573d0 --- /dev/null +++ b/test/build-asan/CMakeFiles/all_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 1 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/arith_garble_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/arith_garble_test.dir/DependInfo.cmake new file mode 100644 index 0000000..359f446 --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_garble_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_garble_test.cpp" "CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o" "gcc" "CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o.d" + "" "bin/arith_garble_test" "gcc" "CMakeFiles/arith_garble_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/arith_garble_test.dir/build.make b/test/build-asan/CMakeFiles/arith_garble_test.dir/build.make new file mode 100644 index 0000000..3f3ccde --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_garble_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/arith_garble_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/arith_garble_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/arith_garble_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/arith_garble_test.dir/flags.make + +CMakeFiles/arith_garble_test.dir/codegen: +.PHONY : CMakeFiles/arith_garble_test.dir/codegen + +CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o: CMakeFiles/arith_garble_test.dir/flags.make +CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_garble_test.cpp +CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o: CMakeFiles/arith_garble_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o -MF CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o.d -o CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_garble_test.cpp + +CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_garble_test.cpp > CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.i + +CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_garble_test.cpp -o CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.s + +# Object files for target arith_garble_test +arith_garble_test_OBJECTS = \ +"CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o" + +# External object files for target arith_garble_test +arith_garble_test_EXTERNAL_OBJECTS = + +bin/arith_garble_test: CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o +bin/arith_garble_test: CMakeFiles/arith_garble_test.dir/build.make +bin/arith_garble_test: CMakeFiles/arith_garble_test.dir/compiler_depend.ts +bin/arith_garble_test: lib/libgtest_main.a +bin/arith_garble_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/arith_garble_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/arith_garble_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/arith_garble_test: lib/libgtest.a +bin/arith_garble_test: CMakeFiles/arith_garble_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/arith_garble_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/arith_garble_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=arith_garble_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/arith_garble_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=arith_garble_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/arith_garble_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/arith_garble_test.dir/build: bin/arith_garble_test +.PHONY : CMakeFiles/arith_garble_test.dir/build + +CMakeFiles/arith_garble_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/arith_garble_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/arith_garble_test.dir/clean + +CMakeFiles/arith_garble_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/arith_garble_test.dir/DependInfo.cmake "--color=$(COLOR)" arith_garble_test +.PHONY : CMakeFiles/arith_garble_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/arith_garble_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/arith_garble_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..4a799ac --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_garble_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/arith_garble_test.dir/link.d" + "CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o" + "CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o.d" + "arith_garble_test[1]_tests.cmake" + "bin/arith_garble_test" + "bin/arith_garble_test.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/arith_garble_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/arith_garble_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/arith_garble_test.dir/compiler_depend.make new file mode 100644 index 0000000..f1b15c0 --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_garble_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for arith_garble_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/arith_garble_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/arith_garble_test.dir/compiler_depend.ts new file mode 100644 index 0000000..55dab13 --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_garble_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for arith_garble_test. diff --git a/test/build-asan/CMakeFiles/arith_garble_test.dir/depend.make b/test/build-asan/CMakeFiles/arith_garble_test.dir/depend.make new file mode 100644 index 0000000..176376b --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_garble_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for arith_garble_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/arith_garble_test.dir/flags.make b/test/build-asan/CMakeFiles/arith_garble_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_garble_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/arith_garble_test.dir/link.txt b/test/build-asan/CMakeFiles/arith_garble_test.dir/link.txt new file mode 100644 index 0000000..cbaeceb --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_garble_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/arith_garble_test.dir/link.d CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o -o bin/arith_garble_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/arith_garble_test.dir/progress.make b/test/build-asan/CMakeFiles/arith_garble_test.dir/progress.make new file mode 100644 index 0000000..e9511b0 --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_garble_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 2 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/arith_payload_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/arith_payload_test.dir/DependInfo.cmake new file mode 100644 index 0000000..f02025a --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_payload_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp" "CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o" "gcc" "CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o.d" + "" "bin/arith_payload_test" "gcc" "CMakeFiles/arith_payload_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/arith_payload_test.dir/build.make b/test/build-asan/CMakeFiles/arith_payload_test.dir/build.make new file mode 100644 index 0000000..a69d552 --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_payload_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/arith_payload_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/arith_payload_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/arith_payload_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/arith_payload_test.dir/flags.make + +CMakeFiles/arith_payload_test.dir/codegen: +.PHONY : CMakeFiles/arith_payload_test.dir/codegen + +CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o: CMakeFiles/arith_payload_test.dir/flags.make +CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp +CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o: CMakeFiles/arith_payload_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o -MF CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o.d -o CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp + +CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp > CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.i + +CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp -o CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.s + +# Object files for target arith_payload_test +arith_payload_test_OBJECTS = \ +"CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o" + +# External object files for target arith_payload_test +arith_payload_test_EXTERNAL_OBJECTS = + +bin/arith_payload_test: CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o +bin/arith_payload_test: CMakeFiles/arith_payload_test.dir/build.make +bin/arith_payload_test: CMakeFiles/arith_payload_test.dir/compiler_depend.ts +bin/arith_payload_test: lib/libgtest_main.a +bin/arith_payload_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/arith_payload_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/arith_payload_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/arith_payload_test: lib/libgtest.a +bin/arith_payload_test: CMakeFiles/arith_payload_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/arith_payload_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/arith_payload_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=arith_payload_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/arith_payload_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=arith_payload_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/arith_payload_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/arith_payload_test.dir/build: bin/arith_payload_test +.PHONY : CMakeFiles/arith_payload_test.dir/build + +CMakeFiles/arith_payload_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/arith_payload_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/arith_payload_test.dir/clean + +CMakeFiles/arith_payload_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/arith_payload_test.dir/DependInfo.cmake "--color=$(COLOR)" arith_payload_test +.PHONY : CMakeFiles/arith_payload_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/arith_payload_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/arith_payload_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..c80c88d --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_payload_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/arith_payload_test.dir/link.d" + "CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o" + "CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o.d" + "arith_payload_test[1]_tests.cmake" + "bin/arith_payload_test" + "bin/arith_payload_test.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/arith_payload_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/arith_payload_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/arith_payload_test.dir/compiler_depend.make new file mode 100644 index 0000000..ea1fd45 --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_payload_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for arith_payload_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/arith_payload_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/arith_payload_test.dir/compiler_depend.ts new file mode 100644 index 0000000..7451859 --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_payload_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for arith_payload_test. diff --git a/test/build-asan/CMakeFiles/arith_payload_test.dir/depend.make b/test/build-asan/CMakeFiles/arith_payload_test.dir/depend.make new file mode 100644 index 0000000..ddc6bd2 --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_payload_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for arith_payload_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/arith_payload_test.dir/flags.make b/test/build-asan/CMakeFiles/arith_payload_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_payload_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/arith_payload_test.dir/link.txt b/test/build-asan/CMakeFiles/arith_payload_test.dir/link.txt new file mode 100644 index 0000000..5a16dd4 --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_payload_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/arith_payload_test.dir/link.d CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o -o bin/arith_payload_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/arith_payload_test.dir/progress.make b/test/build-asan/CMakeFiles/arith_payload_test.dir/progress.make new file mode 100644 index 0000000..d7043a9 --- /dev/null +++ b/test/build-asan/CMakeFiles/arith_payload_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 3 + diff --git a/test/build-asan/CMakeFiles/beaver_party_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/beaver_party_test.dir/DependInfo.cmake new file mode 100644 index 0000000..9c69982 --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_party_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/beaver_party_test.cpp" "CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o" "gcc" "CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o.d" + "" "bin/beaver_party_test" "gcc" "CMakeFiles/beaver_party_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/beaver_party_test.dir/build.make b/test/build-asan/CMakeFiles/beaver_party_test.dir/build.make new file mode 100644 index 0000000..cb78133 --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_party_test.dir/build.make @@ -0,0 +1,125 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/beaver_party_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/beaver_party_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/beaver_party_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/beaver_party_test.dir/flags.make + +CMakeFiles/beaver_party_test.dir/codegen: +.PHONY : CMakeFiles/beaver_party_test.dir/codegen + +CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o: CMakeFiles/beaver_party_test.dir/flags.make +CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/beaver_party_test.cpp +CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o: CMakeFiles/beaver_party_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o -MF CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o.d -o CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/beaver_party_test.cpp + +CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/beaver_party_test.cpp > CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.i + +CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/beaver_party_test.cpp -o CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.s + +# Object files for target beaver_party_test +beaver_party_test_OBJECTS = \ +"CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o" + +# External object files for target beaver_party_test +beaver_party_test_EXTERNAL_OBJECTS = + +bin/beaver_party_test: CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o +bin/beaver_party_test: CMakeFiles/beaver_party_test.dir/build.make +bin/beaver_party_test: CMakeFiles/beaver_party_test.dir/compiler_depend.ts +bin/beaver_party_test: lib/libgtest_main.a +bin/beaver_party_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/beaver_party_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/beaver_party_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/beaver_party_test: libparty_flows.a +bin/beaver_party_test: lib/libgtest_main.a +bin/beaver_party_test: lib/libgtest.a +bin/beaver_party_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/beaver_party_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/beaver_party_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/beaver_party_test: CMakeFiles/beaver_party_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/beaver_party_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/beaver_party_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=beaver_party_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/beaver_party_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=beaver_party_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/beaver_party_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/beaver_party_test.dir/build: bin/beaver_party_test +.PHONY : CMakeFiles/beaver_party_test.dir/build + +CMakeFiles/beaver_party_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/beaver_party_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/beaver_party_test.dir/clean + +CMakeFiles/beaver_party_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/beaver_party_test.dir/DependInfo.cmake "--color=$(COLOR)" beaver_party_test +.PHONY : CMakeFiles/beaver_party_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/beaver_party_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/beaver_party_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..5882817 --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_party_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/beaver_party_test.dir/link.d" + "CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o" + "CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o.d" + "beaver_party_test[1]_tests.cmake" + "bin/beaver_party_test" + "bin/beaver_party_test.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/beaver_party_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/beaver_party_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/beaver_party_test.dir/compiler_depend.make new file mode 100644 index 0000000..f44c6cd --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_party_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for beaver_party_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/beaver_party_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/beaver_party_test.dir/compiler_depend.ts new file mode 100644 index 0000000..70a9343 --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_party_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for beaver_party_test. diff --git a/test/build-asan/CMakeFiles/beaver_party_test.dir/depend.make b/test/build-asan/CMakeFiles/beaver_party_test.dir/depend.make new file mode 100644 index 0000000..159608d --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_party_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for beaver_party_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/beaver_party_test.dir/flags.make b/test/build-asan/CMakeFiles/beaver_party_test.dir/flags.make new file mode 100644 index 0000000..c9f269f --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_party_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" -DLIBDPF_HAS_ASIO -DLIBDPF_HAS_NLOHMANN_JSON -DLIBDPF_PARTY_BIN_DIR=\"/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../party -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/json/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/beaver_party_test.dir/link.txt b/test/build-asan/CMakeFiles/beaver_party_test.dir/link.txt new file mode 100644 index 0000000..d69fa94 --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_party_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/beaver_party_test.dir/link.d CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o -o bin/beaver_party_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so libparty_flows.a lib/libgtest_main.a lib/libgtest.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so -lpthread diff --git a/test/build-asan/CMakeFiles/beaver_party_test.dir/progress.make b/test/build-asan/CMakeFiles/beaver_party_test.dir/progress.make new file mode 100644 index 0000000..e6a48aa --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_party_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 4 + diff --git a/test/build-asan/CMakeFiles/beaver_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/beaver_test.dir/DependInfo.cmake new file mode 100644 index 0000000..833f3bd --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/beaver_test.cpp" "CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o" "gcc" "CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o.d" + "" "bin/beaver_test" "gcc" "CMakeFiles/beaver_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/beaver_test.dir/build.make b/test/build-asan/CMakeFiles/beaver_test.dir/build.make new file mode 100644 index 0000000..ea525a7 --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/beaver_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/beaver_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/beaver_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/beaver_test.dir/flags.make + +CMakeFiles/beaver_test.dir/codegen: +.PHONY : CMakeFiles/beaver_test.dir/codegen + +CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o: CMakeFiles/beaver_test.dir/flags.make +CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/beaver_test.cpp +CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o: CMakeFiles/beaver_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o -MF CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o.d -o CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/beaver_test.cpp + +CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/beaver_test.cpp > CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.i + +CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/beaver_test.cpp -o CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.s + +# Object files for target beaver_test +beaver_test_OBJECTS = \ +"CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o" + +# External object files for target beaver_test +beaver_test_EXTERNAL_OBJECTS = + +bin/beaver_test: CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o +bin/beaver_test: CMakeFiles/beaver_test.dir/build.make +bin/beaver_test: CMakeFiles/beaver_test.dir/compiler_depend.ts +bin/beaver_test: lib/libgtest_main.a +bin/beaver_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/beaver_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/beaver_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/beaver_test: lib/libgtest.a +bin/beaver_test: CMakeFiles/beaver_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/beaver_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/beaver_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=beaver_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/beaver_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=beaver_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/beaver_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/beaver_test.dir/build: bin/beaver_test +.PHONY : CMakeFiles/beaver_test.dir/build + +CMakeFiles/beaver_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/beaver_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/beaver_test.dir/clean + +CMakeFiles/beaver_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/beaver_test.dir/DependInfo.cmake "--color=$(COLOR)" beaver_test +.PHONY : CMakeFiles/beaver_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/beaver_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/beaver_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..214d8a7 --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/beaver_test.dir/link.d" + "CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o" + "CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o.d" + "beaver_test[1]_tests.cmake" + "bin/beaver_test" + "bin/beaver_test.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/beaver_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/beaver_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/beaver_test.dir/compiler_depend.make new file mode 100644 index 0000000..2c80774 --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for beaver_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/beaver_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/beaver_test.dir/compiler_depend.ts new file mode 100644 index 0000000..61437fa --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for beaver_test. diff --git a/test/build-asan/CMakeFiles/beaver_test.dir/depend.make b/test/build-asan/CMakeFiles/beaver_test.dir/depend.make new file mode 100644 index 0000000..46b1d2f --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for beaver_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/beaver_test.dir/flags.make b/test/build-asan/CMakeFiles/beaver_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/beaver_test.dir/link.txt b/test/build-asan/CMakeFiles/beaver_test.dir/link.txt new file mode 100644 index 0000000..ab366a7 --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/beaver_test.dir/link.d CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o -o bin/beaver_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/beaver_test.dir/progress.make b/test/build-asan/CMakeFiles/beaver_test.dir/progress.make new file mode 100644 index 0000000..9867570 --- /dev/null +++ b/test/build-asan/CMakeFiles/beaver_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 5 + diff --git a/test/build-asan/CMakeFiles/bench_cell_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/bench_cell_test.dir/DependInfo.cmake new file mode 100644 index 0000000..00a3348 --- /dev/null +++ b/test/build-asan/CMakeFiles/bench_cell_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/bench_cell_test.cpp" "CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o" "gcc" "CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o.d" + "" "bin/bench_cell_test" "gcc" "CMakeFiles/bench_cell_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/bench_cell_test.dir/build.make b/test/build-asan/CMakeFiles/bench_cell_test.dir/build.make new file mode 100644 index 0000000..cf995ef --- /dev/null +++ b/test/build-asan/CMakeFiles/bench_cell_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/bench_cell_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/bench_cell_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/bench_cell_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/bench_cell_test.dir/flags.make + +CMakeFiles/bench_cell_test.dir/codegen: +.PHONY : CMakeFiles/bench_cell_test.dir/codegen + +CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o: CMakeFiles/bench_cell_test.dir/flags.make +CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/bench_cell_test.cpp +CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o: CMakeFiles/bench_cell_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o -MF CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o.d -o CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/bench_cell_test.cpp + +CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/bench_cell_test.cpp > CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.i + +CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/bench_cell_test.cpp -o CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.s + +# Object files for target bench_cell_test +bench_cell_test_OBJECTS = \ +"CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o" + +# External object files for target bench_cell_test +bench_cell_test_EXTERNAL_OBJECTS = + +bin/bench_cell_test: CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o +bin/bench_cell_test: CMakeFiles/bench_cell_test.dir/build.make +bin/bench_cell_test: CMakeFiles/bench_cell_test.dir/compiler_depend.ts +bin/bench_cell_test: lib/libgtest_main.a +bin/bench_cell_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/bench_cell_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/bench_cell_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/bench_cell_test: lib/libgtest.a +bin/bench_cell_test: CMakeFiles/bench_cell_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/bench_cell_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/bench_cell_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=bench_cell_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/bench_cell_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=bench_cell_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bench_cell_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/bench_cell_test.dir/build: bin/bench_cell_test +.PHONY : CMakeFiles/bench_cell_test.dir/build + +CMakeFiles/bench_cell_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/bench_cell_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/bench_cell_test.dir/clean + +CMakeFiles/bench_cell_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/bench_cell_test.dir/DependInfo.cmake "--color=$(COLOR)" bench_cell_test +.PHONY : CMakeFiles/bench_cell_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/bench_cell_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/bench_cell_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..dc6ffe4 --- /dev/null +++ b/test/build-asan/CMakeFiles/bench_cell_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/bench_cell_test.dir/link.d" + "CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o" + "CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o.d" + "bench_cell_test[1]_tests.cmake" + "bin/bench_cell_test" + "bin/bench_cell_test.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/bench_cell_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/bench_cell_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/bench_cell_test.dir/compiler_depend.make new file mode 100644 index 0000000..38bcbe3 --- /dev/null +++ b/test/build-asan/CMakeFiles/bench_cell_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for bench_cell_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/bench_cell_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/bench_cell_test.dir/compiler_depend.ts new file mode 100644 index 0000000..68b7f7d --- /dev/null +++ b/test/build-asan/CMakeFiles/bench_cell_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for bench_cell_test. diff --git a/test/build-asan/CMakeFiles/bench_cell_test.dir/depend.make b/test/build-asan/CMakeFiles/bench_cell_test.dir/depend.make new file mode 100644 index 0000000..854a8e3 --- /dev/null +++ b/test/build-asan/CMakeFiles/bench_cell_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for bench_cell_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/bench_cell_test.dir/flags.make b/test/build-asan/CMakeFiles/bench_cell_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/bench_cell_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/bench_cell_test.dir/link.txt b/test/build-asan/CMakeFiles/bench_cell_test.dir/link.txt new file mode 100644 index 0000000..f50bcda --- /dev/null +++ b/test/build-asan/CMakeFiles/bench_cell_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/bench_cell_test.dir/link.d CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o -o bin/bench_cell_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so -lpthread lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/bench_cell_test.dir/progress.make b/test/build-asan/CMakeFiles/bench_cell_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/bench_cell_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/bit_array_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/bit_array_test.dir/DependInfo.cmake new file mode 100644 index 0000000..5c80b1e --- /dev/null +++ b/test/build-asan/CMakeFiles/bit_array_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/bit_array_test.cpp" "CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o" "gcc" "CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o.d" + "" "bin/bit_array_test" "gcc" "CMakeFiles/bit_array_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/bit_array_test.dir/build.make b/test/build-asan/CMakeFiles/bit_array_test.dir/build.make new file mode 100644 index 0000000..d10d309 --- /dev/null +++ b/test/build-asan/CMakeFiles/bit_array_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/bit_array_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/bit_array_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/bit_array_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/bit_array_test.dir/flags.make + +CMakeFiles/bit_array_test.dir/codegen: +.PHONY : CMakeFiles/bit_array_test.dir/codegen + +CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o: CMakeFiles/bit_array_test.dir/flags.make +CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/bit_array_test.cpp +CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o: CMakeFiles/bit_array_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o -MF CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o.d -o CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/bit_array_test.cpp + +CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/bit_array_test.cpp > CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.i + +CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/bit_array_test.cpp -o CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.s + +# Object files for target bit_array_test +bit_array_test_OBJECTS = \ +"CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o" + +# External object files for target bit_array_test +bit_array_test_EXTERNAL_OBJECTS = + +bin/bit_array_test: CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o +bin/bit_array_test: CMakeFiles/bit_array_test.dir/build.make +bin/bit_array_test: CMakeFiles/bit_array_test.dir/compiler_depend.ts +bin/bit_array_test: lib/libgtest_main.a +bin/bit_array_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/bit_array_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/bit_array_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/bit_array_test: lib/libgtest.a +bin/bit_array_test: CMakeFiles/bit_array_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/bit_array_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/bit_array_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=bit_array_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/bit_array_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=bit_array_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bit_array_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/bit_array_test.dir/build: bin/bit_array_test +.PHONY : CMakeFiles/bit_array_test.dir/build + +CMakeFiles/bit_array_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/bit_array_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/bit_array_test.dir/clean + +CMakeFiles/bit_array_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/bit_array_test.dir/DependInfo.cmake "--color=$(COLOR)" bit_array_test +.PHONY : CMakeFiles/bit_array_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/bit_array_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/bit_array_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..d510cde --- /dev/null +++ b/test/build-asan/CMakeFiles/bit_array_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/bit_array_test.dir/link.d" + "CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o" + "CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o.d" + "bin/bit_array_test" + "bin/bit_array_test.pdb" + "bit_array_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/bit_array_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/bit_array_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/bit_array_test.dir/compiler_depend.make new file mode 100644 index 0000000..4a7e79f --- /dev/null +++ b/test/build-asan/CMakeFiles/bit_array_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for bit_array_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/bit_array_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/bit_array_test.dir/compiler_depend.ts new file mode 100644 index 0000000..c384e2d --- /dev/null +++ b/test/build-asan/CMakeFiles/bit_array_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for bit_array_test. diff --git a/test/build-asan/CMakeFiles/bit_array_test.dir/depend.make b/test/build-asan/CMakeFiles/bit_array_test.dir/depend.make new file mode 100644 index 0000000..f801ea4 --- /dev/null +++ b/test/build-asan/CMakeFiles/bit_array_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for bit_array_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/bit_array_test.dir/flags.make b/test/build-asan/CMakeFiles/bit_array_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/bit_array_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/bit_array_test.dir/link.txt b/test/build-asan/CMakeFiles/bit_array_test.dir/link.txt new file mode 100644 index 0000000..0b40f67 --- /dev/null +++ b/test/build-asan/CMakeFiles/bit_array_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/bit_array_test.dir/link.d CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o -o bin/bit_array_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/bit_array_test.dir/progress.make b/test/build-asan/CMakeFiles/bit_array_test.dir/progress.make new file mode 100644 index 0000000..26f46ed --- /dev/null +++ b/test/build-asan/CMakeFiles/bit_array_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 6 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/bitmore_mod_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/DependInfo.cmake new file mode 100644 index 0000000..4c29949 --- /dev/null +++ b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/bitmore_mod_test.cpp" "CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o" "gcc" "CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o.d" + "" "bin/bitmore_mod_test" "gcc" "CMakeFiles/bitmore_mod_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/bitmore_mod_test.dir/build.make b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/build.make new file mode 100644 index 0000000..6d3da89 --- /dev/null +++ b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/bitmore_mod_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/bitmore_mod_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/bitmore_mod_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/bitmore_mod_test.dir/flags.make + +CMakeFiles/bitmore_mod_test.dir/codegen: +.PHONY : CMakeFiles/bitmore_mod_test.dir/codegen + +CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o: CMakeFiles/bitmore_mod_test.dir/flags.make +CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/bitmore_mod_test.cpp +CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o: CMakeFiles/bitmore_mod_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o -MF CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o.d -o CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/bitmore_mod_test.cpp + +CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/bitmore_mod_test.cpp > CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.i + +CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/bitmore_mod_test.cpp -o CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.s + +# Object files for target bitmore_mod_test +bitmore_mod_test_OBJECTS = \ +"CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o" + +# External object files for target bitmore_mod_test +bitmore_mod_test_EXTERNAL_OBJECTS = + +bin/bitmore_mod_test: CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o +bin/bitmore_mod_test: CMakeFiles/bitmore_mod_test.dir/build.make +bin/bitmore_mod_test: CMakeFiles/bitmore_mod_test.dir/compiler_depend.ts +bin/bitmore_mod_test: lib/libgtest_main.a +bin/bitmore_mod_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/bitmore_mod_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/bitmore_mod_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/bitmore_mod_test: lib/libgtest.a +bin/bitmore_mod_test: CMakeFiles/bitmore_mod_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/bitmore_mod_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/bitmore_mod_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=bitmore_mod_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/bitmore_mod_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=bitmore_mod_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bitmore_mod_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/bitmore_mod_test.dir/build: bin/bitmore_mod_test +.PHONY : CMakeFiles/bitmore_mod_test.dir/build + +CMakeFiles/bitmore_mod_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/bitmore_mod_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/bitmore_mod_test.dir/clean + +CMakeFiles/bitmore_mod_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/bitmore_mod_test.dir/DependInfo.cmake "--color=$(COLOR)" bitmore_mod_test +.PHONY : CMakeFiles/bitmore_mod_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/bitmore_mod_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..c386223 --- /dev/null +++ b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/bitmore_mod_test.dir/link.d" + "CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o" + "CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o.d" + "bin/bitmore_mod_test" + "bin/bitmore_mod_test.pdb" + "bitmore_mod_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/bitmore_mod_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/bitmore_mod_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/compiler_depend.make new file mode 100644 index 0000000..20344d4 --- /dev/null +++ b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for bitmore_mod_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/bitmore_mod_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/compiler_depend.ts new file mode 100644 index 0000000..0e93b2d --- /dev/null +++ b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for bitmore_mod_test. diff --git a/test/build-asan/CMakeFiles/bitmore_mod_test.dir/depend.make b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/depend.make new file mode 100644 index 0000000..d7d58da --- /dev/null +++ b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for bitmore_mod_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/bitmore_mod_test.dir/flags.make b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/bitmore_mod_test.dir/link.txt b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/link.txt new file mode 100644 index 0000000..d308522 --- /dev/null +++ b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/bitmore_mod_test.dir/link.d CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o -o bin/bitmore_mod_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/bitmore_mod_test.dir/progress.make b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/progress.make new file mode 100644 index 0000000..86f13de --- /dev/null +++ b/test/build-asan/CMakeFiles/bitmore_mod_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 7 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/blob_leaf_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/blob_leaf_test.dir/DependInfo.cmake new file mode 100644 index 0000000..b35f702 --- /dev/null +++ b/test/build-asan/CMakeFiles/blob_leaf_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/blob_leaf_test.cpp" "CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o" "gcc" "CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o.d" + "" "bin/blob_leaf_test" "gcc" "CMakeFiles/blob_leaf_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/blob_leaf_test.dir/build.make b/test/build-asan/CMakeFiles/blob_leaf_test.dir/build.make new file mode 100644 index 0000000..d0bc892 --- /dev/null +++ b/test/build-asan/CMakeFiles/blob_leaf_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/blob_leaf_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/blob_leaf_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/blob_leaf_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/blob_leaf_test.dir/flags.make + +CMakeFiles/blob_leaf_test.dir/codegen: +.PHONY : CMakeFiles/blob_leaf_test.dir/codegen + +CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o: CMakeFiles/blob_leaf_test.dir/flags.make +CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/blob_leaf_test.cpp +CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o: CMakeFiles/blob_leaf_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o -MF CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o.d -o CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/blob_leaf_test.cpp + +CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/blob_leaf_test.cpp > CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.i + +CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/blob_leaf_test.cpp -o CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.s + +# Object files for target blob_leaf_test +blob_leaf_test_OBJECTS = \ +"CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o" + +# External object files for target blob_leaf_test +blob_leaf_test_EXTERNAL_OBJECTS = + +bin/blob_leaf_test: CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o +bin/blob_leaf_test: CMakeFiles/blob_leaf_test.dir/build.make +bin/blob_leaf_test: CMakeFiles/blob_leaf_test.dir/compiler_depend.ts +bin/blob_leaf_test: lib/libgtest_main.a +bin/blob_leaf_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/blob_leaf_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/blob_leaf_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/blob_leaf_test: lib/libgtest.a +bin/blob_leaf_test: CMakeFiles/blob_leaf_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/blob_leaf_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/blob_leaf_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=blob_leaf_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blob_leaf_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=blob_leaf_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/blob_leaf_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/blob_leaf_test.dir/build: bin/blob_leaf_test +.PHONY : CMakeFiles/blob_leaf_test.dir/build + +CMakeFiles/blob_leaf_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/blob_leaf_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/blob_leaf_test.dir/clean + +CMakeFiles/blob_leaf_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/blob_leaf_test.dir/DependInfo.cmake "--color=$(COLOR)" blob_leaf_test +.PHONY : CMakeFiles/blob_leaf_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/blob_leaf_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/blob_leaf_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..b612639 --- /dev/null +++ b/test/build-asan/CMakeFiles/blob_leaf_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/blob_leaf_test.dir/link.d" + "CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o" + "CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o.d" + "bin/blob_leaf_test" + "bin/blob_leaf_test.pdb" + "blob_leaf_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/blob_leaf_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/blob_leaf_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/blob_leaf_test.dir/compiler_depend.make new file mode 100644 index 0000000..d432392 --- /dev/null +++ b/test/build-asan/CMakeFiles/blob_leaf_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for blob_leaf_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/blob_leaf_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/blob_leaf_test.dir/compiler_depend.ts new file mode 100644 index 0000000..27bfe7c --- /dev/null +++ b/test/build-asan/CMakeFiles/blob_leaf_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for blob_leaf_test. diff --git a/test/build-asan/CMakeFiles/blob_leaf_test.dir/depend.make b/test/build-asan/CMakeFiles/blob_leaf_test.dir/depend.make new file mode 100644 index 0000000..9e5c0e5 --- /dev/null +++ b/test/build-asan/CMakeFiles/blob_leaf_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for blob_leaf_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/blob_leaf_test.dir/flags.make b/test/build-asan/CMakeFiles/blob_leaf_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/blob_leaf_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/blob_leaf_test.dir/link.txt b/test/build-asan/CMakeFiles/blob_leaf_test.dir/link.txt new file mode 100644 index 0000000..5134244 --- /dev/null +++ b/test/build-asan/CMakeFiles/blob_leaf_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/blob_leaf_test.dir/link.d CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o -o bin/blob_leaf_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/blob_leaf_test.dir/progress.make b/test/build-asan/CMakeFiles/blob_leaf_test.dir/progress.make new file mode 100644 index 0000000..1481293 --- /dev/null +++ b/test/build-asan/CMakeFiles/blob_leaf_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 8 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/blocked_dcf_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/DependInfo.cmake new file mode 100644 index 0000000..0cda6ef --- /dev/null +++ b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp" "CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o" "gcc" "CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o.d" + "" "bin/blocked_dcf_test" "gcc" "CMakeFiles/blocked_dcf_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/blocked_dcf_test.dir/build.make b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/build.make new file mode 100644 index 0000000..4c90245 --- /dev/null +++ b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/blocked_dcf_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/blocked_dcf_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/blocked_dcf_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/blocked_dcf_test.dir/flags.make + +CMakeFiles/blocked_dcf_test.dir/codegen: +.PHONY : CMakeFiles/blocked_dcf_test.dir/codegen + +CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o: CMakeFiles/blocked_dcf_test.dir/flags.make +CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp +CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o: CMakeFiles/blocked_dcf_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o -MF CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o.d -o CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp + +CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp > CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.i + +CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp -o CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.s + +# Object files for target blocked_dcf_test +blocked_dcf_test_OBJECTS = \ +"CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o" + +# External object files for target blocked_dcf_test +blocked_dcf_test_EXTERNAL_OBJECTS = + +bin/blocked_dcf_test: CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o +bin/blocked_dcf_test: CMakeFiles/blocked_dcf_test.dir/build.make +bin/blocked_dcf_test: CMakeFiles/blocked_dcf_test.dir/compiler_depend.ts +bin/blocked_dcf_test: lib/libgtest_main.a +bin/blocked_dcf_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/blocked_dcf_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/blocked_dcf_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/blocked_dcf_test: lib/libgtest.a +bin/blocked_dcf_test: CMakeFiles/blocked_dcf_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/blocked_dcf_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/blocked_dcf_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=blocked_dcf_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=blocked_dcf_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/blocked_dcf_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/blocked_dcf_test.dir/build: bin/blocked_dcf_test +.PHONY : CMakeFiles/blocked_dcf_test.dir/build + +CMakeFiles/blocked_dcf_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/blocked_dcf_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/blocked_dcf_test.dir/clean + +CMakeFiles/blocked_dcf_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/blocked_dcf_test.dir/DependInfo.cmake "--color=$(COLOR)" blocked_dcf_test +.PHONY : CMakeFiles/blocked_dcf_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/blocked_dcf_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..7190b0a --- /dev/null +++ b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/blocked_dcf_test.dir/link.d" + "CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o" + "CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o.d" + "bin/blocked_dcf_test" + "bin/blocked_dcf_test.pdb" + "blocked_dcf_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/blocked_dcf_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/blocked_dcf_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/compiler_depend.make new file mode 100644 index 0000000..1bf969f --- /dev/null +++ b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for blocked_dcf_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/blocked_dcf_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/compiler_depend.ts new file mode 100644 index 0000000..b70c057 --- /dev/null +++ b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for blocked_dcf_test. diff --git a/test/build-asan/CMakeFiles/blocked_dcf_test.dir/depend.make b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/depend.make new file mode 100644 index 0000000..6a866ed --- /dev/null +++ b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for blocked_dcf_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/blocked_dcf_test.dir/flags.make b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/flags.make new file mode 100644 index 0000000..ba0636b --- /dev/null +++ b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" -DLIBDPF_HAS_NLOHMANN_JSON + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/json/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/blocked_dcf_test.dir/link.txt b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/link.txt new file mode 100644 index 0000000..a4fb67b --- /dev/null +++ b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/blocked_dcf_test.dir/link.d CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o -o bin/blocked_dcf_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/blocked_dcf_test.dir/progress.make b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/progress.make new file mode 100644 index 0000000..cbaed8a --- /dev/null +++ b/test/build-asan/CMakeFiles/blocked_dcf_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 9 + diff --git a/test/build-asan/CMakeFiles/caller_fold_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/caller_fold_test.dir/DependInfo.cmake new file mode 100644 index 0000000..dda0b46 --- /dev/null +++ b/test/build-asan/CMakeFiles/caller_fold_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/caller_fold_test.cpp" "CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o" "gcc" "CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o.d" + "" "bin/caller_fold_test" "gcc" "CMakeFiles/caller_fold_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/caller_fold_test.dir/build.make b/test/build-asan/CMakeFiles/caller_fold_test.dir/build.make new file mode 100644 index 0000000..b3fc67e --- /dev/null +++ b/test/build-asan/CMakeFiles/caller_fold_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/caller_fold_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/caller_fold_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/caller_fold_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/caller_fold_test.dir/flags.make + +CMakeFiles/caller_fold_test.dir/codegen: +.PHONY : CMakeFiles/caller_fold_test.dir/codegen + +CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o: CMakeFiles/caller_fold_test.dir/flags.make +CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/caller_fold_test.cpp +CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o: CMakeFiles/caller_fold_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o -MF CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o.d -o CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/caller_fold_test.cpp + +CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/caller_fold_test.cpp > CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.i + +CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/caller_fold_test.cpp -o CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.s + +# Object files for target caller_fold_test +caller_fold_test_OBJECTS = \ +"CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o" + +# External object files for target caller_fold_test +caller_fold_test_EXTERNAL_OBJECTS = + +bin/caller_fold_test: CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o +bin/caller_fold_test: CMakeFiles/caller_fold_test.dir/build.make +bin/caller_fold_test: CMakeFiles/caller_fold_test.dir/compiler_depend.ts +bin/caller_fold_test: lib/libgtest_main.a +bin/caller_fold_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/caller_fold_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/caller_fold_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/caller_fold_test: lib/libgtest.a +bin/caller_fold_test: CMakeFiles/caller_fold_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/caller_fold_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/caller_fold_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=caller_fold_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/caller_fold_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=caller_fold_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/caller_fold_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/caller_fold_test.dir/build: bin/caller_fold_test +.PHONY : CMakeFiles/caller_fold_test.dir/build + +CMakeFiles/caller_fold_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/caller_fold_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/caller_fold_test.dir/clean + +CMakeFiles/caller_fold_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/caller_fold_test.dir/DependInfo.cmake "--color=$(COLOR)" caller_fold_test +.PHONY : CMakeFiles/caller_fold_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/caller_fold_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/caller_fold_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..e971e83 --- /dev/null +++ b/test/build-asan/CMakeFiles/caller_fold_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/caller_fold_test.dir/link.d" + "CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o" + "CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o.d" + "bin/caller_fold_test" + "bin/caller_fold_test.pdb" + "caller_fold_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/caller_fold_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/caller_fold_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/caller_fold_test.dir/compiler_depend.make new file mode 100644 index 0000000..677188c --- /dev/null +++ b/test/build-asan/CMakeFiles/caller_fold_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for caller_fold_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/caller_fold_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/caller_fold_test.dir/compiler_depend.ts new file mode 100644 index 0000000..2acb9c1 --- /dev/null +++ b/test/build-asan/CMakeFiles/caller_fold_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for caller_fold_test. diff --git a/test/build-asan/CMakeFiles/caller_fold_test.dir/depend.make b/test/build-asan/CMakeFiles/caller_fold_test.dir/depend.make new file mode 100644 index 0000000..fdca499 --- /dev/null +++ b/test/build-asan/CMakeFiles/caller_fold_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for caller_fold_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/caller_fold_test.dir/flags.make b/test/build-asan/CMakeFiles/caller_fold_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/caller_fold_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/caller_fold_test.dir/link.txt b/test/build-asan/CMakeFiles/caller_fold_test.dir/link.txt new file mode 100644 index 0000000..276d134 --- /dev/null +++ b/test/build-asan/CMakeFiles/caller_fold_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/caller_fold_test.dir/link.d CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o -o bin/caller_fold_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/caller_fold_test.dir/progress.make b/test/build-asan/CMakeFiles/caller_fold_test.dir/progress.make new file mode 100644 index 0000000..c20a208 --- /dev/null +++ b/test/build-asan/CMakeFiles/caller_fold_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 10 + diff --git a/test/build-asan/CMakeFiles/carry_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/carry_test.dir/DependInfo.cmake new file mode 100644 index 0000000..6f2c62f --- /dev/null +++ b/test/build-asan/CMakeFiles/carry_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/carry_test.cpp" "CMakeFiles/carry_test.dir/tests/carry_test.cpp.o" "gcc" "CMakeFiles/carry_test.dir/tests/carry_test.cpp.o.d" + "" "bin/carry_test" "gcc" "CMakeFiles/carry_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/carry_test.dir/build.make b/test/build-asan/CMakeFiles/carry_test.dir/build.make new file mode 100644 index 0000000..e0208bc --- /dev/null +++ b/test/build-asan/CMakeFiles/carry_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/carry_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/carry_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/carry_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/carry_test.dir/flags.make + +CMakeFiles/carry_test.dir/codegen: +.PHONY : CMakeFiles/carry_test.dir/codegen + +CMakeFiles/carry_test.dir/tests/carry_test.cpp.o: CMakeFiles/carry_test.dir/flags.make +CMakeFiles/carry_test.dir/tests/carry_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/carry_test.cpp +CMakeFiles/carry_test.dir/tests/carry_test.cpp.o: CMakeFiles/carry_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/carry_test.dir/tests/carry_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/carry_test.dir/tests/carry_test.cpp.o -MF CMakeFiles/carry_test.dir/tests/carry_test.cpp.o.d -o CMakeFiles/carry_test.dir/tests/carry_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/carry_test.cpp + +CMakeFiles/carry_test.dir/tests/carry_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/carry_test.dir/tests/carry_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/carry_test.cpp > CMakeFiles/carry_test.dir/tests/carry_test.cpp.i + +CMakeFiles/carry_test.dir/tests/carry_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/carry_test.dir/tests/carry_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/carry_test.cpp -o CMakeFiles/carry_test.dir/tests/carry_test.cpp.s + +# Object files for target carry_test +carry_test_OBJECTS = \ +"CMakeFiles/carry_test.dir/tests/carry_test.cpp.o" + +# External object files for target carry_test +carry_test_EXTERNAL_OBJECTS = + +bin/carry_test: CMakeFiles/carry_test.dir/tests/carry_test.cpp.o +bin/carry_test: CMakeFiles/carry_test.dir/build.make +bin/carry_test: CMakeFiles/carry_test.dir/compiler_depend.ts +bin/carry_test: lib/libgtest_main.a +bin/carry_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/carry_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/carry_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/carry_test: lib/libgtest.a +bin/carry_test: CMakeFiles/carry_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/carry_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/carry_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=carry_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/carry_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=carry_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/carry_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/carry_test.dir/build: bin/carry_test +.PHONY : CMakeFiles/carry_test.dir/build + +CMakeFiles/carry_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/carry_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/carry_test.dir/clean + +CMakeFiles/carry_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/carry_test.dir/DependInfo.cmake "--color=$(COLOR)" carry_test +.PHONY : CMakeFiles/carry_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/carry_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/carry_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..da183e2 --- /dev/null +++ b/test/build-asan/CMakeFiles/carry_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/carry_test.dir/link.d" + "CMakeFiles/carry_test.dir/tests/carry_test.cpp.o" + "CMakeFiles/carry_test.dir/tests/carry_test.cpp.o.d" + "bin/carry_test" + "bin/carry_test.pdb" + "carry_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/carry_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/carry_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/carry_test.dir/compiler_depend.make new file mode 100644 index 0000000..8292869 --- /dev/null +++ b/test/build-asan/CMakeFiles/carry_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for carry_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/carry_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/carry_test.dir/compiler_depend.ts new file mode 100644 index 0000000..bce480a --- /dev/null +++ b/test/build-asan/CMakeFiles/carry_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for carry_test. diff --git a/test/build-asan/CMakeFiles/carry_test.dir/depend.make b/test/build-asan/CMakeFiles/carry_test.dir/depend.make new file mode 100644 index 0000000..7665c91 --- /dev/null +++ b/test/build-asan/CMakeFiles/carry_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for carry_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/carry_test.dir/flags.make b/test/build-asan/CMakeFiles/carry_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/carry_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/carry_test.dir/link.txt b/test/build-asan/CMakeFiles/carry_test.dir/link.txt new file mode 100644 index 0000000..9613a42 --- /dev/null +++ b/test/build-asan/CMakeFiles/carry_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/carry_test.dir/link.d CMakeFiles/carry_test.dir/tests/carry_test.cpp.o -o bin/carry_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/carry_test.dir/progress.make b/test/build-asan/CMakeFiles/carry_test.dir/progress.make new file mode 100644 index 0000000..3bc71dd --- /dev/null +++ b/test/build-asan/CMakeFiles/carry_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 11 + diff --git a/test/build-asan/CMakeFiles/class_sweep_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/class_sweep_test.dir/DependInfo.cmake new file mode 100644 index 0000000..31018be --- /dev/null +++ b/test/build-asan/CMakeFiles/class_sweep_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/class_sweep_test.cpp" "CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o" "gcc" "CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o.d" + "" "bin/class_sweep_test" "gcc" "CMakeFiles/class_sweep_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/class_sweep_test.dir/build.make b/test/build-asan/CMakeFiles/class_sweep_test.dir/build.make new file mode 100644 index 0000000..e0bb6d8 --- /dev/null +++ b/test/build-asan/CMakeFiles/class_sweep_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/class_sweep_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/class_sweep_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/class_sweep_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/class_sweep_test.dir/flags.make + +CMakeFiles/class_sweep_test.dir/codegen: +.PHONY : CMakeFiles/class_sweep_test.dir/codegen + +CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o: CMakeFiles/class_sweep_test.dir/flags.make +CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/class_sweep_test.cpp +CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o: CMakeFiles/class_sweep_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o -MF CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o.d -o CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/class_sweep_test.cpp + +CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/class_sweep_test.cpp > CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.i + +CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/class_sweep_test.cpp -o CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.s + +# Object files for target class_sweep_test +class_sweep_test_OBJECTS = \ +"CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o" + +# External object files for target class_sweep_test +class_sweep_test_EXTERNAL_OBJECTS = + +bin/class_sweep_test: CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o +bin/class_sweep_test: CMakeFiles/class_sweep_test.dir/build.make +bin/class_sweep_test: CMakeFiles/class_sweep_test.dir/compiler_depend.ts +bin/class_sweep_test: lib/libgtest_main.a +bin/class_sweep_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/class_sweep_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/class_sweep_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/class_sweep_test: lib/libgtest.a +bin/class_sweep_test: CMakeFiles/class_sweep_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/class_sweep_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/class_sweep_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=class_sweep_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/class_sweep_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=class_sweep_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/class_sweep_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/class_sweep_test.dir/build: bin/class_sweep_test +.PHONY : CMakeFiles/class_sweep_test.dir/build + +CMakeFiles/class_sweep_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/class_sweep_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/class_sweep_test.dir/clean + +CMakeFiles/class_sweep_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/class_sweep_test.dir/DependInfo.cmake "--color=$(COLOR)" class_sweep_test +.PHONY : CMakeFiles/class_sweep_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/class_sweep_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/class_sweep_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..674bc64 --- /dev/null +++ b/test/build-asan/CMakeFiles/class_sweep_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/class_sweep_test.dir/link.d" + "CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o" + "CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o.d" + "bin/class_sweep_test" + "bin/class_sweep_test.pdb" + "class_sweep_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/class_sweep_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/class_sweep_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/class_sweep_test.dir/compiler_depend.make new file mode 100644 index 0000000..13523ec --- /dev/null +++ b/test/build-asan/CMakeFiles/class_sweep_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for class_sweep_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/class_sweep_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/class_sweep_test.dir/compiler_depend.ts new file mode 100644 index 0000000..6461bfd --- /dev/null +++ b/test/build-asan/CMakeFiles/class_sweep_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for class_sweep_test. diff --git a/test/build-asan/CMakeFiles/class_sweep_test.dir/depend.make b/test/build-asan/CMakeFiles/class_sweep_test.dir/depend.make new file mode 100644 index 0000000..3f7ccdb --- /dev/null +++ b/test/build-asan/CMakeFiles/class_sweep_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for class_sweep_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/class_sweep_test.dir/flags.make b/test/build-asan/CMakeFiles/class_sweep_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/class_sweep_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/class_sweep_test.dir/link.txt b/test/build-asan/CMakeFiles/class_sweep_test.dir/link.txt new file mode 100644 index 0000000..b5e8e15 --- /dev/null +++ b/test/build-asan/CMakeFiles/class_sweep_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/class_sweep_test.dir/link.d CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o -o bin/class_sweep_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/class_sweep_test.dir/progress.make b/test/build-asan/CMakeFiles/class_sweep_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/class_sweep_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/closed_form_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/closed_form_test.dir/DependInfo.cmake new file mode 100644 index 0000000..7a930ef --- /dev/null +++ b/test/build-asan/CMakeFiles/closed_form_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/closed_form_test.cpp" "CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o" "gcc" "CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o.d" + "" "bin/closed_form_test" "gcc" "CMakeFiles/closed_form_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/closed_form_test.dir/build.make b/test/build-asan/CMakeFiles/closed_form_test.dir/build.make new file mode 100644 index 0000000..aee39b1 --- /dev/null +++ b/test/build-asan/CMakeFiles/closed_form_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/closed_form_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/closed_form_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/closed_form_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/closed_form_test.dir/flags.make + +CMakeFiles/closed_form_test.dir/codegen: +.PHONY : CMakeFiles/closed_form_test.dir/codegen + +CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o: CMakeFiles/closed_form_test.dir/flags.make +CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/closed_form_test.cpp +CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o: CMakeFiles/closed_form_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o -MF CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o.d -o CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/closed_form_test.cpp + +CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/closed_form_test.cpp > CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.i + +CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/closed_form_test.cpp -o CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.s + +# Object files for target closed_form_test +closed_form_test_OBJECTS = \ +"CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o" + +# External object files for target closed_form_test +closed_form_test_EXTERNAL_OBJECTS = + +bin/closed_form_test: CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o +bin/closed_form_test: CMakeFiles/closed_form_test.dir/build.make +bin/closed_form_test: CMakeFiles/closed_form_test.dir/compiler_depend.ts +bin/closed_form_test: lib/libgtest_main.a +bin/closed_form_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/closed_form_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/closed_form_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/closed_form_test: lib/libgtest.a +bin/closed_form_test: CMakeFiles/closed_form_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/closed_form_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/closed_form_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=closed_form_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/closed_form_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=closed_form_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/closed_form_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/closed_form_test.dir/build: bin/closed_form_test +.PHONY : CMakeFiles/closed_form_test.dir/build + +CMakeFiles/closed_form_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/closed_form_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/closed_form_test.dir/clean + +CMakeFiles/closed_form_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/closed_form_test.dir/DependInfo.cmake "--color=$(COLOR)" closed_form_test +.PHONY : CMakeFiles/closed_form_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/closed_form_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/closed_form_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..e9a8115 --- /dev/null +++ b/test/build-asan/CMakeFiles/closed_form_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/closed_form_test.dir/link.d" + "CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o" + "CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o.d" + "bin/closed_form_test" + "bin/closed_form_test.pdb" + "closed_form_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/closed_form_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/closed_form_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/closed_form_test.dir/compiler_depend.make new file mode 100644 index 0000000..e802a55 --- /dev/null +++ b/test/build-asan/CMakeFiles/closed_form_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for closed_form_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/closed_form_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/closed_form_test.dir/compiler_depend.ts new file mode 100644 index 0000000..bad2998 --- /dev/null +++ b/test/build-asan/CMakeFiles/closed_form_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for closed_form_test. diff --git a/test/build-asan/CMakeFiles/closed_form_test.dir/depend.make b/test/build-asan/CMakeFiles/closed_form_test.dir/depend.make new file mode 100644 index 0000000..6092dc8 --- /dev/null +++ b/test/build-asan/CMakeFiles/closed_form_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for closed_form_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/closed_form_test.dir/flags.make b/test/build-asan/CMakeFiles/closed_form_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/closed_form_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/closed_form_test.dir/link.txt b/test/build-asan/CMakeFiles/closed_form_test.dir/link.txt new file mode 100644 index 0000000..1cebdfe --- /dev/null +++ b/test/build-asan/CMakeFiles/closed_form_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/closed_form_test.dir/link.d CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o -o bin/closed_form_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/closed_form_test.dir/progress.make b/test/build-asan/CMakeFiles/closed_form_test.dir/progress.make new file mode 100644 index 0000000..e9875e4 --- /dev/null +++ b/test/build-asan/CMakeFiles/closed_form_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 12 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/cmake.check_cache b/test/build-asan/CMakeFiles/cmake.check_cache new file mode 100644 index 0000000..3dccd73 --- /dev/null +++ b/test/build-asan/CMakeFiles/cmake.check_cache @@ -0,0 +1 @@ +# This file is generated by cmake for dependency checking of the CMakeCache.txt file diff --git a/test/build-asan/CMakeFiles/cohort_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/cohort_test.dir/DependInfo.cmake new file mode 100644 index 0000000..1a67d98 --- /dev/null +++ b/test/build-asan/CMakeFiles/cohort_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/cohort_test.cpp" "CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o" "gcc" "CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o.d" + "" "bin/cohort_test" "gcc" "CMakeFiles/cohort_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/cohort_test.dir/build.make b/test/build-asan/CMakeFiles/cohort_test.dir/build.make new file mode 100644 index 0000000..101d066 --- /dev/null +++ b/test/build-asan/CMakeFiles/cohort_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/cohort_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/cohort_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/cohort_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/cohort_test.dir/flags.make + +CMakeFiles/cohort_test.dir/codegen: +.PHONY : CMakeFiles/cohort_test.dir/codegen + +CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o: CMakeFiles/cohort_test.dir/flags.make +CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/cohort_test.cpp +CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o: CMakeFiles/cohort_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o -MF CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o.d -o CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/cohort_test.cpp + +CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/cohort_test.cpp > CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.i + +CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/cohort_test.cpp -o CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.s + +# Object files for target cohort_test +cohort_test_OBJECTS = \ +"CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o" + +# External object files for target cohort_test +cohort_test_EXTERNAL_OBJECTS = + +bin/cohort_test: CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o +bin/cohort_test: CMakeFiles/cohort_test.dir/build.make +bin/cohort_test: CMakeFiles/cohort_test.dir/compiler_depend.ts +bin/cohort_test: lib/libgtest_main.a +bin/cohort_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/cohort_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/cohort_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/cohort_test: lib/libgtest.a +bin/cohort_test: CMakeFiles/cohort_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/cohort_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/cohort_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=cohort_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/cohort_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=cohort_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/cohort_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/cohort_test.dir/build: bin/cohort_test +.PHONY : CMakeFiles/cohort_test.dir/build + +CMakeFiles/cohort_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/cohort_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/cohort_test.dir/clean + +CMakeFiles/cohort_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/cohort_test.dir/DependInfo.cmake "--color=$(COLOR)" cohort_test +.PHONY : CMakeFiles/cohort_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/cohort_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/cohort_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..6f983ce --- /dev/null +++ b/test/build-asan/CMakeFiles/cohort_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/cohort_test.dir/link.d" + "CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o" + "CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o.d" + "bin/cohort_test" + "bin/cohort_test.pdb" + "cohort_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/cohort_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/cohort_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/cohort_test.dir/compiler_depend.make new file mode 100644 index 0000000..1386bf6 --- /dev/null +++ b/test/build-asan/CMakeFiles/cohort_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for cohort_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/cohort_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/cohort_test.dir/compiler_depend.ts new file mode 100644 index 0000000..d0c67da --- /dev/null +++ b/test/build-asan/CMakeFiles/cohort_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for cohort_test. diff --git a/test/build-asan/CMakeFiles/cohort_test.dir/depend.make b/test/build-asan/CMakeFiles/cohort_test.dir/depend.make new file mode 100644 index 0000000..f50a492 --- /dev/null +++ b/test/build-asan/CMakeFiles/cohort_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for cohort_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/cohort_test.dir/flags.make b/test/build-asan/CMakeFiles/cohort_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/cohort_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/cohort_test.dir/link.txt b/test/build-asan/CMakeFiles/cohort_test.dir/link.txt new file mode 100644 index 0000000..3c591e2 --- /dev/null +++ b/test/build-asan/CMakeFiles/cohort_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/cohort_test.dir/link.d CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o -o bin/cohort_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/cohort_test.dir/progress.make b/test/build-asan/CMakeFiles/cohort_test.dir/progress.make new file mode 100644 index 0000000..6c86c2b --- /dev/null +++ b/test/build-asan/CMakeFiles/cohort_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 13 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/compose_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/compose_test.dir/DependInfo.cmake new file mode 100644 index 0000000..40b9109 --- /dev/null +++ b/test/build-asan/CMakeFiles/compose_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/compose_test.cpp" "CMakeFiles/compose_test.dir/tests/compose_test.cpp.o" "gcc" "CMakeFiles/compose_test.dir/tests/compose_test.cpp.o.d" + "" "bin/compose_test" "gcc" "CMakeFiles/compose_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/compose_test.dir/build.make b/test/build-asan/CMakeFiles/compose_test.dir/build.make new file mode 100644 index 0000000..5f2b515 --- /dev/null +++ b/test/build-asan/CMakeFiles/compose_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/compose_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/compose_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/compose_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/compose_test.dir/flags.make + +CMakeFiles/compose_test.dir/codegen: +.PHONY : CMakeFiles/compose_test.dir/codegen + +CMakeFiles/compose_test.dir/tests/compose_test.cpp.o: CMakeFiles/compose_test.dir/flags.make +CMakeFiles/compose_test.dir/tests/compose_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/compose_test.cpp +CMakeFiles/compose_test.dir/tests/compose_test.cpp.o: CMakeFiles/compose_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/compose_test.dir/tests/compose_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/compose_test.dir/tests/compose_test.cpp.o -MF CMakeFiles/compose_test.dir/tests/compose_test.cpp.o.d -o CMakeFiles/compose_test.dir/tests/compose_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/compose_test.cpp + +CMakeFiles/compose_test.dir/tests/compose_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/compose_test.dir/tests/compose_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/compose_test.cpp > CMakeFiles/compose_test.dir/tests/compose_test.cpp.i + +CMakeFiles/compose_test.dir/tests/compose_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/compose_test.dir/tests/compose_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/compose_test.cpp -o CMakeFiles/compose_test.dir/tests/compose_test.cpp.s + +# Object files for target compose_test +compose_test_OBJECTS = \ +"CMakeFiles/compose_test.dir/tests/compose_test.cpp.o" + +# External object files for target compose_test +compose_test_EXTERNAL_OBJECTS = + +bin/compose_test: CMakeFiles/compose_test.dir/tests/compose_test.cpp.o +bin/compose_test: CMakeFiles/compose_test.dir/build.make +bin/compose_test: CMakeFiles/compose_test.dir/compiler_depend.ts +bin/compose_test: lib/libgtest_main.a +bin/compose_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/compose_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/compose_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/compose_test: lib/libgtest.a +bin/compose_test: CMakeFiles/compose_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/compose_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/compose_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=compose_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/compose_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=compose_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/compose_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/compose_test.dir/build: bin/compose_test +.PHONY : CMakeFiles/compose_test.dir/build + +CMakeFiles/compose_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/compose_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/compose_test.dir/clean + +CMakeFiles/compose_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/compose_test.dir/DependInfo.cmake "--color=$(COLOR)" compose_test +.PHONY : CMakeFiles/compose_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/compose_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/compose_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..cd7058b --- /dev/null +++ b/test/build-asan/CMakeFiles/compose_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/compose_test.dir/link.d" + "CMakeFiles/compose_test.dir/tests/compose_test.cpp.o" + "CMakeFiles/compose_test.dir/tests/compose_test.cpp.o.d" + "bin/compose_test" + "bin/compose_test.pdb" + "compose_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/compose_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/compose_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/compose_test.dir/compiler_depend.make new file mode 100644 index 0000000..2890261 --- /dev/null +++ b/test/build-asan/CMakeFiles/compose_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for compose_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/compose_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/compose_test.dir/compiler_depend.ts new file mode 100644 index 0000000..564dcaa --- /dev/null +++ b/test/build-asan/CMakeFiles/compose_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for compose_test. diff --git a/test/build-asan/CMakeFiles/compose_test.dir/depend.make b/test/build-asan/CMakeFiles/compose_test.dir/depend.make new file mode 100644 index 0000000..fa13efc --- /dev/null +++ b/test/build-asan/CMakeFiles/compose_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for compose_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/compose_test.dir/flags.make b/test/build-asan/CMakeFiles/compose_test.dir/flags.make new file mode 100644 index 0000000..96f7b96 --- /dev/null +++ b/test/build-asan/CMakeFiles/compose_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../party -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/compose_test.dir/link.txt b/test/build-asan/CMakeFiles/compose_test.dir/link.txt new file mode 100644 index 0000000..1112ca5 --- /dev/null +++ b/test/build-asan/CMakeFiles/compose_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/compose_test.dir/link.d CMakeFiles/compose_test.dir/tests/compose_test.cpp.o -o bin/compose_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/compose_test.dir/progress.make b/test/build-asan/CMakeFiles/compose_test.dir/progress.make new file mode 100644 index 0000000..2db8a6d --- /dev/null +++ b/test/build-asan/CMakeFiles/compose_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 14 + diff --git a/test/build-asan/CMakeFiles/constant_lut_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/constant_lut_test.dir/DependInfo.cmake new file mode 100644 index 0000000..64836ae --- /dev/null +++ b/test/build-asan/CMakeFiles/constant_lut_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/constant_lut_test.cpp" "CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o" "gcc" "CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o.d" + "" "bin/constant_lut_test" "gcc" "CMakeFiles/constant_lut_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/constant_lut_test.dir/build.make b/test/build-asan/CMakeFiles/constant_lut_test.dir/build.make new file mode 100644 index 0000000..ad5b966 --- /dev/null +++ b/test/build-asan/CMakeFiles/constant_lut_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/constant_lut_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/constant_lut_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/constant_lut_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/constant_lut_test.dir/flags.make + +CMakeFiles/constant_lut_test.dir/codegen: +.PHONY : CMakeFiles/constant_lut_test.dir/codegen + +CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o: CMakeFiles/constant_lut_test.dir/flags.make +CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/constant_lut_test.cpp +CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o: CMakeFiles/constant_lut_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o -MF CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o.d -o CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/constant_lut_test.cpp + +CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/constant_lut_test.cpp > CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.i + +CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/constant_lut_test.cpp -o CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.s + +# Object files for target constant_lut_test +constant_lut_test_OBJECTS = \ +"CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o" + +# External object files for target constant_lut_test +constant_lut_test_EXTERNAL_OBJECTS = + +bin/constant_lut_test: CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o +bin/constant_lut_test: CMakeFiles/constant_lut_test.dir/build.make +bin/constant_lut_test: CMakeFiles/constant_lut_test.dir/compiler_depend.ts +bin/constant_lut_test: lib/libgtest_main.a +bin/constant_lut_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/constant_lut_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/constant_lut_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/constant_lut_test: lib/libgtest.a +bin/constant_lut_test: CMakeFiles/constant_lut_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/constant_lut_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/constant_lut_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=constant_lut_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/constant_lut_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=constant_lut_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/constant_lut_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/constant_lut_test.dir/build: bin/constant_lut_test +.PHONY : CMakeFiles/constant_lut_test.dir/build + +CMakeFiles/constant_lut_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/constant_lut_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/constant_lut_test.dir/clean + +CMakeFiles/constant_lut_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/constant_lut_test.dir/DependInfo.cmake "--color=$(COLOR)" constant_lut_test +.PHONY : CMakeFiles/constant_lut_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/constant_lut_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/constant_lut_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..dda09d7 --- /dev/null +++ b/test/build-asan/CMakeFiles/constant_lut_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/constant_lut_test.dir/link.d" + "CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o" + "CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o.d" + "bin/constant_lut_test" + "bin/constant_lut_test.pdb" + "constant_lut_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/constant_lut_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/constant_lut_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/constant_lut_test.dir/compiler_depend.make new file mode 100644 index 0000000..7236f77 --- /dev/null +++ b/test/build-asan/CMakeFiles/constant_lut_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for constant_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/constant_lut_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/constant_lut_test.dir/compiler_depend.ts new file mode 100644 index 0000000..2a4ced1 --- /dev/null +++ b/test/build-asan/CMakeFiles/constant_lut_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for constant_lut_test. diff --git a/test/build-asan/CMakeFiles/constant_lut_test.dir/depend.make b/test/build-asan/CMakeFiles/constant_lut_test.dir/depend.make new file mode 100644 index 0000000..084391a --- /dev/null +++ b/test/build-asan/CMakeFiles/constant_lut_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for constant_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/constant_lut_test.dir/flags.make b/test/build-asan/CMakeFiles/constant_lut_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/constant_lut_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/constant_lut_test.dir/link.txt b/test/build-asan/CMakeFiles/constant_lut_test.dir/link.txt new file mode 100644 index 0000000..4f7c5e4 --- /dev/null +++ b/test/build-asan/CMakeFiles/constant_lut_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/constant_lut_test.dir/link.d CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o -o bin/constant_lut_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/constant_lut_test.dir/progress.make b/test/build-asan/CMakeFiles/constant_lut_test.dir/progress.make new file mode 100644 index 0000000..52b6d64 --- /dev/null +++ b/test/build-asan/CMakeFiles/constant_lut_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 15 + diff --git a/test/build-asan/CMakeFiles/constrained_cmp_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/DependInfo.cmake new file mode 100644 index 0000000..bf469b9 --- /dev/null +++ b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/constrained_cmp_test.cpp" "CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o" "gcc" "CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o.d" + "" "bin/constrained_cmp_test" "gcc" "CMakeFiles/constrained_cmp_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/constrained_cmp_test.dir/build.make b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/build.make new file mode 100644 index 0000000..f89c3e5 --- /dev/null +++ b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/constrained_cmp_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/constrained_cmp_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/constrained_cmp_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/constrained_cmp_test.dir/flags.make + +CMakeFiles/constrained_cmp_test.dir/codegen: +.PHONY : CMakeFiles/constrained_cmp_test.dir/codegen + +CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o: CMakeFiles/constrained_cmp_test.dir/flags.make +CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/constrained_cmp_test.cpp +CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o: CMakeFiles/constrained_cmp_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o -MF CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o.d -o CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/constrained_cmp_test.cpp + +CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/constrained_cmp_test.cpp > CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.i + +CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/constrained_cmp_test.cpp -o CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.s + +# Object files for target constrained_cmp_test +constrained_cmp_test_OBJECTS = \ +"CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o" + +# External object files for target constrained_cmp_test +constrained_cmp_test_EXTERNAL_OBJECTS = + +bin/constrained_cmp_test: CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o +bin/constrained_cmp_test: CMakeFiles/constrained_cmp_test.dir/build.make +bin/constrained_cmp_test: CMakeFiles/constrained_cmp_test.dir/compiler_depend.ts +bin/constrained_cmp_test: lib/libgtest_main.a +bin/constrained_cmp_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/constrained_cmp_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/constrained_cmp_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/constrained_cmp_test: lib/libgtest.a +bin/constrained_cmp_test: CMakeFiles/constrained_cmp_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/constrained_cmp_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/constrained_cmp_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=constrained_cmp_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/constrained_cmp_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=constrained_cmp_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/constrained_cmp_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/constrained_cmp_test.dir/build: bin/constrained_cmp_test +.PHONY : CMakeFiles/constrained_cmp_test.dir/build + +CMakeFiles/constrained_cmp_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/constrained_cmp_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/constrained_cmp_test.dir/clean + +CMakeFiles/constrained_cmp_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/constrained_cmp_test.dir/DependInfo.cmake "--color=$(COLOR)" constrained_cmp_test +.PHONY : CMakeFiles/constrained_cmp_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/constrained_cmp_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..3abc081 --- /dev/null +++ b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/constrained_cmp_test.dir/link.d" + "CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o" + "CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o.d" + "bin/constrained_cmp_test" + "bin/constrained_cmp_test.pdb" + "constrained_cmp_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/constrained_cmp_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/constrained_cmp_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/compiler_depend.make new file mode 100644 index 0000000..e9c1d3b --- /dev/null +++ b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for constrained_cmp_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/constrained_cmp_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/compiler_depend.ts new file mode 100644 index 0000000..c2622cb --- /dev/null +++ b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for constrained_cmp_test. diff --git a/test/build-asan/CMakeFiles/constrained_cmp_test.dir/depend.make b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/depend.make new file mode 100644 index 0000000..a120b67 --- /dev/null +++ b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for constrained_cmp_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/constrained_cmp_test.dir/flags.make b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/constrained_cmp_test.dir/link.txt b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/link.txt new file mode 100644 index 0000000..c4b2e2d --- /dev/null +++ b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/constrained_cmp_test.dir/link.d CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o -o bin/constrained_cmp_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/constrained_cmp_test.dir/progress.make b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/progress.make new file mode 100644 index 0000000..2e09f08 --- /dev/null +++ b/test/build-asan/CMakeFiles/constrained_cmp_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 16 + diff --git a/test/build-asan/CMakeFiles/context_blast_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/context_blast_test.dir/DependInfo.cmake new file mode 100644 index 0000000..a995edf --- /dev/null +++ b/test/build-asan/CMakeFiles/context_blast_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/context_blast_test.cpp" "CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o" "gcc" "CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o.d" + "" "bin/context_blast_test" "gcc" "CMakeFiles/context_blast_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/context_blast_test.dir/build.make b/test/build-asan/CMakeFiles/context_blast_test.dir/build.make new file mode 100644 index 0000000..b375748 --- /dev/null +++ b/test/build-asan/CMakeFiles/context_blast_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/context_blast_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/context_blast_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/context_blast_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/context_blast_test.dir/flags.make + +CMakeFiles/context_blast_test.dir/codegen: +.PHONY : CMakeFiles/context_blast_test.dir/codegen + +CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o: CMakeFiles/context_blast_test.dir/flags.make +CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/context_blast_test.cpp +CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o: CMakeFiles/context_blast_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o -MF CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o.d -o CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/context_blast_test.cpp + +CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/context_blast_test.cpp > CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.i + +CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/context_blast_test.cpp -o CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.s + +# Object files for target context_blast_test +context_blast_test_OBJECTS = \ +"CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o" + +# External object files for target context_blast_test +context_blast_test_EXTERNAL_OBJECTS = + +bin/context_blast_test: CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o +bin/context_blast_test: CMakeFiles/context_blast_test.dir/build.make +bin/context_blast_test: CMakeFiles/context_blast_test.dir/compiler_depend.ts +bin/context_blast_test: lib/libgtest_main.a +bin/context_blast_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/context_blast_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/context_blast_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/context_blast_test: lib/libgtest.a +bin/context_blast_test: CMakeFiles/context_blast_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/context_blast_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/context_blast_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=context_blast_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/context_blast_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=context_blast_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/context_blast_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/context_blast_test.dir/build: bin/context_blast_test +.PHONY : CMakeFiles/context_blast_test.dir/build + +CMakeFiles/context_blast_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/context_blast_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/context_blast_test.dir/clean + +CMakeFiles/context_blast_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/context_blast_test.dir/DependInfo.cmake "--color=$(COLOR)" context_blast_test +.PHONY : CMakeFiles/context_blast_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/context_blast_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/context_blast_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..a8c870d --- /dev/null +++ b/test/build-asan/CMakeFiles/context_blast_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/context_blast_test.dir/link.d" + "CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o" + "CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o.d" + "bin/context_blast_test" + "bin/context_blast_test.pdb" + "context_blast_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/context_blast_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/context_blast_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/context_blast_test.dir/compiler_depend.make new file mode 100644 index 0000000..dc8acb3 --- /dev/null +++ b/test/build-asan/CMakeFiles/context_blast_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for context_blast_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/context_blast_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/context_blast_test.dir/compiler_depend.ts new file mode 100644 index 0000000..f381714 --- /dev/null +++ b/test/build-asan/CMakeFiles/context_blast_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for context_blast_test. diff --git a/test/build-asan/CMakeFiles/context_blast_test.dir/depend.make b/test/build-asan/CMakeFiles/context_blast_test.dir/depend.make new file mode 100644 index 0000000..5fbc7d9 --- /dev/null +++ b/test/build-asan/CMakeFiles/context_blast_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for context_blast_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/context_blast_test.dir/flags.make b/test/build-asan/CMakeFiles/context_blast_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/context_blast_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/context_blast_test.dir/link.txt b/test/build-asan/CMakeFiles/context_blast_test.dir/link.txt new file mode 100644 index 0000000..8552d6e --- /dev/null +++ b/test/build-asan/CMakeFiles/context_blast_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/context_blast_test.dir/link.d CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o -o bin/context_blast_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/context_blast_test.dir/progress.make b/test/build-asan/CMakeFiles/context_blast_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/context_blast_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/corner_gaps_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/corner_gaps_test.dir/DependInfo.cmake new file mode 100644 index 0000000..99101f0 --- /dev/null +++ b/test/build-asan/CMakeFiles/corner_gaps_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/corner_gaps_test.cpp" "CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o" "gcc" "CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o.d" + "" "bin/corner_gaps_test" "gcc" "CMakeFiles/corner_gaps_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/corner_gaps_test.dir/build.make b/test/build-asan/CMakeFiles/corner_gaps_test.dir/build.make new file mode 100644 index 0000000..c4d5c81 --- /dev/null +++ b/test/build-asan/CMakeFiles/corner_gaps_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/corner_gaps_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/corner_gaps_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/corner_gaps_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/corner_gaps_test.dir/flags.make + +CMakeFiles/corner_gaps_test.dir/codegen: +.PHONY : CMakeFiles/corner_gaps_test.dir/codegen + +CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o: CMakeFiles/corner_gaps_test.dir/flags.make +CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/corner_gaps_test.cpp +CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o: CMakeFiles/corner_gaps_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o -MF CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o.d -o CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/corner_gaps_test.cpp + +CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/corner_gaps_test.cpp > CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.i + +CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/corner_gaps_test.cpp -o CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.s + +# Object files for target corner_gaps_test +corner_gaps_test_OBJECTS = \ +"CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o" + +# External object files for target corner_gaps_test +corner_gaps_test_EXTERNAL_OBJECTS = + +bin/corner_gaps_test: CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o +bin/corner_gaps_test: CMakeFiles/corner_gaps_test.dir/build.make +bin/corner_gaps_test: CMakeFiles/corner_gaps_test.dir/compiler_depend.ts +bin/corner_gaps_test: lib/libgtest_main.a +bin/corner_gaps_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/corner_gaps_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/corner_gaps_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/corner_gaps_test: lib/libgtest.a +bin/corner_gaps_test: CMakeFiles/corner_gaps_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/corner_gaps_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/corner_gaps_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=corner_gaps_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/corner_gaps_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=corner_gaps_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/corner_gaps_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/corner_gaps_test.dir/build: bin/corner_gaps_test +.PHONY : CMakeFiles/corner_gaps_test.dir/build + +CMakeFiles/corner_gaps_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/corner_gaps_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/corner_gaps_test.dir/clean + +CMakeFiles/corner_gaps_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/corner_gaps_test.dir/DependInfo.cmake "--color=$(COLOR)" corner_gaps_test +.PHONY : CMakeFiles/corner_gaps_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/corner_gaps_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/corner_gaps_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..6c34e09 --- /dev/null +++ b/test/build-asan/CMakeFiles/corner_gaps_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/corner_gaps_test.dir/link.d" + "CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o" + "CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o.d" + "bin/corner_gaps_test" + "bin/corner_gaps_test.pdb" + "corner_gaps_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/corner_gaps_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/corner_gaps_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/corner_gaps_test.dir/compiler_depend.make new file mode 100644 index 0000000..68aa0f5 --- /dev/null +++ b/test/build-asan/CMakeFiles/corner_gaps_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for corner_gaps_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/corner_gaps_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/corner_gaps_test.dir/compiler_depend.ts new file mode 100644 index 0000000..5b9056d --- /dev/null +++ b/test/build-asan/CMakeFiles/corner_gaps_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for corner_gaps_test. diff --git a/test/build-asan/CMakeFiles/corner_gaps_test.dir/depend.make b/test/build-asan/CMakeFiles/corner_gaps_test.dir/depend.make new file mode 100644 index 0000000..39f182d --- /dev/null +++ b/test/build-asan/CMakeFiles/corner_gaps_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for corner_gaps_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/corner_gaps_test.dir/flags.make b/test/build-asan/CMakeFiles/corner_gaps_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/corner_gaps_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/corner_gaps_test.dir/link.txt b/test/build-asan/CMakeFiles/corner_gaps_test.dir/link.txt new file mode 100644 index 0000000..05b6a42 --- /dev/null +++ b/test/build-asan/CMakeFiles/corner_gaps_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/corner_gaps_test.dir/link.d CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o -o bin/corner_gaps_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/corner_gaps_test.dir/progress.make b/test/build-asan/CMakeFiles/corner_gaps_test.dir/progress.make new file mode 100644 index 0000000..e8f20b7 --- /dev/null +++ b/test/build-asan/CMakeFiles/corner_gaps_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 17 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/defer_eval_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/defer_eval_test.dir/DependInfo.cmake new file mode 100644 index 0000000..532f65d --- /dev/null +++ b/test/build-asan/CMakeFiles/defer_eval_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/defer_eval_test.cpp" "CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o" "gcc" "CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o.d" + "" "bin/defer_eval_test" "gcc" "CMakeFiles/defer_eval_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/defer_eval_test.dir/build.make b/test/build-asan/CMakeFiles/defer_eval_test.dir/build.make new file mode 100644 index 0000000..5c500ed --- /dev/null +++ b/test/build-asan/CMakeFiles/defer_eval_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/defer_eval_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/defer_eval_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/defer_eval_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/defer_eval_test.dir/flags.make + +CMakeFiles/defer_eval_test.dir/codegen: +.PHONY : CMakeFiles/defer_eval_test.dir/codegen + +CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o: CMakeFiles/defer_eval_test.dir/flags.make +CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/defer_eval_test.cpp +CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o: CMakeFiles/defer_eval_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o -MF CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o.d -o CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/defer_eval_test.cpp + +CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/defer_eval_test.cpp > CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.i + +CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/defer_eval_test.cpp -o CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.s + +# Object files for target defer_eval_test +defer_eval_test_OBJECTS = \ +"CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o" + +# External object files for target defer_eval_test +defer_eval_test_EXTERNAL_OBJECTS = + +bin/defer_eval_test: CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o +bin/defer_eval_test: CMakeFiles/defer_eval_test.dir/build.make +bin/defer_eval_test: CMakeFiles/defer_eval_test.dir/compiler_depend.ts +bin/defer_eval_test: lib/libgtest_main.a +bin/defer_eval_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/defer_eval_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/defer_eval_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/defer_eval_test: lib/libgtest.a +bin/defer_eval_test: CMakeFiles/defer_eval_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/defer_eval_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/defer_eval_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=defer_eval_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/defer_eval_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=defer_eval_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/defer_eval_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/defer_eval_test.dir/build: bin/defer_eval_test +.PHONY : CMakeFiles/defer_eval_test.dir/build + +CMakeFiles/defer_eval_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/defer_eval_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/defer_eval_test.dir/clean + +CMakeFiles/defer_eval_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/defer_eval_test.dir/DependInfo.cmake "--color=$(COLOR)" defer_eval_test +.PHONY : CMakeFiles/defer_eval_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/defer_eval_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/defer_eval_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..03f8908 --- /dev/null +++ b/test/build-asan/CMakeFiles/defer_eval_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/defer_eval_test.dir/link.d" + "CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o" + "CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o.d" + "bin/defer_eval_test" + "bin/defer_eval_test.pdb" + "defer_eval_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/defer_eval_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/defer_eval_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/defer_eval_test.dir/compiler_depend.make new file mode 100644 index 0000000..a5f7aa2 --- /dev/null +++ b/test/build-asan/CMakeFiles/defer_eval_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for defer_eval_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/defer_eval_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/defer_eval_test.dir/compiler_depend.ts new file mode 100644 index 0000000..bf19635 --- /dev/null +++ b/test/build-asan/CMakeFiles/defer_eval_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for defer_eval_test. diff --git a/test/build-asan/CMakeFiles/defer_eval_test.dir/depend.make b/test/build-asan/CMakeFiles/defer_eval_test.dir/depend.make new file mode 100644 index 0000000..034f160 --- /dev/null +++ b/test/build-asan/CMakeFiles/defer_eval_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for defer_eval_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/defer_eval_test.dir/flags.make b/test/build-asan/CMakeFiles/defer_eval_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/defer_eval_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/defer_eval_test.dir/link.txt b/test/build-asan/CMakeFiles/defer_eval_test.dir/link.txt new file mode 100644 index 0000000..5e00824 --- /dev/null +++ b/test/build-asan/CMakeFiles/defer_eval_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/defer_eval_test.dir/link.d CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o -o bin/defer_eval_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/defer_eval_test.dir/progress.make b/test/build-asan/CMakeFiles/defer_eval_test.dir/progress.make new file mode 100644 index 0000000..98912bb --- /dev/null +++ b/test/build-asan/CMakeFiles/defer_eval_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 18 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/domain128_point_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/domain128_point_test.dir/DependInfo.cmake new file mode 100644 index 0000000..9313ac7 --- /dev/null +++ b/test/build-asan/CMakeFiles/domain128_point_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/domain128_point_test.cpp" "CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o" "gcc" "CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o.d" + "" "bin/domain128_point_test" "gcc" "CMakeFiles/domain128_point_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/domain128_point_test.dir/build.make b/test/build-asan/CMakeFiles/domain128_point_test.dir/build.make new file mode 100644 index 0000000..de377f0 --- /dev/null +++ b/test/build-asan/CMakeFiles/domain128_point_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/domain128_point_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/domain128_point_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/domain128_point_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/domain128_point_test.dir/flags.make + +CMakeFiles/domain128_point_test.dir/codegen: +.PHONY : CMakeFiles/domain128_point_test.dir/codegen + +CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o: CMakeFiles/domain128_point_test.dir/flags.make +CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/domain128_point_test.cpp +CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o: CMakeFiles/domain128_point_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o -MF CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o.d -o CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/domain128_point_test.cpp + +CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/domain128_point_test.cpp > CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.i + +CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/domain128_point_test.cpp -o CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.s + +# Object files for target domain128_point_test +domain128_point_test_OBJECTS = \ +"CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o" + +# External object files for target domain128_point_test +domain128_point_test_EXTERNAL_OBJECTS = + +bin/domain128_point_test: CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o +bin/domain128_point_test: CMakeFiles/domain128_point_test.dir/build.make +bin/domain128_point_test: CMakeFiles/domain128_point_test.dir/compiler_depend.ts +bin/domain128_point_test: lib/libgtest_main.a +bin/domain128_point_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/domain128_point_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/domain128_point_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/domain128_point_test: lib/libgtest.a +bin/domain128_point_test: CMakeFiles/domain128_point_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/domain128_point_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/domain128_point_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=domain128_point_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/domain128_point_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=domain128_point_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/domain128_point_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/domain128_point_test.dir/build: bin/domain128_point_test +.PHONY : CMakeFiles/domain128_point_test.dir/build + +CMakeFiles/domain128_point_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/domain128_point_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/domain128_point_test.dir/clean + +CMakeFiles/domain128_point_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/domain128_point_test.dir/DependInfo.cmake "--color=$(COLOR)" domain128_point_test +.PHONY : CMakeFiles/domain128_point_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/domain128_point_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/domain128_point_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..c1739df --- /dev/null +++ b/test/build-asan/CMakeFiles/domain128_point_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/domain128_point_test.dir/link.d" + "CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o" + "CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o.d" + "bin/domain128_point_test" + "bin/domain128_point_test.pdb" + "domain128_point_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/domain128_point_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/domain128_point_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/domain128_point_test.dir/compiler_depend.make new file mode 100644 index 0000000..0f94805 --- /dev/null +++ b/test/build-asan/CMakeFiles/domain128_point_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for domain128_point_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/domain128_point_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/domain128_point_test.dir/compiler_depend.ts new file mode 100644 index 0000000..b7001e6 --- /dev/null +++ b/test/build-asan/CMakeFiles/domain128_point_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for domain128_point_test. diff --git a/test/build-asan/CMakeFiles/domain128_point_test.dir/depend.make b/test/build-asan/CMakeFiles/domain128_point_test.dir/depend.make new file mode 100644 index 0000000..93a79bd --- /dev/null +++ b/test/build-asan/CMakeFiles/domain128_point_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for domain128_point_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/domain128_point_test.dir/flags.make b/test/build-asan/CMakeFiles/domain128_point_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/domain128_point_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/domain128_point_test.dir/link.txt b/test/build-asan/CMakeFiles/domain128_point_test.dir/link.txt new file mode 100644 index 0000000..d4106e8 --- /dev/null +++ b/test/build-asan/CMakeFiles/domain128_point_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/domain128_point_test.dir/link.d CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o -o bin/domain128_point_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/domain128_point_test.dir/progress.make b/test/build-asan/CMakeFiles/domain128_point_test.dir/progress.make new file mode 100644 index 0000000..f6b9cd7 --- /dev/null +++ b/test/build-asan/CMakeFiles/domain128_point_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 19 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/dpf3_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/dpf3_test.dir/DependInfo.cmake new file mode 100644 index 0000000..4299224 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf3_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/dpf3_test.cpp" "CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o" "gcc" "CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o.d" + "" "bin/dpf3_test" "gcc" "CMakeFiles/dpf3_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/dpf3_test.dir/build.make b/test/build-asan/CMakeFiles/dpf3_test.dir/build.make new file mode 100644 index 0000000..3489788 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf3_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/dpf3_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/dpf3_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/dpf3_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/dpf3_test.dir/flags.make + +CMakeFiles/dpf3_test.dir/codegen: +.PHONY : CMakeFiles/dpf3_test.dir/codegen + +CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o: CMakeFiles/dpf3_test.dir/flags.make +CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/dpf3_test.cpp +CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o: CMakeFiles/dpf3_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o -MF CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o.d -o CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/dpf3_test.cpp + +CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/dpf3_test.cpp > CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.i + +CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/dpf3_test.cpp -o CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.s + +# Object files for target dpf3_test +dpf3_test_OBJECTS = \ +"CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o" + +# External object files for target dpf3_test +dpf3_test_EXTERNAL_OBJECTS = + +bin/dpf3_test: CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o +bin/dpf3_test: CMakeFiles/dpf3_test.dir/build.make +bin/dpf3_test: CMakeFiles/dpf3_test.dir/compiler_depend.ts +bin/dpf3_test: lib/libgtest_main.a +bin/dpf3_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/dpf3_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/dpf3_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/dpf3_test: lib/libgtest.a +bin/dpf3_test: CMakeFiles/dpf3_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/dpf3_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/dpf3_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=dpf3_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/dpf3_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=dpf3_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dpf3_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/dpf3_test.dir/build: bin/dpf3_test +.PHONY : CMakeFiles/dpf3_test.dir/build + +CMakeFiles/dpf3_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/dpf3_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/dpf3_test.dir/clean + +CMakeFiles/dpf3_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/dpf3_test.dir/DependInfo.cmake "--color=$(COLOR)" dpf3_test +.PHONY : CMakeFiles/dpf3_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/dpf3_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/dpf3_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..8818b84 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf3_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/dpf3_test.dir/link.d" + "CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o" + "CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o.d" + "bin/dpf3_test" + "bin/dpf3_test.pdb" + "dpf3_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/dpf3_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/dpf3_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/dpf3_test.dir/compiler_depend.make new file mode 100644 index 0000000..75e9a58 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf3_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for dpf3_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/dpf3_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/dpf3_test.dir/compiler_depend.ts new file mode 100644 index 0000000..abf7a44 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf3_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for dpf3_test. diff --git a/test/build-asan/CMakeFiles/dpf3_test.dir/depend.make b/test/build-asan/CMakeFiles/dpf3_test.dir/depend.make new file mode 100644 index 0000000..3cff8ad --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf3_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for dpf3_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/dpf3_test.dir/flags.make b/test/build-asan/CMakeFiles/dpf3_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf3_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/dpf3_test.dir/link.txt b/test/build-asan/CMakeFiles/dpf3_test.dir/link.txt new file mode 100644 index 0000000..75a9da7 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf3_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/dpf3_test.dir/link.d CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o -o bin/dpf3_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/dpf3_test.dir/progress.make b/test/build-asan/CMakeFiles/dpf3_test.dir/progress.make new file mode 100644 index 0000000..ca90fb6 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf3_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 20 + diff --git a/test/build-asan/CMakeFiles/dpf_key_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/dpf_key_test.dir/DependInfo.cmake new file mode 100644 index 0000000..a02e40f --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf_key_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/dpf_key_test.cpp" "CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o" "gcc" "CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o.d" + "" "bin/dpf_key_test" "gcc" "CMakeFiles/dpf_key_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/dpf_key_test.dir/build.make b/test/build-asan/CMakeFiles/dpf_key_test.dir/build.make new file mode 100644 index 0000000..7384e64 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf_key_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/dpf_key_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/dpf_key_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/dpf_key_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/dpf_key_test.dir/flags.make + +CMakeFiles/dpf_key_test.dir/codegen: +.PHONY : CMakeFiles/dpf_key_test.dir/codegen + +CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o: CMakeFiles/dpf_key_test.dir/flags.make +CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/dpf_key_test.cpp +CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o: CMakeFiles/dpf_key_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o -MF CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o.d -o CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/dpf_key_test.cpp + +CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/dpf_key_test.cpp > CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.i + +CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/dpf_key_test.cpp -o CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.s + +# Object files for target dpf_key_test +dpf_key_test_OBJECTS = \ +"CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o" + +# External object files for target dpf_key_test +dpf_key_test_EXTERNAL_OBJECTS = + +bin/dpf_key_test: CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o +bin/dpf_key_test: CMakeFiles/dpf_key_test.dir/build.make +bin/dpf_key_test: CMakeFiles/dpf_key_test.dir/compiler_depend.ts +bin/dpf_key_test: lib/libgtest_main.a +bin/dpf_key_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/dpf_key_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/dpf_key_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/dpf_key_test: lib/libgtest.a +bin/dpf_key_test: CMakeFiles/dpf_key_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/dpf_key_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/dpf_key_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=dpf_key_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/dpf_key_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=dpf_key_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dpf_key_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/dpf_key_test.dir/build: bin/dpf_key_test +.PHONY : CMakeFiles/dpf_key_test.dir/build + +CMakeFiles/dpf_key_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/dpf_key_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/dpf_key_test.dir/clean + +CMakeFiles/dpf_key_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/dpf_key_test.dir/DependInfo.cmake "--color=$(COLOR)" dpf_key_test +.PHONY : CMakeFiles/dpf_key_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/dpf_key_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/dpf_key_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..1d13922 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf_key_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/dpf_key_test.dir/link.d" + "CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o" + "CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o.d" + "bin/dpf_key_test" + "bin/dpf_key_test.pdb" + "dpf_key_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/dpf_key_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/dpf_key_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/dpf_key_test.dir/compiler_depend.make new file mode 100644 index 0000000..9b343aa --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf_key_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for dpf_key_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/dpf_key_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/dpf_key_test.dir/compiler_depend.ts new file mode 100644 index 0000000..8cdc922 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf_key_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for dpf_key_test. diff --git a/test/build-asan/CMakeFiles/dpf_key_test.dir/depend.make b/test/build-asan/CMakeFiles/dpf_key_test.dir/depend.make new file mode 100644 index 0000000..c01ab65 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf_key_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for dpf_key_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/dpf_key_test.dir/flags.make b/test/build-asan/CMakeFiles/dpf_key_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf_key_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/dpf_key_test.dir/link.txt b/test/build-asan/CMakeFiles/dpf_key_test.dir/link.txt new file mode 100644 index 0000000..ec4bc54 --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf_key_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/dpf_key_test.dir/link.d CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o -o bin/dpf_key_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/dpf_key_test.dir/progress.make b/test/build-asan/CMakeFiles/dpf_key_test.dir/progress.make new file mode 100644 index 0000000..4d2334f --- /dev/null +++ b/test/build-asan/CMakeFiles/dpf_key_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 21 + diff --git a/test/build-asan/CMakeFiles/dwt_lut_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/dwt_lut_test.dir/DependInfo.cmake new file mode 100644 index 0000000..4931000 --- /dev/null +++ b/test/build-asan/CMakeFiles/dwt_lut_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/dwt_lut_test.cpp" "CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o" "gcc" "CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o.d" + "" "bin/dwt_lut_test" "gcc" "CMakeFiles/dwt_lut_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/dwt_lut_test.dir/build.make b/test/build-asan/CMakeFiles/dwt_lut_test.dir/build.make new file mode 100644 index 0000000..fa19bb6 --- /dev/null +++ b/test/build-asan/CMakeFiles/dwt_lut_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/dwt_lut_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/dwt_lut_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/dwt_lut_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/dwt_lut_test.dir/flags.make + +CMakeFiles/dwt_lut_test.dir/codegen: +.PHONY : CMakeFiles/dwt_lut_test.dir/codegen + +CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o: CMakeFiles/dwt_lut_test.dir/flags.make +CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/dwt_lut_test.cpp +CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o: CMakeFiles/dwt_lut_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o -MF CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o.d -o CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/dwt_lut_test.cpp + +CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/dwt_lut_test.cpp > CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.i + +CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/dwt_lut_test.cpp -o CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.s + +# Object files for target dwt_lut_test +dwt_lut_test_OBJECTS = \ +"CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o" + +# External object files for target dwt_lut_test +dwt_lut_test_EXTERNAL_OBJECTS = + +bin/dwt_lut_test: CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o +bin/dwt_lut_test: CMakeFiles/dwt_lut_test.dir/build.make +bin/dwt_lut_test: CMakeFiles/dwt_lut_test.dir/compiler_depend.ts +bin/dwt_lut_test: lib/libgtest_main.a +bin/dwt_lut_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/dwt_lut_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/dwt_lut_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/dwt_lut_test: lib/libgtest.a +bin/dwt_lut_test: CMakeFiles/dwt_lut_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/dwt_lut_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/dwt_lut_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=dwt_lut_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/dwt_lut_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=dwt_lut_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dwt_lut_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/dwt_lut_test.dir/build: bin/dwt_lut_test +.PHONY : CMakeFiles/dwt_lut_test.dir/build + +CMakeFiles/dwt_lut_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/dwt_lut_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/dwt_lut_test.dir/clean + +CMakeFiles/dwt_lut_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/dwt_lut_test.dir/DependInfo.cmake "--color=$(COLOR)" dwt_lut_test +.PHONY : CMakeFiles/dwt_lut_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/dwt_lut_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/dwt_lut_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..f5138d2 --- /dev/null +++ b/test/build-asan/CMakeFiles/dwt_lut_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/dwt_lut_test.dir/link.d" + "CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o" + "CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o.d" + "bin/dwt_lut_test" + "bin/dwt_lut_test.pdb" + "dwt_lut_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/dwt_lut_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/dwt_lut_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/dwt_lut_test.dir/compiler_depend.make new file mode 100644 index 0000000..36dd0b9 --- /dev/null +++ b/test/build-asan/CMakeFiles/dwt_lut_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for dwt_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/dwt_lut_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/dwt_lut_test.dir/compiler_depend.ts new file mode 100644 index 0000000..98486b8 --- /dev/null +++ b/test/build-asan/CMakeFiles/dwt_lut_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for dwt_lut_test. diff --git a/test/build-asan/CMakeFiles/dwt_lut_test.dir/depend.make b/test/build-asan/CMakeFiles/dwt_lut_test.dir/depend.make new file mode 100644 index 0000000..6779f0b --- /dev/null +++ b/test/build-asan/CMakeFiles/dwt_lut_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for dwt_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/dwt_lut_test.dir/flags.make b/test/build-asan/CMakeFiles/dwt_lut_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/dwt_lut_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/dwt_lut_test.dir/link.txt b/test/build-asan/CMakeFiles/dwt_lut_test.dir/link.txt new file mode 100644 index 0000000..551ab5c --- /dev/null +++ b/test/build-asan/CMakeFiles/dwt_lut_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/dwt_lut_test.dir/link.d CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o -o bin/dwt_lut_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/dwt_lut_test.dir/progress.make b/test/build-asan/CMakeFiles/dwt_lut_test.dir/progress.make new file mode 100644 index 0000000..5716e39 --- /dev/null +++ b/test/build-asan/CMakeFiles/dwt_lut_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 22 + diff --git a/test/build-asan/CMakeFiles/dyadic_lut_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/DependInfo.cmake new file mode 100644 index 0000000..cd3e99f --- /dev/null +++ b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/dyadic_lut_test.cpp" "CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o" "gcc" "CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o.d" + "" "bin/dyadic_lut_test" "gcc" "CMakeFiles/dyadic_lut_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/dyadic_lut_test.dir/build.make b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/build.make new file mode 100644 index 0000000..b110f78 --- /dev/null +++ b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/dyadic_lut_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/dyadic_lut_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/dyadic_lut_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/dyadic_lut_test.dir/flags.make + +CMakeFiles/dyadic_lut_test.dir/codegen: +.PHONY : CMakeFiles/dyadic_lut_test.dir/codegen + +CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o: CMakeFiles/dyadic_lut_test.dir/flags.make +CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/dyadic_lut_test.cpp +CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o: CMakeFiles/dyadic_lut_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o -MF CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o.d -o CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/dyadic_lut_test.cpp + +CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/dyadic_lut_test.cpp > CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.i + +CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/dyadic_lut_test.cpp -o CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.s + +# Object files for target dyadic_lut_test +dyadic_lut_test_OBJECTS = \ +"CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o" + +# External object files for target dyadic_lut_test +dyadic_lut_test_EXTERNAL_OBJECTS = + +bin/dyadic_lut_test: CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o +bin/dyadic_lut_test: CMakeFiles/dyadic_lut_test.dir/build.make +bin/dyadic_lut_test: CMakeFiles/dyadic_lut_test.dir/compiler_depend.ts +bin/dyadic_lut_test: lib/libgtest_main.a +bin/dyadic_lut_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/dyadic_lut_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/dyadic_lut_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/dyadic_lut_test: lib/libgtest.a +bin/dyadic_lut_test: CMakeFiles/dyadic_lut_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/dyadic_lut_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/dyadic_lut_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=dyadic_lut_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/dyadic_lut_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=dyadic_lut_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dyadic_lut_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/dyadic_lut_test.dir/build: bin/dyadic_lut_test +.PHONY : CMakeFiles/dyadic_lut_test.dir/build + +CMakeFiles/dyadic_lut_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/dyadic_lut_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/dyadic_lut_test.dir/clean + +CMakeFiles/dyadic_lut_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/dyadic_lut_test.dir/DependInfo.cmake "--color=$(COLOR)" dyadic_lut_test +.PHONY : CMakeFiles/dyadic_lut_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/dyadic_lut_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..7463cef --- /dev/null +++ b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/dyadic_lut_test.dir/link.d" + "CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o" + "CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o.d" + "bin/dyadic_lut_test" + "bin/dyadic_lut_test.pdb" + "dyadic_lut_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/dyadic_lut_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/dyadic_lut_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/compiler_depend.make new file mode 100644 index 0000000..cab3ac4 --- /dev/null +++ b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for dyadic_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/dyadic_lut_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/compiler_depend.ts new file mode 100644 index 0000000..badcb3a --- /dev/null +++ b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for dyadic_lut_test. diff --git a/test/build-asan/CMakeFiles/dyadic_lut_test.dir/depend.make b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/depend.make new file mode 100644 index 0000000..0c80b6c --- /dev/null +++ b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for dyadic_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/dyadic_lut_test.dir/flags.make b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/dyadic_lut_test.dir/link.txt b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/link.txt new file mode 100644 index 0000000..2adae6c --- /dev/null +++ b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/dyadic_lut_test.dir/link.d CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o -o bin/dyadic_lut_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/dyadic_lut_test.dir/progress.make b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/dyadic_lut_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/easy_lut_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/easy_lut_test.dir/DependInfo.cmake new file mode 100644 index 0000000..0c86510 --- /dev/null +++ b/test/build-asan/CMakeFiles/easy_lut_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/easy_lut_test.cpp" "CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o" "gcc" "CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o.d" + "" "bin/easy_lut_test" "gcc" "CMakeFiles/easy_lut_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/easy_lut_test.dir/build.make b/test/build-asan/CMakeFiles/easy_lut_test.dir/build.make new file mode 100644 index 0000000..8c01dbb --- /dev/null +++ b/test/build-asan/CMakeFiles/easy_lut_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/easy_lut_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/easy_lut_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/easy_lut_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/easy_lut_test.dir/flags.make + +CMakeFiles/easy_lut_test.dir/codegen: +.PHONY : CMakeFiles/easy_lut_test.dir/codegen + +CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o: CMakeFiles/easy_lut_test.dir/flags.make +CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/easy_lut_test.cpp +CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o: CMakeFiles/easy_lut_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o -MF CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o.d -o CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/easy_lut_test.cpp + +CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/easy_lut_test.cpp > CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.i + +CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/easy_lut_test.cpp -o CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.s + +# Object files for target easy_lut_test +easy_lut_test_OBJECTS = \ +"CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o" + +# External object files for target easy_lut_test +easy_lut_test_EXTERNAL_OBJECTS = + +bin/easy_lut_test: CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o +bin/easy_lut_test: CMakeFiles/easy_lut_test.dir/build.make +bin/easy_lut_test: CMakeFiles/easy_lut_test.dir/compiler_depend.ts +bin/easy_lut_test: lib/libgtest_main.a +bin/easy_lut_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/easy_lut_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/easy_lut_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/easy_lut_test: lib/libgtest.a +bin/easy_lut_test: CMakeFiles/easy_lut_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/easy_lut_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/easy_lut_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=easy_lut_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/easy_lut_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=easy_lut_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/easy_lut_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/easy_lut_test.dir/build: bin/easy_lut_test +.PHONY : CMakeFiles/easy_lut_test.dir/build + +CMakeFiles/easy_lut_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/easy_lut_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/easy_lut_test.dir/clean + +CMakeFiles/easy_lut_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/easy_lut_test.dir/DependInfo.cmake "--color=$(COLOR)" easy_lut_test +.PHONY : CMakeFiles/easy_lut_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/easy_lut_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/easy_lut_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..c79e90f --- /dev/null +++ b/test/build-asan/CMakeFiles/easy_lut_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/easy_lut_test.dir/link.d" + "CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o" + "CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o.d" + "bin/easy_lut_test" + "bin/easy_lut_test.pdb" + "easy_lut_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/easy_lut_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/easy_lut_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/easy_lut_test.dir/compiler_depend.make new file mode 100644 index 0000000..1393281 --- /dev/null +++ b/test/build-asan/CMakeFiles/easy_lut_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for easy_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/easy_lut_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/easy_lut_test.dir/compiler_depend.ts new file mode 100644 index 0000000..0533af9 --- /dev/null +++ b/test/build-asan/CMakeFiles/easy_lut_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for easy_lut_test. diff --git a/test/build-asan/CMakeFiles/easy_lut_test.dir/depend.make b/test/build-asan/CMakeFiles/easy_lut_test.dir/depend.make new file mode 100644 index 0000000..5407cfa --- /dev/null +++ b/test/build-asan/CMakeFiles/easy_lut_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for easy_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/easy_lut_test.dir/flags.make b/test/build-asan/CMakeFiles/easy_lut_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/easy_lut_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/easy_lut_test.dir/link.txt b/test/build-asan/CMakeFiles/easy_lut_test.dir/link.txt new file mode 100644 index 0000000..37a7ccb --- /dev/null +++ b/test/build-asan/CMakeFiles/easy_lut_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/easy_lut_test.dir/link.d CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o -o bin/easy_lut_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/easy_lut_test.dir/progress.make b/test/build-asan/CMakeFiles/easy_lut_test.dir/progress.make new file mode 100644 index 0000000..bb3eefd --- /dev/null +++ b/test/build-asan/CMakeFiles/easy_lut_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 23 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/eval_full_multi_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/DependInfo.cmake new file mode 100644 index 0000000..8f6b876 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_full_multi_test.cpp" "CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o" "gcc" "CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o.d" + "" "bin/eval_full_multi_test" "gcc" "CMakeFiles/eval_full_multi_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/eval_full_multi_test.dir/build.make b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/build.make new file mode 100644 index 0000000..12da875 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/eval_full_multi_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/eval_full_multi_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/eval_full_multi_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/eval_full_multi_test.dir/flags.make + +CMakeFiles/eval_full_multi_test.dir/codegen: +.PHONY : CMakeFiles/eval_full_multi_test.dir/codegen + +CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o: CMakeFiles/eval_full_multi_test.dir/flags.make +CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_full_multi_test.cpp +CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o: CMakeFiles/eval_full_multi_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o -MF CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o.d -o CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_full_multi_test.cpp + +CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_full_multi_test.cpp > CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.i + +CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_full_multi_test.cpp -o CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.s + +# Object files for target eval_full_multi_test +eval_full_multi_test_OBJECTS = \ +"CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o" + +# External object files for target eval_full_multi_test +eval_full_multi_test_EXTERNAL_OBJECTS = + +bin/eval_full_multi_test: CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o +bin/eval_full_multi_test: CMakeFiles/eval_full_multi_test.dir/build.make +bin/eval_full_multi_test: CMakeFiles/eval_full_multi_test.dir/compiler_depend.ts +bin/eval_full_multi_test: lib/libgtest_main.a +bin/eval_full_multi_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/eval_full_multi_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/eval_full_multi_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/eval_full_multi_test: lib/libgtest.a +bin/eval_full_multi_test: CMakeFiles/eval_full_multi_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/eval_full_multi_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/eval_full_multi_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=eval_full_multi_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/eval_full_multi_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=eval_full_multi_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_full_multi_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/eval_full_multi_test.dir/build: bin/eval_full_multi_test +.PHONY : CMakeFiles/eval_full_multi_test.dir/build + +CMakeFiles/eval_full_multi_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/eval_full_multi_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/eval_full_multi_test.dir/clean + +CMakeFiles/eval_full_multi_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_full_multi_test.dir/DependInfo.cmake "--color=$(COLOR)" eval_full_multi_test +.PHONY : CMakeFiles/eval_full_multi_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/eval_full_multi_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..ab1b359 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/eval_full_multi_test.dir/link.d" + "CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o" + "CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o.d" + "bin/eval_full_multi_test" + "bin/eval_full_multi_test.pdb" + "eval_full_multi_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/eval_full_multi_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/eval_full_multi_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/compiler_depend.make new file mode 100644 index 0000000..5903335 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for eval_full_multi_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_full_multi_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/compiler_depend.ts new file mode 100644 index 0000000..5890a79 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for eval_full_multi_test. diff --git a/test/build-asan/CMakeFiles/eval_full_multi_test.dir/depend.make b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/depend.make new file mode 100644 index 0000000..00927e9 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for eval_full_multi_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_full_multi_test.dir/flags.make b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/eval_full_multi_test.dir/link.txt b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/link.txt new file mode 100644 index 0000000..770273b --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/eval_full_multi_test.dir/link.d CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o -o bin/eval_full_multi_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/eval_full_multi_test.dir/progress.make b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/progress.make new file mode 100644 index 0000000..4a24235 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_multi_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 24 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/eval_full_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/eval_full_test.dir/DependInfo.cmake new file mode 100644 index 0000000..07cb134 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_full_test.cpp" "CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o" "gcc" "CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o.d" + "" "bin/eval_full_test" "gcc" "CMakeFiles/eval_full_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/eval_full_test.dir/build.make b/test/build-asan/CMakeFiles/eval_full_test.dir/build.make new file mode 100644 index 0000000..dd0d95c --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/eval_full_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/eval_full_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/eval_full_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/eval_full_test.dir/flags.make + +CMakeFiles/eval_full_test.dir/codegen: +.PHONY : CMakeFiles/eval_full_test.dir/codegen + +CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o: CMakeFiles/eval_full_test.dir/flags.make +CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_full_test.cpp +CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o: CMakeFiles/eval_full_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o -MF CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o.d -o CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_full_test.cpp + +CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_full_test.cpp > CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.i + +CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_full_test.cpp -o CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.s + +# Object files for target eval_full_test +eval_full_test_OBJECTS = \ +"CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o" + +# External object files for target eval_full_test +eval_full_test_EXTERNAL_OBJECTS = + +bin/eval_full_test: CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o +bin/eval_full_test: CMakeFiles/eval_full_test.dir/build.make +bin/eval_full_test: CMakeFiles/eval_full_test.dir/compiler_depend.ts +bin/eval_full_test: lib/libgtest_main.a +bin/eval_full_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/eval_full_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/eval_full_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/eval_full_test: lib/libgtest.a +bin/eval_full_test: CMakeFiles/eval_full_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/eval_full_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/eval_full_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=eval_full_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/eval_full_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=eval_full_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_full_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/eval_full_test.dir/build: bin/eval_full_test +.PHONY : CMakeFiles/eval_full_test.dir/build + +CMakeFiles/eval_full_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/eval_full_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/eval_full_test.dir/clean + +CMakeFiles/eval_full_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_full_test.dir/DependInfo.cmake "--color=$(COLOR)" eval_full_test +.PHONY : CMakeFiles/eval_full_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/eval_full_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/eval_full_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..6afc902 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/eval_full_test.dir/link.d" + "CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o" + "CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o.d" + "bin/eval_full_test" + "bin/eval_full_test.pdb" + "eval_full_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/eval_full_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/eval_full_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/eval_full_test.dir/compiler_depend.make new file mode 100644 index 0000000..4fafdd5 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for eval_full_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_full_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/eval_full_test.dir/compiler_depend.ts new file mode 100644 index 0000000..6f9c497 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for eval_full_test. diff --git a/test/build-asan/CMakeFiles/eval_full_test.dir/depend.make b/test/build-asan/CMakeFiles/eval_full_test.dir/depend.make new file mode 100644 index 0000000..b809d0c --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for eval_full_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_full_test.dir/flags.make b/test/build-asan/CMakeFiles/eval_full_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/eval_full_test.dir/link.txt b/test/build-asan/CMakeFiles/eval_full_test.dir/link.txt new file mode 100644 index 0000000..c3be7b2 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/eval_full_test.dir/link.d CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o -o bin/eval_full_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/eval_full_test.dir/progress.make b/test/build-asan/CMakeFiles/eval_full_test.dir/progress.make new file mode 100644 index 0000000..5fb6e24 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_full_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 25 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/eval_inner_product_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/DependInfo.cmake new file mode 100644 index 0000000..749a146 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_inner_product_test.cpp" "CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o" "gcc" "CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o.d" + "" "bin/eval_inner_product_test" "gcc" "CMakeFiles/eval_inner_product_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/eval_inner_product_test.dir/build.make b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/build.make new file mode 100644 index 0000000..f40e11a --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/eval_inner_product_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/eval_inner_product_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/eval_inner_product_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/eval_inner_product_test.dir/flags.make + +CMakeFiles/eval_inner_product_test.dir/codegen: +.PHONY : CMakeFiles/eval_inner_product_test.dir/codegen + +CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o: CMakeFiles/eval_inner_product_test.dir/flags.make +CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_inner_product_test.cpp +CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o: CMakeFiles/eval_inner_product_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o -MF CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o.d -o CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_inner_product_test.cpp + +CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_inner_product_test.cpp > CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.i + +CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_inner_product_test.cpp -o CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.s + +# Object files for target eval_inner_product_test +eval_inner_product_test_OBJECTS = \ +"CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o" + +# External object files for target eval_inner_product_test +eval_inner_product_test_EXTERNAL_OBJECTS = + +bin/eval_inner_product_test: CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o +bin/eval_inner_product_test: CMakeFiles/eval_inner_product_test.dir/build.make +bin/eval_inner_product_test: CMakeFiles/eval_inner_product_test.dir/compiler_depend.ts +bin/eval_inner_product_test: lib/libgtest_main.a +bin/eval_inner_product_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/eval_inner_product_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/eval_inner_product_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/eval_inner_product_test: lib/libgtest.a +bin/eval_inner_product_test: CMakeFiles/eval_inner_product_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/eval_inner_product_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/eval_inner_product_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=eval_inner_product_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/eval_inner_product_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=eval_inner_product_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_inner_product_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/eval_inner_product_test.dir/build: bin/eval_inner_product_test +.PHONY : CMakeFiles/eval_inner_product_test.dir/build + +CMakeFiles/eval_inner_product_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/eval_inner_product_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/eval_inner_product_test.dir/clean + +CMakeFiles/eval_inner_product_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_inner_product_test.dir/DependInfo.cmake "--color=$(COLOR)" eval_inner_product_test +.PHONY : CMakeFiles/eval_inner_product_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/eval_inner_product_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..31a3edb --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/eval_inner_product_test.dir/link.d" + "CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o" + "CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o.d" + "bin/eval_inner_product_test" + "bin/eval_inner_product_test.pdb" + "eval_inner_product_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/eval_inner_product_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/eval_inner_product_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/compiler_depend.make new file mode 100644 index 0000000..342fbd3 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for eval_inner_product_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_inner_product_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/compiler_depend.ts new file mode 100644 index 0000000..b95e9a7 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for eval_inner_product_test. diff --git a/test/build-asan/CMakeFiles/eval_inner_product_test.dir/depend.make b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/depend.make new file mode 100644 index 0000000..d0fa328 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for eval_inner_product_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_inner_product_test.dir/flags.make b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/eval_inner_product_test.dir/link.txt b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/link.txt new file mode 100644 index 0000000..b858cbd --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/eval_inner_product_test.dir/link.d CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o -o bin/eval_inner_product_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/eval_inner_product_test.dir/progress.make b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/progress.make new file mode 100644 index 0000000..fd38c8b --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_inner_product_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 26 + diff --git a/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/DependInfo.cmake new file mode 100644 index 0000000..ef783c4 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_interval_multi_test.cpp" "CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o" "gcc" "CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o.d" + "" "bin/eval_interval_multi_test" "gcc" "CMakeFiles/eval_interval_multi_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/build.make b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/build.make new file mode 100644 index 0000000..5dc7c38 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/eval_interval_multi_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/eval_interval_multi_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/eval_interval_multi_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/eval_interval_multi_test.dir/flags.make + +CMakeFiles/eval_interval_multi_test.dir/codegen: +.PHONY : CMakeFiles/eval_interval_multi_test.dir/codegen + +CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o: CMakeFiles/eval_interval_multi_test.dir/flags.make +CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_interval_multi_test.cpp +CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o: CMakeFiles/eval_interval_multi_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o -MF CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o.d -o CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_interval_multi_test.cpp + +CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_interval_multi_test.cpp > CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.i + +CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_interval_multi_test.cpp -o CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.s + +# Object files for target eval_interval_multi_test +eval_interval_multi_test_OBJECTS = \ +"CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o" + +# External object files for target eval_interval_multi_test +eval_interval_multi_test_EXTERNAL_OBJECTS = + +bin/eval_interval_multi_test: CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o +bin/eval_interval_multi_test: CMakeFiles/eval_interval_multi_test.dir/build.make +bin/eval_interval_multi_test: CMakeFiles/eval_interval_multi_test.dir/compiler_depend.ts +bin/eval_interval_multi_test: lib/libgtest_main.a +bin/eval_interval_multi_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/eval_interval_multi_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/eval_interval_multi_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/eval_interval_multi_test: lib/libgtest.a +bin/eval_interval_multi_test: CMakeFiles/eval_interval_multi_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/eval_interval_multi_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/eval_interval_multi_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=eval_interval_multi_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/eval_interval_multi_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=eval_interval_multi_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_interval_multi_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/eval_interval_multi_test.dir/build: bin/eval_interval_multi_test +.PHONY : CMakeFiles/eval_interval_multi_test.dir/build + +CMakeFiles/eval_interval_multi_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/eval_interval_multi_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/eval_interval_multi_test.dir/clean + +CMakeFiles/eval_interval_multi_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/DependInfo.cmake "--color=$(COLOR)" eval_interval_multi_test +.PHONY : CMakeFiles/eval_interval_multi_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..88d66a0 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/eval_interval_multi_test.dir/link.d" + "CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o" + "CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o.d" + "bin/eval_interval_multi_test" + "bin/eval_interval_multi_test.pdb" + "eval_interval_multi_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/eval_interval_multi_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/compiler_depend.make new file mode 100644 index 0000000..c3bd318 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for eval_interval_multi_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/compiler_depend.ts new file mode 100644 index 0000000..5c97a47 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for eval_interval_multi_test. diff --git a/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/depend.make b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/depend.make new file mode 100644 index 0000000..e40d01b --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for eval_interval_multi_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/flags.make b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/link.txt b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/link.txt new file mode 100644 index 0000000..dec9f30 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/eval_interval_multi_test.dir/link.d CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o -o bin/eval_interval_multi_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/progress.make b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/progress.make new file mode 100644 index 0000000..57f57ee --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_multi_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 27 + diff --git a/test/build-asan/CMakeFiles/eval_interval_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/eval_interval_test.dir/DependInfo.cmake new file mode 100644 index 0000000..0ad195e --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_interval_test.cpp" "CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o" "gcc" "CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o.d" + "" "bin/eval_interval_test" "gcc" "CMakeFiles/eval_interval_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/eval_interval_test.dir/build.make b/test/build-asan/CMakeFiles/eval_interval_test.dir/build.make new file mode 100644 index 0000000..1a6b11e --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/eval_interval_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/eval_interval_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/eval_interval_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/eval_interval_test.dir/flags.make + +CMakeFiles/eval_interval_test.dir/codegen: +.PHONY : CMakeFiles/eval_interval_test.dir/codegen + +CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o: CMakeFiles/eval_interval_test.dir/flags.make +CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_interval_test.cpp +CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o: CMakeFiles/eval_interval_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o -MF CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o.d -o CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_interval_test.cpp + +CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_interval_test.cpp > CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.i + +CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_interval_test.cpp -o CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.s + +# Object files for target eval_interval_test +eval_interval_test_OBJECTS = \ +"CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o" + +# External object files for target eval_interval_test +eval_interval_test_EXTERNAL_OBJECTS = + +bin/eval_interval_test: CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o +bin/eval_interval_test: CMakeFiles/eval_interval_test.dir/build.make +bin/eval_interval_test: CMakeFiles/eval_interval_test.dir/compiler_depend.ts +bin/eval_interval_test: lib/libgtest_main.a +bin/eval_interval_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/eval_interval_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/eval_interval_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/eval_interval_test: lib/libgtest.a +bin/eval_interval_test: CMakeFiles/eval_interval_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/eval_interval_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/eval_interval_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=eval_interval_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/eval_interval_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=eval_interval_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_interval_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/eval_interval_test.dir/build: bin/eval_interval_test +.PHONY : CMakeFiles/eval_interval_test.dir/build + +CMakeFiles/eval_interval_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/eval_interval_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/eval_interval_test.dir/clean + +CMakeFiles/eval_interval_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_interval_test.dir/DependInfo.cmake "--color=$(COLOR)" eval_interval_test +.PHONY : CMakeFiles/eval_interval_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/eval_interval_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/eval_interval_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..4b4e60b --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/eval_interval_test.dir/link.d" + "CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o" + "CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o.d" + "bin/eval_interval_test" + "bin/eval_interval_test.pdb" + "eval_interval_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/eval_interval_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/eval_interval_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/eval_interval_test.dir/compiler_depend.make new file mode 100644 index 0000000..ae05324 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for eval_interval_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_interval_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/eval_interval_test.dir/compiler_depend.ts new file mode 100644 index 0000000..99839df --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for eval_interval_test. diff --git a/test/build-asan/CMakeFiles/eval_interval_test.dir/depend.make b/test/build-asan/CMakeFiles/eval_interval_test.dir/depend.make new file mode 100644 index 0000000..fa6275d --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for eval_interval_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_interval_test.dir/flags.make b/test/build-asan/CMakeFiles/eval_interval_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/eval_interval_test.dir/link.txt b/test/build-asan/CMakeFiles/eval_interval_test.dir/link.txt new file mode 100644 index 0000000..e52067c --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/eval_interval_test.dir/link.d CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o -o bin/eval_interval_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/eval_interval_test.dir/progress.make b/test/build-asan/CMakeFiles/eval_interval_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_interval_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/eval_point_multi_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/DependInfo.cmake new file mode 100644 index 0000000..9a612aa --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_point_multi_test.cpp" "CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o" "gcc" "CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o.d" + "" "bin/eval_point_multi_test" "gcc" "CMakeFiles/eval_point_multi_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/eval_point_multi_test.dir/build.make b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/build.make new file mode 100644 index 0000000..721fbc7 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/eval_point_multi_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/eval_point_multi_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/eval_point_multi_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/eval_point_multi_test.dir/flags.make + +CMakeFiles/eval_point_multi_test.dir/codegen: +.PHONY : CMakeFiles/eval_point_multi_test.dir/codegen + +CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o: CMakeFiles/eval_point_multi_test.dir/flags.make +CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_point_multi_test.cpp +CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o: CMakeFiles/eval_point_multi_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o -MF CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o.d -o CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_point_multi_test.cpp + +CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_point_multi_test.cpp > CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.i + +CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_point_multi_test.cpp -o CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.s + +# Object files for target eval_point_multi_test +eval_point_multi_test_OBJECTS = \ +"CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o" + +# External object files for target eval_point_multi_test +eval_point_multi_test_EXTERNAL_OBJECTS = + +bin/eval_point_multi_test: CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o +bin/eval_point_multi_test: CMakeFiles/eval_point_multi_test.dir/build.make +bin/eval_point_multi_test: CMakeFiles/eval_point_multi_test.dir/compiler_depend.ts +bin/eval_point_multi_test: lib/libgtest_main.a +bin/eval_point_multi_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/eval_point_multi_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/eval_point_multi_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/eval_point_multi_test: lib/libgtest.a +bin/eval_point_multi_test: CMakeFiles/eval_point_multi_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/eval_point_multi_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/eval_point_multi_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=eval_point_multi_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/eval_point_multi_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=eval_point_multi_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_point_multi_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/eval_point_multi_test.dir/build: bin/eval_point_multi_test +.PHONY : CMakeFiles/eval_point_multi_test.dir/build + +CMakeFiles/eval_point_multi_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/eval_point_multi_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/eval_point_multi_test.dir/clean + +CMakeFiles/eval_point_multi_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_point_multi_test.dir/DependInfo.cmake "--color=$(COLOR)" eval_point_multi_test +.PHONY : CMakeFiles/eval_point_multi_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/eval_point_multi_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..4b56d8c --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/eval_point_multi_test.dir/link.d" + "CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o" + "CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o.d" + "bin/eval_point_multi_test" + "bin/eval_point_multi_test.pdb" + "eval_point_multi_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/eval_point_multi_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/eval_point_multi_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/compiler_depend.make new file mode 100644 index 0000000..3189243 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for eval_point_multi_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_point_multi_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/compiler_depend.ts new file mode 100644 index 0000000..a5f8fdc --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for eval_point_multi_test. diff --git a/test/build-asan/CMakeFiles/eval_point_multi_test.dir/depend.make b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/depend.make new file mode 100644 index 0000000..22f314a --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for eval_point_multi_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_point_multi_test.dir/flags.make b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/eval_point_multi_test.dir/link.txt b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/link.txt new file mode 100644 index 0000000..8e3144e --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/eval_point_multi_test.dir/link.d CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o -o bin/eval_point_multi_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/eval_point_multi_test.dir/progress.make b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/progress.make new file mode 100644 index 0000000..70f7710 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_multi_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 28 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/eval_point_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/eval_point_test.dir/DependInfo.cmake new file mode 100644 index 0000000..9989c4a --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_point_test.cpp" "CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o" "gcc" "CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o.d" + "" "bin/eval_point_test" "gcc" "CMakeFiles/eval_point_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/eval_point_test.dir/build.make b/test/build-asan/CMakeFiles/eval_point_test.dir/build.make new file mode 100644 index 0000000..a50f146 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/eval_point_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/eval_point_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/eval_point_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/eval_point_test.dir/flags.make + +CMakeFiles/eval_point_test.dir/codegen: +.PHONY : CMakeFiles/eval_point_test.dir/codegen + +CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o: CMakeFiles/eval_point_test.dir/flags.make +CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_point_test.cpp +CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o: CMakeFiles/eval_point_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o -MF CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o.d -o CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_point_test.cpp + +CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_point_test.cpp > CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.i + +CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_point_test.cpp -o CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.s + +# Object files for target eval_point_test +eval_point_test_OBJECTS = \ +"CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o" + +# External object files for target eval_point_test +eval_point_test_EXTERNAL_OBJECTS = + +bin/eval_point_test: CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o +bin/eval_point_test: CMakeFiles/eval_point_test.dir/build.make +bin/eval_point_test: CMakeFiles/eval_point_test.dir/compiler_depend.ts +bin/eval_point_test: lib/libgtest_main.a +bin/eval_point_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/eval_point_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/eval_point_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/eval_point_test: lib/libgtest.a +bin/eval_point_test: CMakeFiles/eval_point_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/eval_point_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/eval_point_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=eval_point_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/eval_point_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=eval_point_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_point_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/eval_point_test.dir/build: bin/eval_point_test +.PHONY : CMakeFiles/eval_point_test.dir/build + +CMakeFiles/eval_point_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/eval_point_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/eval_point_test.dir/clean + +CMakeFiles/eval_point_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_point_test.dir/DependInfo.cmake "--color=$(COLOR)" eval_point_test +.PHONY : CMakeFiles/eval_point_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/eval_point_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/eval_point_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..ca00250 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/eval_point_test.dir/link.d" + "CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o" + "CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o.d" + "bin/eval_point_test" + "bin/eval_point_test.pdb" + "eval_point_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/eval_point_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/eval_point_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/eval_point_test.dir/compiler_depend.make new file mode 100644 index 0000000..df2c925 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for eval_point_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_point_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/eval_point_test.dir/compiler_depend.ts new file mode 100644 index 0000000..72c6f8f --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for eval_point_test. diff --git a/test/build-asan/CMakeFiles/eval_point_test.dir/depend.make b/test/build-asan/CMakeFiles/eval_point_test.dir/depend.make new file mode 100644 index 0000000..93f8127 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for eval_point_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_point_test.dir/flags.make b/test/build-asan/CMakeFiles/eval_point_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/eval_point_test.dir/link.txt b/test/build-asan/CMakeFiles/eval_point_test.dir/link.txt new file mode 100644 index 0000000..a2f38de --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/eval_point_test.dir/link.d CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o -o bin/eval_point_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/eval_point_test.dir/progress.make b/test/build-asan/CMakeFiles/eval_point_test.dir/progress.make new file mode 100644 index 0000000..efb07f4 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_point_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 29 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/DependInfo.cmake new file mode 100644 index 0000000..f82a551 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_sequence_multi_test.cpp" "CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o" "gcc" "CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o.d" + "" "bin/eval_sequence_multi_test" "gcc" "CMakeFiles/eval_sequence_multi_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/build.make b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/build.make new file mode 100644 index 0000000..959a163 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/eval_sequence_multi_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/eval_sequence_multi_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/eval_sequence_multi_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/eval_sequence_multi_test.dir/flags.make + +CMakeFiles/eval_sequence_multi_test.dir/codegen: +.PHONY : CMakeFiles/eval_sequence_multi_test.dir/codegen + +CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o: CMakeFiles/eval_sequence_multi_test.dir/flags.make +CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_sequence_multi_test.cpp +CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o: CMakeFiles/eval_sequence_multi_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o -MF CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o.d -o CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_sequence_multi_test.cpp + +CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_sequence_multi_test.cpp > CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.i + +CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_sequence_multi_test.cpp -o CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.s + +# Object files for target eval_sequence_multi_test +eval_sequence_multi_test_OBJECTS = \ +"CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o" + +# External object files for target eval_sequence_multi_test +eval_sequence_multi_test_EXTERNAL_OBJECTS = + +bin/eval_sequence_multi_test: CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o +bin/eval_sequence_multi_test: CMakeFiles/eval_sequence_multi_test.dir/build.make +bin/eval_sequence_multi_test: CMakeFiles/eval_sequence_multi_test.dir/compiler_depend.ts +bin/eval_sequence_multi_test: lib/libgtest_main.a +bin/eval_sequence_multi_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/eval_sequence_multi_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/eval_sequence_multi_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/eval_sequence_multi_test: lib/libgtest.a +bin/eval_sequence_multi_test: CMakeFiles/eval_sequence_multi_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/eval_sequence_multi_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/eval_sequence_multi_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=eval_sequence_multi_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/eval_sequence_multi_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=eval_sequence_multi_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_sequence_multi_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/eval_sequence_multi_test.dir/build: bin/eval_sequence_multi_test +.PHONY : CMakeFiles/eval_sequence_multi_test.dir/build + +CMakeFiles/eval_sequence_multi_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/eval_sequence_multi_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/eval_sequence_multi_test.dir/clean + +CMakeFiles/eval_sequence_multi_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/DependInfo.cmake "--color=$(COLOR)" eval_sequence_multi_test +.PHONY : CMakeFiles/eval_sequence_multi_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..9e118be --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/eval_sequence_multi_test.dir/link.d" + "CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o" + "CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o.d" + "bin/eval_sequence_multi_test" + "bin/eval_sequence_multi_test.pdb" + "eval_sequence_multi_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/eval_sequence_multi_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/compiler_depend.make new file mode 100644 index 0000000..0a06be5 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for eval_sequence_multi_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/compiler_depend.ts new file mode 100644 index 0000000..f926e31 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for eval_sequence_multi_test. diff --git a/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/depend.make b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/depend.make new file mode 100644 index 0000000..85e1482 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for eval_sequence_multi_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/flags.make b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/link.txt b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/link.txt new file mode 100644 index 0000000..b8b0b9f --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/eval_sequence_multi_test.dir/link.d CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o -o bin/eval_sequence_multi_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/progress.make b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/progress.make new file mode 100644 index 0000000..d599d1b --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_multi_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 30 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/eval_sequence_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/eval_sequence_test.dir/DependInfo.cmake new file mode 100644 index 0000000..6c13e34 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_sequence_test.cpp" "CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o" "gcc" "CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o.d" + "" "bin/eval_sequence_test" "gcc" "CMakeFiles/eval_sequence_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/eval_sequence_test.dir/build.make b/test/build-asan/CMakeFiles/eval_sequence_test.dir/build.make new file mode 100644 index 0000000..f0d6b79 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/eval_sequence_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/eval_sequence_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/eval_sequence_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/eval_sequence_test.dir/flags.make + +CMakeFiles/eval_sequence_test.dir/codegen: +.PHONY : CMakeFiles/eval_sequence_test.dir/codegen + +CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o: CMakeFiles/eval_sequence_test.dir/flags.make +CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_sequence_test.cpp +CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o: CMakeFiles/eval_sequence_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o -MF CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o.d -o CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_sequence_test.cpp + +CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_sequence_test.cpp > CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.i + +CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_sequence_test.cpp -o CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.s + +# Object files for target eval_sequence_test +eval_sequence_test_OBJECTS = \ +"CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o" + +# External object files for target eval_sequence_test +eval_sequence_test_EXTERNAL_OBJECTS = + +bin/eval_sequence_test: CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o +bin/eval_sequence_test: CMakeFiles/eval_sequence_test.dir/build.make +bin/eval_sequence_test: CMakeFiles/eval_sequence_test.dir/compiler_depend.ts +bin/eval_sequence_test: lib/libgtest_main.a +bin/eval_sequence_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/eval_sequence_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/eval_sequence_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/eval_sequence_test: lib/libgtest.a +bin/eval_sequence_test: CMakeFiles/eval_sequence_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/eval_sequence_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/eval_sequence_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=eval_sequence_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/eval_sequence_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=eval_sequence_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_sequence_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/eval_sequence_test.dir/build: bin/eval_sequence_test +.PHONY : CMakeFiles/eval_sequence_test.dir/build + +CMakeFiles/eval_sequence_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/eval_sequence_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/eval_sequence_test.dir/clean + +CMakeFiles/eval_sequence_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_sequence_test.dir/DependInfo.cmake "--color=$(COLOR)" eval_sequence_test +.PHONY : CMakeFiles/eval_sequence_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/eval_sequence_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/eval_sequence_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..85cc43f --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/eval_sequence_test.dir/link.d" + "CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o" + "CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o.d" + "bin/eval_sequence_test" + "bin/eval_sequence_test.pdb" + "eval_sequence_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/eval_sequence_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/eval_sequence_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/eval_sequence_test.dir/compiler_depend.make new file mode 100644 index 0000000..8efe09f --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for eval_sequence_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_sequence_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/eval_sequence_test.dir/compiler_depend.ts new file mode 100644 index 0000000..c4f9668 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for eval_sequence_test. diff --git a/test/build-asan/CMakeFiles/eval_sequence_test.dir/depend.make b/test/build-asan/CMakeFiles/eval_sequence_test.dir/depend.make new file mode 100644 index 0000000..e4f51fe --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for eval_sequence_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_sequence_test.dir/flags.make b/test/build-asan/CMakeFiles/eval_sequence_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/eval_sequence_test.dir/link.txt b/test/build-asan/CMakeFiles/eval_sequence_test.dir/link.txt new file mode 100644 index 0000000..d0ef901 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/eval_sequence_test.dir/link.d CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o -o bin/eval_sequence_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/eval_sequence_test.dir/progress.make b/test/build-asan/CMakeFiles/eval_sequence_test.dir/progress.make new file mode 100644 index 0000000..eda6648 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_sequence_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 31 + diff --git a/test/build-asan/CMakeFiles/eval_until_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/eval_until_test.dir/DependInfo.cmake new file mode 100644 index 0000000..08ec701 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_until_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_until_test.cpp" "CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o" "gcc" "CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o.d" + "" "bin/eval_until_test" "gcc" "CMakeFiles/eval_until_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/eval_until_test.dir/build.make b/test/build-asan/CMakeFiles/eval_until_test.dir/build.make new file mode 100644 index 0000000..b20f90f --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_until_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/eval_until_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/eval_until_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/eval_until_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/eval_until_test.dir/flags.make + +CMakeFiles/eval_until_test.dir/codegen: +.PHONY : CMakeFiles/eval_until_test.dir/codegen + +CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o: CMakeFiles/eval_until_test.dir/flags.make +CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_until_test.cpp +CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o: CMakeFiles/eval_until_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o -MF CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o.d -o CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_until_test.cpp + +CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_until_test.cpp > CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.i + +CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/eval_until_test.cpp -o CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.s + +# Object files for target eval_until_test +eval_until_test_OBJECTS = \ +"CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o" + +# External object files for target eval_until_test +eval_until_test_EXTERNAL_OBJECTS = + +bin/eval_until_test: CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o +bin/eval_until_test: CMakeFiles/eval_until_test.dir/build.make +bin/eval_until_test: CMakeFiles/eval_until_test.dir/compiler_depend.ts +bin/eval_until_test: lib/libgtest_main.a +bin/eval_until_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/eval_until_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/eval_until_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/eval_until_test: lib/libgtest.a +bin/eval_until_test: CMakeFiles/eval_until_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/eval_until_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/eval_until_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=eval_until_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/eval_until_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=eval_until_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_until_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/eval_until_test.dir/build: bin/eval_until_test +.PHONY : CMakeFiles/eval_until_test.dir/build + +CMakeFiles/eval_until_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/eval_until_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/eval_until_test.dir/clean + +CMakeFiles/eval_until_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/eval_until_test.dir/DependInfo.cmake "--color=$(COLOR)" eval_until_test +.PHONY : CMakeFiles/eval_until_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/eval_until_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/eval_until_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..c6cc067 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_until_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/eval_until_test.dir/link.d" + "CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o" + "CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o.d" + "bin/eval_until_test" + "bin/eval_until_test.pdb" + "eval_until_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/eval_until_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/eval_until_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/eval_until_test.dir/compiler_depend.make new file mode 100644 index 0000000..c6ee1fe --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_until_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for eval_until_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_until_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/eval_until_test.dir/compiler_depend.ts new file mode 100644 index 0000000..2185a3f --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_until_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for eval_until_test. diff --git a/test/build-asan/CMakeFiles/eval_until_test.dir/depend.make b/test/build-asan/CMakeFiles/eval_until_test.dir/depend.make new file mode 100644 index 0000000..7550be2 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_until_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for eval_until_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/eval_until_test.dir/flags.make b/test/build-asan/CMakeFiles/eval_until_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_until_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/eval_until_test.dir/link.txt b/test/build-asan/CMakeFiles/eval_until_test.dir/link.txt new file mode 100644 index 0000000..dd24e3d --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_until_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/eval_until_test.dir/link.d CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o -o bin/eval_until_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/eval_until_test.dir/progress.make b/test/build-asan/CMakeFiles/eval_until_test.dir/progress.make new file mode 100644 index 0000000..67f3ae8 --- /dev/null +++ b/test/build-asan/CMakeFiles/eval_until_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 32 + diff --git a/test/build-asan/CMakeFiles/exact_steps_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/exact_steps_test.dir/DependInfo.cmake new file mode 100644 index 0000000..d70aa44 --- /dev/null +++ b/test/build-asan/CMakeFiles/exact_steps_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/exact_steps_test.cpp" "CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o" "gcc" "CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o.d" + "" "bin/exact_steps_test" "gcc" "CMakeFiles/exact_steps_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/exact_steps_test.dir/build.make b/test/build-asan/CMakeFiles/exact_steps_test.dir/build.make new file mode 100644 index 0000000..b9a33b9 --- /dev/null +++ b/test/build-asan/CMakeFiles/exact_steps_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/exact_steps_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/exact_steps_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/exact_steps_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/exact_steps_test.dir/flags.make + +CMakeFiles/exact_steps_test.dir/codegen: +.PHONY : CMakeFiles/exact_steps_test.dir/codegen + +CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o: CMakeFiles/exact_steps_test.dir/flags.make +CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/exact_steps_test.cpp +CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o: CMakeFiles/exact_steps_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o -MF CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o.d -o CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/exact_steps_test.cpp + +CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/exact_steps_test.cpp > CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.i + +CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/exact_steps_test.cpp -o CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.s + +# Object files for target exact_steps_test +exact_steps_test_OBJECTS = \ +"CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o" + +# External object files for target exact_steps_test +exact_steps_test_EXTERNAL_OBJECTS = + +bin/exact_steps_test: CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o +bin/exact_steps_test: CMakeFiles/exact_steps_test.dir/build.make +bin/exact_steps_test: CMakeFiles/exact_steps_test.dir/compiler_depend.ts +bin/exact_steps_test: lib/libgtest_main.a +bin/exact_steps_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/exact_steps_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/exact_steps_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/exact_steps_test: lib/libgtest.a +bin/exact_steps_test: CMakeFiles/exact_steps_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/exact_steps_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/exact_steps_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=exact_steps_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/exact_steps_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=exact_steps_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/exact_steps_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/exact_steps_test.dir/build: bin/exact_steps_test +.PHONY : CMakeFiles/exact_steps_test.dir/build + +CMakeFiles/exact_steps_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/exact_steps_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/exact_steps_test.dir/clean + +CMakeFiles/exact_steps_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/exact_steps_test.dir/DependInfo.cmake "--color=$(COLOR)" exact_steps_test +.PHONY : CMakeFiles/exact_steps_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/exact_steps_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/exact_steps_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..8bf1430 --- /dev/null +++ b/test/build-asan/CMakeFiles/exact_steps_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/exact_steps_test.dir/link.d" + "CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o" + "CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o.d" + "bin/exact_steps_test" + "bin/exact_steps_test.pdb" + "exact_steps_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/exact_steps_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/exact_steps_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/exact_steps_test.dir/compiler_depend.make new file mode 100644 index 0000000..2481876 --- /dev/null +++ b/test/build-asan/CMakeFiles/exact_steps_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for exact_steps_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/exact_steps_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/exact_steps_test.dir/compiler_depend.ts new file mode 100644 index 0000000..5962fa2 --- /dev/null +++ b/test/build-asan/CMakeFiles/exact_steps_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for exact_steps_test. diff --git a/test/build-asan/CMakeFiles/exact_steps_test.dir/depend.make b/test/build-asan/CMakeFiles/exact_steps_test.dir/depend.make new file mode 100644 index 0000000..63b2787 --- /dev/null +++ b/test/build-asan/CMakeFiles/exact_steps_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for exact_steps_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/exact_steps_test.dir/flags.make b/test/build-asan/CMakeFiles/exact_steps_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/exact_steps_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/exact_steps_test.dir/link.txt b/test/build-asan/CMakeFiles/exact_steps_test.dir/link.txt new file mode 100644 index 0000000..2c35eba --- /dev/null +++ b/test/build-asan/CMakeFiles/exact_steps_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/exact_steps_test.dir/link.d CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o -o bin/exact_steps_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/exact_steps_test.dir/progress.make b/test/build-asan/CMakeFiles/exact_steps_test.dir/progress.make new file mode 100644 index 0000000..1b6d3a4 --- /dev/null +++ b/test/build-asan/CMakeFiles/exact_steps_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 33 + diff --git a/test/build-asan/CMakeFiles/experiment_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/experiment_test.dir/DependInfo.cmake new file mode 100644 index 0000000..c69c1b5 --- /dev/null +++ b/test/build-asan/CMakeFiles/experiment_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/experiment_test.cpp" "CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o" "gcc" "CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o.d" + "" "bin/experiment_test" "gcc" "CMakeFiles/experiment_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/experiment_test.dir/build.make b/test/build-asan/CMakeFiles/experiment_test.dir/build.make new file mode 100644 index 0000000..6285a73 --- /dev/null +++ b/test/build-asan/CMakeFiles/experiment_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/experiment_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/experiment_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/experiment_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/experiment_test.dir/flags.make + +CMakeFiles/experiment_test.dir/codegen: +.PHONY : CMakeFiles/experiment_test.dir/codegen + +CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o: CMakeFiles/experiment_test.dir/flags.make +CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/experiment_test.cpp +CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o: CMakeFiles/experiment_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o -MF CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o.d -o CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/experiment_test.cpp + +CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/experiment_test.cpp > CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.i + +CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/experiment_test.cpp -o CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.s + +# Object files for target experiment_test +experiment_test_OBJECTS = \ +"CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o" + +# External object files for target experiment_test +experiment_test_EXTERNAL_OBJECTS = + +bin/experiment_test: CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o +bin/experiment_test: CMakeFiles/experiment_test.dir/build.make +bin/experiment_test: CMakeFiles/experiment_test.dir/compiler_depend.ts +bin/experiment_test: lib/libgtest_main.a +bin/experiment_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/experiment_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/experiment_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/experiment_test: lib/libgtest.a +bin/experiment_test: CMakeFiles/experiment_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/experiment_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/experiment_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=experiment_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/experiment_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=experiment_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/experiment_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/experiment_test.dir/build: bin/experiment_test +.PHONY : CMakeFiles/experiment_test.dir/build + +CMakeFiles/experiment_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/experiment_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/experiment_test.dir/clean + +CMakeFiles/experiment_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/experiment_test.dir/DependInfo.cmake "--color=$(COLOR)" experiment_test +.PHONY : CMakeFiles/experiment_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/experiment_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/experiment_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..479cbdd --- /dev/null +++ b/test/build-asan/CMakeFiles/experiment_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/experiment_test.dir/link.d" + "CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o" + "CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o.d" + "bin/experiment_test" + "bin/experiment_test.pdb" + "experiment_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/experiment_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/experiment_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/experiment_test.dir/compiler_depend.make new file mode 100644 index 0000000..0110322 --- /dev/null +++ b/test/build-asan/CMakeFiles/experiment_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for experiment_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/experiment_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/experiment_test.dir/compiler_depend.ts new file mode 100644 index 0000000..bab362b --- /dev/null +++ b/test/build-asan/CMakeFiles/experiment_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for experiment_test. diff --git a/test/build-asan/CMakeFiles/experiment_test.dir/depend.make b/test/build-asan/CMakeFiles/experiment_test.dir/depend.make new file mode 100644 index 0000000..a60d3a9 --- /dev/null +++ b/test/build-asan/CMakeFiles/experiment_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for experiment_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/experiment_test.dir/flags.make b/test/build-asan/CMakeFiles/experiment_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/experiment_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/experiment_test.dir/link.txt b/test/build-asan/CMakeFiles/experiment_test.dir/link.txt new file mode 100644 index 0000000..261a1c9 --- /dev/null +++ b/test/build-asan/CMakeFiles/experiment_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/experiment_test.dir/link.d CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o -o bin/experiment_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/experiment_test.dir/progress.make b/test/build-asan/CMakeFiles/experiment_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/experiment_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/extractable_full_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/extractable_full_test.dir/DependInfo.cmake new file mode 100644 index 0000000..93db7eb --- /dev/null +++ b/test/build-asan/CMakeFiles/extractable_full_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/extractable_full_test.cpp" "CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o" "gcc" "CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o.d" + "" "bin/extractable_full_test" "gcc" "CMakeFiles/extractable_full_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/extractable_full_test.dir/build.make b/test/build-asan/CMakeFiles/extractable_full_test.dir/build.make new file mode 100644 index 0000000..c1a42da --- /dev/null +++ b/test/build-asan/CMakeFiles/extractable_full_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/extractable_full_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/extractable_full_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/extractable_full_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/extractable_full_test.dir/flags.make + +CMakeFiles/extractable_full_test.dir/codegen: +.PHONY : CMakeFiles/extractable_full_test.dir/codegen + +CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o: CMakeFiles/extractable_full_test.dir/flags.make +CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/extractable_full_test.cpp +CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o: CMakeFiles/extractable_full_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o -MF CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o.d -o CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/extractable_full_test.cpp + +CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/extractable_full_test.cpp > CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.i + +CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/extractable_full_test.cpp -o CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.s + +# Object files for target extractable_full_test +extractable_full_test_OBJECTS = \ +"CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o" + +# External object files for target extractable_full_test +extractable_full_test_EXTERNAL_OBJECTS = + +bin/extractable_full_test: CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o +bin/extractable_full_test: CMakeFiles/extractable_full_test.dir/build.make +bin/extractable_full_test: CMakeFiles/extractable_full_test.dir/compiler_depend.ts +bin/extractable_full_test: lib/libgtest_main.a +bin/extractable_full_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/extractable_full_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/extractable_full_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/extractable_full_test: lib/libgtest.a +bin/extractable_full_test: CMakeFiles/extractable_full_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/extractable_full_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/extractable_full_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=extractable_full_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/extractable_full_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=extractable_full_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/extractable_full_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/extractable_full_test.dir/build: bin/extractable_full_test +.PHONY : CMakeFiles/extractable_full_test.dir/build + +CMakeFiles/extractable_full_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/extractable_full_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/extractable_full_test.dir/clean + +CMakeFiles/extractable_full_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/extractable_full_test.dir/DependInfo.cmake "--color=$(COLOR)" extractable_full_test +.PHONY : CMakeFiles/extractable_full_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/extractable_full_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/extractable_full_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..5a27770 --- /dev/null +++ b/test/build-asan/CMakeFiles/extractable_full_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/extractable_full_test.dir/link.d" + "CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o" + "CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o.d" + "bin/extractable_full_test" + "bin/extractable_full_test.pdb" + "extractable_full_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/extractable_full_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/extractable_full_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/extractable_full_test.dir/compiler_depend.make new file mode 100644 index 0000000..0581c42 --- /dev/null +++ b/test/build-asan/CMakeFiles/extractable_full_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for extractable_full_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/extractable_full_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/extractable_full_test.dir/compiler_depend.ts new file mode 100644 index 0000000..e668d79 --- /dev/null +++ b/test/build-asan/CMakeFiles/extractable_full_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for extractable_full_test. diff --git a/test/build-asan/CMakeFiles/extractable_full_test.dir/depend.make b/test/build-asan/CMakeFiles/extractable_full_test.dir/depend.make new file mode 100644 index 0000000..151f368 --- /dev/null +++ b/test/build-asan/CMakeFiles/extractable_full_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for extractable_full_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/extractable_full_test.dir/flags.make b/test/build-asan/CMakeFiles/extractable_full_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/extractable_full_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/extractable_full_test.dir/link.txt b/test/build-asan/CMakeFiles/extractable_full_test.dir/link.txt new file mode 100644 index 0000000..0e7089b --- /dev/null +++ b/test/build-asan/CMakeFiles/extractable_full_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/extractable_full_test.dir/link.d CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o -o bin/extractable_full_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/extractable_full_test.dir/progress.make b/test/build-asan/CMakeFiles/extractable_full_test.dir/progress.make new file mode 100644 index 0000000..527b7e9 --- /dev/null +++ b/test/build-asan/CMakeFiles/extractable_full_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 34 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/field_output_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/field_output_test.dir/DependInfo.cmake new file mode 100644 index 0000000..4bf1b7a --- /dev/null +++ b/test/build-asan/CMakeFiles/field_output_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/field_output_test.cpp" "CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o" "gcc" "CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o.d" + "" "bin/field_output_test" "gcc" "CMakeFiles/field_output_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/field_output_test.dir/build.make b/test/build-asan/CMakeFiles/field_output_test.dir/build.make new file mode 100644 index 0000000..381a016 --- /dev/null +++ b/test/build-asan/CMakeFiles/field_output_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/field_output_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/field_output_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/field_output_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/field_output_test.dir/flags.make + +CMakeFiles/field_output_test.dir/codegen: +.PHONY : CMakeFiles/field_output_test.dir/codegen + +CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o: CMakeFiles/field_output_test.dir/flags.make +CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/field_output_test.cpp +CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o: CMakeFiles/field_output_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o -MF CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o.d -o CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/field_output_test.cpp + +CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/field_output_test.cpp > CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.i + +CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/field_output_test.cpp -o CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.s + +# Object files for target field_output_test +field_output_test_OBJECTS = \ +"CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o" + +# External object files for target field_output_test +field_output_test_EXTERNAL_OBJECTS = + +bin/field_output_test: CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o +bin/field_output_test: CMakeFiles/field_output_test.dir/build.make +bin/field_output_test: CMakeFiles/field_output_test.dir/compiler_depend.ts +bin/field_output_test: lib/libgtest_main.a +bin/field_output_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/field_output_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/field_output_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/field_output_test: lib/libgtest.a +bin/field_output_test: CMakeFiles/field_output_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/field_output_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/field_output_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=field_output_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/field_output_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=field_output_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/field_output_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/field_output_test.dir/build: bin/field_output_test +.PHONY : CMakeFiles/field_output_test.dir/build + +CMakeFiles/field_output_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/field_output_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/field_output_test.dir/clean + +CMakeFiles/field_output_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/field_output_test.dir/DependInfo.cmake "--color=$(COLOR)" field_output_test +.PHONY : CMakeFiles/field_output_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/field_output_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/field_output_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..8e821b0 --- /dev/null +++ b/test/build-asan/CMakeFiles/field_output_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/field_output_test.dir/link.d" + "CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o" + "CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o.d" + "bin/field_output_test" + "bin/field_output_test.pdb" + "field_output_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/field_output_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/field_output_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/field_output_test.dir/compiler_depend.make new file mode 100644 index 0000000..28c8c65 --- /dev/null +++ b/test/build-asan/CMakeFiles/field_output_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for field_output_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/field_output_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/field_output_test.dir/compiler_depend.ts new file mode 100644 index 0000000..e04f62a --- /dev/null +++ b/test/build-asan/CMakeFiles/field_output_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for field_output_test. diff --git a/test/build-asan/CMakeFiles/field_output_test.dir/depend.make b/test/build-asan/CMakeFiles/field_output_test.dir/depend.make new file mode 100644 index 0000000..34ce6be --- /dev/null +++ b/test/build-asan/CMakeFiles/field_output_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for field_output_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/field_output_test.dir/flags.make b/test/build-asan/CMakeFiles/field_output_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/field_output_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/field_output_test.dir/link.txt b/test/build-asan/CMakeFiles/field_output_test.dir/link.txt new file mode 100644 index 0000000..ba67874 --- /dev/null +++ b/test/build-asan/CMakeFiles/field_output_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/field_output_test.dir/link.d CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o -o bin/field_output_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/field_output_test.dir/progress.make b/test/build-asan/CMakeFiles/field_output_test.dir/progress.make new file mode 100644 index 0000000..7bd5b17 --- /dev/null +++ b/test/build-asan/CMakeFiles/field_output_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 35 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/DependInfo.cmake new file mode 100644 index 0000000..df96474 --- /dev/null +++ b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/fixedpoint_beaver_test.cpp" "CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o" "gcc" "CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o.d" + "" "bin/fixedpoint_beaver_test" "gcc" "CMakeFiles/fixedpoint_beaver_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/build.make b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/build.make new file mode 100644 index 0000000..9c8c66d --- /dev/null +++ b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/fixedpoint_beaver_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/fixedpoint_beaver_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/fixedpoint_beaver_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/fixedpoint_beaver_test.dir/flags.make + +CMakeFiles/fixedpoint_beaver_test.dir/codegen: +.PHONY : CMakeFiles/fixedpoint_beaver_test.dir/codegen + +CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o: CMakeFiles/fixedpoint_beaver_test.dir/flags.make +CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/fixedpoint_beaver_test.cpp +CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o: CMakeFiles/fixedpoint_beaver_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o -MF CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o.d -o CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/fixedpoint_beaver_test.cpp + +CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/fixedpoint_beaver_test.cpp > CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.i + +CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/fixedpoint_beaver_test.cpp -o CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.s + +# Object files for target fixedpoint_beaver_test +fixedpoint_beaver_test_OBJECTS = \ +"CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o" + +# External object files for target fixedpoint_beaver_test +fixedpoint_beaver_test_EXTERNAL_OBJECTS = + +bin/fixedpoint_beaver_test: CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o +bin/fixedpoint_beaver_test: CMakeFiles/fixedpoint_beaver_test.dir/build.make +bin/fixedpoint_beaver_test: CMakeFiles/fixedpoint_beaver_test.dir/compiler_depend.ts +bin/fixedpoint_beaver_test: lib/libgtest_main.a +bin/fixedpoint_beaver_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/fixedpoint_beaver_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/fixedpoint_beaver_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/fixedpoint_beaver_test: lib/libgtest.a +bin/fixedpoint_beaver_test: CMakeFiles/fixedpoint_beaver_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/fixedpoint_beaver_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/fixedpoint_beaver_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=fixedpoint_beaver_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/fixedpoint_beaver_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=fixedpoint_beaver_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/fixedpoint_beaver_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/fixedpoint_beaver_test.dir/build: bin/fixedpoint_beaver_test +.PHONY : CMakeFiles/fixedpoint_beaver_test.dir/build + +CMakeFiles/fixedpoint_beaver_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/fixedpoint_beaver_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/fixedpoint_beaver_test.dir/clean + +CMakeFiles/fixedpoint_beaver_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/DependInfo.cmake "--color=$(COLOR)" fixedpoint_beaver_test +.PHONY : CMakeFiles/fixedpoint_beaver_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..0a8c41e --- /dev/null +++ b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/fixedpoint_beaver_test.dir/link.d" + "CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o" + "CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o.d" + "bin/fixedpoint_beaver_test" + "bin/fixedpoint_beaver_test.pdb" + "fixedpoint_beaver_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/fixedpoint_beaver_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/compiler_depend.make new file mode 100644 index 0000000..81d1ea9 --- /dev/null +++ b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for fixedpoint_beaver_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/compiler_depend.ts new file mode 100644 index 0000000..18561d5 --- /dev/null +++ b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for fixedpoint_beaver_test. diff --git a/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/depend.make b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/depend.make new file mode 100644 index 0000000..942a05f --- /dev/null +++ b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for fixedpoint_beaver_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/flags.make b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/link.txt b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/link.txt new file mode 100644 index 0000000..7f8066f --- /dev/null +++ b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/fixedpoint_beaver_test.dir/link.d CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o -o bin/fixedpoint_beaver_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/progress.make b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/progress.make new file mode 100644 index 0000000..6e0170c --- /dev/null +++ b/test/build-asan/CMakeFiles/fixedpoint_beaver_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 36 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/flute_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/flute_test.dir/DependInfo.cmake new file mode 100644 index 0000000..e669825 --- /dev/null +++ b/test/build-asan/CMakeFiles/flute_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/flute_test.cpp" "CMakeFiles/flute_test.dir/tests/flute_test.cpp.o" "gcc" "CMakeFiles/flute_test.dir/tests/flute_test.cpp.o.d" + "" "bin/flute_test" "gcc" "CMakeFiles/flute_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/flute_test.dir/build.make b/test/build-asan/CMakeFiles/flute_test.dir/build.make new file mode 100644 index 0000000..c629eec --- /dev/null +++ b/test/build-asan/CMakeFiles/flute_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/flute_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/flute_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/flute_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/flute_test.dir/flags.make + +CMakeFiles/flute_test.dir/codegen: +.PHONY : CMakeFiles/flute_test.dir/codegen + +CMakeFiles/flute_test.dir/tests/flute_test.cpp.o: CMakeFiles/flute_test.dir/flags.make +CMakeFiles/flute_test.dir/tests/flute_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/flute_test.cpp +CMakeFiles/flute_test.dir/tests/flute_test.cpp.o: CMakeFiles/flute_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/flute_test.dir/tests/flute_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/flute_test.dir/tests/flute_test.cpp.o -MF CMakeFiles/flute_test.dir/tests/flute_test.cpp.o.d -o CMakeFiles/flute_test.dir/tests/flute_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/flute_test.cpp + +CMakeFiles/flute_test.dir/tests/flute_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/flute_test.dir/tests/flute_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/flute_test.cpp > CMakeFiles/flute_test.dir/tests/flute_test.cpp.i + +CMakeFiles/flute_test.dir/tests/flute_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/flute_test.dir/tests/flute_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/flute_test.cpp -o CMakeFiles/flute_test.dir/tests/flute_test.cpp.s + +# Object files for target flute_test +flute_test_OBJECTS = \ +"CMakeFiles/flute_test.dir/tests/flute_test.cpp.o" + +# External object files for target flute_test +flute_test_EXTERNAL_OBJECTS = + +bin/flute_test: CMakeFiles/flute_test.dir/tests/flute_test.cpp.o +bin/flute_test: CMakeFiles/flute_test.dir/build.make +bin/flute_test: CMakeFiles/flute_test.dir/compiler_depend.ts +bin/flute_test: lib/libgtest_main.a +bin/flute_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/flute_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/flute_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/flute_test: lib/libgtest.a +bin/flute_test: CMakeFiles/flute_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/flute_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/flute_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=flute_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/flute_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=flute_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/flute_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/flute_test.dir/build: bin/flute_test +.PHONY : CMakeFiles/flute_test.dir/build + +CMakeFiles/flute_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/flute_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/flute_test.dir/clean + +CMakeFiles/flute_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/flute_test.dir/DependInfo.cmake "--color=$(COLOR)" flute_test +.PHONY : CMakeFiles/flute_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/flute_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/flute_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..4681a1a --- /dev/null +++ b/test/build-asan/CMakeFiles/flute_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/flute_test.dir/link.d" + "CMakeFiles/flute_test.dir/tests/flute_test.cpp.o" + "CMakeFiles/flute_test.dir/tests/flute_test.cpp.o.d" + "bin/flute_test" + "bin/flute_test.pdb" + "flute_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/flute_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/flute_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/flute_test.dir/compiler_depend.make new file mode 100644 index 0000000..1b0036f --- /dev/null +++ b/test/build-asan/CMakeFiles/flute_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for flute_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/flute_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/flute_test.dir/compiler_depend.ts new file mode 100644 index 0000000..31fb74a --- /dev/null +++ b/test/build-asan/CMakeFiles/flute_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for flute_test. diff --git a/test/build-asan/CMakeFiles/flute_test.dir/depend.make b/test/build-asan/CMakeFiles/flute_test.dir/depend.make new file mode 100644 index 0000000..87ec65f --- /dev/null +++ b/test/build-asan/CMakeFiles/flute_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for flute_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/flute_test.dir/flags.make b/test/build-asan/CMakeFiles/flute_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/flute_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/flute_test.dir/link.txt b/test/build-asan/CMakeFiles/flute_test.dir/link.txt new file mode 100644 index 0000000..ce4db87 --- /dev/null +++ b/test/build-asan/CMakeFiles/flute_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/flute_test.dir/link.d CMakeFiles/flute_test.dir/tests/flute_test.cpp.o -o bin/flute_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/flute_test.dir/progress.make b/test/build-asan/CMakeFiles/flute_test.dir/progress.make new file mode 100644 index 0000000..cf9bccf --- /dev/null +++ b/test/build-asan/CMakeFiles/flute_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 37 + diff --git a/test/build-asan/CMakeFiles/fp61_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/fp61_test.dir/DependInfo.cmake new file mode 100644 index 0000000..d71f5ca --- /dev/null +++ b/test/build-asan/CMakeFiles/fp61_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/fp61_test.cpp" "CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o" "gcc" "CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o.d" + "" "bin/fp61_test" "gcc" "CMakeFiles/fp61_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/fp61_test.dir/build.make b/test/build-asan/CMakeFiles/fp61_test.dir/build.make new file mode 100644 index 0000000..c56a285 --- /dev/null +++ b/test/build-asan/CMakeFiles/fp61_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/fp61_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/fp61_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/fp61_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/fp61_test.dir/flags.make + +CMakeFiles/fp61_test.dir/codegen: +.PHONY : CMakeFiles/fp61_test.dir/codegen + +CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o: CMakeFiles/fp61_test.dir/flags.make +CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/fp61_test.cpp +CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o: CMakeFiles/fp61_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o -MF CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o.d -o CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/fp61_test.cpp + +CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/fp61_test.cpp > CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.i + +CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/fp61_test.cpp -o CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.s + +# Object files for target fp61_test +fp61_test_OBJECTS = \ +"CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o" + +# External object files for target fp61_test +fp61_test_EXTERNAL_OBJECTS = + +bin/fp61_test: CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o +bin/fp61_test: CMakeFiles/fp61_test.dir/build.make +bin/fp61_test: CMakeFiles/fp61_test.dir/compiler_depend.ts +bin/fp61_test: lib/libgtest_main.a +bin/fp61_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/fp61_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/fp61_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/fp61_test: lib/libgtest.a +bin/fp61_test: CMakeFiles/fp61_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/fp61_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/fp61_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=fp61_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/fp61_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=fp61_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/fp61_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/fp61_test.dir/build: bin/fp61_test +.PHONY : CMakeFiles/fp61_test.dir/build + +CMakeFiles/fp61_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/fp61_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/fp61_test.dir/clean + +CMakeFiles/fp61_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/fp61_test.dir/DependInfo.cmake "--color=$(COLOR)" fp61_test +.PHONY : CMakeFiles/fp61_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/fp61_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/fp61_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..de24efc --- /dev/null +++ b/test/build-asan/CMakeFiles/fp61_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/fp61_test.dir/link.d" + "CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o" + "CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o.d" + "bin/fp61_test" + "bin/fp61_test.pdb" + "fp61_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/fp61_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/fp61_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/fp61_test.dir/compiler_depend.make new file mode 100644 index 0000000..83dbdfc --- /dev/null +++ b/test/build-asan/CMakeFiles/fp61_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for fp61_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/fp61_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/fp61_test.dir/compiler_depend.ts new file mode 100644 index 0000000..f7224a0 --- /dev/null +++ b/test/build-asan/CMakeFiles/fp61_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for fp61_test. diff --git a/test/build-asan/CMakeFiles/fp61_test.dir/depend.make b/test/build-asan/CMakeFiles/fp61_test.dir/depend.make new file mode 100644 index 0000000..f602f1d --- /dev/null +++ b/test/build-asan/CMakeFiles/fp61_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for fp61_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/fp61_test.dir/flags.make b/test/build-asan/CMakeFiles/fp61_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/fp61_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/fp61_test.dir/link.txt b/test/build-asan/CMakeFiles/fp61_test.dir/link.txt new file mode 100644 index 0000000..d889d8c --- /dev/null +++ b/test/build-asan/CMakeFiles/fp61_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/fp61_test.dir/link.d CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o -o bin/fp61_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/fp61_test.dir/progress.make b/test/build-asan/CMakeFiles/fp61_test.dir/progress.make new file mode 100644 index 0000000..6abee2c --- /dev/null +++ b/test/build-asan/CMakeFiles/fp61_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 38 + diff --git a/test/build-asan/CMakeFiles/geneval_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/geneval_test.dir/DependInfo.cmake new file mode 100644 index 0000000..4e3625d --- /dev/null +++ b/test/build-asan/CMakeFiles/geneval_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp" "CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o" "gcc" "CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o.d" + "" "bin/geneval_test" "gcc" "CMakeFiles/geneval_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/geneval_test.dir/build.make b/test/build-asan/CMakeFiles/geneval_test.dir/build.make new file mode 100644 index 0000000..f1bc833 --- /dev/null +++ b/test/build-asan/CMakeFiles/geneval_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/geneval_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/geneval_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/geneval_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/geneval_test.dir/flags.make + +CMakeFiles/geneval_test.dir/codegen: +.PHONY : CMakeFiles/geneval_test.dir/codegen + +CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o: CMakeFiles/geneval_test.dir/flags.make +CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp +CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o: CMakeFiles/geneval_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o -MF CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o.d -o CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp + +CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp > CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.i + +CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp -o CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.s + +# Object files for target geneval_test +geneval_test_OBJECTS = \ +"CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o" + +# External object files for target geneval_test +geneval_test_EXTERNAL_OBJECTS = + +bin/geneval_test: CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o +bin/geneval_test: CMakeFiles/geneval_test.dir/build.make +bin/geneval_test: CMakeFiles/geneval_test.dir/compiler_depend.ts +bin/geneval_test: lib/libgtest_main.a +bin/geneval_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/geneval_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/geneval_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/geneval_test: lib/libgtest.a +bin/geneval_test: CMakeFiles/geneval_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/geneval_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/geneval_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=geneval_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=geneval_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/geneval_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/geneval_test.dir/build: bin/geneval_test +.PHONY : CMakeFiles/geneval_test.dir/build + +CMakeFiles/geneval_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/geneval_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/geneval_test.dir/clean + +CMakeFiles/geneval_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/geneval_test.dir/DependInfo.cmake "--color=$(COLOR)" geneval_test +.PHONY : CMakeFiles/geneval_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/geneval_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/geneval_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..aaea476 --- /dev/null +++ b/test/build-asan/CMakeFiles/geneval_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/geneval_test.dir/link.d" + "CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o" + "CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o.d" + "bin/geneval_test" + "bin/geneval_test.pdb" + "geneval_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/geneval_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/geneval_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/geneval_test.dir/compiler_depend.make new file mode 100644 index 0000000..dda38f3 --- /dev/null +++ b/test/build-asan/CMakeFiles/geneval_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for geneval_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/geneval_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/geneval_test.dir/compiler_depend.ts new file mode 100644 index 0000000..80330c3 --- /dev/null +++ b/test/build-asan/CMakeFiles/geneval_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for geneval_test. diff --git a/test/build-asan/CMakeFiles/geneval_test.dir/depend.make b/test/build-asan/CMakeFiles/geneval_test.dir/depend.make new file mode 100644 index 0000000..5a1cea8 --- /dev/null +++ b/test/build-asan/CMakeFiles/geneval_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for geneval_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/geneval_test.dir/flags.make b/test/build-asan/CMakeFiles/geneval_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/geneval_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/geneval_test.dir/link.txt b/test/build-asan/CMakeFiles/geneval_test.dir/link.txt new file mode 100644 index 0000000..95d087d --- /dev/null +++ b/test/build-asan/CMakeFiles/geneval_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/geneval_test.dir/link.d CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o -o bin/geneval_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/geneval_test.dir/progress.make b/test/build-asan/CMakeFiles/geneval_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/geneval_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/DependInfo.cmake new file mode 100644 index 0000000..fee172c --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/gf2_adversarial_test.cpp" "CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o" "gcc" "CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o.d" + "" "bin/gf2_adversarial_test" "gcc" "CMakeFiles/gf2_adversarial_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/build.make b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/build.make new file mode 100644 index 0000000..e55ac09 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/gf2_adversarial_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/gf2_adversarial_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/gf2_adversarial_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/gf2_adversarial_test.dir/flags.make + +CMakeFiles/gf2_adversarial_test.dir/codegen: +.PHONY : CMakeFiles/gf2_adversarial_test.dir/codegen + +CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o: CMakeFiles/gf2_adversarial_test.dir/flags.make +CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/gf2_adversarial_test.cpp +CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o: CMakeFiles/gf2_adversarial_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o -MF CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o.d -o CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/gf2_adversarial_test.cpp + +CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/gf2_adversarial_test.cpp > CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.i + +CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/gf2_adversarial_test.cpp -o CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.s + +# Object files for target gf2_adversarial_test +gf2_adversarial_test_OBJECTS = \ +"CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o" + +# External object files for target gf2_adversarial_test +gf2_adversarial_test_EXTERNAL_OBJECTS = + +bin/gf2_adversarial_test: CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o +bin/gf2_adversarial_test: CMakeFiles/gf2_adversarial_test.dir/build.make +bin/gf2_adversarial_test: CMakeFiles/gf2_adversarial_test.dir/compiler_depend.ts +bin/gf2_adversarial_test: lib/libgtest_main.a +bin/gf2_adversarial_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/gf2_adversarial_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/gf2_adversarial_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/gf2_adversarial_test: lib/libgtest.a +bin/gf2_adversarial_test: CMakeFiles/gf2_adversarial_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/gf2_adversarial_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/gf2_adversarial_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=gf2_adversarial_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/gf2_adversarial_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=gf2_adversarial_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/gf2_adversarial_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/gf2_adversarial_test.dir/build: bin/gf2_adversarial_test +.PHONY : CMakeFiles/gf2_adversarial_test.dir/build + +CMakeFiles/gf2_adversarial_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/gf2_adversarial_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/gf2_adversarial_test.dir/clean + +CMakeFiles/gf2_adversarial_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/DependInfo.cmake "--color=$(COLOR)" gf2_adversarial_test +.PHONY : CMakeFiles/gf2_adversarial_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..8ec7e78 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/gf2_adversarial_test.dir/link.d" + "CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o" + "CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o.d" + "bin/gf2_adversarial_test" + "bin/gf2_adversarial_test.pdb" + "gf2_adversarial_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/gf2_adversarial_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/compiler_depend.make new file mode 100644 index 0000000..0961e7e --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for gf2_adversarial_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/compiler_depend.ts new file mode 100644 index 0000000..3b0c27c --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for gf2_adversarial_test. diff --git a/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/depend.make b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/depend.make new file mode 100644 index 0000000..8619ed0 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for gf2_adversarial_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/flags.make b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/link.txt b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/link.txt new file mode 100644 index 0000000..108d7e4 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/gf2_adversarial_test.dir/link.d CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o -o bin/gf2_adversarial_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/progress.make b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/progress.make new file mode 100644 index 0000000..878d1f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_adversarial_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 39 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/gf2_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/gf2_test.dir/DependInfo.cmake new file mode 100644 index 0000000..9b36ba5 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/gf2_test.cpp" "CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o" "gcc" "CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o.d" + "" "bin/gf2_test" "gcc" "CMakeFiles/gf2_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/gf2_test.dir/build.make b/test/build-asan/CMakeFiles/gf2_test.dir/build.make new file mode 100644 index 0000000..767a0c0 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/gf2_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/gf2_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/gf2_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/gf2_test.dir/flags.make + +CMakeFiles/gf2_test.dir/codegen: +.PHONY : CMakeFiles/gf2_test.dir/codegen + +CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o: CMakeFiles/gf2_test.dir/flags.make +CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/gf2_test.cpp +CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o: CMakeFiles/gf2_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o -MF CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o.d -o CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/gf2_test.cpp + +CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/gf2_test.cpp > CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.i + +CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/gf2_test.cpp -o CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.s + +# Object files for target gf2_test +gf2_test_OBJECTS = \ +"CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o" + +# External object files for target gf2_test +gf2_test_EXTERNAL_OBJECTS = + +bin/gf2_test: CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o +bin/gf2_test: CMakeFiles/gf2_test.dir/build.make +bin/gf2_test: CMakeFiles/gf2_test.dir/compiler_depend.ts +bin/gf2_test: lib/libgtest_main.a +bin/gf2_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/gf2_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/gf2_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/gf2_test: lib/libgtest.a +bin/gf2_test: CMakeFiles/gf2_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/gf2_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/gf2_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=gf2_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/gf2_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=gf2_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/gf2_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/gf2_test.dir/build: bin/gf2_test +.PHONY : CMakeFiles/gf2_test.dir/build + +CMakeFiles/gf2_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/gf2_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/gf2_test.dir/clean + +CMakeFiles/gf2_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/gf2_test.dir/DependInfo.cmake "--color=$(COLOR)" gf2_test +.PHONY : CMakeFiles/gf2_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/gf2_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/gf2_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..d89b9d2 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/gf2_test.dir/link.d" + "CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o" + "CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o.d" + "bin/gf2_test" + "bin/gf2_test.pdb" + "gf2_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/gf2_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/gf2_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/gf2_test.dir/compiler_depend.make new file mode 100644 index 0000000..b354354 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for gf2_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/gf2_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/gf2_test.dir/compiler_depend.ts new file mode 100644 index 0000000..255afb9 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for gf2_test. diff --git a/test/build-asan/CMakeFiles/gf2_test.dir/depend.make b/test/build-asan/CMakeFiles/gf2_test.dir/depend.make new file mode 100644 index 0000000..82a21e5 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for gf2_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/gf2_test.dir/flags.make b/test/build-asan/CMakeFiles/gf2_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/gf2_test.dir/link.txt b/test/build-asan/CMakeFiles/gf2_test.dir/link.txt new file mode 100644 index 0000000..c7c246e --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/gf2_test.dir/link.d CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o -o bin/gf2_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/gf2_test.dir/progress.make b/test/build-asan/CMakeFiles/gf2_test.dir/progress.make new file mode 100644 index 0000000..d0499d0 --- /dev/null +++ b/test/build-asan/CMakeFiles/gf2_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 40 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/growing_idpf_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/growing_idpf_test.dir/DependInfo.cmake new file mode 100644 index 0000000..d172669 --- /dev/null +++ b/test/build-asan/CMakeFiles/growing_idpf_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp" "CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o" "gcc" "CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o.d" + "" "bin/growing_idpf_test" "gcc" "CMakeFiles/growing_idpf_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/growing_idpf_test.dir/build.make b/test/build-asan/CMakeFiles/growing_idpf_test.dir/build.make new file mode 100644 index 0000000..aeede1b --- /dev/null +++ b/test/build-asan/CMakeFiles/growing_idpf_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/growing_idpf_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/growing_idpf_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/growing_idpf_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/growing_idpf_test.dir/flags.make + +CMakeFiles/growing_idpf_test.dir/codegen: +.PHONY : CMakeFiles/growing_idpf_test.dir/codegen + +CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o: CMakeFiles/growing_idpf_test.dir/flags.make +CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp +CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o: CMakeFiles/growing_idpf_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o -MF CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o.d -o CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp + +CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp > CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.i + +CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp -o CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.s + +# Object files for target growing_idpf_test +growing_idpf_test_OBJECTS = \ +"CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o" + +# External object files for target growing_idpf_test +growing_idpf_test_EXTERNAL_OBJECTS = + +bin/growing_idpf_test: CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o +bin/growing_idpf_test: CMakeFiles/growing_idpf_test.dir/build.make +bin/growing_idpf_test: CMakeFiles/growing_idpf_test.dir/compiler_depend.ts +bin/growing_idpf_test: lib/libgtest_main.a +bin/growing_idpf_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/growing_idpf_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/growing_idpf_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/growing_idpf_test: lib/libgtest.a +bin/growing_idpf_test: CMakeFiles/growing_idpf_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/growing_idpf_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/growing_idpf_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=growing_idpf_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=growing_idpf_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/growing_idpf_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/growing_idpf_test.dir/build: bin/growing_idpf_test +.PHONY : CMakeFiles/growing_idpf_test.dir/build + +CMakeFiles/growing_idpf_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/growing_idpf_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/growing_idpf_test.dir/clean + +CMakeFiles/growing_idpf_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/growing_idpf_test.dir/DependInfo.cmake "--color=$(COLOR)" growing_idpf_test +.PHONY : CMakeFiles/growing_idpf_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/growing_idpf_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/growing_idpf_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..87db380 --- /dev/null +++ b/test/build-asan/CMakeFiles/growing_idpf_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/growing_idpf_test.dir/link.d" + "CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o" + "CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o.d" + "bin/growing_idpf_test" + "bin/growing_idpf_test.pdb" + "growing_idpf_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/growing_idpf_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/growing_idpf_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/growing_idpf_test.dir/compiler_depend.make new file mode 100644 index 0000000..fac8501 --- /dev/null +++ b/test/build-asan/CMakeFiles/growing_idpf_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for growing_idpf_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/growing_idpf_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/growing_idpf_test.dir/compiler_depend.ts new file mode 100644 index 0000000..ec14691 --- /dev/null +++ b/test/build-asan/CMakeFiles/growing_idpf_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for growing_idpf_test. diff --git a/test/build-asan/CMakeFiles/growing_idpf_test.dir/depend.make b/test/build-asan/CMakeFiles/growing_idpf_test.dir/depend.make new file mode 100644 index 0000000..d6e403f --- /dev/null +++ b/test/build-asan/CMakeFiles/growing_idpf_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for growing_idpf_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/growing_idpf_test.dir/flags.make b/test/build-asan/CMakeFiles/growing_idpf_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/growing_idpf_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/growing_idpf_test.dir/link.txt b/test/build-asan/CMakeFiles/growing_idpf_test.dir/link.txt new file mode 100644 index 0000000..18f340a --- /dev/null +++ b/test/build-asan/CMakeFiles/growing_idpf_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/growing_idpf_test.dir/link.d CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o -o bin/growing_idpf_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/growing_idpf_test.dir/progress.make b/test/build-asan/CMakeFiles/growing_idpf_test.dir/progress.make new file mode 100644 index 0000000..99f4ee9 --- /dev/null +++ b/test/build-asan/CMakeFiles/growing_idpf_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 41 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/half_tree_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/half_tree_test.dir/DependInfo.cmake new file mode 100644 index 0000000..9f65539 --- /dev/null +++ b/test/build-asan/CMakeFiles/half_tree_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp" "CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o" "gcc" "CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o.d" + "" "bin/half_tree_test" "gcc" "CMakeFiles/half_tree_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/half_tree_test.dir/build.make b/test/build-asan/CMakeFiles/half_tree_test.dir/build.make new file mode 100644 index 0000000..36e17a3 --- /dev/null +++ b/test/build-asan/CMakeFiles/half_tree_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/half_tree_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/half_tree_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/half_tree_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/half_tree_test.dir/flags.make + +CMakeFiles/half_tree_test.dir/codegen: +.PHONY : CMakeFiles/half_tree_test.dir/codegen + +CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o: CMakeFiles/half_tree_test.dir/flags.make +CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp +CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o: CMakeFiles/half_tree_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o -MF CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o.d -o CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp + +CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp > CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.i + +CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp -o CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.s + +# Object files for target half_tree_test +half_tree_test_OBJECTS = \ +"CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o" + +# External object files for target half_tree_test +half_tree_test_EXTERNAL_OBJECTS = + +bin/half_tree_test: CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o +bin/half_tree_test: CMakeFiles/half_tree_test.dir/build.make +bin/half_tree_test: CMakeFiles/half_tree_test.dir/compiler_depend.ts +bin/half_tree_test: lib/libgtest_main.a +bin/half_tree_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/half_tree_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/half_tree_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/half_tree_test: lib/libgtest.a +bin/half_tree_test: CMakeFiles/half_tree_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/half_tree_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/half_tree_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=half_tree_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/half_tree_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=half_tree_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/half_tree_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/half_tree_test.dir/build: bin/half_tree_test +.PHONY : CMakeFiles/half_tree_test.dir/build + +CMakeFiles/half_tree_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/half_tree_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/half_tree_test.dir/clean + +CMakeFiles/half_tree_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/half_tree_test.dir/DependInfo.cmake "--color=$(COLOR)" half_tree_test +.PHONY : CMakeFiles/half_tree_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/half_tree_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/half_tree_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..287f7db --- /dev/null +++ b/test/build-asan/CMakeFiles/half_tree_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/half_tree_test.dir/link.d" + "CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o" + "CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o.d" + "bin/half_tree_test" + "bin/half_tree_test.pdb" + "half_tree_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/half_tree_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/half_tree_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/half_tree_test.dir/compiler_depend.make new file mode 100644 index 0000000..192d753 --- /dev/null +++ b/test/build-asan/CMakeFiles/half_tree_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for half_tree_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/half_tree_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/half_tree_test.dir/compiler_depend.ts new file mode 100644 index 0000000..7e96a69 --- /dev/null +++ b/test/build-asan/CMakeFiles/half_tree_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for half_tree_test. diff --git a/test/build-asan/CMakeFiles/half_tree_test.dir/depend.make b/test/build-asan/CMakeFiles/half_tree_test.dir/depend.make new file mode 100644 index 0000000..19fc7be --- /dev/null +++ b/test/build-asan/CMakeFiles/half_tree_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for half_tree_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/half_tree_test.dir/flags.make b/test/build-asan/CMakeFiles/half_tree_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/half_tree_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/half_tree_test.dir/link.txt b/test/build-asan/CMakeFiles/half_tree_test.dir/link.txt new file mode 100644 index 0000000..09395f3 --- /dev/null +++ b/test/build-asan/CMakeFiles/half_tree_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/half_tree_test.dir/link.d CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o -o bin/half_tree_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/half_tree_test.dir/progress.make b/test/build-asan/CMakeFiles/half_tree_test.dir/progress.make new file mode 100644 index 0000000..ad6384a --- /dev/null +++ b/test/build-asan/CMakeFiles/half_tree_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 44 + diff --git a/test/build-asan/CMakeFiles/ic_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/ic_test.dir/DependInfo.cmake new file mode 100644 index 0000000..88edfb1 --- /dev/null +++ b/test/build-asan/CMakeFiles/ic_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp" "CMakeFiles/ic_test.dir/tests/ic_test.cpp.o" "gcc" "CMakeFiles/ic_test.dir/tests/ic_test.cpp.o.d" + "" "bin/ic_test" "gcc" "CMakeFiles/ic_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/ic_test.dir/build.make b/test/build-asan/CMakeFiles/ic_test.dir/build.make new file mode 100644 index 0000000..02b5150 --- /dev/null +++ b/test/build-asan/CMakeFiles/ic_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/ic_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/ic_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/ic_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/ic_test.dir/flags.make + +CMakeFiles/ic_test.dir/codegen: +.PHONY : CMakeFiles/ic_test.dir/codegen + +CMakeFiles/ic_test.dir/tests/ic_test.cpp.o: CMakeFiles/ic_test.dir/flags.make +CMakeFiles/ic_test.dir/tests/ic_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp +CMakeFiles/ic_test.dir/tests/ic_test.cpp.o: CMakeFiles/ic_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/ic_test.dir/tests/ic_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/ic_test.dir/tests/ic_test.cpp.o -MF CMakeFiles/ic_test.dir/tests/ic_test.cpp.o.d -o CMakeFiles/ic_test.dir/tests/ic_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp + +CMakeFiles/ic_test.dir/tests/ic_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/ic_test.dir/tests/ic_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp > CMakeFiles/ic_test.dir/tests/ic_test.cpp.i + +CMakeFiles/ic_test.dir/tests/ic_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/ic_test.dir/tests/ic_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp -o CMakeFiles/ic_test.dir/tests/ic_test.cpp.s + +# Object files for target ic_test +ic_test_OBJECTS = \ +"CMakeFiles/ic_test.dir/tests/ic_test.cpp.o" + +# External object files for target ic_test +ic_test_EXTERNAL_OBJECTS = + +bin/ic_test: CMakeFiles/ic_test.dir/tests/ic_test.cpp.o +bin/ic_test: CMakeFiles/ic_test.dir/build.make +bin/ic_test: CMakeFiles/ic_test.dir/compiler_depend.ts +bin/ic_test: lib/libgtest_main.a +bin/ic_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/ic_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/ic_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/ic_test: lib/libgtest.a +bin/ic_test: CMakeFiles/ic_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/ic_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/ic_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=ic_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=ic_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/ic_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/ic_test.dir/build: bin/ic_test +.PHONY : CMakeFiles/ic_test.dir/build + +CMakeFiles/ic_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/ic_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/ic_test.dir/clean + +CMakeFiles/ic_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/ic_test.dir/DependInfo.cmake "--color=$(COLOR)" ic_test +.PHONY : CMakeFiles/ic_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/ic_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/ic_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..fcd19f4 --- /dev/null +++ b/test/build-asan/CMakeFiles/ic_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/ic_test.dir/link.d" + "CMakeFiles/ic_test.dir/tests/ic_test.cpp.o" + "CMakeFiles/ic_test.dir/tests/ic_test.cpp.o.d" + "bin/ic_test" + "bin/ic_test.pdb" + "ic_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/ic_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/ic_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/ic_test.dir/compiler_depend.make new file mode 100644 index 0000000..75c0cfc --- /dev/null +++ b/test/build-asan/CMakeFiles/ic_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for ic_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/ic_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/ic_test.dir/compiler_depend.ts new file mode 100644 index 0000000..b9ae4fb --- /dev/null +++ b/test/build-asan/CMakeFiles/ic_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for ic_test. diff --git a/test/build-asan/CMakeFiles/ic_test.dir/depend.make b/test/build-asan/CMakeFiles/ic_test.dir/depend.make new file mode 100644 index 0000000..3494765 --- /dev/null +++ b/test/build-asan/CMakeFiles/ic_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for ic_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/ic_test.dir/flags.make b/test/build-asan/CMakeFiles/ic_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/ic_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/ic_test.dir/link.txt b/test/build-asan/CMakeFiles/ic_test.dir/link.txt new file mode 100644 index 0000000..5b0759d --- /dev/null +++ b/test/build-asan/CMakeFiles/ic_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/ic_test.dir/link.d CMakeFiles/ic_test.dir/tests/ic_test.cpp.o -o bin/ic_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/ic_test.dir/progress.make b/test/build-asan/CMakeFiles/ic_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/ic_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/idpf_agg_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/idpf_agg_test.dir/DependInfo.cmake new file mode 100644 index 0000000..0e38b6e --- /dev/null +++ b/test/build-asan/CMakeFiles/idpf_agg_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/idpf_agg_test.cpp" "CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o" "gcc" "CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o.d" + "" "bin/idpf_agg_test" "gcc" "CMakeFiles/idpf_agg_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/idpf_agg_test.dir/build.make b/test/build-asan/CMakeFiles/idpf_agg_test.dir/build.make new file mode 100644 index 0000000..d223633 --- /dev/null +++ b/test/build-asan/CMakeFiles/idpf_agg_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/idpf_agg_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/idpf_agg_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/idpf_agg_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/idpf_agg_test.dir/flags.make + +CMakeFiles/idpf_agg_test.dir/codegen: +.PHONY : CMakeFiles/idpf_agg_test.dir/codegen + +CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o: CMakeFiles/idpf_agg_test.dir/flags.make +CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/idpf_agg_test.cpp +CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o: CMakeFiles/idpf_agg_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o -MF CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o.d -o CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/idpf_agg_test.cpp + +CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/idpf_agg_test.cpp > CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.i + +CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/idpf_agg_test.cpp -o CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.s + +# Object files for target idpf_agg_test +idpf_agg_test_OBJECTS = \ +"CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o" + +# External object files for target idpf_agg_test +idpf_agg_test_EXTERNAL_OBJECTS = + +bin/idpf_agg_test: CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o +bin/idpf_agg_test: CMakeFiles/idpf_agg_test.dir/build.make +bin/idpf_agg_test: CMakeFiles/idpf_agg_test.dir/compiler_depend.ts +bin/idpf_agg_test: lib/libgtest_main.a +bin/idpf_agg_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/idpf_agg_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/idpf_agg_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/idpf_agg_test: lib/libgtest.a +bin/idpf_agg_test: CMakeFiles/idpf_agg_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/idpf_agg_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/idpf_agg_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=idpf_agg_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/idpf_agg_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=idpf_agg_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/idpf_agg_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/idpf_agg_test.dir/build: bin/idpf_agg_test +.PHONY : CMakeFiles/idpf_agg_test.dir/build + +CMakeFiles/idpf_agg_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/idpf_agg_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/idpf_agg_test.dir/clean + +CMakeFiles/idpf_agg_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/idpf_agg_test.dir/DependInfo.cmake "--color=$(COLOR)" idpf_agg_test +.PHONY : CMakeFiles/idpf_agg_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/idpf_agg_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/idpf_agg_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..748965c --- /dev/null +++ b/test/build-asan/CMakeFiles/idpf_agg_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/idpf_agg_test.dir/link.d" + "CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o" + "CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o.d" + "bin/idpf_agg_test" + "bin/idpf_agg_test.pdb" + "idpf_agg_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/idpf_agg_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/idpf_agg_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/idpf_agg_test.dir/compiler_depend.make new file mode 100644 index 0000000..e512a59 --- /dev/null +++ b/test/build-asan/CMakeFiles/idpf_agg_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for idpf_agg_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/idpf_agg_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/idpf_agg_test.dir/compiler_depend.ts new file mode 100644 index 0000000..64a47c2 --- /dev/null +++ b/test/build-asan/CMakeFiles/idpf_agg_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for idpf_agg_test. diff --git a/test/build-asan/CMakeFiles/idpf_agg_test.dir/depend.make b/test/build-asan/CMakeFiles/idpf_agg_test.dir/depend.make new file mode 100644 index 0000000..32aa0d9 --- /dev/null +++ b/test/build-asan/CMakeFiles/idpf_agg_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for idpf_agg_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/idpf_agg_test.dir/flags.make b/test/build-asan/CMakeFiles/idpf_agg_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/idpf_agg_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/idpf_agg_test.dir/link.txt b/test/build-asan/CMakeFiles/idpf_agg_test.dir/link.txt new file mode 100644 index 0000000..1f8d2d7 --- /dev/null +++ b/test/build-asan/CMakeFiles/idpf_agg_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/idpf_agg_test.dir/link.d CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o -o bin/idpf_agg_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/idpf_agg_test.dir/progress.make b/test/build-asan/CMakeFiles/idpf_agg_test.dir/progress.make new file mode 100644 index 0000000..f18f1bf --- /dev/null +++ b/test/build-asan/CMakeFiles/idpf_agg_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 45 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/iknp_party_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/iknp_party_test.dir/DependInfo.cmake new file mode 100644 index 0000000..6da751a --- /dev/null +++ b/test/build-asan/CMakeFiles/iknp_party_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/iknp_party_test.cpp" "CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o" "gcc" "CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o.d" + "" "bin/iknp_party_test" "gcc" "CMakeFiles/iknp_party_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/iknp_party_test.dir/build.make b/test/build-asan/CMakeFiles/iknp_party_test.dir/build.make new file mode 100644 index 0000000..7be8cd0 --- /dev/null +++ b/test/build-asan/CMakeFiles/iknp_party_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/iknp_party_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/iknp_party_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/iknp_party_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/iknp_party_test.dir/flags.make + +CMakeFiles/iknp_party_test.dir/codegen: +.PHONY : CMakeFiles/iknp_party_test.dir/codegen + +CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o: CMakeFiles/iknp_party_test.dir/flags.make +CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/iknp_party_test.cpp +CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o: CMakeFiles/iknp_party_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o -MF CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o.d -o CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/iknp_party_test.cpp + +CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/iknp_party_test.cpp > CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.i + +CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/iknp_party_test.cpp -o CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.s + +# Object files for target iknp_party_test +iknp_party_test_OBJECTS = \ +"CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o" + +# External object files for target iknp_party_test +iknp_party_test_EXTERNAL_OBJECTS = + +bin/iknp_party_test: CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o +bin/iknp_party_test: CMakeFiles/iknp_party_test.dir/build.make +bin/iknp_party_test: CMakeFiles/iknp_party_test.dir/compiler_depend.ts +bin/iknp_party_test: lib/libgtest_main.a +bin/iknp_party_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/iknp_party_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/iknp_party_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/iknp_party_test: lib/libgtest.a +bin/iknp_party_test: CMakeFiles/iknp_party_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/iknp_party_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/iknp_party_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=iknp_party_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/iknp_party_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=iknp_party_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/iknp_party_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/iknp_party_test.dir/build: bin/iknp_party_test +.PHONY : CMakeFiles/iknp_party_test.dir/build + +CMakeFiles/iknp_party_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/iknp_party_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/iknp_party_test.dir/clean + +CMakeFiles/iknp_party_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/iknp_party_test.dir/DependInfo.cmake "--color=$(COLOR)" iknp_party_test +.PHONY : CMakeFiles/iknp_party_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/iknp_party_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/iknp_party_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..7584c9b --- /dev/null +++ b/test/build-asan/CMakeFiles/iknp_party_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/iknp_party_test.dir/link.d" + "CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o" + "CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o.d" + "bin/iknp_party_test" + "bin/iknp_party_test.pdb" + "iknp_party_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/iknp_party_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/iknp_party_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/iknp_party_test.dir/compiler_depend.make new file mode 100644 index 0000000..e8af10a --- /dev/null +++ b/test/build-asan/CMakeFiles/iknp_party_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for iknp_party_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/iknp_party_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/iknp_party_test.dir/compiler_depend.ts new file mode 100644 index 0000000..1e02de6 --- /dev/null +++ b/test/build-asan/CMakeFiles/iknp_party_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for iknp_party_test. diff --git a/test/build-asan/CMakeFiles/iknp_party_test.dir/depend.make b/test/build-asan/CMakeFiles/iknp_party_test.dir/depend.make new file mode 100644 index 0000000..4da263c --- /dev/null +++ b/test/build-asan/CMakeFiles/iknp_party_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for iknp_party_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/iknp_party_test.dir/flags.make b/test/build-asan/CMakeFiles/iknp_party_test.dir/flags.make new file mode 100644 index 0000000..1a3a08d --- /dev/null +++ b/test/build-asan/CMakeFiles/iknp_party_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../party -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result -O2 + diff --git a/test/build-asan/CMakeFiles/iknp_party_test.dir/link.txt b/test/build-asan/CMakeFiles/iknp_party_test.dir/link.txt new file mode 100644 index 0000000..f534f65 --- /dev/null +++ b/test/build-asan/CMakeFiles/iknp_party_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/iknp_party_test.dir/link.d CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o -o bin/iknp_party_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so -lpthread lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/iknp_party_test.dir/progress.make b/test/build-asan/CMakeFiles/iknp_party_test.dir/progress.make new file mode 100644 index 0000000..661b7ff --- /dev/null +++ b/test/build-asan/CMakeFiles/iknp_party_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 46 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/incremental_json_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/incremental_json_test.dir/DependInfo.cmake new file mode 100644 index 0000000..eef9b17 --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_json_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_json_test.cpp" "CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o" "gcc" "CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o.d" + "" "bin/incremental_json_test" "gcc" "CMakeFiles/incremental_json_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/incremental_json_test.dir/build.make b/test/build-asan/CMakeFiles/incremental_json_test.dir/build.make new file mode 100644 index 0000000..901931d --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_json_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/incremental_json_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/incremental_json_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/incremental_json_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/incremental_json_test.dir/flags.make + +CMakeFiles/incremental_json_test.dir/codegen: +.PHONY : CMakeFiles/incremental_json_test.dir/codegen + +CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o: CMakeFiles/incremental_json_test.dir/flags.make +CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_json_test.cpp +CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o: CMakeFiles/incremental_json_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o -MF CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o.d -o CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_json_test.cpp + +CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_json_test.cpp > CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.i + +CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_json_test.cpp -o CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.s + +# Object files for target incremental_json_test +incremental_json_test_OBJECTS = \ +"CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o" + +# External object files for target incremental_json_test +incremental_json_test_EXTERNAL_OBJECTS = + +bin/incremental_json_test: CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o +bin/incremental_json_test: CMakeFiles/incremental_json_test.dir/build.make +bin/incremental_json_test: CMakeFiles/incremental_json_test.dir/compiler_depend.ts +bin/incremental_json_test: lib/libgtest_main.a +bin/incremental_json_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/incremental_json_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/incremental_json_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/incremental_json_test: lib/libgtest.a +bin/incremental_json_test: CMakeFiles/incremental_json_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/incremental_json_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/incremental_json_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=incremental_json_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_json_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=incremental_json_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/incremental_json_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/incremental_json_test.dir/build: bin/incremental_json_test +.PHONY : CMakeFiles/incremental_json_test.dir/build + +CMakeFiles/incremental_json_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/incremental_json_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/incremental_json_test.dir/clean + +CMakeFiles/incremental_json_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/incremental_json_test.dir/DependInfo.cmake "--color=$(COLOR)" incremental_json_test +.PHONY : CMakeFiles/incremental_json_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/incremental_json_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/incremental_json_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..788c624 --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_json_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/incremental_json_test.dir/link.d" + "CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o" + "CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o.d" + "bin/incremental_json_test" + "bin/incremental_json_test.pdb" + "incremental_json_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/incremental_json_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/incremental_json_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/incremental_json_test.dir/compiler_depend.make new file mode 100644 index 0000000..72293e7 --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_json_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for incremental_json_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/incremental_json_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/incremental_json_test.dir/compiler_depend.ts new file mode 100644 index 0000000..1721482 --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_json_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for incremental_json_test. diff --git a/test/build-asan/CMakeFiles/incremental_json_test.dir/depend.make b/test/build-asan/CMakeFiles/incremental_json_test.dir/depend.make new file mode 100644 index 0000000..5e19143 --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_json_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for incremental_json_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/incremental_json_test.dir/flags.make b/test/build-asan/CMakeFiles/incremental_json_test.dir/flags.make new file mode 100644 index 0000000..ba0636b --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_json_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" -DLIBDPF_HAS_NLOHMANN_JSON + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/json/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/incremental_json_test.dir/link.txt b/test/build-asan/CMakeFiles/incremental_json_test.dir/link.txt new file mode 100644 index 0000000..767ee3b --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_json_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/incremental_json_test.dir/link.d CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o -o bin/incremental_json_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/incremental_json_test.dir/progress.make b/test/build-asan/CMakeFiles/incremental_json_test.dir/progress.make new file mode 100644 index 0000000..e767016 --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_json_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 47 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/incremental_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/incremental_test.dir/DependInfo.cmake new file mode 100644 index 0000000..5733b51 --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp" "CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o" "gcc" "CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o.d" + "" "bin/incremental_test" "gcc" "CMakeFiles/incremental_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/incremental_test.dir/build.make b/test/build-asan/CMakeFiles/incremental_test.dir/build.make new file mode 100644 index 0000000..0f720b3 --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/incremental_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/incremental_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/incremental_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/incremental_test.dir/flags.make + +CMakeFiles/incremental_test.dir/codegen: +.PHONY : CMakeFiles/incremental_test.dir/codegen + +CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o: CMakeFiles/incremental_test.dir/flags.make +CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp +CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o: CMakeFiles/incremental_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o -MF CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o.d -o CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp + +CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp > CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.i + +CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp -o CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.s + +# Object files for target incremental_test +incremental_test_OBJECTS = \ +"CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o" + +# External object files for target incremental_test +incremental_test_EXTERNAL_OBJECTS = + +bin/incremental_test: CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o +bin/incremental_test: CMakeFiles/incremental_test.dir/build.make +bin/incremental_test: CMakeFiles/incremental_test.dir/compiler_depend.ts +bin/incremental_test: lib/libgtest_main.a +bin/incremental_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/incremental_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/incremental_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/incremental_test: lib/libgtest.a +bin/incremental_test: CMakeFiles/incremental_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/incremental_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/incremental_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=incremental_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=incremental_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/incremental_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/incremental_test.dir/build: bin/incremental_test +.PHONY : CMakeFiles/incremental_test.dir/build + +CMakeFiles/incremental_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/incremental_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/incremental_test.dir/clean + +CMakeFiles/incremental_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/incremental_test.dir/DependInfo.cmake "--color=$(COLOR)" incremental_test +.PHONY : CMakeFiles/incremental_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/incremental_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/incremental_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..eefdbdd --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/incremental_test.dir/link.d" + "CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o" + "CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o.d" + "bin/incremental_test" + "bin/incremental_test.pdb" + "incremental_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/incremental_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/incremental_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/incremental_test.dir/compiler_depend.make new file mode 100644 index 0000000..dbeda2d --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for incremental_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/incremental_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/incremental_test.dir/compiler_depend.ts new file mode 100644 index 0000000..0c8d1c9 --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for incremental_test. diff --git a/test/build-asan/CMakeFiles/incremental_test.dir/depend.make b/test/build-asan/CMakeFiles/incremental_test.dir/depend.make new file mode 100644 index 0000000..cd60d25 --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for incremental_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/incremental_test.dir/flags.make b/test/build-asan/CMakeFiles/incremental_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/incremental_test.dir/link.txt b/test/build-asan/CMakeFiles/incremental_test.dir/link.txt new file mode 100644 index 0000000..c4f4757 --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/incremental_test.dir/link.d CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o -o bin/incremental_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/incremental_test.dir/progress.make b/test/build-asan/CMakeFiles/incremental_test.dir/progress.make new file mode 100644 index 0000000..b39c96b --- /dev/null +++ b/test/build-asan/CMakeFiles/incremental_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 48 + diff --git a/test/build-asan/CMakeFiles/interleave_leaves_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/DependInfo.cmake new file mode 100644 index 0000000..552d92f --- /dev/null +++ b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/interleave_leaves_test.cpp" "CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o" "gcc" "CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o.d" + "" "bin/interleave_leaves_test" "gcc" "CMakeFiles/interleave_leaves_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/interleave_leaves_test.dir/build.make b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/build.make new file mode 100644 index 0000000..05b8dda --- /dev/null +++ b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/interleave_leaves_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/interleave_leaves_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/interleave_leaves_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/interleave_leaves_test.dir/flags.make + +CMakeFiles/interleave_leaves_test.dir/codegen: +.PHONY : CMakeFiles/interleave_leaves_test.dir/codegen + +CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o: CMakeFiles/interleave_leaves_test.dir/flags.make +CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/interleave_leaves_test.cpp +CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o: CMakeFiles/interleave_leaves_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o -MF CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o.d -o CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/interleave_leaves_test.cpp + +CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/interleave_leaves_test.cpp > CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.i + +CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/interleave_leaves_test.cpp -o CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.s + +# Object files for target interleave_leaves_test +interleave_leaves_test_OBJECTS = \ +"CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o" + +# External object files for target interleave_leaves_test +interleave_leaves_test_EXTERNAL_OBJECTS = + +bin/interleave_leaves_test: CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o +bin/interleave_leaves_test: CMakeFiles/interleave_leaves_test.dir/build.make +bin/interleave_leaves_test: CMakeFiles/interleave_leaves_test.dir/compiler_depend.ts +bin/interleave_leaves_test: lib/libgtest_main.a +bin/interleave_leaves_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/interleave_leaves_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/interleave_leaves_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/interleave_leaves_test: lib/libgtest.a +bin/interleave_leaves_test: CMakeFiles/interleave_leaves_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/interleave_leaves_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/interleave_leaves_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=interleave_leaves_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/interleave_leaves_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=interleave_leaves_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/interleave_leaves_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/interleave_leaves_test.dir/build: bin/interleave_leaves_test +.PHONY : CMakeFiles/interleave_leaves_test.dir/build + +CMakeFiles/interleave_leaves_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/interleave_leaves_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/interleave_leaves_test.dir/clean + +CMakeFiles/interleave_leaves_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/interleave_leaves_test.dir/DependInfo.cmake "--color=$(COLOR)" interleave_leaves_test +.PHONY : CMakeFiles/interleave_leaves_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/interleave_leaves_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..9879f95 --- /dev/null +++ b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/interleave_leaves_test.dir/link.d" + "CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o" + "CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o.d" + "bin/interleave_leaves_test" + "bin/interleave_leaves_test.pdb" + "interleave_leaves_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/interleave_leaves_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/interleave_leaves_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/compiler_depend.make new file mode 100644 index 0000000..f859aeb --- /dev/null +++ b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for interleave_leaves_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/interleave_leaves_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/compiler_depend.ts new file mode 100644 index 0000000..3a46f27 --- /dev/null +++ b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for interleave_leaves_test. diff --git a/test/build-asan/CMakeFiles/interleave_leaves_test.dir/depend.make b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/depend.make new file mode 100644 index 0000000..a0b40c6 --- /dev/null +++ b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for interleave_leaves_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/interleave_leaves_test.dir/flags.make b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/interleave_leaves_test.dir/link.txt b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/link.txt new file mode 100644 index 0000000..d802d7c --- /dev/null +++ b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/interleave_leaves_test.dir/link.d CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o -o bin/interleave_leaves_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/interleave_leaves_test.dir/progress.make b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/progress.make new file mode 100644 index 0000000..05fbf59 --- /dev/null +++ b/test/build-asan/CMakeFiles/interleave_leaves_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 49 + diff --git a/test/build-asan/CMakeFiles/it_dpf3_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/it_dpf3_test.dir/DependInfo.cmake new file mode 100644 index 0000000..2a54daa --- /dev/null +++ b/test/build-asan/CMakeFiles/it_dpf3_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/it_dpf3_test.cpp" "CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o" "gcc" "CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o.d" + "" "bin/it_dpf3_test" "gcc" "CMakeFiles/it_dpf3_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/it_dpf3_test.dir/build.make b/test/build-asan/CMakeFiles/it_dpf3_test.dir/build.make new file mode 100644 index 0000000..606fb6e --- /dev/null +++ b/test/build-asan/CMakeFiles/it_dpf3_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/it_dpf3_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/it_dpf3_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/it_dpf3_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/it_dpf3_test.dir/flags.make + +CMakeFiles/it_dpf3_test.dir/codegen: +.PHONY : CMakeFiles/it_dpf3_test.dir/codegen + +CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o: CMakeFiles/it_dpf3_test.dir/flags.make +CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/it_dpf3_test.cpp +CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o: CMakeFiles/it_dpf3_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o -MF CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o.d -o CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/it_dpf3_test.cpp + +CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/it_dpf3_test.cpp > CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.i + +CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/it_dpf3_test.cpp -o CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.s + +# Object files for target it_dpf3_test +it_dpf3_test_OBJECTS = \ +"CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o" + +# External object files for target it_dpf3_test +it_dpf3_test_EXTERNAL_OBJECTS = + +bin/it_dpf3_test: CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o +bin/it_dpf3_test: CMakeFiles/it_dpf3_test.dir/build.make +bin/it_dpf3_test: CMakeFiles/it_dpf3_test.dir/compiler_depend.ts +bin/it_dpf3_test: lib/libgtest_main.a +bin/it_dpf3_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/it_dpf3_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/it_dpf3_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/it_dpf3_test: lib/libgtest.a +bin/it_dpf3_test: CMakeFiles/it_dpf3_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/it_dpf3_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/it_dpf3_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=it_dpf3_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/it_dpf3_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=it_dpf3_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/it_dpf3_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/it_dpf3_test.dir/build: bin/it_dpf3_test +.PHONY : CMakeFiles/it_dpf3_test.dir/build + +CMakeFiles/it_dpf3_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/it_dpf3_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/it_dpf3_test.dir/clean + +CMakeFiles/it_dpf3_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/it_dpf3_test.dir/DependInfo.cmake "--color=$(COLOR)" it_dpf3_test +.PHONY : CMakeFiles/it_dpf3_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/it_dpf3_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/it_dpf3_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..30c583d --- /dev/null +++ b/test/build-asan/CMakeFiles/it_dpf3_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/it_dpf3_test.dir/link.d" + "CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o" + "CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o.d" + "bin/it_dpf3_test" + "bin/it_dpf3_test.pdb" + "it_dpf3_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/it_dpf3_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/it_dpf3_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/it_dpf3_test.dir/compiler_depend.make new file mode 100644 index 0000000..ac9ca56 --- /dev/null +++ b/test/build-asan/CMakeFiles/it_dpf3_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for it_dpf3_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/it_dpf3_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/it_dpf3_test.dir/compiler_depend.ts new file mode 100644 index 0000000..23a6d40 --- /dev/null +++ b/test/build-asan/CMakeFiles/it_dpf3_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for it_dpf3_test. diff --git a/test/build-asan/CMakeFiles/it_dpf3_test.dir/depend.make b/test/build-asan/CMakeFiles/it_dpf3_test.dir/depend.make new file mode 100644 index 0000000..8eb695c --- /dev/null +++ b/test/build-asan/CMakeFiles/it_dpf3_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for it_dpf3_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/it_dpf3_test.dir/flags.make b/test/build-asan/CMakeFiles/it_dpf3_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/it_dpf3_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/it_dpf3_test.dir/link.txt b/test/build-asan/CMakeFiles/it_dpf3_test.dir/link.txt new file mode 100644 index 0000000..e1140ef --- /dev/null +++ b/test/build-asan/CMakeFiles/it_dpf3_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/it_dpf3_test.dir/link.d CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o -o bin/it_dpf3_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/it_dpf3_test.dir/progress.make b/test/build-asan/CMakeFiles/it_dpf3_test.dir/progress.make new file mode 100644 index 0000000..cc669c1 --- /dev/null +++ b/test/build-asan/CMakeFiles/it_dpf3_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 50 + diff --git a/test/build-asan/CMakeFiles/keyword2_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/keyword2_test.dir/DependInfo.cmake new file mode 100644 index 0000000..f3cda01 --- /dev/null +++ b/test/build-asan/CMakeFiles/keyword2_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/keyword2_test.cpp" "CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o" "gcc" "CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o.d" + "" "bin/keyword2_test" "gcc" "CMakeFiles/keyword2_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/keyword2_test.dir/build.make b/test/build-asan/CMakeFiles/keyword2_test.dir/build.make new file mode 100644 index 0000000..e5a5230 --- /dev/null +++ b/test/build-asan/CMakeFiles/keyword2_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/keyword2_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/keyword2_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/keyword2_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/keyword2_test.dir/flags.make + +CMakeFiles/keyword2_test.dir/codegen: +.PHONY : CMakeFiles/keyword2_test.dir/codegen + +CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o: CMakeFiles/keyword2_test.dir/flags.make +CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/keyword2_test.cpp +CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o: CMakeFiles/keyword2_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o -MF CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o.d -o CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/keyword2_test.cpp + +CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/keyword2_test.cpp > CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.i + +CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/keyword2_test.cpp -o CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.s + +# Object files for target keyword2_test +keyword2_test_OBJECTS = \ +"CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o" + +# External object files for target keyword2_test +keyword2_test_EXTERNAL_OBJECTS = + +bin/keyword2_test: CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o +bin/keyword2_test: CMakeFiles/keyword2_test.dir/build.make +bin/keyword2_test: CMakeFiles/keyword2_test.dir/compiler_depend.ts +bin/keyword2_test: lib/libgtest_main.a +bin/keyword2_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/keyword2_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/keyword2_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/keyword2_test: lib/libgtest.a +bin/keyword2_test: CMakeFiles/keyword2_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/keyword2_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/keyword2_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=keyword2_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/keyword2_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=keyword2_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/keyword2_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/keyword2_test.dir/build: bin/keyword2_test +.PHONY : CMakeFiles/keyword2_test.dir/build + +CMakeFiles/keyword2_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/keyword2_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/keyword2_test.dir/clean + +CMakeFiles/keyword2_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/keyword2_test.dir/DependInfo.cmake "--color=$(COLOR)" keyword2_test +.PHONY : CMakeFiles/keyword2_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/keyword2_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/keyword2_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..86e401c --- /dev/null +++ b/test/build-asan/CMakeFiles/keyword2_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/keyword2_test.dir/link.d" + "CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o" + "CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o.d" + "bin/keyword2_test" + "bin/keyword2_test.pdb" + "keyword2_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/keyword2_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/keyword2_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/keyword2_test.dir/compiler_depend.make new file mode 100644 index 0000000..2f00da9 --- /dev/null +++ b/test/build-asan/CMakeFiles/keyword2_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for keyword2_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/keyword2_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/keyword2_test.dir/compiler_depend.ts new file mode 100644 index 0000000..1b55af1 --- /dev/null +++ b/test/build-asan/CMakeFiles/keyword2_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for keyword2_test. diff --git a/test/build-asan/CMakeFiles/keyword2_test.dir/depend.make b/test/build-asan/CMakeFiles/keyword2_test.dir/depend.make new file mode 100644 index 0000000..5b307d6 --- /dev/null +++ b/test/build-asan/CMakeFiles/keyword2_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for keyword2_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/keyword2_test.dir/flags.make b/test/build-asan/CMakeFiles/keyword2_test.dir/flags.make new file mode 100644 index 0000000..9dc6855 --- /dev/null +++ b/test/build-asan/CMakeFiles/keyword2_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result -fconstexpr-ops-limit=100000000 + diff --git a/test/build-asan/CMakeFiles/keyword2_test.dir/link.txt b/test/build-asan/CMakeFiles/keyword2_test.dir/link.txt new file mode 100644 index 0000000..0efdd39 --- /dev/null +++ b/test/build-asan/CMakeFiles/keyword2_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/keyword2_test.dir/link.d CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o -o bin/keyword2_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/keyword2_test.dir/progress.make b/test/build-asan/CMakeFiles/keyword2_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/keyword2_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/lane_blast_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/lane_blast_test.dir/DependInfo.cmake new file mode 100644 index 0000000..54239b6 --- /dev/null +++ b/test/build-asan/CMakeFiles/lane_blast_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp" "CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o" "gcc" "CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o.d" + "" "bin/lane_blast_test" "gcc" "CMakeFiles/lane_blast_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/lane_blast_test.dir/build.make b/test/build-asan/CMakeFiles/lane_blast_test.dir/build.make new file mode 100644 index 0000000..38f9763 --- /dev/null +++ b/test/build-asan/CMakeFiles/lane_blast_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/lane_blast_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/lane_blast_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/lane_blast_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/lane_blast_test.dir/flags.make + +CMakeFiles/lane_blast_test.dir/codegen: +.PHONY : CMakeFiles/lane_blast_test.dir/codegen + +CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o: CMakeFiles/lane_blast_test.dir/flags.make +CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp +CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o: CMakeFiles/lane_blast_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o -MF CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o.d -o CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp + +CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp > CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.i + +CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp -o CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.s + +# Object files for target lane_blast_test +lane_blast_test_OBJECTS = \ +"CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o" + +# External object files for target lane_blast_test +lane_blast_test_EXTERNAL_OBJECTS = + +bin/lane_blast_test: CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o +bin/lane_blast_test: CMakeFiles/lane_blast_test.dir/build.make +bin/lane_blast_test: CMakeFiles/lane_blast_test.dir/compiler_depend.ts +bin/lane_blast_test: lib/libgtest_main.a +bin/lane_blast_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/lane_blast_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/lane_blast_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/lane_blast_test: lib/libgtest.a +bin/lane_blast_test: CMakeFiles/lane_blast_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/lane_blast_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/lane_blast_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=lane_blast_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/lane_blast_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=lane_blast_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/lane_blast_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/lane_blast_test.dir/build: bin/lane_blast_test +.PHONY : CMakeFiles/lane_blast_test.dir/build + +CMakeFiles/lane_blast_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/lane_blast_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/lane_blast_test.dir/clean + +CMakeFiles/lane_blast_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/lane_blast_test.dir/DependInfo.cmake "--color=$(COLOR)" lane_blast_test +.PHONY : CMakeFiles/lane_blast_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/lane_blast_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/lane_blast_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..0f646c5 --- /dev/null +++ b/test/build-asan/CMakeFiles/lane_blast_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/lane_blast_test.dir/link.d" + "CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o" + "CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o.d" + "bin/lane_blast_test" + "bin/lane_blast_test.pdb" + "lane_blast_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/lane_blast_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/lane_blast_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/lane_blast_test.dir/compiler_depend.make new file mode 100644 index 0000000..f73adbf --- /dev/null +++ b/test/build-asan/CMakeFiles/lane_blast_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for lane_blast_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/lane_blast_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/lane_blast_test.dir/compiler_depend.ts new file mode 100644 index 0000000..d9e7af5 --- /dev/null +++ b/test/build-asan/CMakeFiles/lane_blast_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for lane_blast_test. diff --git a/test/build-asan/CMakeFiles/lane_blast_test.dir/depend.make b/test/build-asan/CMakeFiles/lane_blast_test.dir/depend.make new file mode 100644 index 0000000..7f4b18d --- /dev/null +++ b/test/build-asan/CMakeFiles/lane_blast_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for lane_blast_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/lane_blast_test.dir/flags.make b/test/build-asan/CMakeFiles/lane_blast_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/lane_blast_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/lane_blast_test.dir/link.txt b/test/build-asan/CMakeFiles/lane_blast_test.dir/link.txt new file mode 100644 index 0000000..8a09c0e --- /dev/null +++ b/test/build-asan/CMakeFiles/lane_blast_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/lane_blast_test.dir/link.d CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o -o bin/lane_blast_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/lane_blast_test.dir/progress.make b/test/build-asan/CMakeFiles/lane_blast_test.dir/progress.make new file mode 100644 index 0000000..5ffbfe8 --- /dev/null +++ b/test/build-asan/CMakeFiles/lane_blast_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 51 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/leaf_later_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/leaf_later_test.dir/DependInfo.cmake new file mode 100644 index 0000000..544d058 --- /dev/null +++ b/test/build-asan/CMakeFiles/leaf_later_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/leaf_later_test.cpp" "CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o" "gcc" "CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o.d" + "" "bin/leaf_later_test" "gcc" "CMakeFiles/leaf_later_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/leaf_later_test.dir/build.make b/test/build-asan/CMakeFiles/leaf_later_test.dir/build.make new file mode 100644 index 0000000..11fe45d --- /dev/null +++ b/test/build-asan/CMakeFiles/leaf_later_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/leaf_later_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/leaf_later_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/leaf_later_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/leaf_later_test.dir/flags.make + +CMakeFiles/leaf_later_test.dir/codegen: +.PHONY : CMakeFiles/leaf_later_test.dir/codegen + +CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o: CMakeFiles/leaf_later_test.dir/flags.make +CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/leaf_later_test.cpp +CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o: CMakeFiles/leaf_later_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o -MF CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o.d -o CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/leaf_later_test.cpp + +CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/leaf_later_test.cpp > CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.i + +CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/leaf_later_test.cpp -o CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.s + +# Object files for target leaf_later_test +leaf_later_test_OBJECTS = \ +"CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o" + +# External object files for target leaf_later_test +leaf_later_test_EXTERNAL_OBJECTS = + +bin/leaf_later_test: CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o +bin/leaf_later_test: CMakeFiles/leaf_later_test.dir/build.make +bin/leaf_later_test: CMakeFiles/leaf_later_test.dir/compiler_depend.ts +bin/leaf_later_test: lib/libgtest_main.a +bin/leaf_later_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/leaf_later_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/leaf_later_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/leaf_later_test: lib/libgtest.a +bin/leaf_later_test: CMakeFiles/leaf_later_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/leaf_later_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/leaf_later_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=leaf_later_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/leaf_later_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=leaf_later_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/leaf_later_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/leaf_later_test.dir/build: bin/leaf_later_test +.PHONY : CMakeFiles/leaf_later_test.dir/build + +CMakeFiles/leaf_later_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/leaf_later_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/leaf_later_test.dir/clean + +CMakeFiles/leaf_later_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/leaf_later_test.dir/DependInfo.cmake "--color=$(COLOR)" leaf_later_test +.PHONY : CMakeFiles/leaf_later_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/leaf_later_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/leaf_later_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..cf6e540 --- /dev/null +++ b/test/build-asan/CMakeFiles/leaf_later_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/leaf_later_test.dir/link.d" + "CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o" + "CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o.d" + "bin/leaf_later_test" + "bin/leaf_later_test.pdb" + "leaf_later_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/leaf_later_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/leaf_later_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/leaf_later_test.dir/compiler_depend.make new file mode 100644 index 0000000..399ac62 --- /dev/null +++ b/test/build-asan/CMakeFiles/leaf_later_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for leaf_later_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/leaf_later_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/leaf_later_test.dir/compiler_depend.ts new file mode 100644 index 0000000..417aff9 --- /dev/null +++ b/test/build-asan/CMakeFiles/leaf_later_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for leaf_later_test. diff --git a/test/build-asan/CMakeFiles/leaf_later_test.dir/depend.make b/test/build-asan/CMakeFiles/leaf_later_test.dir/depend.make new file mode 100644 index 0000000..f12dc6d --- /dev/null +++ b/test/build-asan/CMakeFiles/leaf_later_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for leaf_later_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/leaf_later_test.dir/flags.make b/test/build-asan/CMakeFiles/leaf_later_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/leaf_later_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/leaf_later_test.dir/link.txt b/test/build-asan/CMakeFiles/leaf_later_test.dir/link.txt new file mode 100644 index 0000000..cae9f13 --- /dev/null +++ b/test/build-asan/CMakeFiles/leaf_later_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/leaf_later_test.dir/link.d CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o -o bin/leaf_later_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/leaf_later_test.dir/progress.make b/test/build-asan/CMakeFiles/leaf_later_test.dir/progress.make new file mode 100644 index 0000000..fabbd7e --- /dev/null +++ b/test/build-asan/CMakeFiles/leaf_later_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 52 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/log_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/log_test.dir/DependInfo.cmake new file mode 100644 index 0000000..f50eeab --- /dev/null +++ b/test/build-asan/CMakeFiles/log_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/log_test.cpp" "CMakeFiles/log_test.dir/tests/log_test.cpp.o" "gcc" "CMakeFiles/log_test.dir/tests/log_test.cpp.o.d" + "" "bin/log_test" "gcc" "CMakeFiles/log_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/log_test.dir/build.make b/test/build-asan/CMakeFiles/log_test.dir/build.make new file mode 100644 index 0000000..967df4f --- /dev/null +++ b/test/build-asan/CMakeFiles/log_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/log_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/log_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/log_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/log_test.dir/flags.make + +CMakeFiles/log_test.dir/codegen: +.PHONY : CMakeFiles/log_test.dir/codegen + +CMakeFiles/log_test.dir/tests/log_test.cpp.o: CMakeFiles/log_test.dir/flags.make +CMakeFiles/log_test.dir/tests/log_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/log_test.cpp +CMakeFiles/log_test.dir/tests/log_test.cpp.o: CMakeFiles/log_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/log_test.dir/tests/log_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/log_test.dir/tests/log_test.cpp.o -MF CMakeFiles/log_test.dir/tests/log_test.cpp.o.d -o CMakeFiles/log_test.dir/tests/log_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/log_test.cpp + +CMakeFiles/log_test.dir/tests/log_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/log_test.dir/tests/log_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/log_test.cpp > CMakeFiles/log_test.dir/tests/log_test.cpp.i + +CMakeFiles/log_test.dir/tests/log_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/log_test.dir/tests/log_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/log_test.cpp -o CMakeFiles/log_test.dir/tests/log_test.cpp.s + +# Object files for target log_test +log_test_OBJECTS = \ +"CMakeFiles/log_test.dir/tests/log_test.cpp.o" + +# External object files for target log_test +log_test_EXTERNAL_OBJECTS = + +bin/log_test: CMakeFiles/log_test.dir/tests/log_test.cpp.o +bin/log_test: CMakeFiles/log_test.dir/build.make +bin/log_test: CMakeFiles/log_test.dir/compiler_depend.ts +bin/log_test: lib/libgtest_main.a +bin/log_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/log_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/log_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/log_test: lib/libgtest.a +bin/log_test: CMakeFiles/log_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/log_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/log_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=log_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/log_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=log_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/log_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/log_test.dir/build: bin/log_test +.PHONY : CMakeFiles/log_test.dir/build + +CMakeFiles/log_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/log_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/log_test.dir/clean + +CMakeFiles/log_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/log_test.dir/DependInfo.cmake "--color=$(COLOR)" log_test +.PHONY : CMakeFiles/log_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/log_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/log_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..6f40af7 --- /dev/null +++ b/test/build-asan/CMakeFiles/log_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/log_test.dir/link.d" + "CMakeFiles/log_test.dir/tests/log_test.cpp.o" + "CMakeFiles/log_test.dir/tests/log_test.cpp.o.d" + "bin/log_test" + "bin/log_test.pdb" + "log_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/log_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/log_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/log_test.dir/compiler_depend.make new file mode 100644 index 0000000..309c6cc --- /dev/null +++ b/test/build-asan/CMakeFiles/log_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for log_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/log_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/log_test.dir/compiler_depend.ts new file mode 100644 index 0000000..d591661 --- /dev/null +++ b/test/build-asan/CMakeFiles/log_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for log_test. diff --git a/test/build-asan/CMakeFiles/log_test.dir/depend.make b/test/build-asan/CMakeFiles/log_test.dir/depend.make new file mode 100644 index 0000000..5318315 --- /dev/null +++ b/test/build-asan/CMakeFiles/log_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for log_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/log_test.dir/flags.make b/test/build-asan/CMakeFiles/log_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/log_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/log_test.dir/link.txt b/test/build-asan/CMakeFiles/log_test.dir/link.txt new file mode 100644 index 0000000..d45d35c --- /dev/null +++ b/test/build-asan/CMakeFiles/log_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/log_test.dir/link.d CMakeFiles/log_test.dir/tests/log_test.cpp.o -o bin/log_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/log_test.dir/progress.make b/test/build-asan/CMakeFiles/log_test.dir/progress.make new file mode 100644 index 0000000..356049e --- /dev/null +++ b/test/build-asan/CMakeFiles/log_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 53 + diff --git a/test/build-asan/CMakeFiles/lut_union_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/lut_union_test.dir/DependInfo.cmake new file mode 100644 index 0000000..5653127 --- /dev/null +++ b/test/build-asan/CMakeFiles/lut_union_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/lut_union_test.cpp" "CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o" "gcc" "CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o.d" + "" "bin/lut_union_test" "gcc" "CMakeFiles/lut_union_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/lut_union_test.dir/build.make b/test/build-asan/CMakeFiles/lut_union_test.dir/build.make new file mode 100644 index 0000000..11f45dd --- /dev/null +++ b/test/build-asan/CMakeFiles/lut_union_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/lut_union_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/lut_union_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/lut_union_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/lut_union_test.dir/flags.make + +CMakeFiles/lut_union_test.dir/codegen: +.PHONY : CMakeFiles/lut_union_test.dir/codegen + +CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o: CMakeFiles/lut_union_test.dir/flags.make +CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/lut_union_test.cpp +CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o: CMakeFiles/lut_union_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o -MF CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o.d -o CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/lut_union_test.cpp + +CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/lut_union_test.cpp > CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.i + +CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/lut_union_test.cpp -o CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.s + +# Object files for target lut_union_test +lut_union_test_OBJECTS = \ +"CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o" + +# External object files for target lut_union_test +lut_union_test_EXTERNAL_OBJECTS = + +bin/lut_union_test: CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o +bin/lut_union_test: CMakeFiles/lut_union_test.dir/build.make +bin/lut_union_test: CMakeFiles/lut_union_test.dir/compiler_depend.ts +bin/lut_union_test: lib/libgtest_main.a +bin/lut_union_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/lut_union_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/lut_union_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/lut_union_test: lib/libgtest.a +bin/lut_union_test: CMakeFiles/lut_union_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/lut_union_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/lut_union_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=lut_union_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/lut_union_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=lut_union_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/lut_union_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/lut_union_test.dir/build: bin/lut_union_test +.PHONY : CMakeFiles/lut_union_test.dir/build + +CMakeFiles/lut_union_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/lut_union_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/lut_union_test.dir/clean + +CMakeFiles/lut_union_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/lut_union_test.dir/DependInfo.cmake "--color=$(COLOR)" lut_union_test +.PHONY : CMakeFiles/lut_union_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/lut_union_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/lut_union_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..1d6efc4 --- /dev/null +++ b/test/build-asan/CMakeFiles/lut_union_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/lut_union_test.dir/link.d" + "CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o" + "CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o.d" + "bin/lut_union_test" + "bin/lut_union_test.pdb" + "lut_union_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/lut_union_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/lut_union_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/lut_union_test.dir/compiler_depend.make new file mode 100644 index 0000000..a2e24bc --- /dev/null +++ b/test/build-asan/CMakeFiles/lut_union_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for lut_union_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/lut_union_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/lut_union_test.dir/compiler_depend.ts new file mode 100644 index 0000000..8873c9c --- /dev/null +++ b/test/build-asan/CMakeFiles/lut_union_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for lut_union_test. diff --git a/test/build-asan/CMakeFiles/lut_union_test.dir/depend.make b/test/build-asan/CMakeFiles/lut_union_test.dir/depend.make new file mode 100644 index 0000000..29222d4 --- /dev/null +++ b/test/build-asan/CMakeFiles/lut_union_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for lut_union_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/lut_union_test.dir/flags.make b/test/build-asan/CMakeFiles/lut_union_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/lut_union_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/lut_union_test.dir/link.txt b/test/build-asan/CMakeFiles/lut_union_test.dir/link.txt new file mode 100644 index 0000000..4358554 --- /dev/null +++ b/test/build-asan/CMakeFiles/lut_union_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/lut_union_test.dir/link.d CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o -o bin/lut_union_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/lut_union_test.dir/progress.make b/test/build-asan/CMakeFiles/lut_union_test.dir/progress.make new file mode 100644 index 0000000..3ac26ef --- /dev/null +++ b/test/build-asan/CMakeFiles/lut_union_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 54 + diff --git a/test/build-asan/CMakeFiles/multipoint_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/multipoint_test.dir/DependInfo.cmake new file mode 100644 index 0000000..9851711 --- /dev/null +++ b/test/build-asan/CMakeFiles/multipoint_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/multipoint_test.cpp" "CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o" "gcc" "CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o.d" + "" "bin/multipoint_test" "gcc" "CMakeFiles/multipoint_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/multipoint_test.dir/build.make b/test/build-asan/CMakeFiles/multipoint_test.dir/build.make new file mode 100644 index 0000000..c95ad6e --- /dev/null +++ b/test/build-asan/CMakeFiles/multipoint_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/multipoint_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/multipoint_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/multipoint_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/multipoint_test.dir/flags.make + +CMakeFiles/multipoint_test.dir/codegen: +.PHONY : CMakeFiles/multipoint_test.dir/codegen + +CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o: CMakeFiles/multipoint_test.dir/flags.make +CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/multipoint_test.cpp +CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o: CMakeFiles/multipoint_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o -MF CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o.d -o CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/multipoint_test.cpp + +CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/multipoint_test.cpp > CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.i + +CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/multipoint_test.cpp -o CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.s + +# Object files for target multipoint_test +multipoint_test_OBJECTS = \ +"CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o" + +# External object files for target multipoint_test +multipoint_test_EXTERNAL_OBJECTS = + +bin/multipoint_test: CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o +bin/multipoint_test: CMakeFiles/multipoint_test.dir/build.make +bin/multipoint_test: CMakeFiles/multipoint_test.dir/compiler_depend.ts +bin/multipoint_test: lib/libgtest_main.a +bin/multipoint_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/multipoint_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/multipoint_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/multipoint_test: lib/libgtest.a +bin/multipoint_test: CMakeFiles/multipoint_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/multipoint_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/multipoint_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=multipoint_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/multipoint_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=multipoint_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/multipoint_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/multipoint_test.dir/build: bin/multipoint_test +.PHONY : CMakeFiles/multipoint_test.dir/build + +CMakeFiles/multipoint_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/multipoint_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/multipoint_test.dir/clean + +CMakeFiles/multipoint_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/multipoint_test.dir/DependInfo.cmake "--color=$(COLOR)" multipoint_test +.PHONY : CMakeFiles/multipoint_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/multipoint_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/multipoint_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..18e0d2b --- /dev/null +++ b/test/build-asan/CMakeFiles/multipoint_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/multipoint_test.dir/link.d" + "CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o" + "CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o.d" + "bin/multipoint_test" + "bin/multipoint_test.pdb" + "multipoint_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/multipoint_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/multipoint_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/multipoint_test.dir/compiler_depend.make new file mode 100644 index 0000000..c352e30 --- /dev/null +++ b/test/build-asan/CMakeFiles/multipoint_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for multipoint_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/multipoint_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/multipoint_test.dir/compiler_depend.ts new file mode 100644 index 0000000..8e25175 --- /dev/null +++ b/test/build-asan/CMakeFiles/multipoint_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for multipoint_test. diff --git a/test/build-asan/CMakeFiles/multipoint_test.dir/depend.make b/test/build-asan/CMakeFiles/multipoint_test.dir/depend.make new file mode 100644 index 0000000..09c36cc --- /dev/null +++ b/test/build-asan/CMakeFiles/multipoint_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for multipoint_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/multipoint_test.dir/flags.make b/test/build-asan/CMakeFiles/multipoint_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/multipoint_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/multipoint_test.dir/link.txt b/test/build-asan/CMakeFiles/multipoint_test.dir/link.txt new file mode 100644 index 0000000..0e4fa8b --- /dev/null +++ b/test/build-asan/CMakeFiles/multipoint_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/multipoint_test.dir/link.d CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o -o bin/multipoint_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/multipoint_test.dir/progress.make b/test/build-asan/CMakeFiles/multipoint_test.dir/progress.make new file mode 100644 index 0000000..3fab501 --- /dev/null +++ b/test/build-asan/CMakeFiles/multipoint_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 55 + diff --git a/test/build-asan/CMakeFiles/net_control_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/net_control_test.dir/DependInfo.cmake new file mode 100644 index 0000000..30c704d --- /dev/null +++ b/test/build-asan/CMakeFiles/net_control_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp" "CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o" "gcc" "CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o.d" + "" "bin/net_control_test" "gcc" "CMakeFiles/net_control_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/net_control_test.dir/build.make b/test/build-asan/CMakeFiles/net_control_test.dir/build.make new file mode 100644 index 0000000..6e526d3 --- /dev/null +++ b/test/build-asan/CMakeFiles/net_control_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/net_control_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/net_control_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/net_control_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/net_control_test.dir/flags.make + +CMakeFiles/net_control_test.dir/codegen: +.PHONY : CMakeFiles/net_control_test.dir/codegen + +CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o: CMakeFiles/net_control_test.dir/flags.make +CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp +CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o: CMakeFiles/net_control_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o -MF CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o.d -o CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp + +CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp > CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.i + +CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp -o CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.s + +# Object files for target net_control_test +net_control_test_OBJECTS = \ +"CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o" + +# External object files for target net_control_test +net_control_test_EXTERNAL_OBJECTS = + +bin/net_control_test: CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o +bin/net_control_test: CMakeFiles/net_control_test.dir/build.make +bin/net_control_test: CMakeFiles/net_control_test.dir/compiler_depend.ts +bin/net_control_test: lib/libgtest_main.a +bin/net_control_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/net_control_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/net_control_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/net_control_test: lib/libgtest.a +bin/net_control_test: CMakeFiles/net_control_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/net_control_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/net_control_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=net_control_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=net_control_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/net_control_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/net_control_test.dir/build: bin/net_control_test +.PHONY : CMakeFiles/net_control_test.dir/build + +CMakeFiles/net_control_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/net_control_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/net_control_test.dir/clean + +CMakeFiles/net_control_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/net_control_test.dir/DependInfo.cmake "--color=$(COLOR)" net_control_test +.PHONY : CMakeFiles/net_control_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/net_control_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/net_control_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..6e8a4f5 --- /dev/null +++ b/test/build-asan/CMakeFiles/net_control_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/net_control_test.dir/link.d" + "CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o" + "CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o.d" + "bin/net_control_test" + "bin/net_control_test.pdb" + "net_control_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/net_control_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/net_control_test.dir/compiler_depend.internal b/test/build-asan/CMakeFiles/net_control_test.dir/compiler_depend.internal new file mode 100644 index 0000000..ea6b768 --- /dev/null +++ b/test/build-asan/CMakeFiles/net_control_test.dir/compiler_depend.internal @@ -0,0 +1,1239 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o + /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/aligned_allocator.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_flow.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_plans.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_runtime.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/beaver.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit_array.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit_inject.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bitstring.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/blob.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/buffered_prg.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/compose.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/compose_async.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/edabit.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/experiment.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/experiment_note.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/fp61.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/launch.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/leaf_arithmetic.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/leaf_node.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/literals.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/log.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/mesh_apps.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/modint.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/asio_ns.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_round_sink.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_sctp_stream_array.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_stream_array.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/buffer_pool.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/channel.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/connect.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/dealer_cursor.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/edge_mesh.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/io_pool.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/link_log.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/memory_sink.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/party_session.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/policy.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/round_lane.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/round_sink.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/sink_exchange.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/socket_tune.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_array.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_edge_mesh.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_mesh.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/tcp_mesh.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/nyble.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/online_session.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/ot_pack.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/packed_lane.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/packed_lane_arithmetic.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/pad_graphs.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/party_run.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/party_runner.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/placement.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prep_source.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_aes.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_aes_ccr.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_chacha.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_count.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_dummy.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_lowmc.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol_factory.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol_roles.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/random.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/rss_seed.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/run_config.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/run_log.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/secret_share.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/session_host.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/shamir.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/trunc.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/twiddle.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/twobit.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/uint256_t.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/utils.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/verifiable.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/wildcard.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/xor_wrapper.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/grotto/fixedpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/grotto/fixedpoint_mul.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_completion_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_completion_handler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_io_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/append.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/as_tuple.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_allocator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_cancellation_slot.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_immediate_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/async_result.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/awaitable.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_datagram_socket.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_deadline_timer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_file.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_io_object.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_random_access_file.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_raw_socket.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_readable_pipe.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_seq_packet_socket.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_serial_port.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_signal_set.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_acceptor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_iostream.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_streambuf.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_stream_file.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_stream_socket.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_streambuf.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_streambuf_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_waitable_timer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_writable_pipe.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_allocator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_cancellation_slot.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_immediate_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffer_registration.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_read_stream.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_read_stream_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_stream.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_stream_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_write_stream.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_write_stream_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffers_iterator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_signal.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_state.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_type.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/co_spawn.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/completion_condition.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/compose.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/connect.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/connect_pipe.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/consign.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/coroutine.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/deadline_timer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/defer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/deferred.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detached.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/array.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/array_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/assert.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/atomic_count.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/base_from_cancellation_state.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/base_from_completion_cond.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/bind_handler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/blocking_executor_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffer_resize_guard.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffer_sequence_adapter.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffered_stream_storage.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/bulk_executor_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/call_stack.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/chrono.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/chrono_time_traits.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/completion_handler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/composed_work.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/concurrency_hint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/conditionally_enabled_event.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/conditionally_enabled_mutex.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/config.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/consuming_buffers.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/cstddef.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/cstdint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/date_time_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/deadline_timer_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/dependent_type.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_ops.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_read_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_write_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/epoll_reactor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/event.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/eventfd_select_interrupter.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/executor_function.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/executor_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/fenced_block.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/functional.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/future.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/global.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_alloc_helpers.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_cont_helpers.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_invoke_helpers.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_tracking.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_type_requirements.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_work.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/descriptor_ops.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/epoll_reactor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/epoll_reactor.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/eventfd_select_interrupter.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/handler_tracking.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/null_event.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_event.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_mutex.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_serial_port_service.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_thread.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/reactive_descriptor_service.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/reactive_socket_service_base.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/resolver_service_base.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/scheduler.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/service_registry.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/service_registry.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/signal_set_service.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/socket_ops.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_executor_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_executor_service.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_service.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/thread_context.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/throw_error.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/timer_queue_set.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_defer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_dispatch.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_post.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/io_control.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/io_object_impl.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/is_buffer_sequence.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/is_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/keyword_tss_ptr.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/limits.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/local_free_on_block_exit.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/memory.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/mutex.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/non_const_lvalue.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/noncopyable.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/null_event.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/object_pool.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/op_queue.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/operation.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/pop_options.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_event.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_global.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_mutex.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_serial_port_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_signal_blocker.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_static_mutex.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_thread.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/push_options.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_descriptor_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_null_buffers_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_accept_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_connect_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recv_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recvfrom_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recvmsg_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_send_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_sendto_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_service_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_wait_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactor_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/recycling_allocator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/regex_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_endpoint_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_query_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolver_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolver_service_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_operation.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_task.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_thread_info.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scoped_lock.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scoped_ptr.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/select_interrupter.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/service_registry.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_blocker.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_handler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_set_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_holder.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_ops.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_option.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_types.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/static_mutex.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/std_fenced_block.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/strand_executor_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/strand_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/string_view.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_group.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_info_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/throw_error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/throw_exception.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_ptime.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_set.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_scheduler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_scheduler_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/tss_ptr.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/type_traits.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/utility.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/variadic_templates.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wait_handler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wait_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/winsock_init.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/work_dispatcher.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wrapped_handler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/dispatch.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/error_code.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/allocator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/any_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bad_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/blocking.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/blocking_adaptation.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bulk_execute.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bulk_guarantee.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/connect.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/context_as.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_invocable.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_operation.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_receiver.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/bulk_sender.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/submit_receiver.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/void_receiver.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/execute.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/impl/bad_executor.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/impl/receiver_invocation_error.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/invocable_archetype.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/mapping.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/occupancy.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/operation_state.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/outstanding_work.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/prefer_only.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/receiver.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/receiver_invocation_error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/relationship.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/schedule.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/scheduler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/sender.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_done.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_value.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/start.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/submit.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/executor_work_guard.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/file_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/basic_endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/datagram_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/detail/endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/detail/impl/endpoint.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/raw_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/seq_packet_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/stream_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_alloc_hook.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_continuation_hook.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_invoke_hook.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/high_resolution_timer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/any_completion_executor.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/any_io_executor.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/append.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/as_tuple.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/buffered_read_stream.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/buffered_write_stream.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/cancellation_signal.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect_pipe.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect_pipe.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/consign.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/deferred.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/detached.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/error.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/error_code.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/execution_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/execution_context.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/executor.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/handler_alloc_hook.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/io_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/io_context.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/multiple_exceptions.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/prepend.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read_at.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read_until.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/redirect_error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/serial_port_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/serial_port_base.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_context.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/thread_pool.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/thread_pool.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/use_future.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/write.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/write_at.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_context_strand.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_service_strand.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4_iterator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4_range.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6_iterator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6_range.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/bad_address_cast.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_entry.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_iterator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_query.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_results.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/impl/endpoint.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/socket_option.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/host_name.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/icmp.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v4.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v4.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v6.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v6.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/basic_endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/host_name.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v4.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v4.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v6.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v6.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/multicast.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/network_v4.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/network_v6.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/resolver_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/resolver_query_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/tcp.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/udp.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/unicast.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/v6_only.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_applicable_property.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_contiguous_iterator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_read_buffered.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_write_buffered.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/basic_endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/connect_pair.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/datagram_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/detail/endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/detail/impl/endpoint.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/seq_packet_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/stream_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/multiple_exceptions.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/packaged_task.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/placeholders.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/basic_descriptor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/basic_stream_descriptor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/descriptor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/descriptor_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/stream_descriptor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/post.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/prefer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/prepend.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/query.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/random_access_file.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read_at.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read_until.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/readable_pipe.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/recycling_allocator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/redirect_error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/registered_buffer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/require.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/require_concept.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/serial_port.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/serial_port_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/signal_set.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/signal_set_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/socket_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/static_thread_pool.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/steady_timer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/strand.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/stream_file.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/streambuf.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_timer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/this_coro.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/thread.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/thread_pool.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/time_traits.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/bulk_execute_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/bulk_execute_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/connect_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/connect_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/equality_comparable.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/execute_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/execute_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/prefer_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/prefer_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_static_constexpr_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_concept_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_concept_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/schedule_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/schedule_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_done_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_done_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_error_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_error_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_value_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_value_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/start_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/start_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_query.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_require.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_require_concept.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/submit_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/submit_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/use_awaitable.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/use_future.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/uses_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/version.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/wait_traits.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_object_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_overlapped_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_random_access_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_stream_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/object_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/overlapped_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/overlapped_ptr.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/random_access_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/stream_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/writable_pipe.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/write.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/write_at.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/libutil.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/stdio.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/stdlib.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/unistd.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/hash-library/sha256.cpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/hash-library/sha256.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/hedley/hedley.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/lowmc/LowMC.cpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/lowmc/LowMC.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/builtin/builtin.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/endian/endian.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/exact-int/exact-int.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/check.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/debug-trap.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/hedley.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-align.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-arch.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-common.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-constify.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-detect-clang.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-diagnostic.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-f16.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-features.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-math.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/avx.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/avx2.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/mmx.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse2.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse3.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse4.1.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse4.2.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/ssse3.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/endianness.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/uint128_t.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/uint256_t.hpp + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-assertion-result.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-death-test.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-matchers.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-message.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-param-test.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-printers.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-test-part.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-typed-test.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_pred_impl.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_prod.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-port.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-printers.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-filepath.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-internal.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-param-util.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port-arch.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-string.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-type-util.h + /usr/include/alloca.h + /usr/include/arpa/inet.h + /usr/include/asm-generic/bitsperlong.h + /usr/include/asm-generic/errno-base.h + /usr/include/asm-generic/errno.h + /usr/include/asm-generic/int-ll64.h + /usr/include/asm-generic/ioctl.h + /usr/include/asm-generic/ioctls.h + /usr/include/asm-generic/posix_types.h + /usr/include/asm-generic/socket.h + /usr/include/asm-generic/sockios.h + /usr/include/asm-generic/types.h + /usr/include/assert.h + /usr/include/c++/15/algorithm + /usr/include/c++/15/any + /usr/include/c++/15/array + /usr/include/c++/15/atomic + /usr/include/c++/15/backward/auto_ptr.h + /usr/include/c++/15/backward/binders.h + /usr/include/c++/15/bit + /usr/include/c++/15/bits/algorithmfwd.h + /usr/include/c++/15/bits/align.h + /usr/include/c++/15/bits/alloc_traits.h + /usr/include/c++/15/bits/allocated_ptr.h + /usr/include/c++/15/bits/allocator.h + /usr/include/c++/15/bits/atomic_base.h + /usr/include/c++/15/bits/atomic_futex.h + /usr/include/c++/15/bits/atomic_lockfree_defines.h + /usr/include/c++/15/bits/basic_ios.h + /usr/include/c++/15/bits/basic_ios.tcc + /usr/include/c++/15/bits/basic_string.h + /usr/include/c++/15/bits/basic_string.tcc + /usr/include/c++/15/bits/char_traits.h + /usr/include/c++/15/bits/charconv.h + /usr/include/c++/15/bits/chrono.h + /usr/include/c++/15/bits/codecvt.h + /usr/include/c++/15/bits/concept_check.h + /usr/include/c++/15/bits/cpp_type_traits.h + /usr/include/c++/15/bits/cxxabi_forced.h + /usr/include/c++/15/bits/cxxabi_init_exception.h + /usr/include/c++/15/bits/deque.tcc + /usr/include/c++/15/bits/enable_special_members.h + /usr/include/c++/15/bits/erase_if.h + /usr/include/c++/15/bits/exception.h + /usr/include/c++/15/bits/exception_defines.h + /usr/include/c++/15/bits/exception_ptr.h + /usr/include/c++/15/bits/fstream.tcc + /usr/include/c++/15/bits/functexcept.h + /usr/include/c++/15/bits/functional_hash.h + /usr/include/c++/15/bits/hash_bytes.h + /usr/include/c++/15/bits/hashtable.h + /usr/include/c++/15/bits/hashtable_policy.h + /usr/include/c++/15/bits/invoke.h + /usr/include/c++/15/bits/ios_base.h + /usr/include/c++/15/bits/istream.tcc + /usr/include/c++/15/bits/locale_classes.h + /usr/include/c++/15/bits/locale_classes.tcc + /usr/include/c++/15/bits/locale_conv.h + /usr/include/c++/15/bits/locale_facets.h + /usr/include/c++/15/bits/locale_facets.tcc + /usr/include/c++/15/bits/locale_facets_nonio.h + /usr/include/c++/15/bits/locale_facets_nonio.tcc + /usr/include/c++/15/bits/localefwd.h + /usr/include/c++/15/bits/memory_resource.h + /usr/include/c++/15/bits/memoryfwd.h + /usr/include/c++/15/bits/monostate.h + /usr/include/c++/15/bits/move.h + /usr/include/c++/15/bits/nested_exception.h + /usr/include/c++/15/bits/new_allocator.h + /usr/include/c++/15/bits/node_handle.h + /usr/include/c++/15/bits/ostream.h + /usr/include/c++/15/bits/ostream.tcc + /usr/include/c++/15/bits/ostream_insert.h + /usr/include/c++/15/bits/parse_numbers.h + /usr/include/c++/15/bits/postypes.h + /usr/include/c++/15/bits/predefined_ops.h + /usr/include/c++/15/bits/ptr_traits.h + /usr/include/c++/15/bits/quoted_string.h + /usr/include/c++/15/bits/random.h + /usr/include/c++/15/bits/random.tcc + /usr/include/c++/15/bits/range_access.h + /usr/include/c++/15/bits/refwrap.h + /usr/include/c++/15/bits/requires_hosted.h + /usr/include/c++/15/bits/shared_ptr.h + /usr/include/c++/15/bits/shared_ptr_atomic.h + /usr/include/c++/15/bits/shared_ptr_base.h + /usr/include/c++/15/bits/specfun.h + /usr/include/c++/15/bits/sstream.tcc + /usr/include/c++/15/bits/std_abs.h + /usr/include/c++/15/bits/std_function.h + /usr/include/c++/15/bits/std_mutex.h + /usr/include/c++/15/bits/std_thread.h + /usr/include/c++/15/bits/stl_algo.h + /usr/include/c++/15/bits/stl_algobase.h + /usr/include/c++/15/bits/stl_bvector.h + /usr/include/c++/15/bits/stl_construct.h + /usr/include/c++/15/bits/stl_deque.h + /usr/include/c++/15/bits/stl_function.h + /usr/include/c++/15/bits/stl_heap.h + /usr/include/c++/15/bits/stl_iterator.h + /usr/include/c++/15/bits/stl_iterator_base_funcs.h + /usr/include/c++/15/bits/stl_iterator_base_types.h + /usr/include/c++/15/bits/stl_map.h + /usr/include/c++/15/bits/stl_multimap.h + /usr/include/c++/15/bits/stl_multiset.h + /usr/include/c++/15/bits/stl_numeric.h + /usr/include/c++/15/bits/stl_pair.h + /usr/include/c++/15/bits/stl_raw_storage_iter.h + /usr/include/c++/15/bits/stl_relops.h + /usr/include/c++/15/bits/stl_set.h + /usr/include/c++/15/bits/stl_tempbuf.h + /usr/include/c++/15/bits/stl_tree.h + /usr/include/c++/15/bits/stl_uninitialized.h + /usr/include/c++/15/bits/stl_vector.h + /usr/include/c++/15/bits/stream_iterator.h + /usr/include/c++/15/bits/streambuf.tcc + /usr/include/c++/15/bits/streambuf_iterator.h + /usr/include/c++/15/bits/string_view.tcc + /usr/include/c++/15/bits/stringfwd.h + /usr/include/c++/15/bits/this_thread_sleep.h + /usr/include/c++/15/bits/uniform_int_dist.h + /usr/include/c++/15/bits/unique_lock.h + /usr/include/c++/15/bits/unique_ptr.h + /usr/include/c++/15/bits/unordered_map.h + /usr/include/c++/15/bits/uses_allocator.h + /usr/include/c++/15/bits/uses_allocator_args.h + /usr/include/c++/15/bits/utility.h + /usr/include/c++/15/bits/vector.tcc + /usr/include/c++/15/bits/version.h + /usr/include/c++/15/bitset + /usr/include/c++/15/cassert + /usr/include/c++/15/cctype + /usr/include/c++/15/cerrno + /usr/include/c++/15/cfenv + /usr/include/c++/15/chrono + /usr/include/c++/15/cinttypes + /usr/include/c++/15/climits + /usr/include/c++/15/clocale + /usr/include/c++/15/cmath + /usr/include/c++/15/compare + /usr/include/c++/15/concepts + /usr/include/c++/15/condition_variable + /usr/include/c++/15/csignal + /usr/include/c++/15/cstddef + /usr/include/c++/15/cstdint + /usr/include/c++/15/cstdio + /usr/include/c++/15/cstdlib + /usr/include/c++/15/cstring + /usr/include/c++/15/ctime + /usr/include/c++/15/cwchar + /usr/include/c++/15/cwctype + /usr/include/c++/15/cxxabi.h + /usr/include/c++/15/debug/assertions.h + /usr/include/c++/15/debug/debug.h + /usr/include/c++/15/deque + /usr/include/c++/15/exception + /usr/include/c++/15/ext/aligned_buffer.h + /usr/include/c++/15/ext/alloc_traits.h + /usr/include/c++/15/ext/atomicity.h + /usr/include/c++/15/ext/concurrence.h + /usr/include/c++/15/ext/numeric_traits.h + /usr/include/c++/15/ext/string_conversions.h + /usr/include/c++/15/ext/type_traits.h + /usr/include/c++/15/fenv.h + /usr/include/c++/15/fstream + /usr/include/c++/15/functional + /usr/include/c++/15/future + /usr/include/c++/15/initializer_list + /usr/include/c++/15/iomanip + /usr/include/c++/15/ios + /usr/include/c++/15/iosfwd + /usr/include/c++/15/iostream + /usr/include/c++/15/istream + /usr/include/c++/15/iterator + /usr/include/c++/15/limits + /usr/include/c++/15/locale + /usr/include/c++/15/map + /usr/include/c++/15/memory + /usr/include/c++/15/mutex + /usr/include/c++/15/new + /usr/include/c++/15/numeric + /usr/include/c++/15/optional + /usr/include/c++/15/ostream + /usr/include/c++/15/pstl/execution_defs.h + /usr/include/c++/15/pstl/glue_algorithm_defs.h + /usr/include/c++/15/pstl/glue_memory_defs.h + /usr/include/c++/15/pstl/glue_numeric_defs.h + /usr/include/c++/15/pstl/pstl_config.h + /usr/include/c++/15/random + /usr/include/c++/15/ratio + /usr/include/c++/15/set + /usr/include/c++/15/sstream + /usr/include/c++/15/stdexcept + /usr/include/c++/15/stdlib.h + /usr/include/c++/15/streambuf + /usr/include/c++/15/string + /usr/include/c++/15/string_view + /usr/include/c++/15/system_error + /usr/include/c++/15/thread + /usr/include/c++/15/tr1/bessel_function.tcc + /usr/include/c++/15/tr1/beta_function.tcc + /usr/include/c++/15/tr1/ell_integral.tcc + /usr/include/c++/15/tr1/exp_integral.tcc + /usr/include/c++/15/tr1/gamma.tcc + /usr/include/c++/15/tr1/hypergeometric.tcc + /usr/include/c++/15/tr1/legendre_function.tcc + /usr/include/c++/15/tr1/modified_bessel_func.tcc + /usr/include/c++/15/tr1/poly_hermite.tcc + /usr/include/c++/15/tr1/poly_laguerre.tcc + /usr/include/c++/15/tr1/riemann_zeta.tcc + /usr/include/c++/15/tr1/special_function_util.h + /usr/include/c++/15/tuple + /usr/include/c++/15/type_traits + /usr/include/c++/15/typeindex + /usr/include/c++/15/typeinfo + /usr/include/c++/15/unordered_map + /usr/include/c++/15/utility + /usr/include/c++/15/variant + /usr/include/c++/15/vector + /usr/include/c++/15/version + /usr/include/ctype.h + /usr/include/endian.h + /usr/include/errno.h + /usr/include/fcntl.h + /usr/include/features-time64.h + /usr/include/features.h + /usr/include/fenv.h + /usr/include/ifaddrs.h + /usr/include/inttypes.h + /usr/include/libintl.h + /usr/include/limits.h + /usr/include/linux/close_range.h + /usr/include/linux/errno.h + /usr/include/linux/falloc.h + /usr/include/linux/ioctl.h + /usr/include/linux/limits.h + /usr/include/linux/openat2.h + /usr/include/linux/posix_types.h + /usr/include/linux/sched/types.h + /usr/include/linux/sctp.h + /usr/include/linux/socket.h + /usr/include/linux/sockios.h + /usr/include/linux/stat.h + /usr/include/linux/stddef.h + /usr/include/linux/types.h + /usr/include/linux/version.h + /usr/include/locale.h + /usr/include/math.h + /usr/include/net/if.h + /usr/include/netdb.h + /usr/include/netinet/in.h + /usr/include/netinet/sctp.h + /usr/include/netinet/tcp.h + /usr/include/poll.h + /usr/include/pthread.h + /usr/include/regex.h + /usr/include/rpc/netdb.h + /usr/include/sched.h + /usr/include/signal.h + /usr/include/stdc-predef.h + /usr/include/stdint.h + /usr/include/stdio.h + /usr/include/stdlib.h + /usr/include/string.h + /usr/include/strings.h + /usr/include/syslog.h + /usr/include/termios.h + /usr/include/time.h + /usr/include/unistd.h + /usr/include/wchar.h + /usr/include/wctype.h + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h + /usr/include/x86_64-linux-gnu/asm/errno.h + /usr/include/x86_64-linux-gnu/asm/ioctl.h + /usr/include/x86_64-linux-gnu/asm/ioctls.h + /usr/include/x86_64-linux-gnu/asm/posix_types.h + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h + /usr/include/x86_64-linux-gnu/asm/socket.h + /usr/include/x86_64-linux-gnu/asm/sockios.h + /usr/include/x86_64-linux-gnu/asm/types.h + /usr/include/x86_64-linux-gnu/asm/unistd.h + /usr/include/x86_64-linux-gnu/asm/unistd_64.h + /usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h + /usr/include/x86_64-linux-gnu/bits/byteswap.h + /usr/include/x86_64-linux-gnu/bits/confname.h + /usr/include/x86_64-linux-gnu/bits/cpu-set.h + /usr/include/x86_64-linux-gnu/bits/endian.h + /usr/include/x86_64-linux-gnu/bits/endianness.h + /usr/include/x86_64-linux-gnu/bits/environments.h + /usr/include/x86_64-linux-gnu/bits/epoll.h + /usr/include/x86_64-linux-gnu/bits/errno.h + /usr/include/x86_64-linux-gnu/bits/eventfd.h + /usr/include/x86_64-linux-gnu/bits/fcntl-linux-fortify.h + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h + /usr/include/x86_64-linux-gnu/bits/fcntl.h + /usr/include/x86_64-linux-gnu/bits/fcntl2.h + /usr/include/x86_64-linux-gnu/bits/fenv.h + /usr/include/x86_64-linux-gnu/bits/floatn-common.h + /usr/include/x86_64-linux-gnu/bits/floatn.h + /usr/include/x86_64-linux-gnu/bits/flt-eval-method.h + /usr/include/x86_64-linux-gnu/bits/fp-fast.h + /usr/include/x86_64-linux-gnu/bits/fp-logb.h + /usr/include/x86_64-linux-gnu/bits/getopt_core.h + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h + /usr/include/x86_64-linux-gnu/bits/in.h + /usr/include/x86_64-linux-gnu/bits/inet-fortified-decl.h + /usr/include/x86_64-linux-gnu/bits/inet-fortified.h + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h + /usr/include/x86_64-linux-gnu/bits/ioctls.h + /usr/include/x86_64-linux-gnu/bits/iscanonical.h + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h + /usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h + /usr/include/x86_64-linux-gnu/bits/local_lim.h + /usr/include/x86_64-linux-gnu/bits/locale.h + /usr/include/x86_64-linux-gnu/bits/long-double.h + /usr/include/x86_64-linux-gnu/bits/math-vector.h + /usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h + /usr/include/x86_64-linux-gnu/bits/mathcalls-macros.h + /usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h + /usr/include/x86_64-linux-gnu/bits/mathcalls.h + /usr/include/x86_64-linux-gnu/bits/netdb.h + /usr/include/x86_64-linux-gnu/bits/openat2.h + /usr/include/x86_64-linux-gnu/bits/poll.h + /usr/include/x86_64-linux-gnu/bits/poll2.h + /usr/include/x86_64-linux-gnu/bits/posix1_lim.h + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h + /usr/include/x86_64-linux-gnu/bits/posix_opt.h + /usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h + /usr/include/x86_64-linux-gnu/bits/sched.h + /usr/include/x86_64-linux-gnu/bits/select-decl.h + /usr/include/x86_64-linux-gnu/bits/select.h + /usr/include/x86_64-linux-gnu/bits/select2.h + /usr/include/x86_64-linux-gnu/bits/setjmp.h + /usr/include/x86_64-linux-gnu/bits/sigaction.h + /usr/include/x86_64-linux-gnu/bits/sigcontext.h + /usr/include/x86_64-linux-gnu/bits/sigevent-consts.h + /usr/include/x86_64-linux-gnu/bits/siginfo-arch.h + /usr/include/x86_64-linux-gnu/bits/siginfo-consts-arch.h + /usr/include/x86_64-linux-gnu/bits/siginfo-consts.h + /usr/include/x86_64-linux-gnu/bits/signal_ext.h + /usr/include/x86_64-linux-gnu/bits/signum-arch.h + /usr/include/x86_64-linux-gnu/bits/signum-generic.h + /usr/include/x86_64-linux-gnu/bits/sigstack.h + /usr/include/x86_64-linux-gnu/bits/sigstksz.h + /usr/include/x86_64-linux-gnu/bits/sigthread.h + /usr/include/x86_64-linux-gnu/bits/sockaddr.h + /usr/include/x86_64-linux-gnu/bits/socket.h + /usr/include/x86_64-linux-gnu/bits/socket2.h + /usr/include/x86_64-linux-gnu/bits/socket_type.h + /usr/include/x86_64-linux-gnu/bits/ss_flags.h + /usr/include/x86_64-linux-gnu/bits/stat.h + /usr/include/x86_64-linux-gnu/bits/statx-generic.h + /usr/include/x86_64-linux-gnu/bits/statx.h + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h + /usr/include/x86_64-linux-gnu/bits/stdint-least.h + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h + /usr/include/x86_64-linux-gnu/bits/stdio.h + /usr/include/x86_64-linux-gnu/bits/stdio2-decl.h + /usr/include/x86_64-linux-gnu/bits/stdio2.h + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h + /usr/include/x86_64-linux-gnu/bits/stdlib.h + /usr/include/x86_64-linux-gnu/bits/string_fortified.h + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h + /usr/include/x86_64-linux-gnu/bits/struct_stat.h + /usr/include/x86_64-linux-gnu/bits/syscall.h + /usr/include/x86_64-linux-gnu/bits/syslog-decl.h + /usr/include/x86_64-linux-gnu/bits/syslog-path.h + /usr/include/x86_64-linux-gnu/bits/syslog.h + /usr/include/x86_64-linux-gnu/bits/termios-baud.h + /usr/include/x86_64-linux-gnu/bits/termios-c_cc.h + /usr/include/x86_64-linux-gnu/bits/termios-c_cflag.h + /usr/include/x86_64-linux-gnu/bits/termios-c_iflag.h + /usr/include/x86_64-linux-gnu/bits/termios-c_lflag.h + /usr/include/x86_64-linux-gnu/bits/termios-c_oflag.h + /usr/include/x86_64-linux-gnu/bits/termios-cbaud.h + /usr/include/x86_64-linux-gnu/bits/termios-misc.h + /usr/include/x86_64-linux-gnu/bits/termios-struct.h + /usr/include/x86_64-linux-gnu/bits/termios-tcflow.h + /usr/include/x86_64-linux-gnu/bits/termios.h + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h + /usr/include/x86_64-linux-gnu/bits/time.h + /usr/include/x86_64-linux-gnu/bits/time64.h + /usr/include/x86_64-linux-gnu/bits/timerfd.h + /usr/include/x86_64-linux-gnu/bits/timesize.h + /usr/include/x86_64-linux-gnu/bits/timex.h + /usr/include/x86_64-linux-gnu/bits/types.h + /usr/include/x86_64-linux-gnu/bits/types/FILE.h + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h + /usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h + /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h + /usr/include/x86_64-linux-gnu/bits/types/error_t.h + /usr/include/x86_64-linux-gnu/bits/types/idtype_t.h + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h + /usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h + /usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigval_t.h + /usr/include/x86_64-linux-gnu/bits/types/stack_t.h + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h + /usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h + /usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h + /usr/include/x86_64-linux-gnu/bits/types/struct_statx.h + /usr/include/x86_64-linux-gnu/bits/types/struct_statx_timestamp.h + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h + /usr/include/x86_64-linux-gnu/bits/types/time_t.h + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h + /usr/include/x86_64-linux-gnu/bits/types/wint_t.h + /usr/include/x86_64-linux-gnu/bits/typesizes.h + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h + /usr/include/x86_64-linux-gnu/bits/uio-ext.h + /usr/include/x86_64-linux-gnu/bits/uio_lim.h + /usr/include/x86_64-linux-gnu/bits/unistd-decl.h + /usr/include/x86_64-linux-gnu/bits/unistd.h + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h + /usr/include/x86_64-linux-gnu/bits/utsname.h + /usr/include/x86_64-linux-gnu/bits/waitflags.h + /usr/include/x86_64-linux-gnu/bits/waitstatus.h + /usr/include/x86_64-linux-gnu/bits/wchar.h + /usr/include/x86_64-linux-gnu/bits/wchar2-decl.h + /usr/include/x86_64-linux-gnu/bits/wchar2.h + /usr/include/x86_64-linux-gnu/bits/wctype-wchar.h + /usr/include/x86_64-linux-gnu/bits/wordsize.h + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h + /usr/include/x86_64-linux-gnu/c++/15/bits/atomic_word.h + /usr/include/x86_64-linux-gnu/c++/15/bits/basic_file.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++allocator.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++config.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++io.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++locale.h + /usr/include/x86_64-linux-gnu/c++/15/bits/cpu_defines.h + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_base.h + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_inline.h + /usr/include/x86_64-linux-gnu/c++/15/bits/cxxabi_tweaks.h + /usr/include/x86_64-linux-gnu/c++/15/bits/error_constants.h + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr-default.h + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr.h + /usr/include/x86_64-linux-gnu/c++/15/bits/messages_members.h + /usr/include/x86_64-linux-gnu/c++/15/bits/opt_random.h + /usr/include/x86_64-linux-gnu/c++/15/bits/os_defines.h + /usr/include/x86_64-linux-gnu/c++/15/bits/time_members.h + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h + /usr/include/x86_64-linux-gnu/gnu/stubs.h + /usr/include/x86_64-linux-gnu/sys/cdefs.h + /usr/include/x86_64-linux-gnu/sys/epoll.h + /usr/include/x86_64-linux-gnu/sys/eventfd.h + /usr/include/x86_64-linux-gnu/sys/ioctl.h + /usr/include/x86_64-linux-gnu/sys/poll.h + /usr/include/x86_64-linux-gnu/sys/select.h + /usr/include/x86_64-linux-gnu/sys/single_threaded.h + /usr/include/x86_64-linux-gnu/sys/socket.h + /usr/include/x86_64-linux-gnu/sys/stat.h + /usr/include/x86_64-linux-gnu/sys/syscall.h + /usr/include/x86_64-linux-gnu/sys/syslog.h + /usr/include/x86_64-linux-gnu/sys/timerfd.h + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h + /usr/include/x86_64-linux-gnu/sys/types.h + /usr/include/x86_64-linux-gnu/sys/ucontext.h + /usr/include/x86_64-linux-gnu/sys/uio.h + /usr/include/x86_64-linux-gnu/sys/un.h + /usr/include/x86_64-linux-gnu/sys/utsname.h + /usr/include/x86_64-linux-gnu/sys/wait.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/adxintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/ammintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxavx512intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxbf16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxcomplexintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxfp16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxfp8intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxint8intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxmovrsintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxtf32intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxtileintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxtransposeintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512bf16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512convertintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512mediaintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512minmaxintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512satcvtintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2bf16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2convertintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2copyintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2mediaintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2minmaxintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2satcvtintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx2intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bf16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bf16vlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bitalgintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bitalgvlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bwintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512cdintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512dqintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fp16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fp16vlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512ifmaintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512ifmavlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmi2intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmi2vlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmiintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmivlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vlbwintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vldqintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vnniintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vnnivlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vp2intersectintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vp2intersectvlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vpopcntdqintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vpopcntdqvlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxifmaintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxneconvertintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniint16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniint8intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/bmi2intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/bmiintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/cetintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/cldemoteintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/clflushoptintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/clwbintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/clzerointrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/cmpccxaddintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/emmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/enqcmdintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/f16cintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/float.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/fma4intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/fmaintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/fxsrintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/gfniintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/hresetintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/ia32intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/immintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/keylockerintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/limits.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/lwpintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/lzcntintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/mm3dnow.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/mm_malloc.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/mmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/movdirintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/movrsintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/mwaitintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/mwaitxintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/pconfigintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/pkuintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/pmmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/popcntintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/prfchiintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/prfchwintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/raointintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/rdseedintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/rtmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/serializeintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/sgxintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/sha512intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/shaintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/sm3intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/sm4intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/smmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdarg.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/syslimits.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/tbmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/tmmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/tsxldtrkintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/uintrintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/usermsrintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/vaesintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/vpclmulqdqintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/waitpkgintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/wbnoinvdintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/wmmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/x86gprintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/x86intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xmmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xopintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsavecintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsaveintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsaveoptintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsavesintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xtestintrin.h + +bin/net_control_test + /lib64/ld-linux-x86-64.so.2 + /usr/lib/x86_64-linux-gnu/Scrt1.o + /usr/lib/x86_64-linux-gnu/crti.o + /usr/lib/x86_64-linux-gnu/crtn.o + /usr/lib/x86_64-linux-gnu/libbsd.so + /usr/lib/x86_64-linux-gnu/libc.so + /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 + /usr/lib/x86_64-linux-gnu/libm.so + /usr/lib/x86_64-linux-gnu/libmd.so + /usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o + /usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o + /usr/lib/gcc/x86_64-linux-gnu/15/libasan.so + /usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o + /usr/lib/gcc/x86_64-linux-gnu/15/libgcc.a + /usr/lib/gcc/x86_64-linux-gnu/15/libgcc_s.so + /usr/lib/gcc/x86_64-linux-gnu/15/libstdc++.so + /usr/lib/gcc/x86_64-linux-gnu/15/libubsan.so + /usr/lib/x86_64-linux-gnu/libbsd.so.0.12.2 + /usr/lib/x86_64-linux-gnu/libc.so.6 + /usr/lib/x86_64-linux-gnu/libc_nonshared.a + /usr/lib/x86_64-linux-gnu/libm.so.6 + /usr/lib/x86_64-linux-gnu/libmvec.so.1 + /usr/lib/x86_64-linux-gnu/libsctp.so + /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o + /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/lib/libgtest.a + /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/lib/libgtest_main.a + diff --git a/test/build-asan/CMakeFiles/net_control_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/net_control_test.dir/compiler_depend.make new file mode 100644 index 0000000..16e07fe --- /dev/null +++ b/test/build-asan/CMakeFiles/net_control_test.dir/compiler_depend.make @@ -0,0 +1,3701 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/aligned_allocator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_flow.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_plans.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_runtime.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/beaver.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit_array.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit_inject.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bitstring.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/blob.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/buffered_prg.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/compose.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/compose_async.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/edabit.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/experiment.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/experiment_note.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/fp61.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/launch.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/leaf_arithmetic.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/leaf_node.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/literals.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/log.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/mesh_apps.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/modint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/asio_ns.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_round_sink.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_sctp_stream_array.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_stream_array.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/buffer_pool.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/channel.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/connect.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/dealer_cursor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/edge_mesh.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/io_pool.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/link_log.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/memory_sink.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/party_session.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/policy.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/round_lane.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/round_sink.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/sink_exchange.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/socket_tune.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_array.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_edge_mesh.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_mesh.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/tcp_mesh.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/nyble.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/online_session.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/ot_pack.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/packed_lane.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/packed_lane_arithmetic.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/pad_graphs.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/party_run.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/party_runner.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/placement.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prep_source.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_aes.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_aes_ccr.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_chacha.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_count.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_dummy.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_lowmc.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol_factory.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol_roles.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/random.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/rss_seed.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/run_config.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/run_log.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/secret_share.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/session_host.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/shamir.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/trunc.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/twiddle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/twobit.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/uint256_t.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/utils.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/verifiable.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/wildcard.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/xor_wrapper.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/grotto/fixedpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/grotto/fixedpoint_mul.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_completion_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_completion_handler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_io_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/append.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/as_tuple.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_allocator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_cancellation_slot.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_immediate_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/async_result.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/awaitable.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_datagram_socket.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_deadline_timer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_file.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_io_object.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_random_access_file.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_raw_socket.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_readable_pipe.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_seq_packet_socket.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_serial_port.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_signal_set.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_acceptor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_iostream.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_streambuf.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_stream_file.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_stream_socket.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_streambuf.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_streambuf_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_waitable_timer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_writable_pipe.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_allocator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_cancellation_slot.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_immediate_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffer_registration.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_read_stream.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_read_stream_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_stream.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_stream_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_write_stream.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_write_stream_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffers_iterator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_signal.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_state.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_type.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/co_spawn.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/completion_condition.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/compose.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/connect.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/connect_pipe.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/consign.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/coroutine.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/deadline_timer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/defer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/deferred.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detached.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/array.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/array_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/assert.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/atomic_count.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/base_from_cancellation_state.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/base_from_completion_cond.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/bind_handler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/blocking_executor_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffer_resize_guard.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffer_sequence_adapter.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffered_stream_storage.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/bulk_executor_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/call_stack.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/chrono.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/chrono_time_traits.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/completion_handler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/composed_work.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/concurrency_hint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/conditionally_enabled_event.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/conditionally_enabled_mutex.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/config.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/consuming_buffers.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/cstddef.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/cstdint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/date_time_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/deadline_timer_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/dependent_type.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_ops.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_read_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_write_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/epoll_reactor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/event.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/eventfd_select_interrupter.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/executor_function.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/executor_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/fenced_block.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/functional.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/future.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/global.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_alloc_helpers.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_cont_helpers.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_invoke_helpers.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_tracking.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_type_requirements.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_work.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/descriptor_ops.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/epoll_reactor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/epoll_reactor.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/eventfd_select_interrupter.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/handler_tracking.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/null_event.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_event.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_mutex.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_serial_port_service.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_thread.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/reactive_descriptor_service.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/reactive_socket_service_base.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/resolver_service_base.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/scheduler.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/service_registry.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/service_registry.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/signal_set_service.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/socket_ops.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_executor_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_executor_service.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_service.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/thread_context.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/throw_error.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/timer_queue_set.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_defer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_dispatch.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_post.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/io_control.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/io_object_impl.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/is_buffer_sequence.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/is_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/keyword_tss_ptr.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/limits.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/local_free_on_block_exit.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/memory.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/mutex.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/non_const_lvalue.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/noncopyable.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/null_event.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/object_pool.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/op_queue.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/operation.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/pop_options.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_event.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_global.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_mutex.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_serial_port_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_signal_blocker.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_static_mutex.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_thread.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/push_options.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_descriptor_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_null_buffers_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_accept_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_connect_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recv_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recvfrom_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recvmsg_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_send_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_sendto_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_service_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_wait_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactor_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/recycling_allocator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/regex_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_endpoint_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_query_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolver_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolver_service_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_operation.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_task.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_thread_info.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scoped_lock.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scoped_ptr.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/select_interrupter.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/service_registry.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_blocker.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_handler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_set_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_holder.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_ops.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_option.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_types.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/static_mutex.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/std_fenced_block.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/strand_executor_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/strand_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/string_view.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_group.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_info_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/throw_error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/throw_exception.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_ptime.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_set.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_scheduler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_scheduler_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/tss_ptr.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/type_traits.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/utility.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/variadic_templates.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wait_handler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wait_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/winsock_init.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/work_dispatcher.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wrapped_handler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/dispatch.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/error_code.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/allocator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/any_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bad_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/blocking.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/blocking_adaptation.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bulk_execute.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bulk_guarantee.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/connect.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/context_as.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_invocable.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_operation.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_receiver.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/bulk_sender.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/submit_receiver.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/void_receiver.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/execute.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/impl/bad_executor.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/impl/receiver_invocation_error.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/invocable_archetype.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/mapping.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/occupancy.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/operation_state.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/outstanding_work.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/prefer_only.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/receiver.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/receiver_invocation_error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/relationship.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/schedule.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/scheduler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/sender.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_done.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_value.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/start.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/submit.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/executor_work_guard.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/file_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/basic_endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/datagram_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/detail/endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/detail/impl/endpoint.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/raw_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/seq_packet_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/stream_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_alloc_hook.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_continuation_hook.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_invoke_hook.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/high_resolution_timer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/any_completion_executor.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/any_io_executor.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/append.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/as_tuple.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/buffered_read_stream.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/buffered_write_stream.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/cancellation_signal.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect_pipe.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect_pipe.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/consign.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/deferred.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/detached.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/error.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/error_code.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/execution_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/execution_context.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/executor.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/handler_alloc_hook.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/io_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/io_context.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/multiple_exceptions.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/prepend.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read_at.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read_until.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/redirect_error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/serial_port_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/serial_port_base.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_context.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/thread_pool.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/thread_pool.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/use_future.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/write.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/write_at.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_context_strand.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_service_strand.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4_iterator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4_range.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6_iterator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6_range.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/bad_address_cast.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_entry.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_iterator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_query.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_results.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/impl/endpoint.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/socket_option.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/host_name.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/icmp.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v4.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v4.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v6.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v6.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/basic_endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/host_name.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v4.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v4.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v6.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v6.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/multicast.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/network_v4.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/network_v6.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/resolver_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/resolver_query_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/tcp.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/udp.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/unicast.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/v6_only.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_applicable_property.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_contiguous_iterator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_read_buffered.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_write_buffered.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/basic_endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/connect_pair.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/datagram_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/detail/endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/detail/impl/endpoint.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/seq_packet_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/stream_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/multiple_exceptions.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/packaged_task.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/placeholders.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/basic_descriptor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/basic_stream_descriptor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/descriptor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/descriptor_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/stream_descriptor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/post.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/prefer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/prepend.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/query.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/random_access_file.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read_at.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read_until.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/readable_pipe.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/recycling_allocator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/redirect_error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/registered_buffer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/require.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/require_concept.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/serial_port.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/serial_port_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/signal_set.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/signal_set_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/socket_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/static_thread_pool.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/steady_timer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/strand.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/stream_file.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/streambuf.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_timer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/this_coro.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/thread.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/thread_pool.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/time_traits.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/bulk_execute_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/bulk_execute_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/connect_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/connect_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/equality_comparable.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/execute_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/execute_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/prefer_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/prefer_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_static_constexpr_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_concept_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_concept_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/schedule_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/schedule_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_done_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_done_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_error_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_error_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_value_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_value_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/start_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/start_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_query.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_require.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_require_concept.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/submit_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/submit_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/use_awaitable.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/use_future.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/uses_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/version.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/wait_traits.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_object_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_overlapped_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_random_access_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_stream_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/object_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/overlapped_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/overlapped_ptr.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/random_access_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/stream_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/writable_pipe.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/write.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/write_at.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/libutil.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/stdio.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/stdlib.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/unistd.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/hash-library/sha256.cpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/hash-library/sha256.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/hedley/hedley.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/lowmc/LowMC.cpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/lowmc/LowMC.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/builtin/builtin.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/endian/endian.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/exact-int/exact-int.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/check.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/debug-trap.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/hedley.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-align.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-arch.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-common.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-constify.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-detect-clang.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-diagnostic.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-f16.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-features.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-math.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/avx.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/avx2.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/mmx.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse2.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse3.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse4.1.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse4.2.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/ssse3.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/endianness.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/uint128_t.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/uint256_t.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-assertion-result.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-death-test.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-matchers.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-message.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-param-test.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-printers.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-test-part.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-typed-test.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_pred_impl.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_prod.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-port.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-printers.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-filepath.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-internal.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-param-util.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port-arch.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-string.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-type-util.h \ + /usr/include/alloca.h \ + /usr/include/arpa/inet.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/asm-generic/errno-base.h \ + /usr/include/asm-generic/errno.h \ + /usr/include/asm-generic/int-ll64.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/asm-generic/ioctls.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/asm-generic/types.h \ + /usr/include/assert.h \ + /usr/include/c++/15/algorithm \ + /usr/include/c++/15/any \ + /usr/include/c++/15/array \ + /usr/include/c++/15/atomic \ + /usr/include/c++/15/backward/auto_ptr.h \ + /usr/include/c++/15/backward/binders.h \ + /usr/include/c++/15/bit \ + /usr/include/c++/15/bits/algorithmfwd.h \ + /usr/include/c++/15/bits/align.h \ + /usr/include/c++/15/bits/alloc_traits.h \ + /usr/include/c++/15/bits/allocated_ptr.h \ + /usr/include/c++/15/bits/allocator.h \ + /usr/include/c++/15/bits/atomic_base.h \ + /usr/include/c++/15/bits/atomic_futex.h \ + /usr/include/c++/15/bits/atomic_lockfree_defines.h \ + /usr/include/c++/15/bits/basic_ios.h \ + /usr/include/c++/15/bits/basic_ios.tcc \ + /usr/include/c++/15/bits/basic_string.h \ + /usr/include/c++/15/bits/basic_string.tcc \ + /usr/include/c++/15/bits/char_traits.h \ + /usr/include/c++/15/bits/charconv.h \ + /usr/include/c++/15/bits/chrono.h \ + /usr/include/c++/15/bits/codecvt.h \ + /usr/include/c++/15/bits/concept_check.h \ + /usr/include/c++/15/bits/cpp_type_traits.h \ + /usr/include/c++/15/bits/cxxabi_forced.h \ + /usr/include/c++/15/bits/cxxabi_init_exception.h \ + /usr/include/c++/15/bits/deque.tcc \ + /usr/include/c++/15/bits/enable_special_members.h \ + /usr/include/c++/15/bits/erase_if.h \ + /usr/include/c++/15/bits/exception.h \ + /usr/include/c++/15/bits/exception_defines.h \ + /usr/include/c++/15/bits/exception_ptr.h \ + /usr/include/c++/15/bits/fstream.tcc \ + /usr/include/c++/15/bits/functexcept.h \ + /usr/include/c++/15/bits/functional_hash.h \ + /usr/include/c++/15/bits/hash_bytes.h \ + /usr/include/c++/15/bits/hashtable.h \ + /usr/include/c++/15/bits/hashtable_policy.h \ + /usr/include/c++/15/bits/invoke.h \ + /usr/include/c++/15/bits/ios_base.h \ + /usr/include/c++/15/bits/istream.tcc \ + /usr/include/c++/15/bits/locale_classes.h \ + /usr/include/c++/15/bits/locale_classes.tcc \ + /usr/include/c++/15/bits/locale_conv.h \ + /usr/include/c++/15/bits/locale_facets.h \ + /usr/include/c++/15/bits/locale_facets.tcc \ + /usr/include/c++/15/bits/locale_facets_nonio.h \ + /usr/include/c++/15/bits/locale_facets_nonio.tcc \ + /usr/include/c++/15/bits/localefwd.h \ + /usr/include/c++/15/bits/memory_resource.h \ + /usr/include/c++/15/bits/memoryfwd.h \ + /usr/include/c++/15/bits/monostate.h \ + /usr/include/c++/15/bits/move.h \ + /usr/include/c++/15/bits/nested_exception.h \ + /usr/include/c++/15/bits/new_allocator.h \ + /usr/include/c++/15/bits/node_handle.h \ + /usr/include/c++/15/bits/ostream.h \ + /usr/include/c++/15/bits/ostream.tcc \ + /usr/include/c++/15/bits/ostream_insert.h \ + /usr/include/c++/15/bits/parse_numbers.h \ + /usr/include/c++/15/bits/postypes.h \ + /usr/include/c++/15/bits/predefined_ops.h \ + /usr/include/c++/15/bits/ptr_traits.h \ + /usr/include/c++/15/bits/quoted_string.h \ + /usr/include/c++/15/bits/random.h \ + /usr/include/c++/15/bits/random.tcc \ + /usr/include/c++/15/bits/range_access.h \ + /usr/include/c++/15/bits/refwrap.h \ + /usr/include/c++/15/bits/requires_hosted.h \ + /usr/include/c++/15/bits/shared_ptr.h \ + /usr/include/c++/15/bits/shared_ptr_atomic.h \ + /usr/include/c++/15/bits/shared_ptr_base.h \ + /usr/include/c++/15/bits/specfun.h \ + /usr/include/c++/15/bits/sstream.tcc \ + /usr/include/c++/15/bits/std_abs.h \ + /usr/include/c++/15/bits/std_function.h \ + /usr/include/c++/15/bits/std_mutex.h \ + /usr/include/c++/15/bits/std_thread.h \ + /usr/include/c++/15/bits/stl_algo.h \ + /usr/include/c++/15/bits/stl_algobase.h \ + /usr/include/c++/15/bits/stl_bvector.h \ + /usr/include/c++/15/bits/stl_construct.h \ + /usr/include/c++/15/bits/stl_deque.h \ + /usr/include/c++/15/bits/stl_function.h \ + /usr/include/c++/15/bits/stl_heap.h \ + /usr/include/c++/15/bits/stl_iterator.h \ + /usr/include/c++/15/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/15/bits/stl_iterator_base_types.h \ + /usr/include/c++/15/bits/stl_map.h \ + /usr/include/c++/15/bits/stl_multimap.h \ + /usr/include/c++/15/bits/stl_multiset.h \ + /usr/include/c++/15/bits/stl_numeric.h \ + /usr/include/c++/15/bits/stl_pair.h \ + /usr/include/c++/15/bits/stl_raw_storage_iter.h \ + /usr/include/c++/15/bits/stl_relops.h \ + /usr/include/c++/15/bits/stl_set.h \ + /usr/include/c++/15/bits/stl_tempbuf.h \ + /usr/include/c++/15/bits/stl_tree.h \ + /usr/include/c++/15/bits/stl_uninitialized.h \ + /usr/include/c++/15/bits/stl_vector.h \ + /usr/include/c++/15/bits/stream_iterator.h \ + /usr/include/c++/15/bits/streambuf.tcc \ + /usr/include/c++/15/bits/streambuf_iterator.h \ + /usr/include/c++/15/bits/string_view.tcc \ + /usr/include/c++/15/bits/stringfwd.h \ + /usr/include/c++/15/bits/this_thread_sleep.h \ + /usr/include/c++/15/bits/uniform_int_dist.h \ + /usr/include/c++/15/bits/unique_lock.h \ + /usr/include/c++/15/bits/unique_ptr.h \ + /usr/include/c++/15/bits/unordered_map.h \ + /usr/include/c++/15/bits/uses_allocator.h \ + /usr/include/c++/15/bits/uses_allocator_args.h \ + /usr/include/c++/15/bits/utility.h \ + /usr/include/c++/15/bits/vector.tcc \ + /usr/include/c++/15/bits/version.h \ + /usr/include/c++/15/bitset \ + /usr/include/c++/15/cassert \ + /usr/include/c++/15/cctype \ + /usr/include/c++/15/cerrno \ + /usr/include/c++/15/cfenv \ + /usr/include/c++/15/chrono \ + /usr/include/c++/15/cinttypes \ + /usr/include/c++/15/climits \ + /usr/include/c++/15/clocale \ + /usr/include/c++/15/cmath \ + /usr/include/c++/15/compare \ + /usr/include/c++/15/concepts \ + /usr/include/c++/15/condition_variable \ + /usr/include/c++/15/csignal \ + /usr/include/c++/15/cstddef \ + /usr/include/c++/15/cstdint \ + /usr/include/c++/15/cstdio \ + /usr/include/c++/15/cstdlib \ + /usr/include/c++/15/cstring \ + /usr/include/c++/15/ctime \ + /usr/include/c++/15/cwchar \ + /usr/include/c++/15/cwctype \ + /usr/include/c++/15/cxxabi.h \ + /usr/include/c++/15/debug/assertions.h \ + /usr/include/c++/15/debug/debug.h \ + /usr/include/c++/15/deque \ + /usr/include/c++/15/exception \ + /usr/include/c++/15/ext/aligned_buffer.h \ + /usr/include/c++/15/ext/alloc_traits.h \ + /usr/include/c++/15/ext/atomicity.h \ + /usr/include/c++/15/ext/concurrence.h \ + /usr/include/c++/15/ext/numeric_traits.h \ + /usr/include/c++/15/ext/string_conversions.h \ + /usr/include/c++/15/ext/type_traits.h \ + /usr/include/c++/15/fenv.h \ + /usr/include/c++/15/fstream \ + /usr/include/c++/15/functional \ + /usr/include/c++/15/future \ + /usr/include/c++/15/initializer_list \ + /usr/include/c++/15/iomanip \ + /usr/include/c++/15/ios \ + /usr/include/c++/15/iosfwd \ + /usr/include/c++/15/iostream \ + /usr/include/c++/15/istream \ + /usr/include/c++/15/iterator \ + /usr/include/c++/15/limits \ + /usr/include/c++/15/locale \ + /usr/include/c++/15/map \ + /usr/include/c++/15/memory \ + /usr/include/c++/15/mutex \ + /usr/include/c++/15/new \ + /usr/include/c++/15/numeric \ + /usr/include/c++/15/optional \ + /usr/include/c++/15/ostream \ + /usr/include/c++/15/pstl/execution_defs.h \ + /usr/include/c++/15/pstl/glue_algorithm_defs.h \ + /usr/include/c++/15/pstl/glue_memory_defs.h \ + /usr/include/c++/15/pstl/glue_numeric_defs.h \ + /usr/include/c++/15/pstl/pstl_config.h \ + /usr/include/c++/15/random \ + /usr/include/c++/15/ratio \ + /usr/include/c++/15/set \ + /usr/include/c++/15/sstream \ + /usr/include/c++/15/stdexcept \ + /usr/include/c++/15/stdlib.h \ + /usr/include/c++/15/streambuf \ + /usr/include/c++/15/string \ + /usr/include/c++/15/string_view \ + /usr/include/c++/15/system_error \ + /usr/include/c++/15/thread \ + /usr/include/c++/15/tr1/bessel_function.tcc \ + /usr/include/c++/15/tr1/beta_function.tcc \ + /usr/include/c++/15/tr1/ell_integral.tcc \ + /usr/include/c++/15/tr1/exp_integral.tcc \ + /usr/include/c++/15/tr1/gamma.tcc \ + /usr/include/c++/15/tr1/hypergeometric.tcc \ + /usr/include/c++/15/tr1/legendre_function.tcc \ + /usr/include/c++/15/tr1/modified_bessel_func.tcc \ + /usr/include/c++/15/tr1/poly_hermite.tcc \ + /usr/include/c++/15/tr1/poly_laguerre.tcc \ + /usr/include/c++/15/tr1/riemann_zeta.tcc \ + /usr/include/c++/15/tr1/special_function_util.h \ + /usr/include/c++/15/tuple \ + /usr/include/c++/15/type_traits \ + /usr/include/c++/15/typeindex \ + /usr/include/c++/15/typeinfo \ + /usr/include/c++/15/unordered_map \ + /usr/include/c++/15/utility \ + /usr/include/c++/15/variant \ + /usr/include/c++/15/vector \ + /usr/include/c++/15/version \ + /usr/include/ctype.h \ + /usr/include/endian.h \ + /usr/include/errno.h \ + /usr/include/fcntl.h \ + /usr/include/features-time64.h \ + /usr/include/features.h \ + /usr/include/fenv.h \ + /usr/include/ifaddrs.h \ + /usr/include/inttypes.h \ + /usr/include/libintl.h \ + /usr/include/limits.h \ + /usr/include/linux/close_range.h \ + /usr/include/linux/errno.h \ + /usr/include/linux/falloc.h \ + /usr/include/linux/ioctl.h \ + /usr/include/linux/limits.h \ + /usr/include/linux/openat2.h \ + /usr/include/linux/posix_types.h \ + /usr/include/linux/sched/types.h \ + /usr/include/linux/sctp.h \ + /usr/include/linux/socket.h \ + /usr/include/linux/sockios.h \ + /usr/include/linux/stat.h \ + /usr/include/linux/stddef.h \ + /usr/include/linux/types.h \ + /usr/include/linux/version.h \ + /usr/include/locale.h \ + /usr/include/math.h \ + /usr/include/net/if.h \ + /usr/include/netdb.h \ + /usr/include/netinet/in.h \ + /usr/include/netinet/sctp.h \ + /usr/include/netinet/tcp.h \ + /usr/include/poll.h \ + /usr/include/pthread.h \ + /usr/include/regex.h \ + /usr/include/rpc/netdb.h \ + /usr/include/sched.h \ + /usr/include/signal.h \ + /usr/include/stdc-predef.h \ + /usr/include/stdint.h \ + /usr/include/stdio.h \ + /usr/include/stdlib.h \ + /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/syslog.h \ + /usr/include/termios.h \ + /usr/include/time.h \ + /usr/include/unistd.h \ + /usr/include/wchar.h \ + /usr/include/wctype.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/x86_64-linux-gnu/asm/unistd.h \ + /usr/include/x86_64-linux-gnu/asm/unistd_64.h \ + /usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/epoll.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/x86_64-linux-gnu/bits/eventfd.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux-fortify.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl2.h \ + /usr/include/x86_64-linux-gnu/bits/fenv.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/flt-eval-method.h \ + /usr/include/x86_64-linux-gnu/bits/fp-fast.h \ + /usr/include/x86_64-linux-gnu/bits/fp-logb.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/in.h \ + /usr/include/x86_64-linux-gnu/bits/inet-fortified-decl.h \ + /usr/include/x86_64-linux-gnu/bits/inet-fortified.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/bits/iscanonical.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/bits/math-vector.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls-macros.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/openat2.h \ + /usr/include/x86_64-linux-gnu/bits/poll.h \ + /usr/include/x86_64-linux-gnu/bits/poll2.h \ + /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/select-decl.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigevent-consts.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-arch.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-consts-arch.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-consts.h \ + /usr/include/x86_64-linux-gnu/bits/signal_ext.h \ + /usr/include/x86_64-linux-gnu/bits/signum-arch.h \ + /usr/include/x86_64-linux-gnu/bits/signum-generic.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/sigstksz.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/ss_flags.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h \ + /usr/include/x86_64-linux-gnu/bits/statx-generic.h \ + /usr/include/x86_64-linux-gnu/bits/statx.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2-decl.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/struct_stat.h \ + /usr/include/x86_64-linux-gnu/bits/syscall.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-decl.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ + /usr/include/x86_64-linux-gnu/bits/syslog.h \ + /usr/include/x86_64-linux-gnu/bits/termios-baud.h \ + /usr/include/x86_64-linux-gnu/bits/termios-c_cc.h \ + /usr/include/x86_64-linux-gnu/bits/termios-c_cflag.h \ + /usr/include/x86_64-linux-gnu/bits/termios-c_iflag.h \ + /usr/include/x86_64-linux-gnu/bits/termios-c_lflag.h \ + /usr/include/x86_64-linux-gnu/bits/termios-c_oflag.h \ + /usr/include/x86_64-linux-gnu/bits/termios-cbaud.h \ + /usr/include/x86_64-linux-gnu/bits/termios-misc.h \ + /usr/include/x86_64-linux-gnu/bits/termios-struct.h \ + /usr/include/x86_64-linux-gnu/bits/termios-tcflow.h \ + /usr/include/x86_64-linux-gnu/bits/termios.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/timerfd.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/error_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/idtype_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/stack_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_statx.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_statx_timestamp.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/wint_t.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/bits/uio-ext.h \ + /usr/include/x86_64-linux-gnu/bits/uio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/unistd-decl.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h \ + /usr/include/x86_64-linux-gnu/bits/utsname.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2-decl.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2.h \ + /usr/include/x86_64-linux-gnu/bits/wctype-wchar.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/atomic_word.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/basic_file.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++allocator.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++config.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++io.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++locale.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/cpu_defines.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_base.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_inline.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/cxxabi_tweaks.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/error_constants.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr-default.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/messages_members.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/opt_random.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/os_defines.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/time_members.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/sys/epoll.h \ + /usr/include/x86_64-linux-gnu/sys/eventfd.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/sys/poll.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/sys/single_threaded.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/syscall.h \ + /usr/include/x86_64-linux-gnu/sys/syslog.h \ + /usr/include/x86_64-linux-gnu/sys/timerfd.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/sys/uio.h \ + /usr/include/x86_64-linux-gnu/sys/un.h \ + /usr/include/x86_64-linux-gnu/sys/utsname.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/adxintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/ammintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxavx512intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxbf16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxcomplexintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxfp16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxfp8intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxint8intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxmovrsintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxtf32intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxtileintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxtransposeintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512bf16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512convertintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512mediaintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512minmaxintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512satcvtintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2bf16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2convertintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2copyintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2mediaintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2minmaxintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2satcvtintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx2intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bf16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bf16vlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bitalgintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bitalgvlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bwintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512cdintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512dqintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fp16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fp16vlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512ifmaintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512ifmavlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmi2intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmi2vlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmiintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmivlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vlbwintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vldqintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vnniintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vnnivlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vp2intersectintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vp2intersectvlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vpopcntdqintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vpopcntdqvlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxifmaintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxneconvertintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniint16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniint8intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/bmi2intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/bmiintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/cetintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/cldemoteintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/clflushoptintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/clwbintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/clzerointrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/cmpccxaddintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/emmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/enqcmdintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/f16cintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/float.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/fma4intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/fmaintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/fxsrintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/gfniintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/hresetintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/ia32intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/immintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/keylockerintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/lwpintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/lzcntintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/mm3dnow.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/mm_malloc.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/mmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/movdirintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/movrsintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/mwaitintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/mwaitxintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/pconfigintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/pkuintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/pmmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/popcntintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/prfchiintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/prfchwintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/raointintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/rdseedintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/rtmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/serializeintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/sgxintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/sha512intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/shaintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/sm3intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/sm4intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/smmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdarg.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/syslimits.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/tbmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/tmmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/tsxldtrkintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/uintrintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/usermsrintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/vaesintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/vpclmulqdqintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/waitpkgintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/wbnoinvdintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/wmmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/x86gprintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/x86intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xmmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xopintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsavecintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsaveintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsaveoptintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsavesintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xtestintrin.h + +bin/net_control_test: /lib64/ld-linux-x86-64.so.2 \ + /usr/lib/x86_64-linux-gnu/Scrt1.o \ + /usr/lib/x86_64-linux-gnu/crti.o \ + /usr/lib/x86_64-linux-gnu/crtn.o \ + /usr/lib/x86_64-linux-gnu/libbsd.so \ + /usr/lib/x86_64-linux-gnu/libc.so \ + /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 \ + /usr/lib/x86_64-linux-gnu/libm.so \ + /usr/lib/x86_64-linux-gnu/libmd.so \ + /usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o \ + /usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o \ + /usr/lib/gcc/x86_64-linux-gnu/15/libasan.so \ + /usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o \ + /usr/lib/gcc/x86_64-linux-gnu/15/libgcc.a \ + /usr/lib/gcc/x86_64-linux-gnu/15/libgcc_s.so \ + /usr/lib/gcc/x86_64-linux-gnu/15/libstdc++.so \ + /usr/lib/gcc/x86_64-linux-gnu/15/libubsan.so \ + /usr/lib/x86_64-linux-gnu/libbsd.so.0.12.2 \ + /usr/lib/x86_64-linux-gnu/libc.so.6 \ + /usr/lib/x86_64-linux-gnu/libc_nonshared.a \ + /usr/lib/x86_64-linux-gnu/libm.so.6 \ + /usr/lib/x86_64-linux-gnu/libmvec.so.1 \ + /usr/lib/x86_64-linux-gnu/libsctp.so \ + CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o \ + lib/libgtest.a \ + lib/libgtest_main.a + + +lib/libgtest.a: + +/usr/lib/x86_64-linux-gnu/libsctp.so: + +/usr/lib/x86_64-linux-gnu/libmvec.so.1: + +/usr/lib/x86_64-linux-gnu/libc_nonshared.a: + +/usr/lib/x86_64-linux-gnu/libbsd.so.0.12.2: + +/usr/lib/gcc/x86_64-linux-gnu/15/libubsan.so: + +/usr/lib/gcc/x86_64-linux-gnu/15/libstdc++.so: + +/usr/lib/gcc/x86_64-linux-gnu/15/libgcc_s.so: + +/usr/lib/gcc/x86_64-linux-gnu/15/libgcc.a: + +/usr/lib/gcc/x86_64-linux-gnu/15/libasan.so: + +/usr/lib/gcc/x86_64-linux-gnu/15/crtbeginS.o: + +/usr/lib/x86_64-linux-gnu/libmd.so: + +/usr/lib/x86_64-linux-gnu/libm.so: + +/usr/lib/x86_64-linux-gnu/libc.so: + +/usr/lib/x86_64-linux-gnu/crti.o: + +/usr/lib/x86_64-linux-gnu/Scrt1.o: + +/lib64/ld-linux-x86-64.so.2: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xtestintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xsaveoptintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xsaveintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/libasan_preinit.o: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xopintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xmmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/x86intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/x86gprintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/wmmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/wbnoinvdintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/vaesintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/usermsrintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/tsxldtrkintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/tmmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/tbmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/syslimits.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: + +/usr/lib/x86_64-linux-gnu/libm.so.6: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/smmintrin.h: + +lib/libgtest_main.a: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/sm3intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/shaintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/serializeintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/rdseedintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/raointintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/prfchwintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/prfchiintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/popcntintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/pconfigintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/mwaitxintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/mwaitintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/movrsintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/movdirintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/mm_malloc.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/keylockerintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/immintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/ia32intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/gfniintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/fxsrintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/fmaintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/enqcmdintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/emmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/cmpccxaddintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/clzerointrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/cetintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/bmiintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avxifmaintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vpopcntdqvlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vp2intersectvlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vnnivlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmiintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmi2vlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmi2intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512ifmavlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512ifmaintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fp16vlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fp16intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/rtmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512cdintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bwintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bitalgvlintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/writable_pipe.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_null_buffers_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/stream_handle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/blob.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/random_access_handle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_stream_handle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/scheduler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detached.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/wait_traits.hpp: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/version.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_serial_port_service.ipp: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_require.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-common.h: + +/usr/include/x86_64-linux-gnu/bits/flt-eval-method.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/schedule_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_value_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_concept_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/bulk_execute_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/time_traits.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_timer.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/execute_member.hpp: + +/usr/lib/x86_64-linux-gnu/crtn.o: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_ptime.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_error.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/signal_set.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_context.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/waitpkgintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/string_view.hpp: + +/usr/include/c++/15/concepts: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/serial_port.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/require_concept.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/registered_buffer.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/object_handle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_scheduler_fwd.hpp: + +/usr/include/c++/15/tr1/poly_laguerre.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/random_access_file.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/multicast.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/descriptor_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/basic_descriptor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_concept_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/detail/impl/endpoint.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v4.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v4.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v4.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit_inject.hpp: + +/usr/include/linux/types.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_waitable_timer.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_prod.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/icmp.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/socket_option.hpp: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/mm3dnow.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/impl/endpoint.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/connect_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4_range.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4.hpp: + +/usr/include/c++/15/tr1/riemann_zeta.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/lowmc/LowMC.cpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/prefer_member.hpp: + +/usr/include/x86_64-linux-gnu/bits/fp-logb.h: + +/usr/include/x86_64-linux-gnu/bits/types/idtype_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_endpoint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/write.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/use_future.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_set_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/thread_pool.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_option.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/crtendS.o: + +/usr/include/linux/close_range.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/overlapped_handle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/serial_port_base.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/serial_port_base.hpp: + +/usr/include/c++/15/bits/stl_multiset.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read_until.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/handler_alloc_hook.ipp: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/c++/15/bits/unordered_map.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/error_code.ipp: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/detached.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/stdarg.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-port.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/buffered_read_stream.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/socket_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/thread.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/any_io_executor.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/timer_queue_set.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/any_completion_executor.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_invoke_hook.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/write_at.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_receiver.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/write.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/stream_protocol.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/select_interrupter.hpp: + +/usr/include/c++/15/string: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/sha512intrin.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/bmi2intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/asio_ns.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse2.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/redirect_error.hpp: + +/usr/include/c++/15/typeindex: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/datagram_protocol.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/basic_endpoint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/file_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/connect_pair.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/bitstring.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_value.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/executor_work_guard.hpp: + +/usr/include/c++/15/locale: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_error.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_event.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_done.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/prefer.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/float.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-path.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/schedule.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/receiver_invocation_error.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/prefer_only.hpp: + +/usr/lib/x86_64-linux-gnu/libbsd.so: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/connect_member.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/uintrintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/outstanding_work.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/exact-int/exact-int.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/operation_state.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/occupancy.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/experiment.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/mapping.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/invocable_archetype.hpp: + +/usr/include/linux/stat.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/impl/bad_executor.ipp: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/executor.hpp: + +/usr/include/regex.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/sm4intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_query.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/execute.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/detail/endpoint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_context.hpp: + +/usr/lib/x86_64-linux-gnu/libc.so.6: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/submit_receiver.hpp: + +/usr/include/c++/15/cstdio: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/connect.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/stream_protocol.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bulk_guarantee.hpp: + +/usr/include/netinet/sctp.h: + +/usr/include/c++/15/tr1/bessel_function.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6_iterator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-printers.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bad_executor.hpp: + +/usr/include/c++/15/bits/streambuf_iterator.h: + +/usr/include/poll.h: + +/usr/include/x86_64-linux-gnu/bits/types/error_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/io_context.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/any_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/allocator.hpp: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/work_dispatcher.hpp: + +/usr/include/linux/socket.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wait_handler.hpp: + +/usr/include/c++/15/iostream: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_runtime.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/udp.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/utility.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/f16cintrin.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/network_v6.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/tss_ptr.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_datagram_socket.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_scheduler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_set.hpp: + +/usr/include/assert.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/completion_handler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue.hpp: + +/usr/include/c++/15/typeinfo: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/throw_exception.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/future.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avxneconvertintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_info_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/error.hpp: + +/usr/include/x86_64-linux-gnu/bits/statx.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_context.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/multiple_exceptions.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/execution_context.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/stdlib.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/context_as.hpp: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/hresetintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/static_thread_pool.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/uses_executor.hpp: + +/usr/include/c++/15/bits/ptr_traits.h: + +/usr/include/x86_64-linux-gnu/bits/unistd-decl.h: + +/usr/include/c++/15/optional: + +/usr/include/x86_64-linux-gnu/bits/termios-c_lflag.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_ops.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read_at.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-death-test.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_blocker.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scoped_ptr.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_immediate_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_endpoint_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/regex_fwd.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_executor.hpp: + +/usr/include/c++/15/type_traits: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v6.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4_iterator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_streambuf_fwd.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/readable_pipe.hpp: + +/usr/include/c++/15/bits/locale_facets.tcc: + +/usr/include/stdlib.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_stream_file.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xsavecintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/bulk_sender.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/uint256_t.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/limits.hpp: + +/usr/include/c++/15/bits/stringfwd.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolver_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/executor.ipp: + +/usr/include/c++/15/bits/stl_tempbuf.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/beaver.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_signal_set.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/functional.hpp: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/bits/fp-fast.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect_pipe.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_results.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_seq_packet_socket.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_write_stream_fwd.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_aes_ccr.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_stream.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/descriptor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/handler_tracking.ipp: + +/usr/include/c++/15/bits/stl_deque.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/lzcntintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_file.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v6.ipp: + +/usr/include/c++/15/bits/std_thread.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxfp8intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/launch.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffers_iterator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/as_tuple.hpp: + +/usr/include/c++/15/bits/vector.tcc: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/c++/15/climits: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vlbwintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/coroutine.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_object_handle.hpp: + +/usr/include/endian.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/atomic_count.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/post.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/prepend.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_value_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_io_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/unicast.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_static_constexpr_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/fenced_block.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/detail/impl/endpoint.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/high_resolution_timer.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_writable_pipe.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_types.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/host_name.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_immediate_executor.hpp: + +/usr/include/c++/15/ext/aligned_buffer.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxcomplexintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_completion_handler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/placement.hpp: + +/usr/include/c++/15/thread: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/lwpintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vp2intersectintrin.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/assert.hpp: + +/usr/include/c++/15/algorithm: + +/home/cryptolicious/hushmap-specified/libdpf/include/grotto/fixedpoint_mul.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/eventfd_select_interrupter.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scoped_lock.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_mesh.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vlintrin.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigval_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/consign.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/execute_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_pred_impl.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/bad_address_cast.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/grotto/fixedpoint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/compose.hpp: + +/usr/include/c++/15/bits/allocated_ptr.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_stream_socket.hpp: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/winsock_init.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_read_stream_fwd.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/compose.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/mutex.hpp: + +/usr/include/locale.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v6.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/twiddle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/verifiable.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/round_sink.hpp: + +/usr/include/x86_64-linux-gnu/bits/mathcalls-macros.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_error_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/execution_context.ipp: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/awaitable.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_service_strand.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v4.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/rss_seed.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/variadic_templates.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_sendto_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/executor_function.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/ot_pack.hpp: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/bits/wchar2-decl.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/random.hpp: + +/usr/include/wctype.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/context.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/use_awaitable.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_lowmc.hpp: + +/usr/include/stdio.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/buffered_write_stream.hpp: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/throw_error.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_contiguous_iterator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/scheduler.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_done_free.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512convertintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_random_access_file.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_dummy.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/cldemoteintrin.h: + +/usr/include/linux/posix_types.h: + +/usr/include/x86_64-linux-gnu/bits/openat2.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/twobit.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_chacha.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_global.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/signal_set_base.hpp: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/receiver.hpp: + +/usr/include/net/if.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/aligned_allocator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-f16.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-filepath.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/compose_async.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/strand_executor_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect_pipe.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/bulk_execute_free.hpp: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/relationship.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_query_op.hpp: + +/usr/include/ifaddrs.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/utils.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/datagram_protocol.hpp: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_round_sink.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_require_concept.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/eventfd_select_interrupter.ipp: + +/usr/include/c++/15/bits/predefined_ops.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/secret_share.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/shamir.hpp: + +/usr/include/x86_64-linux-gnu/bits/sigstksz.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/pmmintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_raw_socket.hpp: + +/usr/include/c++/15/bits/locale_facets.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/epoll_reactor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_streambuf.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/avx2.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/clflushoptintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/v6_only.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/fp61.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_sctp_stream_array.hpp: + +/usr/include/c++/15/bits/stl_vector.h: + +/usr/include/linux/openat2.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/chrono.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/append.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/channel.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/network_v4.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_handler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution_context.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/base_from_cancellation_state.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_send_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_cont_helpers.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/uint128_t.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_holder.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/dependent_type.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/connect_pipe.hpp: + +/usr/include/c++/15/bits/alloc_traits.h: + +/usr/include/x86_64-linux-gnu/bits/termios-tcflow.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++allocator.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_cancellation_slot.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_deadline_timer.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read_until.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/serial_port_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v6.ipp: + +/usr/include/linux/stddef.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_query.hpp: + +/usr/include/ctype.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/deferred.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/call_stack.hpp: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/append.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avxintrin.h: + +/usr/include/c++/15/fenv.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_stream_array.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/dealer_cursor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prep_source.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/multiple_exceptions.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/pad_graphs.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/host_name.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/streambuf.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffer_registration.hpp: + +/usr/include/c++/15/set: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_cancellation_slot.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmivlintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_invocable.hpp: + +/usr/include/c++/15/cstring: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/strand_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/buffer_pool.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread.hpp: + +/usr/include/c++/15/bits/version.h: + +/usr/include/c++/15/bits/node_handle.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/is_buffer_sequence.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_signal.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/type_traits.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/literals.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_plans.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xsavesintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_edge_mesh.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/log.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/buffered_prg.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/blocking.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wrapped_handler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/resolver_service_base.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_flow.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/cstddef.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_read_stream.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/nyble.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/leaf_arithmetic.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/party_session.hpp: + +/usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/noncopyable.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_type.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_overlapped_handle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/require.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_free.hpp: + +/usr/include/c++/15/bits/shared_ptr_atomic.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_descriptor_service.hpp: + +/usr/include/c++/15/limits: + +/usr/include/x86_64-linux-gnu/asm/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/thread_pool.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/static_mutex.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/stream_descriptor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_acceptor.hpp: + +/usr/include/errno.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/sink_exchange.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_readable_pipe.hpp: + +/usr/include/x86_64-linux-gnu/bits/termios-c_cc.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/socket_ops.ipp: + +/usr/include/features-time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/mesh_apps.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_task.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/memory_sink.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_operation.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_post.hpp: + +/usr/include/x86_64-linux-gnu/bits/signum-arch.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_count.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/online_session.hpp: + +/usr/include/c++/15/cwchar: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/run_log.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/experiment_note.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/impl/receiver_invocation_error.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/query.hpp: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/push_options.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_accept_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/edabit.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_context.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/wildcard.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-assertion-result.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/blocking_adaptation.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/base_from_completion_cond.hpp: + +/usr/include/x86_64-linux-gnu/bits/syslog.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2bf16intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/party_run.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/epoll_reactor.ipp: + +/usr/include/c++/15/bits/codecvt.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_write_stream.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/party_runner.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/global.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/conditionally_enabled_mutex.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/deferred.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associator.hpp: + +/usr/include/c++/15/stdexcept: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/ammintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/policy.hpp: + +/usr/include/c++/15/functional: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/event.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/os_defines.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/date_time_fwd.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/edge_mesh.hpp: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/basic_file.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/completion_condition.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/error_code.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/connect.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/redirect_error.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit_array.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/hash-library/sha256.h: + +/usr/include/c++/15/bits/atomic_futex.h: + +/usr/include/c++/15/initializer_list: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/overlapped_ptr.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_work.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_service_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_thread.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_iterator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/cstdint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_defer.hpp: + +/usr/include/c++/15/bits/uses_allocator_args.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/consign.hpp: + +/usr/include/c++/15/iosfwd: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/defer.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_completion_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/submit_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/tcp_mesh.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/array_fwd.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/hedley.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read_at.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse4.2.h: + +/usr/include/c++/15/bits/stl_set.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/void_receiver.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wait_op.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniint16intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactor_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_entry.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_service.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/blocking_executor_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/is_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_mutex.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_static_mutex.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_iostream.hpp: + +/usr/include/c++/15/bits/invoke.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-arch.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/bulk_executor_op.hpp: + +/usr/include/c++/15/bits/sstream.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_serial_port.hpp: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/schedule_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/concurrency_hint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/conditionally_enabled_event.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_array.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/config.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/session_host.hpp: + +/usr/include/libintl.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/reactive_descriptor_service.ipp: + +/usr/include/x86_64-linux-gnu/bits/termios-struct.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/consuming_buffers.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/operation.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/check.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/mmx.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_thread_info.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/modint.hpp: + +/usr/include/netinet/in.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_write_buffered.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/deadline_timer_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/io_control.hpp: + +/usr/include/x86_64-linux-gnu/bits/stdint-least.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/tcp.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port-arch.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_read_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/epoll_reactor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/basic_endpoint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_alloc_helpers.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_io_object.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-matchers.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/trunc.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_tracking.hpp: + +/usr/include/alloca.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_type_requirements.hpp: + +/usr/include/x86_64-linux-gnu/bits/inet-fortified-decl.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recvmsg_op.hpp: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/stream_file.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/io_pool.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/bind_handler.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++locale.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/descriptor_ops.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_state.hpp: + +/usr/include/c++/15/iomanip: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/sender.hpp: + +/usr/include/c++/15/bits/chrono.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/executor_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolver_service_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/reactive_socket_service_base.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/null_event.hpp: + +/usr/include/x86_64-linux-gnu/bits/wctype-wchar.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/connect.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_member.hpp: + +/usr/include/c++/15/bits/ostream.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/write_at.hpp: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/pkuintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/prefer_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/pop_options.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/service_registry.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/thread_context.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/keyword_tss_ptr.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_dispatch.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/op_queue.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/local_free_on_block_exit.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/io_object_impl.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2minmaxintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/memory.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/composed_work.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/non_const_lvalue.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/raw_protocol.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffered_stream_storage.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-detect-clang.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/cancellation_signal.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_done_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/null_event.ipp: + +/usr/include/asm-generic/bitsperlong.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_event.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recv_op.hpp: + +/usr/include/x86_64-linux-gnu/bits/poll.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recvfrom_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/dispatch.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_wait_op.hpp: + +/usr/include/x86_64-linux-gnu/bits/iscanonical.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/object_pool.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/use_future.hpp: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/unistd.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/recycling_allocator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/libutil.h: + +/usr/include/c++/15/string_view: + +/usr/include/c++/15/bits/basic_string.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/signal_set_service.ipp: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/hash-library/sha256.cpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/hedley/hedley.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxfp16intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/run_config.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/lowmc/LowMC.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/debug-trap.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-constify.h: + +/usr/include/c++/15/bitset: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-diagnostic.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-features.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-math.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/avx.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse3.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/link_log.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse4.1.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/ssse3.h: + +/usr/include/x86_64-linux-gnu/sys/single_threaded.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/endianness.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/uint256_t.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_signal_blocker.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/cpu_defines.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/fma4intrin.h: + +/usr/include/fenv.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-param-test.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/equality_comparable.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-test-part.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/async_result.hpp: + +/usr/include/inttypes.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-typed-test.h: + +/usr/include/c++/15/backward/auto_ptr.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_alloc_hook.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-internal.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_statx_timestamp.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-param-util.h: + +/usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/start_member.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++io.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/packed_lane_arithmetic.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-type-util.h: + +/usr/include/arpa/inet.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/asm-generic/errno.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/service_registry.hpp: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/c++/15/csignal: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/asm-generic/socket.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-align.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vnniintrin.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/asm-generic/types.h: + +/usr/include/c++/15/any: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/xor_wrapper.hpp: + +/usr/include/c++/15/atomic: + +/usr/include/c++/15/backward/binders.h: + +/usr/include/c++/15/exception: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/basic_stream_descriptor.hpp: + +/usr/include/c++/15/bits/algorithmfwd.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/std_fenced_block.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-message.h: + +/usr/include/c++/15/bits/align.h: + +/usr/include/x86_64-linux-gnu/sys/syscall.h: + +/usr/include/c++/15/bits/allocator.h: + +/usr/include/c++/15/bits/atomic_base.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/vpclmulqdqintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-string.h: + +/usr/include/c++/15/bits/basic_ios.h: + +/usr/include/c++/15/variant: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/resolver_base.hpp: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxtransposeintrin.h: + +/usr/include/c++/15/bits/basic_ios.tcc: + +/usr/include/c++/15/pstl/pstl_config.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_service.hpp: + +/usr/include/c++/15/bits/basic_string.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/c++/15/ostream: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_executor_service.hpp: + +/usr/include/c++/15/bits/char_traits.h: + +/usr/include/x86_64-linux-gnu/bits/termios-cbaud.h: + +/usr/include/c++/15/bits/charconv.h: + +/usr/include/c++/15/bits/concept_check.h: + +/usr/include/x86_64-linux-gnu/sys/uio.h: + +/usr/include/c++/15/bits/cpp_type_traits.h: + +/usr/include/c++/15/bits/cxxabi_forced.h: + +/usr/include/c++/15/bits/cxxabi_init_exception.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/this_coro.hpp: + +/usr/include/c++/15/bits/enable_special_members.h: + +/usr/include/c++/15/bits/erase_if.h: + +/usr/include/c++/15/cctype: + +/usr/include/c++/15/bits/std_mutex.h: + +/usr/include/c++/15/bits/exception.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_serial_port_service.hpp: + +/usr/include/c++/15/bits/exception_defines.h: + +/usr/include/c++/15/bits/exception_ptr.h: + +/usr/include/c++/15/bits/fstream.tcc: + +/usr/include/c++/15/bits/functexcept.h: + +/usr/include/c++/15/bits/functional_hash.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/socket_tune.hpp: + +/usr/include/c++/15/bits/hash_bytes.h: + +/usr/include/c++/15/bits/hashtable.h: + +/usr/include/c++/15/bits/hashtable_policy.h: + +/usr/include/c++/15/bits/ios_base.h: + +/usr/include/c++/15/bits/istream.tcc: + +/usr/include/c++/15/bits/locale_classes.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/c++/15/bits/locale_classes.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/endian/endian.h: + +/usr/include/c++/15/bits/locale_conv.h: + +/usr/include/c++/15/bits/locale_facets_nonio.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/array.hpp: + +/usr/include/c++/15/bits/memory_resource.h: + +/usr/include/c++/15/bits/stl_function.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_read_buffered.hpp: + +/usr/include/c++/15/bits/memoryfwd.h: + +/usr/include/c++/15/bits/monostate.h: + +/usr/include/c++/15/bits/move.h: + +/usr/include/c++/15/bits/unique_ptr.h: + +/usr/include/c++/15/bits/new_allocator.h: + +/usr/include/c++/15/bits/ostream.h: + +/usr/include/c++/15/bits/stl_raw_storage_iter.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/seq_packet_protocol.hpp: + +/usr/include/c++/15/bits/ostream_insert.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_context_strand.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/start.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffer.hpp: + +/usr/include/c++/15/bits/parse_numbers.h: + +/usr/include/c++/15/bits/postypes.h: + +/usr/include/c++/15/bits/quoted_string.h: + +/usr/include/c++/15/bits/random.h: + +/usr/include/c++/15/bits/random.tcc: + +/usr/include/c++/15/bits/stl_relops.h: + +/usr/include/c++/15/bits/range_access.h: + +/usr/include/c++/15/map: + +/usr/include/c++/15/bits/requires_hosted.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_stream_fwd.hpp: + +/usr/include/c++/15/bits/shared_ptr_base.h: + +/usr/include/c++/15/bits/std_abs.h: + +/usr/include/c++/15/ios: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_context.hpp: + +/usr/include/c++/15/bits/nested_exception.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h: + +/usr/include/netinet/tcp.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/c++/15/bits/std_function.h: + +/usr/include/c++/15/bits/stl_algo.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/placeholders.hpp: + +/usr/include/c++/15/random: + +/usr/include/c++/15/array: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/detail/endpoint.hpp: + +/usr/include/c++/15/bits/stl_bvector.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2-decl.h: + +/usr/include/c++/15/bits/stl_construct.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/chrono_time_traits.hpp: + +/usr/include/c++/15/bits/stl_heap.h: + +/usr/include/c++/15/bits/stream_iterator.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/round_lane.hpp: + +/usr/include/c++/15/bits/stl_iterator.h: + +/usr/include/x86_64-linux-gnu/sys/epoll.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_allocator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_connect_op.hpp: + +/usr/include/c++/15/bits/stl_iterator_base_types.h: + +/usr/include/c++/15/bits/stl_map.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/start_free.hpp: + +/usr/include/c++/15/ratio: + +/usr/include/c++/15/bits/stl_multimap.h: + +/usr/include/x86_64-linux-gnu/bits/fenv.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/stdio.h: + +/usr/include/c++/15/bits/stl_numeric.h: + +/usr/include/c++/15/bits/stl_pair.h: + +/usr/include/c++/15/bits/shared_ptr.h: + +/usr/include/c++/15/cstdint: + +/usr/include/c++/15/bits/stl_tree.h: + +/usr/include/string.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/throw_error.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxint8intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_continuation_hook.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxtileintrin.h: + +/usr/include/c++/15/bits/stl_uninitialized.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/builtin/builtin.h: + +/usr/include/x86_64-linux-gnu/bits/poll2.h: + +/usr/include/c++/15/bits/string_view.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/co_spawn.hpp: + +/usr/include/c++/15/bits/this_thread_sleep.h: + +/usr/include/c++/15/bits/uniform_int_dist.h: + +/usr/include/c++/15/bits/unique_lock.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bf16vlintrin.h: + +/usr/include/c++/15/bits/uses_allocator.h: + +/usr/include/c++/15/bits/utility.h: + +/usr/include/c++/15/cassert: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/sgxintrin.h: + +/usr/include/c++/15/cerrno: + +/usr/include/c++/15/cfenv: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_thread.hpp: + +/usr/include/c++/15/tr1/ell_integral.tcc: + +/usr/include/stdc-predef.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/error.ipp: + +/usr/include/c++/15/chrono: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_random_access_handle.hpp: + +/usr/include/c++/15/cinttypes: + +/usr/include/math.h: + +/usr/include/c++/15/clocale: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxmovrsintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/basic_endpoint.hpp: + +/usr/include/c++/15/condition_variable: + +/usr/include/linux/falloc.h: + +/usr/include/c++/15/cstddef: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffer_resize_guard.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/recycling_allocator.hpp: + +/usr/include/c++/15/cstdlib: + +/usr/lib/x86_64-linux-gnu/libgcc_s.so.1: + +/usr/include/c++/15/ctime: + +/usr/include/c++/15/cwctype: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/c++/15/debug/assertions.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/submit_free.hpp: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/bits/ss_flags.h: + +/usr/include/c++/15/debug/debug.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/c++/15/deque: + +/usr/include/c++/15/bits/locale_facets_nonio.h: + +/usr/include/c++/15/ext/alloc_traits.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/c++/15/ext/concurrence.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512dqintrin.h: + +/usr/include/c++/15/ext/numeric_traits.h: + +/usr/include/c++/15/ext/string_conversions.h: + +/usr/include/c++/15/ext/type_traits.h: + +/usr/include/c++/15/fstream: + +/usr/include/c++/15/istream: + +/usr/include/c++/15/iterator: + +/usr/include/x86_64-linux-gnu/bits/epoll.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution.hpp: + +/usr/include/x86_64-linux-gnu/bits/types/stack_t.h: + +/usr/include/c++/15/memory: + +/usr/include/c++/15/mutex: + +/usr/include/c++/15/new: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/c++/15/numeric: + +/usr/include/c++/15/pstl/execution_defs.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_allocator.hpp: + +/usr/include/c++/15/pstl/glue_algorithm_defs.h: + +/usr/include/c++/15/ext/atomicity.h: + +/usr/include/c++/15/pstl/glue_memory_defs.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_mutex.ipp: + +/usr/include/c++/15/pstl/glue_numeric_defs.h: + +/usr/include/c++/15/stdlib.h: + +/usr/include/c++/15/streambuf: + +/usr/include/c++/15/system_error: + +/usr/include/c++/15/tr1/beta_function.tcc: + +/usr/include/c++/15/tr1/exp_integral.tcc: + +/usr/include/c++/15/sstream: + +/usr/include/c++/15/tr1/gamma.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/thread_pool.hpp: + +/usr/include/limits.h: + +/usr/include/c++/15/tr1/hypergeometric.tcc: + +/usr/include/time.h: + +/usr/include/c++/15/future: + +/usr/include/c++/15/tr1/legendre_function.tcc: + +/usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h: + +/usr/include/c++/15/tr1/modified_bessel_func.tcc: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/uio-ext.h: + +/usr/include/x86_64-linux-gnu/sys/poll.h: + +/usr/include/c++/15/tr1/special_function_util.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/clwbintrin.h: + +/usr/include/c++/15/unordered_map: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/prepend.hpp: + +/usr/include/c++/15/utility: + +/usr/include/c++/15/vector: + +/usr/include/c++/15/compare: + +/usr/include/c++/15/version: + +/usr/include/features.h: + +/usr/include/c++/15/bits/deque.tcc: + +/usr/include/c++/15/bits/streambuf.tcc: + +/usr/include/linux/ioctl.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/leaf_node.hpp: + +/usr/include/linux/sched/types.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_group.hpp: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vpopcntdqintrin.h: + +/usr/include/linux/sctp.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_streambuf.hpp: + +/usr/include/linux/sockios.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_invoke_helpers.hpp: + +/usr/include/linux/version.h: + +/usr/include/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h: + +/usr/include/sched.h: + +/usr/include/pthread.h: + +/usr/include/rpc/netdb.h: + +/usr/include/signal.h: + +/usr/include/c++/15/bits/stl_iterator_base_funcs.h: + +/usr/include/x86_64-linux-gnu/bits/struct_stat.h: + +/usr/include/x86_64-linux-gnu/bits/types/wint_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/packed_lane.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2copyintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/mmintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_write_op.hpp: + +/usr/include/stdint.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/steady_timer.hpp: + +/usr/include/strings.h: + +/usr/include/syslog.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_aes.hpp: + +/usr/include/termios.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/ctype_inline.h: + +/usr/include/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/statx-generic.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/c++/15/bits/specfun.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++config.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniint8intrin.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o: + +/usr/include/x86_64-linux-gnu/asm/unistd_64.h: + +/usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/seq_packet_protocol.hpp: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_ops.hpp: + +/usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bitalgintrin.h: + +/usr/include/c++/15/bits/localefwd.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls.h: + +/usr/include/x86_64-linux-gnu/bits/eventfd.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/endpoint.hpp: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux-fortify.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl2.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_executor_service.ipp: + +/usr/include/x86_64-linux-gnu/bits/inet-fortified.h: + +/usr/include/c++/15/cmath: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol_roles.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/cxxabi_tweaks.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-printers.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/math-vector.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/resolver_query_base.hpp: + +/usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/x86_64-linux-gnu/bits/select-decl.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigevent-consts.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-arch.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-consts-arch.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-consts.h: + +/usr/include/x86_64-linux-gnu/bits/signal_ext.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/executor.hpp: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/strand.hpp: + +/usr/include/x86_64-linux-gnu/bits/signum-generic.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/sys/eventfd.h: + +/usr/include/x86_64-linux-gnu/bits/syscall.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vldqintrin.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-decl.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/service_registry.hpp: + +/usr/include/x86_64-linux-gnu/bits/termios-baud.h: + +/usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/termios-c_cflag.h: + +/usr/include/x86_64-linux-gnu/bits/termios-c_iflag.h: + +/usr/include/c++/15/tr1/poly_hermite.tcc: + +/usr/include/x86_64-linux-gnu/bits/termios-c_oflag.h: + +/usr/include/x86_64-linux-gnu/bits/termios-misc.h: + +/usr/include/x86_64-linux-gnu/bits/termios.h: + +/usr/include/c++/15/bits/atomic_lockfree_defines.h: + +/usr/include/x86_64-linux-gnu/bits/timerfd.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffer_sequence_adapter.hpp: + +/usr/include/c++/15/bits/refwrap.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/io_context.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver.hpp: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/c++/15/bit: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/adxintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bulk_execute.hpp: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_statx.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/packaged_task.hpp: + +/usr/include/x86_64-linux-gnu/bits/uio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/utsname.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/wchar2.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol_factory.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/atomic_word.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/submit.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/ctype_base.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/error_constants.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/gthr-default.h: + +/usr/include/c++/15/bits/stl_algobase.h: + +/usr/include/x86_64-linux-gnu/sys/un.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2satcvtintrin.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/gthr.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/messages_members.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/opt_random.h: + +/usr/include/c++/15/tuple: + +/usr/include/x86_64-linux-gnu/c++/15/bits/time_members.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6_range.hpp: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/c++/15/cxxabi.h: + +/usr/include/x86_64-linux-gnu/sys/syslog.h: + +/usr/include/x86_64-linux-gnu/sys/timerfd.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/utsname.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxavx512intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxbf16intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/deadline_timer.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxtf32intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_operation.hpp: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512bf16intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512mediaintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512minmaxintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/as_tuple.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512satcvtintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2convertintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_applicable_property.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2mediaintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_error_member.hpp: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx2intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bf16intrin.h: diff --git a/test/build-asan/CMakeFiles/net_control_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/net_control_test.dir/compiler_depend.ts new file mode 100644 index 0000000..4172d2a --- /dev/null +++ b/test/build-asan/CMakeFiles/net_control_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for net_control_test. diff --git a/test/build-asan/CMakeFiles/net_control_test.dir/depend.make b/test/build-asan/CMakeFiles/net_control_test.dir/depend.make new file mode 100644 index 0000000..8fb6abe --- /dev/null +++ b/test/build-asan/CMakeFiles/net_control_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for net_control_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/net_control_test.dir/flags.make b/test/build-asan/CMakeFiles/net_control_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/net_control_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/net_control_test.dir/link.txt b/test/build-asan/CMakeFiles/net_control_test.dir/link.txt new file mode 100644 index 0000000..d3b1227 --- /dev/null +++ b/test/build-asan/CMakeFiles/net_control_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/net_control_test.dir/link.d CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o -o bin/net_control_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/net_control_test.dir/progress.make b/test/build-asan/CMakeFiles/net_control_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/net_control_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/nmod_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/nmod_test.dir/DependInfo.cmake new file mode 100644 index 0000000..c22eae2 --- /dev/null +++ b/test/build-asan/CMakeFiles/nmod_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/nmod_test.cpp" "CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o" "gcc" "CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o.d" + "" "bin/nmod_test" "gcc" "CMakeFiles/nmod_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/nmod_test.dir/build.make b/test/build-asan/CMakeFiles/nmod_test.dir/build.make new file mode 100644 index 0000000..abf20b8 --- /dev/null +++ b/test/build-asan/CMakeFiles/nmod_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/nmod_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/nmod_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/nmod_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/nmod_test.dir/flags.make + +CMakeFiles/nmod_test.dir/codegen: +.PHONY : CMakeFiles/nmod_test.dir/codegen + +CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o: CMakeFiles/nmod_test.dir/flags.make +CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/nmod_test.cpp +CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o: CMakeFiles/nmod_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o -MF CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o.d -o CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/nmod_test.cpp + +CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/nmod_test.cpp > CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.i + +CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/nmod_test.cpp -o CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.s + +# Object files for target nmod_test +nmod_test_OBJECTS = \ +"CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o" + +# External object files for target nmod_test +nmod_test_EXTERNAL_OBJECTS = + +bin/nmod_test: CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o +bin/nmod_test: CMakeFiles/nmod_test.dir/build.make +bin/nmod_test: CMakeFiles/nmod_test.dir/compiler_depend.ts +bin/nmod_test: lib/libgtest_main.a +bin/nmod_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/nmod_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/nmod_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/nmod_test: lib/libgtest.a +bin/nmod_test: CMakeFiles/nmod_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/nmod_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/nmod_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=nmod_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/nmod_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=nmod_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/nmod_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/nmod_test.dir/build: bin/nmod_test +.PHONY : CMakeFiles/nmod_test.dir/build + +CMakeFiles/nmod_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/nmod_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/nmod_test.dir/clean + +CMakeFiles/nmod_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/nmod_test.dir/DependInfo.cmake "--color=$(COLOR)" nmod_test +.PHONY : CMakeFiles/nmod_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/nmod_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/nmod_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..8227876 --- /dev/null +++ b/test/build-asan/CMakeFiles/nmod_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/nmod_test.dir/link.d" + "CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o" + "CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o.d" + "bin/nmod_test" + "bin/nmod_test.pdb" + "nmod_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/nmod_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/nmod_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/nmod_test.dir/compiler_depend.make new file mode 100644 index 0000000..26380a1 --- /dev/null +++ b/test/build-asan/CMakeFiles/nmod_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for nmod_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/nmod_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/nmod_test.dir/compiler_depend.ts new file mode 100644 index 0000000..3a78998 --- /dev/null +++ b/test/build-asan/CMakeFiles/nmod_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for nmod_test. diff --git a/test/build-asan/CMakeFiles/nmod_test.dir/depend.make b/test/build-asan/CMakeFiles/nmod_test.dir/depend.make new file mode 100644 index 0000000..3915ae2 --- /dev/null +++ b/test/build-asan/CMakeFiles/nmod_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for nmod_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/nmod_test.dir/flags.make b/test/build-asan/CMakeFiles/nmod_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/nmod_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/nmod_test.dir/link.txt b/test/build-asan/CMakeFiles/nmod_test.dir/link.txt new file mode 100644 index 0000000..501da8b --- /dev/null +++ b/test/build-asan/CMakeFiles/nmod_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/nmod_test.dir/link.d CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o -o bin/nmod_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/nmod_test.dir/progress.make b/test/build-asan/CMakeFiles/nmod_test.dir/progress.make new file mode 100644 index 0000000..d999701 --- /dev/null +++ b/test/build-asan/CMakeFiles/nmod_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 56 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/offset_horner_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/offset_horner_test.dir/DependInfo.cmake new file mode 100644 index 0000000..6b26780 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_horner_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp" "CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o" "gcc" "CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o.d" + "" "bin/offset_horner_test" "gcc" "CMakeFiles/offset_horner_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/offset_horner_test.dir/build.make b/test/build-asan/CMakeFiles/offset_horner_test.dir/build.make new file mode 100644 index 0000000..65b8325 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_horner_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/offset_horner_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/offset_horner_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/offset_horner_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/offset_horner_test.dir/flags.make + +CMakeFiles/offset_horner_test.dir/codegen: +.PHONY : CMakeFiles/offset_horner_test.dir/codegen + +CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o: CMakeFiles/offset_horner_test.dir/flags.make +CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp +CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o: CMakeFiles/offset_horner_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o -MF CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o.d -o CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp + +CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp > CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.i + +CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp -o CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.s + +# Object files for target offset_horner_test +offset_horner_test_OBJECTS = \ +"CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o" + +# External object files for target offset_horner_test +offset_horner_test_EXTERNAL_OBJECTS = + +bin/offset_horner_test: CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o +bin/offset_horner_test: CMakeFiles/offset_horner_test.dir/build.make +bin/offset_horner_test: CMakeFiles/offset_horner_test.dir/compiler_depend.ts +bin/offset_horner_test: lib/libgtest_main.a +bin/offset_horner_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/offset_horner_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/offset_horner_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/offset_horner_test: lib/libgtest.a +bin/offset_horner_test: CMakeFiles/offset_horner_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/offset_horner_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/offset_horner_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=offset_horner_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=offset_horner_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_horner_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/offset_horner_test.dir/build: bin/offset_horner_test +.PHONY : CMakeFiles/offset_horner_test.dir/build + +CMakeFiles/offset_horner_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/offset_horner_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/offset_horner_test.dir/clean + +CMakeFiles/offset_horner_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/offset_horner_test.dir/DependInfo.cmake "--color=$(COLOR)" offset_horner_test +.PHONY : CMakeFiles/offset_horner_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/offset_horner_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/offset_horner_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..025ef71 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_horner_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/offset_horner_test.dir/link.d" + "CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o" + "CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o.d" + "bin/offset_horner_test" + "bin/offset_horner_test.pdb" + "offset_horner_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/offset_horner_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/offset_horner_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/offset_horner_test.dir/compiler_depend.make new file mode 100644 index 0000000..54f70d1 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_horner_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for offset_horner_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/offset_horner_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/offset_horner_test.dir/compiler_depend.ts new file mode 100644 index 0000000..6ad8cdd --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_horner_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for offset_horner_test. diff --git a/test/build-asan/CMakeFiles/offset_horner_test.dir/depend.make b/test/build-asan/CMakeFiles/offset_horner_test.dir/depend.make new file mode 100644 index 0000000..9925767 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_horner_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for offset_horner_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/offset_horner_test.dir/flags.make b/test/build-asan/CMakeFiles/offset_horner_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_horner_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/offset_horner_test.dir/link.txt b/test/build-asan/CMakeFiles/offset_horner_test.dir/link.txt new file mode 100644 index 0000000..66ac759 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_horner_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/offset_horner_test.dir/link.d CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o -o bin/offset_horner_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/offset_horner_test.dir/progress.make b/test/build-asan/CMakeFiles/offset_horner_test.dir/progress.make new file mode 100644 index 0000000..d2a6ead --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_horner_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 57 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/offset_jet_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/offset_jet_test.dir/DependInfo.cmake new file mode 100644 index 0000000..311965c --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_jet_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_jet_test.cpp" "CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o" "gcc" "CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o.d" + "" "bin/offset_jet_test" "gcc" "CMakeFiles/offset_jet_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/offset_jet_test.dir/build.make b/test/build-asan/CMakeFiles/offset_jet_test.dir/build.make new file mode 100644 index 0000000..6f2548d --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_jet_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/offset_jet_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/offset_jet_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/offset_jet_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/offset_jet_test.dir/flags.make + +CMakeFiles/offset_jet_test.dir/codegen: +.PHONY : CMakeFiles/offset_jet_test.dir/codegen + +CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o: CMakeFiles/offset_jet_test.dir/flags.make +CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_jet_test.cpp +CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o: CMakeFiles/offset_jet_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o -MF CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o.d -o CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_jet_test.cpp + +CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_jet_test.cpp > CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.i + +CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_jet_test.cpp -o CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.s + +# Object files for target offset_jet_test +offset_jet_test_OBJECTS = \ +"CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o" + +# External object files for target offset_jet_test +offset_jet_test_EXTERNAL_OBJECTS = + +bin/offset_jet_test: CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o +bin/offset_jet_test: CMakeFiles/offset_jet_test.dir/build.make +bin/offset_jet_test: CMakeFiles/offset_jet_test.dir/compiler_depend.ts +bin/offset_jet_test: lib/libgtest_main.a +bin/offset_jet_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/offset_jet_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/offset_jet_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/offset_jet_test: lib/libgtest.a +bin/offset_jet_test: CMakeFiles/offset_jet_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/offset_jet_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/offset_jet_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=offset_jet_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_jet_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=offset_jet_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_jet_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/offset_jet_test.dir/build: bin/offset_jet_test +.PHONY : CMakeFiles/offset_jet_test.dir/build + +CMakeFiles/offset_jet_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/offset_jet_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/offset_jet_test.dir/clean + +CMakeFiles/offset_jet_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/offset_jet_test.dir/DependInfo.cmake "--color=$(COLOR)" offset_jet_test +.PHONY : CMakeFiles/offset_jet_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/offset_jet_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/offset_jet_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..b709614 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_jet_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/offset_jet_test.dir/link.d" + "CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o" + "CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o.d" + "bin/offset_jet_test" + "bin/offset_jet_test.pdb" + "offset_jet_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/offset_jet_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/offset_jet_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/offset_jet_test.dir/compiler_depend.make new file mode 100644 index 0000000..8fbc8a2 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_jet_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for offset_jet_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/offset_jet_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/offset_jet_test.dir/compiler_depend.ts new file mode 100644 index 0000000..564814f --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_jet_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for offset_jet_test. diff --git a/test/build-asan/CMakeFiles/offset_jet_test.dir/depend.make b/test/build-asan/CMakeFiles/offset_jet_test.dir/depend.make new file mode 100644 index 0000000..09dcea6 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_jet_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for offset_jet_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/offset_jet_test.dir/flags.make b/test/build-asan/CMakeFiles/offset_jet_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_jet_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/offset_jet_test.dir/link.txt b/test/build-asan/CMakeFiles/offset_jet_test.dir/link.txt new file mode 100644 index 0000000..049af6d --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_jet_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/offset_jet_test.dir/link.d CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o -o bin/offset_jet_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/offset_jet_test.dir/progress.make b/test/build-asan/CMakeFiles/offset_jet_test.dir/progress.make new file mode 100644 index 0000000..b46bf58 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_jet_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 58 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/offset_poly_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/offset_poly_test.dir/DependInfo.cmake new file mode 100644 index 0000000..c324e05 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_poly_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_poly_test.cpp" "CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o" "gcc" "CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o.d" + "" "bin/offset_poly_test" "gcc" "CMakeFiles/offset_poly_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/offset_poly_test.dir/build.make b/test/build-asan/CMakeFiles/offset_poly_test.dir/build.make new file mode 100644 index 0000000..0c6581f --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_poly_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/offset_poly_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/offset_poly_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/offset_poly_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/offset_poly_test.dir/flags.make + +CMakeFiles/offset_poly_test.dir/codegen: +.PHONY : CMakeFiles/offset_poly_test.dir/codegen + +CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o: CMakeFiles/offset_poly_test.dir/flags.make +CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_poly_test.cpp +CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o: CMakeFiles/offset_poly_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o -MF CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o.d -o CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_poly_test.cpp + +CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_poly_test.cpp > CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.i + +CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_poly_test.cpp -o CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.s + +# Object files for target offset_poly_test +offset_poly_test_OBJECTS = \ +"CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o" + +# External object files for target offset_poly_test +offset_poly_test_EXTERNAL_OBJECTS = + +bin/offset_poly_test: CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o +bin/offset_poly_test: CMakeFiles/offset_poly_test.dir/build.make +bin/offset_poly_test: CMakeFiles/offset_poly_test.dir/compiler_depend.ts +bin/offset_poly_test: lib/libgtest_main.a +bin/offset_poly_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/offset_poly_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/offset_poly_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/offset_poly_test: lib/libgtest.a +bin/offset_poly_test: CMakeFiles/offset_poly_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/offset_poly_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/offset_poly_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=offset_poly_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_poly_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=offset_poly_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_poly_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/offset_poly_test.dir/build: bin/offset_poly_test +.PHONY : CMakeFiles/offset_poly_test.dir/build + +CMakeFiles/offset_poly_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/offset_poly_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/offset_poly_test.dir/clean + +CMakeFiles/offset_poly_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/offset_poly_test.dir/DependInfo.cmake "--color=$(COLOR)" offset_poly_test +.PHONY : CMakeFiles/offset_poly_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/offset_poly_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/offset_poly_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..0cdccf4 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_poly_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/offset_poly_test.dir/link.d" + "CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o" + "CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o.d" + "bin/offset_poly_test" + "bin/offset_poly_test.pdb" + "offset_poly_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/offset_poly_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/offset_poly_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/offset_poly_test.dir/compiler_depend.make new file mode 100644 index 0000000..d625b9c --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_poly_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for offset_poly_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/offset_poly_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/offset_poly_test.dir/compiler_depend.ts new file mode 100644 index 0000000..5395e1d --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_poly_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for offset_poly_test. diff --git a/test/build-asan/CMakeFiles/offset_poly_test.dir/depend.make b/test/build-asan/CMakeFiles/offset_poly_test.dir/depend.make new file mode 100644 index 0000000..d884cc1 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_poly_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for offset_poly_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/offset_poly_test.dir/flags.make b/test/build-asan/CMakeFiles/offset_poly_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_poly_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/offset_poly_test.dir/link.txt b/test/build-asan/CMakeFiles/offset_poly_test.dir/link.txt new file mode 100644 index 0000000..80d168c --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_poly_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/offset_poly_test.dir/link.d CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o -o bin/offset_poly_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/offset_poly_test.dir/progress.make b/test/build-asan/CMakeFiles/offset_poly_test.dir/progress.make new file mode 100644 index 0000000..5b6b61f --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_poly_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 59 + diff --git a/test/build-asan/CMakeFiles/offset_repr_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/offset_repr_test.dir/DependInfo.cmake new file mode 100644 index 0000000..e59c880 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_repr_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_repr_test.cpp" "CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o" "gcc" "CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o.d" + "" "bin/offset_repr_test" "gcc" "CMakeFiles/offset_repr_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/offset_repr_test.dir/build.make b/test/build-asan/CMakeFiles/offset_repr_test.dir/build.make new file mode 100644 index 0000000..08cd1ef --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_repr_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/offset_repr_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/offset_repr_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/offset_repr_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/offset_repr_test.dir/flags.make + +CMakeFiles/offset_repr_test.dir/codegen: +.PHONY : CMakeFiles/offset_repr_test.dir/codegen + +CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o: CMakeFiles/offset_repr_test.dir/flags.make +CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_repr_test.cpp +CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o: CMakeFiles/offset_repr_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o -MF CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o.d -o CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_repr_test.cpp + +CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_repr_test.cpp > CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.i + +CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_repr_test.cpp -o CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.s + +# Object files for target offset_repr_test +offset_repr_test_OBJECTS = \ +"CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o" + +# External object files for target offset_repr_test +offset_repr_test_EXTERNAL_OBJECTS = + +bin/offset_repr_test: CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o +bin/offset_repr_test: CMakeFiles/offset_repr_test.dir/build.make +bin/offset_repr_test: CMakeFiles/offset_repr_test.dir/compiler_depend.ts +bin/offset_repr_test: lib/libgtest_main.a +bin/offset_repr_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/offset_repr_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/offset_repr_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/offset_repr_test: lib/libgtest.a +bin/offset_repr_test: CMakeFiles/offset_repr_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/offset_repr_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/offset_repr_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=offset_repr_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_repr_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=offset_repr_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_repr_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/offset_repr_test.dir/build: bin/offset_repr_test +.PHONY : CMakeFiles/offset_repr_test.dir/build + +CMakeFiles/offset_repr_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/offset_repr_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/offset_repr_test.dir/clean + +CMakeFiles/offset_repr_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/offset_repr_test.dir/DependInfo.cmake "--color=$(COLOR)" offset_repr_test +.PHONY : CMakeFiles/offset_repr_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/offset_repr_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/offset_repr_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..319e8ca --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_repr_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/offset_repr_test.dir/link.d" + "CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o" + "CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o.d" + "bin/offset_repr_test" + "bin/offset_repr_test.pdb" + "offset_repr_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/offset_repr_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/offset_repr_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/offset_repr_test.dir/compiler_depend.make new file mode 100644 index 0000000..10bd507 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_repr_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for offset_repr_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/offset_repr_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/offset_repr_test.dir/compiler_depend.ts new file mode 100644 index 0000000..0b902bc --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_repr_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for offset_repr_test. diff --git a/test/build-asan/CMakeFiles/offset_repr_test.dir/depend.make b/test/build-asan/CMakeFiles/offset_repr_test.dir/depend.make new file mode 100644 index 0000000..9caf798 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_repr_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for offset_repr_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/offset_repr_test.dir/flags.make b/test/build-asan/CMakeFiles/offset_repr_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_repr_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/offset_repr_test.dir/link.txt b/test/build-asan/CMakeFiles/offset_repr_test.dir/link.txt new file mode 100644 index 0000000..9a0378c --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_repr_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/offset_repr_test.dir/link.d CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o -o bin/offset_repr_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/offset_repr_test.dir/progress.make b/test/build-asan/CMakeFiles/offset_repr_test.dir/progress.make new file mode 100644 index 0000000..fc0867f --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_repr_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 60 + diff --git a/test/build-asan/CMakeFiles/offset_twist_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/offset_twist_test.dir/DependInfo.cmake new file mode 100644 index 0000000..28436fb --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_twist_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_twist_test.cpp" "CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o" "gcc" "CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o.d" + "" "bin/offset_twist_test" "gcc" "CMakeFiles/offset_twist_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/offset_twist_test.dir/build.make b/test/build-asan/CMakeFiles/offset_twist_test.dir/build.make new file mode 100644 index 0000000..baaa32a --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_twist_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/offset_twist_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/offset_twist_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/offset_twist_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/offset_twist_test.dir/flags.make + +CMakeFiles/offset_twist_test.dir/codegen: +.PHONY : CMakeFiles/offset_twist_test.dir/codegen + +CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o: CMakeFiles/offset_twist_test.dir/flags.make +CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_twist_test.cpp +CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o: CMakeFiles/offset_twist_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o -MF CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o.d -o CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_twist_test.cpp + +CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_twist_test.cpp > CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.i + +CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_twist_test.cpp -o CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.s + +# Object files for target offset_twist_test +offset_twist_test_OBJECTS = \ +"CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o" + +# External object files for target offset_twist_test +offset_twist_test_EXTERNAL_OBJECTS = + +bin/offset_twist_test: CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o +bin/offset_twist_test: CMakeFiles/offset_twist_test.dir/build.make +bin/offset_twist_test: CMakeFiles/offset_twist_test.dir/compiler_depend.ts +bin/offset_twist_test: lib/libgtest_main.a +bin/offset_twist_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/offset_twist_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/offset_twist_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/offset_twist_test: lib/libgtest.a +bin/offset_twist_test: CMakeFiles/offset_twist_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/offset_twist_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/offset_twist_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=offset_twist_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_twist_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=offset_twist_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_twist_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/offset_twist_test.dir/build: bin/offset_twist_test +.PHONY : CMakeFiles/offset_twist_test.dir/build + +CMakeFiles/offset_twist_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/offset_twist_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/offset_twist_test.dir/clean + +CMakeFiles/offset_twist_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/offset_twist_test.dir/DependInfo.cmake "--color=$(COLOR)" offset_twist_test +.PHONY : CMakeFiles/offset_twist_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/offset_twist_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/offset_twist_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..e3e5b68 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_twist_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/offset_twist_test.dir/link.d" + "CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o" + "CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o.d" + "bin/offset_twist_test" + "bin/offset_twist_test.pdb" + "offset_twist_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/offset_twist_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/offset_twist_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/offset_twist_test.dir/compiler_depend.make new file mode 100644 index 0000000..381a9c7 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_twist_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for offset_twist_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/offset_twist_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/offset_twist_test.dir/compiler_depend.ts new file mode 100644 index 0000000..143f4ec --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_twist_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for offset_twist_test. diff --git a/test/build-asan/CMakeFiles/offset_twist_test.dir/depend.make b/test/build-asan/CMakeFiles/offset_twist_test.dir/depend.make new file mode 100644 index 0000000..f951868 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_twist_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for offset_twist_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/offset_twist_test.dir/flags.make b/test/build-asan/CMakeFiles/offset_twist_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_twist_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/offset_twist_test.dir/link.txt b/test/build-asan/CMakeFiles/offset_twist_test.dir/link.txt new file mode 100644 index 0000000..10378b5 --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_twist_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/offset_twist_test.dir/link.d CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o -o bin/offset_twist_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/offset_twist_test.dir/progress.make b/test/build-asan/CMakeFiles/offset_twist_test.dir/progress.make new file mode 100644 index 0000000..deeeb9c --- /dev/null +++ b/test/build-asan/CMakeFiles/offset_twist_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 61 + diff --git a/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/DependInfo.cmake new file mode 100644 index 0000000..804f261 --- /dev/null +++ b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/opt_in_malicious_test.cpp" "CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o" "gcc" "CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o.d" + "" "bin/opt_in_malicious_test" "gcc" "CMakeFiles/opt_in_malicious_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/build.make b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/build.make new file mode 100644 index 0000000..2a415a4 --- /dev/null +++ b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/opt_in_malicious_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/opt_in_malicious_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/opt_in_malicious_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/opt_in_malicious_test.dir/flags.make + +CMakeFiles/opt_in_malicious_test.dir/codegen: +.PHONY : CMakeFiles/opt_in_malicious_test.dir/codegen + +CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o: CMakeFiles/opt_in_malicious_test.dir/flags.make +CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/opt_in_malicious_test.cpp +CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o: CMakeFiles/opt_in_malicious_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o -MF CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o.d -o CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/opt_in_malicious_test.cpp + +CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/opt_in_malicious_test.cpp > CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.i + +CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/opt_in_malicious_test.cpp -o CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.s + +# Object files for target opt_in_malicious_test +opt_in_malicious_test_OBJECTS = \ +"CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o" + +# External object files for target opt_in_malicious_test +opt_in_malicious_test_EXTERNAL_OBJECTS = + +bin/opt_in_malicious_test: CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o +bin/opt_in_malicious_test: CMakeFiles/opt_in_malicious_test.dir/build.make +bin/opt_in_malicious_test: CMakeFiles/opt_in_malicious_test.dir/compiler_depend.ts +bin/opt_in_malicious_test: lib/libgtest_main.a +bin/opt_in_malicious_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/opt_in_malicious_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/opt_in_malicious_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/opt_in_malicious_test: lib/libgtest.a +bin/opt_in_malicious_test: CMakeFiles/opt_in_malicious_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/opt_in_malicious_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/opt_in_malicious_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=opt_in_malicious_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/opt_in_malicious_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=opt_in_malicious_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/opt_in_malicious_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/opt_in_malicious_test.dir/build: bin/opt_in_malicious_test +.PHONY : CMakeFiles/opt_in_malicious_test.dir/build + +CMakeFiles/opt_in_malicious_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/opt_in_malicious_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/opt_in_malicious_test.dir/clean + +CMakeFiles/opt_in_malicious_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/DependInfo.cmake "--color=$(COLOR)" opt_in_malicious_test +.PHONY : CMakeFiles/opt_in_malicious_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..78c376f --- /dev/null +++ b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/opt_in_malicious_test.dir/link.d" + "CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o" + "CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o.d" + "bin/opt_in_malicious_test" + "bin/opt_in_malicious_test.pdb" + "opt_in_malicious_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/opt_in_malicious_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/compiler_depend.make new file mode 100644 index 0000000..906b44f --- /dev/null +++ b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for opt_in_malicious_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/compiler_depend.ts new file mode 100644 index 0000000..3283a1c --- /dev/null +++ b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for opt_in_malicious_test. diff --git a/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/depend.make b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/depend.make new file mode 100644 index 0000000..5d18f41 --- /dev/null +++ b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for opt_in_malicious_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/flags.make b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/link.txt b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/link.txt new file mode 100644 index 0000000..cb81da6 --- /dev/null +++ b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/opt_in_malicious_test.dir/link.d CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o -o bin/opt_in_malicious_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/progress.make b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/opt_in_malicious_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/p0.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/p0.dir/DependInfo.cmake new file mode 100644 index 0000000..b3d37a1 --- /dev/null +++ b/test/build-asan/CMakeFiles/p0.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp" "CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o" "gcc" "CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o.d" + "" "bin/p0" "gcc" "CMakeFiles/p0.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/p0.dir/build.make b/test/build-asan/CMakeFiles/p0.dir/build.make new file mode 100644 index 0000000..556bb95 --- /dev/null +++ b/test/build-asan/CMakeFiles/p0.dir/build.make @@ -0,0 +1,124 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/p0.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/p0.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/p0.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/p0.dir/flags.make + +CMakeFiles/p0.dir/codegen: +.PHONY : CMakeFiles/p0.dir/codegen + +CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o: CMakeFiles/p0.dir/flags.make +CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp +CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o: CMakeFiles/p0.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o -MF CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o.d -o CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp + +CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp > CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.i + +CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp -o CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.s + +# Object files for target p0 +p0_OBJECTS = \ +"CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o" + +# External object files for target p0 +p0_EXTERNAL_OBJECTS = + +bin/p0: CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o +bin/p0: CMakeFiles/p0.dir/build.make +bin/p0: CMakeFiles/p0.dir/compiler_depend.ts +bin/p0: lib/libgtest_main.a +bin/p0: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/p0: /usr/lib/x86_64-linux-gnu/libssl.so +bin/p0: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/p0: libparty_flows.a +bin/p0: lib/libgtest_main.a +bin/p0: lib/libgtest.a +bin/p0: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/p0: /usr/lib/x86_64-linux-gnu/libssl.so +bin/p0: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/p0: CMakeFiles/p0.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/p0" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/p0.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +CMakeFiles/p0.dir/build: bin/p0 +.PHONY : CMakeFiles/p0.dir/build + +CMakeFiles/p0.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/p0.dir/cmake_clean.cmake +.PHONY : CMakeFiles/p0.dir/clean + +CMakeFiles/p0.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/p0.dir/DependInfo.cmake "--color=$(COLOR)" p0 +.PHONY : CMakeFiles/p0.dir/depend + diff --git a/test/build-asan/CMakeFiles/p0.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/p0.dir/cmake_clean.cmake new file mode 100644 index 0000000..19873fa --- /dev/null +++ b/test/build-asan/CMakeFiles/p0.dir/cmake_clean.cmake @@ -0,0 +1,12 @@ +file(REMOVE_RECURSE + "CMakeFiles/p0.dir/link.d" + "CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o" + "CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o.d" + "bin/p0" + "bin/p0.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/p0.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/p0.dir/compiler_depend.make b/test/build-asan/CMakeFiles/p0.dir/compiler_depend.make new file mode 100644 index 0000000..fdc3701 --- /dev/null +++ b/test/build-asan/CMakeFiles/p0.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for p0. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/p0.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/p0.dir/compiler_depend.ts new file mode 100644 index 0000000..ea75606 --- /dev/null +++ b/test/build-asan/CMakeFiles/p0.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for p0. diff --git a/test/build-asan/CMakeFiles/p0.dir/depend.make b/test/build-asan/CMakeFiles/p0.dir/depend.make new file mode 100644 index 0000000..20a8266 --- /dev/null +++ b/test/build-asan/CMakeFiles/p0.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for p0. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/p0.dir/flags.make b/test/build-asan/CMakeFiles/p0.dir/flags.make new file mode 100644 index 0000000..c9f269f --- /dev/null +++ b/test/build-asan/CMakeFiles/p0.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" -DLIBDPF_HAS_ASIO -DLIBDPF_HAS_NLOHMANN_JSON -DLIBDPF_PARTY_BIN_DIR=\"/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../party -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/json/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/p0.dir/link.txt b/test/build-asan/CMakeFiles/p0.dir/link.txt new file mode 100644 index 0000000..ff444d6 --- /dev/null +++ b/test/build-asan/CMakeFiles/p0.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/p0.dir/link.d "CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o" -o bin/p0 lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so libparty_flows.a lib/libgtest_main.a lib/libgtest.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so -lpthread diff --git a/test/build-asan/CMakeFiles/p0.dir/progress.make b/test/build-asan/CMakeFiles/p0.dir/progress.make new file mode 100644 index 0000000..5eeab3e --- /dev/null +++ b/test/build-asan/CMakeFiles/p0.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 62 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/p1.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/p1.dir/DependInfo.cmake new file mode 100644 index 0000000..1bfe7fd --- /dev/null +++ b/test/build-asan/CMakeFiles/p1.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp" "CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o" "gcc" "CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o.d" + "" "bin/p1" "gcc" "CMakeFiles/p1.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/p1.dir/build.make b/test/build-asan/CMakeFiles/p1.dir/build.make new file mode 100644 index 0000000..f534f37 --- /dev/null +++ b/test/build-asan/CMakeFiles/p1.dir/build.make @@ -0,0 +1,124 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/p1.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/p1.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/p1.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/p1.dir/flags.make + +CMakeFiles/p1.dir/codegen: +.PHONY : CMakeFiles/p1.dir/codegen + +CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o: CMakeFiles/p1.dir/flags.make +CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp +CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o: CMakeFiles/p1.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o -MF CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o.d -o CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp + +CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp > CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.i + +CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp -o CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.s + +# Object files for target p1 +p1_OBJECTS = \ +"CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o" + +# External object files for target p1 +p1_EXTERNAL_OBJECTS = + +bin/p1: CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o +bin/p1: CMakeFiles/p1.dir/build.make +bin/p1: CMakeFiles/p1.dir/compiler_depend.ts +bin/p1: lib/libgtest_main.a +bin/p1: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/p1: /usr/lib/x86_64-linux-gnu/libssl.so +bin/p1: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/p1: libparty_flows.a +bin/p1: lib/libgtest_main.a +bin/p1: lib/libgtest.a +bin/p1: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/p1: /usr/lib/x86_64-linux-gnu/libssl.so +bin/p1: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/p1: CMakeFiles/p1.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/p1" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/p1.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +CMakeFiles/p1.dir/build: bin/p1 +.PHONY : CMakeFiles/p1.dir/build + +CMakeFiles/p1.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/p1.dir/cmake_clean.cmake +.PHONY : CMakeFiles/p1.dir/clean + +CMakeFiles/p1.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/p1.dir/DependInfo.cmake "--color=$(COLOR)" p1 +.PHONY : CMakeFiles/p1.dir/depend + diff --git a/test/build-asan/CMakeFiles/p1.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/p1.dir/cmake_clean.cmake new file mode 100644 index 0000000..864abb6 --- /dev/null +++ b/test/build-asan/CMakeFiles/p1.dir/cmake_clean.cmake @@ -0,0 +1,12 @@ +file(REMOVE_RECURSE + "CMakeFiles/p1.dir/link.d" + "CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o" + "CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o.d" + "bin/p1" + "bin/p1.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/p1.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/p1.dir/compiler_depend.make b/test/build-asan/CMakeFiles/p1.dir/compiler_depend.make new file mode 100644 index 0000000..4613513 --- /dev/null +++ b/test/build-asan/CMakeFiles/p1.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for p1. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/p1.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/p1.dir/compiler_depend.ts new file mode 100644 index 0000000..c7fcc86 --- /dev/null +++ b/test/build-asan/CMakeFiles/p1.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for p1. diff --git a/test/build-asan/CMakeFiles/p1.dir/depend.make b/test/build-asan/CMakeFiles/p1.dir/depend.make new file mode 100644 index 0000000..8b9082a --- /dev/null +++ b/test/build-asan/CMakeFiles/p1.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for p1. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/p1.dir/flags.make b/test/build-asan/CMakeFiles/p1.dir/flags.make new file mode 100644 index 0000000..c9f269f --- /dev/null +++ b/test/build-asan/CMakeFiles/p1.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" -DLIBDPF_HAS_ASIO -DLIBDPF_HAS_NLOHMANN_JSON -DLIBDPF_PARTY_BIN_DIR=\"/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../party -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/json/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/p1.dir/link.txt b/test/build-asan/CMakeFiles/p1.dir/link.txt new file mode 100644 index 0000000..83a5b05 --- /dev/null +++ b/test/build-asan/CMakeFiles/p1.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/p1.dir/link.d "CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o" -o bin/p1 lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so libparty_flows.a lib/libgtest_main.a lib/libgtest.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so -lpthread diff --git a/test/build-asan/CMakeFiles/p1.dir/progress.make b/test/build-asan/CMakeFiles/p1.dir/progress.make new file mode 100644 index 0000000..22956c6 --- /dev/null +++ b/test/build-asan/CMakeFiles/p1.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 63 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/p2.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/p2.dir/DependInfo.cmake new file mode 100644 index 0000000..d7da665 --- /dev/null +++ b/test/build-asan/CMakeFiles/p2.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp" "CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o" "gcc" "CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o.d" + "" "bin/p2" "gcc" "CMakeFiles/p2.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/p2.dir/build.make b/test/build-asan/CMakeFiles/p2.dir/build.make new file mode 100644 index 0000000..6579cf7 --- /dev/null +++ b/test/build-asan/CMakeFiles/p2.dir/build.make @@ -0,0 +1,124 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/p2.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/p2.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/p2.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/p2.dir/flags.make + +CMakeFiles/p2.dir/codegen: +.PHONY : CMakeFiles/p2.dir/codegen + +CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o: CMakeFiles/p2.dir/flags.make +CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp +CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o: CMakeFiles/p2.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o -MF CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o.d -o CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp + +CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp > CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.i + +CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp -o CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.s + +# Object files for target p2 +p2_OBJECTS = \ +"CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o" + +# External object files for target p2 +p2_EXTERNAL_OBJECTS = + +bin/p2: CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o +bin/p2: CMakeFiles/p2.dir/build.make +bin/p2: CMakeFiles/p2.dir/compiler_depend.ts +bin/p2: lib/libgtest_main.a +bin/p2: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/p2: /usr/lib/x86_64-linux-gnu/libssl.so +bin/p2: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/p2: libparty_flows.a +bin/p2: lib/libgtest_main.a +bin/p2: lib/libgtest.a +bin/p2: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/p2: /usr/lib/x86_64-linux-gnu/libssl.so +bin/p2: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/p2: CMakeFiles/p2.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/p2" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/p2.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +CMakeFiles/p2.dir/build: bin/p2 +.PHONY : CMakeFiles/p2.dir/build + +CMakeFiles/p2.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/p2.dir/cmake_clean.cmake +.PHONY : CMakeFiles/p2.dir/clean + +CMakeFiles/p2.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/p2.dir/DependInfo.cmake "--color=$(COLOR)" p2 +.PHONY : CMakeFiles/p2.dir/depend + diff --git a/test/build-asan/CMakeFiles/p2.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/p2.dir/cmake_clean.cmake new file mode 100644 index 0000000..ef0647b --- /dev/null +++ b/test/build-asan/CMakeFiles/p2.dir/cmake_clean.cmake @@ -0,0 +1,12 @@ +file(REMOVE_RECURSE + "CMakeFiles/p2.dir/link.d" + "CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o" + "CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o.d" + "bin/p2" + "bin/p2.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/p2.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/p2.dir/compiler_depend.make b/test/build-asan/CMakeFiles/p2.dir/compiler_depend.make new file mode 100644 index 0000000..539ac43 --- /dev/null +++ b/test/build-asan/CMakeFiles/p2.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for p2. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/p2.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/p2.dir/compiler_depend.ts new file mode 100644 index 0000000..b25916c --- /dev/null +++ b/test/build-asan/CMakeFiles/p2.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for p2. diff --git a/test/build-asan/CMakeFiles/p2.dir/depend.make b/test/build-asan/CMakeFiles/p2.dir/depend.make new file mode 100644 index 0000000..6a4af24 --- /dev/null +++ b/test/build-asan/CMakeFiles/p2.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for p2. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/p2.dir/flags.make b/test/build-asan/CMakeFiles/p2.dir/flags.make new file mode 100644 index 0000000..c9f269f --- /dev/null +++ b/test/build-asan/CMakeFiles/p2.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" -DLIBDPF_HAS_ASIO -DLIBDPF_HAS_NLOHMANN_JSON -DLIBDPF_PARTY_BIN_DIR=\"/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../party -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/json/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/p2.dir/link.txt b/test/build-asan/CMakeFiles/p2.dir/link.txt new file mode 100644 index 0000000..5107fad --- /dev/null +++ b/test/build-asan/CMakeFiles/p2.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/p2.dir/link.d "CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o" -o bin/p2 lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so libparty_flows.a lib/libgtest_main.a lib/libgtest.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so -lpthread diff --git a/test/build-asan/CMakeFiles/p2.dir/progress.make b/test/build-asan/CMakeFiles/p2.dir/progress.make new file mode 100644 index 0000000..842e7d8 --- /dev/null +++ b/test/build-asan/CMakeFiles/p2.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 64 + diff --git a/test/build-asan/CMakeFiles/packed_lane_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/packed_lane_test.dir/DependInfo.cmake new file mode 100644 index 0000000..ea9aab0 --- /dev/null +++ b/test/build-asan/CMakeFiles/packed_lane_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/packed_lane_test.cpp" "CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o" "gcc" "CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o.d" + "" "bin/packed_lane_test" "gcc" "CMakeFiles/packed_lane_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/packed_lane_test.dir/build.make b/test/build-asan/CMakeFiles/packed_lane_test.dir/build.make new file mode 100644 index 0000000..fba47e5 --- /dev/null +++ b/test/build-asan/CMakeFiles/packed_lane_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/packed_lane_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/packed_lane_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/packed_lane_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/packed_lane_test.dir/flags.make + +CMakeFiles/packed_lane_test.dir/codegen: +.PHONY : CMakeFiles/packed_lane_test.dir/codegen + +CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o: CMakeFiles/packed_lane_test.dir/flags.make +CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/packed_lane_test.cpp +CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o: CMakeFiles/packed_lane_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o -MF CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o.d -o CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/packed_lane_test.cpp + +CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/packed_lane_test.cpp > CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.i + +CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/packed_lane_test.cpp -o CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.s + +# Object files for target packed_lane_test +packed_lane_test_OBJECTS = \ +"CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o" + +# External object files for target packed_lane_test +packed_lane_test_EXTERNAL_OBJECTS = + +bin/packed_lane_test: CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o +bin/packed_lane_test: CMakeFiles/packed_lane_test.dir/build.make +bin/packed_lane_test: CMakeFiles/packed_lane_test.dir/compiler_depend.ts +bin/packed_lane_test: lib/libgtest_main.a +bin/packed_lane_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/packed_lane_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/packed_lane_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/packed_lane_test: lib/libgtest.a +bin/packed_lane_test: CMakeFiles/packed_lane_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/packed_lane_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/packed_lane_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=packed_lane_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/packed_lane_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=packed_lane_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/packed_lane_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/packed_lane_test.dir/build: bin/packed_lane_test +.PHONY : CMakeFiles/packed_lane_test.dir/build + +CMakeFiles/packed_lane_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/packed_lane_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/packed_lane_test.dir/clean + +CMakeFiles/packed_lane_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/packed_lane_test.dir/DependInfo.cmake "--color=$(COLOR)" packed_lane_test +.PHONY : CMakeFiles/packed_lane_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/packed_lane_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/packed_lane_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..9bb4025 --- /dev/null +++ b/test/build-asan/CMakeFiles/packed_lane_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/packed_lane_test.dir/link.d" + "CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o" + "CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o.d" + "bin/packed_lane_test" + "bin/packed_lane_test.pdb" + "packed_lane_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/packed_lane_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/packed_lane_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/packed_lane_test.dir/compiler_depend.make new file mode 100644 index 0000000..8156526 --- /dev/null +++ b/test/build-asan/CMakeFiles/packed_lane_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for packed_lane_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/packed_lane_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/packed_lane_test.dir/compiler_depend.ts new file mode 100644 index 0000000..ef434cd --- /dev/null +++ b/test/build-asan/CMakeFiles/packed_lane_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for packed_lane_test. diff --git a/test/build-asan/CMakeFiles/packed_lane_test.dir/depend.make b/test/build-asan/CMakeFiles/packed_lane_test.dir/depend.make new file mode 100644 index 0000000..8b794d8 --- /dev/null +++ b/test/build-asan/CMakeFiles/packed_lane_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for packed_lane_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/packed_lane_test.dir/flags.make b/test/build-asan/CMakeFiles/packed_lane_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/packed_lane_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/packed_lane_test.dir/link.txt b/test/build-asan/CMakeFiles/packed_lane_test.dir/link.txt new file mode 100644 index 0000000..e37439d --- /dev/null +++ b/test/build-asan/CMakeFiles/packed_lane_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/packed_lane_test.dir/link.d CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o -o bin/packed_lane_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/packed_lane_test.dir/progress.make b/test/build-asan/CMakeFiles/packed_lane_test.dir/progress.make new file mode 100644 index 0000000..05e01bb --- /dev/null +++ b/test/build-asan/CMakeFiles/packed_lane_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 65 + diff --git a/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/DependInfo.cmake new file mode 100644 index 0000000..53d7a33 --- /dev/null +++ b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/parallel_bit_iterable_test.cpp" "CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o" "gcc" "CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o.d" + "" "bin/parallel_bit_iterable_test" "gcc" "CMakeFiles/parallel_bit_iterable_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/build.make b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/build.make new file mode 100644 index 0000000..2fc44f7 --- /dev/null +++ b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/parallel_bit_iterable_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/parallel_bit_iterable_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/parallel_bit_iterable_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/parallel_bit_iterable_test.dir/flags.make + +CMakeFiles/parallel_bit_iterable_test.dir/codegen: +.PHONY : CMakeFiles/parallel_bit_iterable_test.dir/codegen + +CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o: CMakeFiles/parallel_bit_iterable_test.dir/flags.make +CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/parallel_bit_iterable_test.cpp +CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o: CMakeFiles/parallel_bit_iterable_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o -MF CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o.d -o CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/parallel_bit_iterable_test.cpp + +CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/parallel_bit_iterable_test.cpp > CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.i + +CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/parallel_bit_iterable_test.cpp -o CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.s + +# Object files for target parallel_bit_iterable_test +parallel_bit_iterable_test_OBJECTS = \ +"CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o" + +# External object files for target parallel_bit_iterable_test +parallel_bit_iterable_test_EXTERNAL_OBJECTS = + +bin/parallel_bit_iterable_test: CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o +bin/parallel_bit_iterable_test: CMakeFiles/parallel_bit_iterable_test.dir/build.make +bin/parallel_bit_iterable_test: CMakeFiles/parallel_bit_iterable_test.dir/compiler_depend.ts +bin/parallel_bit_iterable_test: lib/libgtest_main.a +bin/parallel_bit_iterable_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/parallel_bit_iterable_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/parallel_bit_iterable_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/parallel_bit_iterable_test: lib/libgtest.a +bin/parallel_bit_iterable_test: CMakeFiles/parallel_bit_iterable_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/parallel_bit_iterable_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/parallel_bit_iterable_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=parallel_bit_iterable_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/parallel_bit_iterable_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=parallel_bit_iterable_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/parallel_bit_iterable_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/parallel_bit_iterable_test.dir/build: bin/parallel_bit_iterable_test +.PHONY : CMakeFiles/parallel_bit_iterable_test.dir/build + +CMakeFiles/parallel_bit_iterable_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/parallel_bit_iterable_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/parallel_bit_iterable_test.dir/clean + +CMakeFiles/parallel_bit_iterable_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/DependInfo.cmake "--color=$(COLOR)" parallel_bit_iterable_test +.PHONY : CMakeFiles/parallel_bit_iterable_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..1b6183e --- /dev/null +++ b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/parallel_bit_iterable_test.dir/link.d" + "CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o" + "CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o.d" + "bin/parallel_bit_iterable_test" + "bin/parallel_bit_iterable_test.pdb" + "parallel_bit_iterable_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/parallel_bit_iterable_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/compiler_depend.make new file mode 100644 index 0000000..d87ee66 --- /dev/null +++ b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for parallel_bit_iterable_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/compiler_depend.ts new file mode 100644 index 0000000..3e7f090 --- /dev/null +++ b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for parallel_bit_iterable_test. diff --git a/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/depend.make b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/depend.make new file mode 100644 index 0000000..0491754 --- /dev/null +++ b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for parallel_bit_iterable_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/flags.make b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/link.txt b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/link.txt new file mode 100644 index 0000000..dd4a4dc --- /dev/null +++ b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/parallel_bit_iterable_test.dir/link.d CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o -o bin/parallel_bit_iterable_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/progress.make b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/progress.make new file mode 100644 index 0000000..81b9ee5 --- /dev/null +++ b/test/build-asan/CMakeFiles/parallel_bit_iterable_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 66 + diff --git a/test/build-asan/CMakeFiles/party_bench.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/party_bench.dir/DependInfo.cmake new file mode 100644 index 0000000..8961aec --- /dev/null +++ b/test/build-asan/CMakeFiles/party_bench.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp" "CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o" "gcc" "CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o.d" + "" "bin/party_bench" "gcc" "CMakeFiles/party_bench.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/party_bench.dir/build.make b/test/build-asan/CMakeFiles/party_bench.dir/build.make new file mode 100644 index 0000000..ae21b3e --- /dev/null +++ b/test/build-asan/CMakeFiles/party_bench.dir/build.make @@ -0,0 +1,124 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/party_bench.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/party_bench.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/party_bench.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/party_bench.dir/flags.make + +CMakeFiles/party_bench.dir/codegen: +.PHONY : CMakeFiles/party_bench.dir/codegen + +CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o: CMakeFiles/party_bench.dir/flags.make +CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp +CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o: CMakeFiles/party_bench.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o -MF CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o.d -o CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp + +CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp > CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.i + +CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp -o CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.s + +# Object files for target party_bench +party_bench_OBJECTS = \ +"CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o" + +# External object files for target party_bench +party_bench_EXTERNAL_OBJECTS = + +bin/party_bench: CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o +bin/party_bench: CMakeFiles/party_bench.dir/build.make +bin/party_bench: CMakeFiles/party_bench.dir/compiler_depend.ts +bin/party_bench: lib/libgtest_main.a +bin/party_bench: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/party_bench: /usr/lib/x86_64-linux-gnu/libssl.so +bin/party_bench: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/party_bench: libparty_flows.a +bin/party_bench: lib/libgtest_main.a +bin/party_bench: lib/libgtest.a +bin/party_bench: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/party_bench: /usr/lib/x86_64-linux-gnu/libssl.so +bin/party_bench: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/party_bench: CMakeFiles/party_bench.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/party_bench" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/party_bench.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +CMakeFiles/party_bench.dir/build: bin/party_bench +.PHONY : CMakeFiles/party_bench.dir/build + +CMakeFiles/party_bench.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/party_bench.dir/cmake_clean.cmake +.PHONY : CMakeFiles/party_bench.dir/clean + +CMakeFiles/party_bench.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/party_bench.dir/DependInfo.cmake "--color=$(COLOR)" party_bench +.PHONY : CMakeFiles/party_bench.dir/depend + diff --git a/test/build-asan/CMakeFiles/party_bench.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/party_bench.dir/cmake_clean.cmake new file mode 100644 index 0000000..b4c369d --- /dev/null +++ b/test/build-asan/CMakeFiles/party_bench.dir/cmake_clean.cmake @@ -0,0 +1,12 @@ +file(REMOVE_RECURSE + "CMakeFiles/party_bench.dir/link.d" + "CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o" + "CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o.d" + "bin/party_bench" + "bin/party_bench.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/party_bench.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/party_bench.dir/compiler_depend.make b/test/build-asan/CMakeFiles/party_bench.dir/compiler_depend.make new file mode 100644 index 0000000..d6b1495 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_bench.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for party_bench. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/party_bench.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/party_bench.dir/compiler_depend.ts new file mode 100644 index 0000000..c580ed8 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_bench.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for party_bench. diff --git a/test/build-asan/CMakeFiles/party_bench.dir/depend.make b/test/build-asan/CMakeFiles/party_bench.dir/depend.make new file mode 100644 index 0000000..53e5799 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_bench.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for party_bench. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/party_bench.dir/flags.make b/test/build-asan/CMakeFiles/party_bench.dir/flags.make new file mode 100644 index 0000000..c9f269f --- /dev/null +++ b/test/build-asan/CMakeFiles/party_bench.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" -DLIBDPF_HAS_ASIO -DLIBDPF_HAS_NLOHMANN_JSON -DLIBDPF_PARTY_BIN_DIR=\"/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../party -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/json/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/party_bench.dir/link.txt b/test/build-asan/CMakeFiles/party_bench.dir/link.txt new file mode 100644 index 0000000..646c690 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_bench.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/party_bench.dir/link.d "CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o" -o bin/party_bench lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so libparty_flows.a lib/libgtest_main.a lib/libgtest.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so -lpthread diff --git a/test/build-asan/CMakeFiles/party_bench.dir/progress.make b/test/build-asan/CMakeFiles/party_bench.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_bench.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/party_flows.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/party_flows.dir/DependInfo.cmake new file mode 100644 index 0000000..f367493 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_flows.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp" "CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o" "gcc" "CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o.d" + "/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp" "CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o" "gcc" "CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/party_flows.dir/build.make b/test/build-asan/CMakeFiles/party_flows.dir/build.make new file mode 100644 index 0000000..1c4dee9 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_flows.dir/build.make @@ -0,0 +1,130 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/party_flows.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/party_flows.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/party_flows.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/party_flows.dir/flags.make + +CMakeFiles/party_flows.dir/codegen: +.PHONY : CMakeFiles/party_flows.dir/codegen + +CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o: CMakeFiles/party_flows.dir/flags.make +CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp +CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o: CMakeFiles/party_flows.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o -MF CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o.d -o CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp + +CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp > CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.i + +CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp -o CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.s + +CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o: CMakeFiles/party_flows.dir/flags.make +CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/party/run.cpp +CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o: CMakeFiles/party_flows.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Building CXX object CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o -MF CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o.d -o CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/party/run.cpp + +CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/party/run.cpp > CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.i + +CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/party/run.cpp -o CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.s + +# Object files for target party_flows +party_flows_OBJECTS = \ +"CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o" \ +"CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o" + +# External object files for target party_flows +party_flows_EXTERNAL_OBJECTS = + +libparty_flows.a: CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o +libparty_flows.a: CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o +libparty_flows.a: CMakeFiles/party_flows.dir/build.make +libparty_flows.a: CMakeFiles/party_flows.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Linking CXX static library libparty_flows.a" + $(CMAKE_COMMAND) -P CMakeFiles/party_flows.dir/cmake_clean_target.cmake + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/party_flows.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +CMakeFiles/party_flows.dir/build: libparty_flows.a +.PHONY : CMakeFiles/party_flows.dir/build + +CMakeFiles/party_flows.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/party_flows.dir/cmake_clean.cmake +.PHONY : CMakeFiles/party_flows.dir/clean + +CMakeFiles/party_flows.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/party_flows.dir/DependInfo.cmake "--color=$(COLOR)" party_flows +.PHONY : CMakeFiles/party_flows.dir/depend + diff --git a/test/build-asan/CMakeFiles/party_flows.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/party_flows.dir/cmake_clean.cmake new file mode 100644 index 0000000..cc92124 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_flows.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o" + "CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o.d" + "CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o" + "CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o.d" + "libparty_flows.a" + "libparty_flows.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/party_flows.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/party_flows.dir/cmake_clean_target.cmake b/test/build-asan/CMakeFiles/party_flows.dir/cmake_clean_target.cmake new file mode 100644 index 0000000..af76917 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_flows.dir/cmake_clean_target.cmake @@ -0,0 +1,3 @@ +file(REMOVE_RECURSE + "libparty_flows.a" +) diff --git a/test/build-asan/CMakeFiles/party_flows.dir/compiler_depend.make b/test/build-asan/CMakeFiles/party_flows.dir/compiler_depend.make new file mode 100644 index 0000000..02cc586 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_flows.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for party_flows. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/party_flows.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/party_flows.dir/compiler_depend.ts new file mode 100644 index 0000000..f7f4110 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_flows.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for party_flows. diff --git a/test/build-asan/CMakeFiles/party_flows.dir/depend.make b/test/build-asan/CMakeFiles/party_flows.dir/depend.make new file mode 100644 index 0000000..6a0ef18 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_flows.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for party_flows. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/party_flows.dir/flags.make b/test/build-asan/CMakeFiles/party_flows.dir/flags.make new file mode 100644 index 0000000..d800c00 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_flows.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" -DLIBDPF_HAS_ASIO -DLIBDPF_HAS_NLOHMANN_JSON + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../party -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/json/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/party_flows.dir/link.txt b/test/build-asan/CMakeFiles/party_flows.dir/link.txt new file mode 100644 index 0000000..fb8197f --- /dev/null +++ b/test/build-asan/CMakeFiles/party_flows.dir/link.txt @@ -0,0 +1,2 @@ +/usr/bin/ar qc libparty_flows.a "CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o" "CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o" +/usr/bin/ranlib libparty_flows.a diff --git a/test/build-asan/CMakeFiles/party_flows.dir/progress.make b/test/build-asan/CMakeFiles/party_flows.dir/progress.make new file mode 100644 index 0000000..52fa544 --- /dev/null +++ b/test/build-asan/CMakeFiles/party_flows.dir/progress.make @@ -0,0 +1,4 @@ +CMAKE_PROGRESS_1 = 67 +CMAKE_PROGRESS_2 = +CMAKE_PROGRESS_3 = 68 + diff --git a/test/build-asan/CMakeFiles/path_recipe_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/path_recipe_test.dir/DependInfo.cmake new file mode 100644 index 0000000..97f3ab4 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_recipe_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/path_recipe_test.cpp" "CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o" "gcc" "CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o.d" + "" "bin/path_recipe_test" "gcc" "CMakeFiles/path_recipe_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/path_recipe_test.dir/build.make b/test/build-asan/CMakeFiles/path_recipe_test.dir/build.make new file mode 100644 index 0000000..28384c4 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_recipe_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/path_recipe_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/path_recipe_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/path_recipe_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/path_recipe_test.dir/flags.make + +CMakeFiles/path_recipe_test.dir/codegen: +.PHONY : CMakeFiles/path_recipe_test.dir/codegen + +CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o: CMakeFiles/path_recipe_test.dir/flags.make +CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/path_recipe_test.cpp +CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o: CMakeFiles/path_recipe_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o -MF CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o.d -o CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/path_recipe_test.cpp + +CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/path_recipe_test.cpp > CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.i + +CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/path_recipe_test.cpp -o CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.s + +# Object files for target path_recipe_test +path_recipe_test_OBJECTS = \ +"CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o" + +# External object files for target path_recipe_test +path_recipe_test_EXTERNAL_OBJECTS = + +bin/path_recipe_test: CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o +bin/path_recipe_test: CMakeFiles/path_recipe_test.dir/build.make +bin/path_recipe_test: CMakeFiles/path_recipe_test.dir/compiler_depend.ts +bin/path_recipe_test: lib/libgtest_main.a +bin/path_recipe_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/path_recipe_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/path_recipe_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/path_recipe_test: lib/libgtest.a +bin/path_recipe_test: CMakeFiles/path_recipe_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/path_recipe_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/path_recipe_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=path_recipe_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/path_recipe_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=path_recipe_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/path_recipe_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/path_recipe_test.dir/build: bin/path_recipe_test +.PHONY : CMakeFiles/path_recipe_test.dir/build + +CMakeFiles/path_recipe_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/path_recipe_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/path_recipe_test.dir/clean + +CMakeFiles/path_recipe_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/path_recipe_test.dir/DependInfo.cmake "--color=$(COLOR)" path_recipe_test +.PHONY : CMakeFiles/path_recipe_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/path_recipe_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/path_recipe_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..672f99a --- /dev/null +++ b/test/build-asan/CMakeFiles/path_recipe_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/path_recipe_test.dir/link.d" + "CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o" + "CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o.d" + "bin/path_recipe_test" + "bin/path_recipe_test.pdb" + "path_recipe_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/path_recipe_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/path_recipe_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/path_recipe_test.dir/compiler_depend.make new file mode 100644 index 0000000..9a35092 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_recipe_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for path_recipe_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/path_recipe_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/path_recipe_test.dir/compiler_depend.ts new file mode 100644 index 0000000..c762566 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_recipe_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for path_recipe_test. diff --git a/test/build-asan/CMakeFiles/path_recipe_test.dir/depend.make b/test/build-asan/CMakeFiles/path_recipe_test.dir/depend.make new file mode 100644 index 0000000..2299ec0 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_recipe_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for path_recipe_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/path_recipe_test.dir/flags.make b/test/build-asan/CMakeFiles/path_recipe_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_recipe_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/path_recipe_test.dir/link.txt b/test/build-asan/CMakeFiles/path_recipe_test.dir/link.txt new file mode 100644 index 0000000..c8b0f11 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_recipe_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/path_recipe_test.dir/link.d CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o -o bin/path_recipe_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/path_recipe_test.dir/progress.make b/test/build-asan/CMakeFiles/path_recipe_test.dir/progress.make new file mode 100644 index 0000000..2e7701f --- /dev/null +++ b/test/build-asan/CMakeFiles/path_recipe_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 69 + diff --git a/test/build-asan/CMakeFiles/path_sketch_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/path_sketch_test.dir/DependInfo.cmake new file mode 100644 index 0000000..e142027 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_sketch_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/path_sketch_test.cpp" "CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o" "gcc" "CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o.d" + "" "bin/path_sketch_test" "gcc" "CMakeFiles/path_sketch_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/path_sketch_test.dir/build.make b/test/build-asan/CMakeFiles/path_sketch_test.dir/build.make new file mode 100644 index 0000000..c852c67 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_sketch_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/path_sketch_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/path_sketch_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/path_sketch_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/path_sketch_test.dir/flags.make + +CMakeFiles/path_sketch_test.dir/codegen: +.PHONY : CMakeFiles/path_sketch_test.dir/codegen + +CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o: CMakeFiles/path_sketch_test.dir/flags.make +CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/path_sketch_test.cpp +CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o: CMakeFiles/path_sketch_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o -MF CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o.d -o CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/path_sketch_test.cpp + +CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/path_sketch_test.cpp > CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.i + +CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/path_sketch_test.cpp -o CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.s + +# Object files for target path_sketch_test +path_sketch_test_OBJECTS = \ +"CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o" + +# External object files for target path_sketch_test +path_sketch_test_EXTERNAL_OBJECTS = + +bin/path_sketch_test: CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o +bin/path_sketch_test: CMakeFiles/path_sketch_test.dir/build.make +bin/path_sketch_test: CMakeFiles/path_sketch_test.dir/compiler_depend.ts +bin/path_sketch_test: lib/libgtest_main.a +bin/path_sketch_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/path_sketch_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/path_sketch_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/path_sketch_test: lib/libgtest.a +bin/path_sketch_test: CMakeFiles/path_sketch_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/path_sketch_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/path_sketch_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=path_sketch_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/path_sketch_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=path_sketch_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/path_sketch_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/path_sketch_test.dir/build: bin/path_sketch_test +.PHONY : CMakeFiles/path_sketch_test.dir/build + +CMakeFiles/path_sketch_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/path_sketch_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/path_sketch_test.dir/clean + +CMakeFiles/path_sketch_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/path_sketch_test.dir/DependInfo.cmake "--color=$(COLOR)" path_sketch_test +.PHONY : CMakeFiles/path_sketch_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/path_sketch_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/path_sketch_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..946f958 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_sketch_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/path_sketch_test.dir/link.d" + "CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o" + "CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o.d" + "bin/path_sketch_test" + "bin/path_sketch_test.pdb" + "path_sketch_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/path_sketch_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/path_sketch_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/path_sketch_test.dir/compiler_depend.make new file mode 100644 index 0000000..0de503d --- /dev/null +++ b/test/build-asan/CMakeFiles/path_sketch_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for path_sketch_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/path_sketch_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/path_sketch_test.dir/compiler_depend.ts new file mode 100644 index 0000000..d63898d --- /dev/null +++ b/test/build-asan/CMakeFiles/path_sketch_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for path_sketch_test. diff --git a/test/build-asan/CMakeFiles/path_sketch_test.dir/depend.make b/test/build-asan/CMakeFiles/path_sketch_test.dir/depend.make new file mode 100644 index 0000000..f9a9b16 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_sketch_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for path_sketch_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/path_sketch_test.dir/flags.make b/test/build-asan/CMakeFiles/path_sketch_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_sketch_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/path_sketch_test.dir/link.txt b/test/build-asan/CMakeFiles/path_sketch_test.dir/link.txt new file mode 100644 index 0000000..7365228 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_sketch_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/path_sketch_test.dir/link.d CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o -o bin/path_sketch_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/path_sketch_test.dir/progress.make b/test/build-asan/CMakeFiles/path_sketch_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/path_sketch_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/pprf_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/pprf_test.dir/DependInfo.cmake new file mode 100644 index 0000000..074a138 --- /dev/null +++ b/test/build-asan/CMakeFiles/pprf_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/pprf_test.cpp" "CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o" "gcc" "CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o.d" + "" "bin/pprf_test" "gcc" "CMakeFiles/pprf_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/pprf_test.dir/build.make b/test/build-asan/CMakeFiles/pprf_test.dir/build.make new file mode 100644 index 0000000..4c95163 --- /dev/null +++ b/test/build-asan/CMakeFiles/pprf_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/pprf_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/pprf_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/pprf_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/pprf_test.dir/flags.make + +CMakeFiles/pprf_test.dir/codegen: +.PHONY : CMakeFiles/pprf_test.dir/codegen + +CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o: CMakeFiles/pprf_test.dir/flags.make +CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/pprf_test.cpp +CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o: CMakeFiles/pprf_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o -MF CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o.d -o CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/pprf_test.cpp + +CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/pprf_test.cpp > CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.i + +CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/pprf_test.cpp -o CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.s + +# Object files for target pprf_test +pprf_test_OBJECTS = \ +"CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o" + +# External object files for target pprf_test +pprf_test_EXTERNAL_OBJECTS = + +bin/pprf_test: CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o +bin/pprf_test: CMakeFiles/pprf_test.dir/build.make +bin/pprf_test: CMakeFiles/pprf_test.dir/compiler_depend.ts +bin/pprf_test: lib/libgtest_main.a +bin/pprf_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/pprf_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/pprf_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/pprf_test: lib/libgtest.a +bin/pprf_test: CMakeFiles/pprf_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/pprf_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/pprf_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=pprf_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/pprf_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=pprf_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/pprf_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/pprf_test.dir/build: bin/pprf_test +.PHONY : CMakeFiles/pprf_test.dir/build + +CMakeFiles/pprf_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/pprf_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/pprf_test.dir/clean + +CMakeFiles/pprf_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/pprf_test.dir/DependInfo.cmake "--color=$(COLOR)" pprf_test +.PHONY : CMakeFiles/pprf_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/pprf_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/pprf_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..1706ffe --- /dev/null +++ b/test/build-asan/CMakeFiles/pprf_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/pprf_test.dir/link.d" + "CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o" + "CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o.d" + "bin/pprf_test" + "bin/pprf_test.pdb" + "pprf_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/pprf_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/pprf_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/pprf_test.dir/compiler_depend.make new file mode 100644 index 0000000..b326817 --- /dev/null +++ b/test/build-asan/CMakeFiles/pprf_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for pprf_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/pprf_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/pprf_test.dir/compiler_depend.ts new file mode 100644 index 0000000..3dd935a --- /dev/null +++ b/test/build-asan/CMakeFiles/pprf_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for pprf_test. diff --git a/test/build-asan/CMakeFiles/pprf_test.dir/depend.make b/test/build-asan/CMakeFiles/pprf_test.dir/depend.make new file mode 100644 index 0000000..0e4d7cc --- /dev/null +++ b/test/build-asan/CMakeFiles/pprf_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for pprf_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/pprf_test.dir/flags.make b/test/build-asan/CMakeFiles/pprf_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/pprf_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/pprf_test.dir/link.txt b/test/build-asan/CMakeFiles/pprf_test.dir/link.txt new file mode 100644 index 0000000..e1c04db --- /dev/null +++ b/test/build-asan/CMakeFiles/pprf_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/pprf_test.dir/link.d CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o -o bin/pprf_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/pprf_test.dir/progress.make b/test/build-asan/CMakeFiles/pprf_test.dir/progress.make new file mode 100644 index 0000000..fadf742 --- /dev/null +++ b/test/build-asan/CMakeFiles/pprf_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 70 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/ppvc_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/ppvc_test.dir/DependInfo.cmake new file mode 100644 index 0000000..4f376f0 --- /dev/null +++ b/test/build-asan/CMakeFiles/ppvc_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp" "CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o" "gcc" "CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o.d" + "" "bin/ppvc_test" "gcc" "CMakeFiles/ppvc_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/ppvc_test.dir/build.make b/test/build-asan/CMakeFiles/ppvc_test.dir/build.make new file mode 100644 index 0000000..2d26864 --- /dev/null +++ b/test/build-asan/CMakeFiles/ppvc_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/ppvc_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/ppvc_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/ppvc_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/ppvc_test.dir/flags.make + +CMakeFiles/ppvc_test.dir/codegen: +.PHONY : CMakeFiles/ppvc_test.dir/codegen + +CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o: CMakeFiles/ppvc_test.dir/flags.make +CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp +CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o: CMakeFiles/ppvc_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o -MF CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o.d -o CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp + +CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp > CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.i + +CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp -o CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.s + +# Object files for target ppvc_test +ppvc_test_OBJECTS = \ +"CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o" + +# External object files for target ppvc_test +ppvc_test_EXTERNAL_OBJECTS = + +bin/ppvc_test: CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o +bin/ppvc_test: CMakeFiles/ppvc_test.dir/build.make +bin/ppvc_test: CMakeFiles/ppvc_test.dir/compiler_depend.ts +bin/ppvc_test: lib/libgtest_main.a +bin/ppvc_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/ppvc_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/ppvc_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/ppvc_test: lib/libgtest.a +bin/ppvc_test: CMakeFiles/ppvc_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/ppvc_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/ppvc_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=ppvc_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=ppvc_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/ppvc_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/ppvc_test.dir/build: bin/ppvc_test +.PHONY : CMakeFiles/ppvc_test.dir/build + +CMakeFiles/ppvc_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/ppvc_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/ppvc_test.dir/clean + +CMakeFiles/ppvc_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/ppvc_test.dir/DependInfo.cmake "--color=$(COLOR)" ppvc_test +.PHONY : CMakeFiles/ppvc_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/ppvc_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/ppvc_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..2ac6e1b --- /dev/null +++ b/test/build-asan/CMakeFiles/ppvc_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/ppvc_test.dir/link.d" + "CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o" + "CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o.d" + "bin/ppvc_test" + "bin/ppvc_test.pdb" + "ppvc_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/ppvc_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/ppvc_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/ppvc_test.dir/compiler_depend.make new file mode 100644 index 0000000..13d7b9d --- /dev/null +++ b/test/build-asan/CMakeFiles/ppvc_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for ppvc_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/ppvc_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/ppvc_test.dir/compiler_depend.ts new file mode 100644 index 0000000..2c68de3 --- /dev/null +++ b/test/build-asan/CMakeFiles/ppvc_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for ppvc_test. diff --git a/test/build-asan/CMakeFiles/ppvc_test.dir/depend.make b/test/build-asan/CMakeFiles/ppvc_test.dir/depend.make new file mode 100644 index 0000000..d9eab2b --- /dev/null +++ b/test/build-asan/CMakeFiles/ppvc_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for ppvc_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/ppvc_test.dir/flags.make b/test/build-asan/CMakeFiles/ppvc_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/ppvc_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/ppvc_test.dir/link.txt b/test/build-asan/CMakeFiles/ppvc_test.dir/link.txt new file mode 100644 index 0000000..6d9b042 --- /dev/null +++ b/test/build-asan/CMakeFiles/ppvc_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/ppvc_test.dir/link.d CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o -o bin/ppvc_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/ppvc_test.dir/progress.make b/test/build-asan/CMakeFiles/ppvc_test.dir/progress.make new file mode 100644 index 0000000..eb08766 --- /dev/null +++ b/test/build-asan/CMakeFiles/ppvc_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 71 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/DependInfo.cmake new file mode 100644 index 0000000..e60c24c --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_aes_ccr_test.cpp" "CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o" "gcc" "CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o.d" + "" "bin/prg_aes_ccr_test" "gcc" "CMakeFiles/prg_aes_ccr_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/build.make b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/build.make new file mode 100644 index 0000000..6cc1e33 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/prg_aes_ccr_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/prg_aes_ccr_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/prg_aes_ccr_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/prg_aes_ccr_test.dir/flags.make + +CMakeFiles/prg_aes_ccr_test.dir/codegen: +.PHONY : CMakeFiles/prg_aes_ccr_test.dir/codegen + +CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o: CMakeFiles/prg_aes_ccr_test.dir/flags.make +CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_aes_ccr_test.cpp +CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o: CMakeFiles/prg_aes_ccr_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o -MF CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o.d -o CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_aes_ccr_test.cpp + +CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_aes_ccr_test.cpp > CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.i + +CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_aes_ccr_test.cpp -o CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.s + +# Object files for target prg_aes_ccr_test +prg_aes_ccr_test_OBJECTS = \ +"CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o" + +# External object files for target prg_aes_ccr_test +prg_aes_ccr_test_EXTERNAL_OBJECTS = + +bin/prg_aes_ccr_test: CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o +bin/prg_aes_ccr_test: CMakeFiles/prg_aes_ccr_test.dir/build.make +bin/prg_aes_ccr_test: CMakeFiles/prg_aes_ccr_test.dir/compiler_depend.ts +bin/prg_aes_ccr_test: lib/libgtest_main.a +bin/prg_aes_ccr_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/prg_aes_ccr_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/prg_aes_ccr_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/prg_aes_ccr_test: lib/libgtest.a +bin/prg_aes_ccr_test: CMakeFiles/prg_aes_ccr_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/prg_aes_ccr_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/prg_aes_ccr_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=prg_aes_ccr_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/prg_aes_ccr_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=prg_aes_ccr_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/prg_aes_ccr_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/prg_aes_ccr_test.dir/build: bin/prg_aes_ccr_test +.PHONY : CMakeFiles/prg_aes_ccr_test.dir/build + +CMakeFiles/prg_aes_ccr_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/prg_aes_ccr_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/prg_aes_ccr_test.dir/clean + +CMakeFiles/prg_aes_ccr_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/DependInfo.cmake "--color=$(COLOR)" prg_aes_ccr_test +.PHONY : CMakeFiles/prg_aes_ccr_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..30a65fb --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/prg_aes_ccr_test.dir/link.d" + "CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o" + "CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o.d" + "bin/prg_aes_ccr_test" + "bin/prg_aes_ccr_test.pdb" + "prg_aes_ccr_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/prg_aes_ccr_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/compiler_depend.make new file mode 100644 index 0000000..1238c0b --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for prg_aes_ccr_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/compiler_depend.ts new file mode 100644 index 0000000..a216460 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for prg_aes_ccr_test. diff --git a/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/depend.make b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/depend.make new file mode 100644 index 0000000..8db4a07 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for prg_aes_ccr_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/flags.make b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/link.txt b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/link.txt new file mode 100644 index 0000000..71ae8af --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/prg_aes_ccr_test.dir/link.d CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o -o bin/prg_aes_ccr_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/progress.make b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/progress.make new file mode 100644 index 0000000..242ed69 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_aes_ccr_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 72 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/prg_chacha_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/prg_chacha_test.dir/DependInfo.cmake new file mode 100644 index 0000000..7ef7374 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_chacha_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_chacha_test.cpp" "CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o" "gcc" "CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o.d" + "" "bin/prg_chacha_test" "gcc" "CMakeFiles/prg_chacha_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/prg_chacha_test.dir/build.make b/test/build-asan/CMakeFiles/prg_chacha_test.dir/build.make new file mode 100644 index 0000000..ac216aa --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_chacha_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/prg_chacha_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/prg_chacha_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/prg_chacha_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/prg_chacha_test.dir/flags.make + +CMakeFiles/prg_chacha_test.dir/codegen: +.PHONY : CMakeFiles/prg_chacha_test.dir/codegen + +CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o: CMakeFiles/prg_chacha_test.dir/flags.make +CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_chacha_test.cpp +CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o: CMakeFiles/prg_chacha_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o -MF CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o.d -o CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_chacha_test.cpp + +CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_chacha_test.cpp > CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.i + +CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_chacha_test.cpp -o CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.s + +# Object files for target prg_chacha_test +prg_chacha_test_OBJECTS = \ +"CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o" + +# External object files for target prg_chacha_test +prg_chacha_test_EXTERNAL_OBJECTS = + +bin/prg_chacha_test: CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o +bin/prg_chacha_test: CMakeFiles/prg_chacha_test.dir/build.make +bin/prg_chacha_test: CMakeFiles/prg_chacha_test.dir/compiler_depend.ts +bin/prg_chacha_test: lib/libgtest_main.a +bin/prg_chacha_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/prg_chacha_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/prg_chacha_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/prg_chacha_test: lib/libgtest.a +bin/prg_chacha_test: CMakeFiles/prg_chacha_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/prg_chacha_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/prg_chacha_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=prg_chacha_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/prg_chacha_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=prg_chacha_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/prg_chacha_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/prg_chacha_test.dir/build: bin/prg_chacha_test +.PHONY : CMakeFiles/prg_chacha_test.dir/build + +CMakeFiles/prg_chacha_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/prg_chacha_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/prg_chacha_test.dir/clean + +CMakeFiles/prg_chacha_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/prg_chacha_test.dir/DependInfo.cmake "--color=$(COLOR)" prg_chacha_test +.PHONY : CMakeFiles/prg_chacha_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/prg_chacha_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/prg_chacha_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..6f2248b --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_chacha_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/prg_chacha_test.dir/link.d" + "CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o" + "CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o.d" + "bin/prg_chacha_test" + "bin/prg_chacha_test.pdb" + "prg_chacha_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/prg_chacha_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/prg_chacha_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/prg_chacha_test.dir/compiler_depend.make new file mode 100644 index 0000000..1a6673a --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_chacha_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for prg_chacha_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/prg_chacha_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/prg_chacha_test.dir/compiler_depend.ts new file mode 100644 index 0000000..f6e5fdd --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_chacha_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for prg_chacha_test. diff --git a/test/build-asan/CMakeFiles/prg_chacha_test.dir/depend.make b/test/build-asan/CMakeFiles/prg_chacha_test.dir/depend.make new file mode 100644 index 0000000..fd99889 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_chacha_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for prg_chacha_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/prg_chacha_test.dir/flags.make b/test/build-asan/CMakeFiles/prg_chacha_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_chacha_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/prg_chacha_test.dir/link.txt b/test/build-asan/CMakeFiles/prg_chacha_test.dir/link.txt new file mode 100644 index 0000000..8e84821 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_chacha_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/prg_chacha_test.dir/link.d CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o -o bin/prg_chacha_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/prg_chacha_test.dir/progress.make b/test/build-asan/CMakeFiles/prg_chacha_test.dir/progress.make new file mode 100644 index 0000000..f0bc12b --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_chacha_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 73 + diff --git a/test/build-asan/CMakeFiles/prg_lowmc_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/DependInfo.cmake new file mode 100644 index 0000000..ccb993a --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_lowmc_test.cpp" "CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o" "gcc" "CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o.d" + "" "bin/prg_lowmc_test" "gcc" "CMakeFiles/prg_lowmc_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/prg_lowmc_test.dir/build.make b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/build.make new file mode 100644 index 0000000..0d14139 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/prg_lowmc_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/prg_lowmc_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/prg_lowmc_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/prg_lowmc_test.dir/flags.make + +CMakeFiles/prg_lowmc_test.dir/codegen: +.PHONY : CMakeFiles/prg_lowmc_test.dir/codegen + +CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o: CMakeFiles/prg_lowmc_test.dir/flags.make +CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_lowmc_test.cpp +CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o: CMakeFiles/prg_lowmc_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o -MF CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o.d -o CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_lowmc_test.cpp + +CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_lowmc_test.cpp > CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.i + +CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/prg_lowmc_test.cpp -o CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.s + +# Object files for target prg_lowmc_test +prg_lowmc_test_OBJECTS = \ +"CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o" + +# External object files for target prg_lowmc_test +prg_lowmc_test_EXTERNAL_OBJECTS = + +bin/prg_lowmc_test: CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o +bin/prg_lowmc_test: CMakeFiles/prg_lowmc_test.dir/build.make +bin/prg_lowmc_test: CMakeFiles/prg_lowmc_test.dir/compiler_depend.ts +bin/prg_lowmc_test: lib/libgtest_main.a +bin/prg_lowmc_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/prg_lowmc_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/prg_lowmc_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/prg_lowmc_test: lib/libgtest.a +bin/prg_lowmc_test: CMakeFiles/prg_lowmc_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/prg_lowmc_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/prg_lowmc_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=prg_lowmc_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/prg_lowmc_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=prg_lowmc_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/prg_lowmc_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/prg_lowmc_test.dir/build: bin/prg_lowmc_test +.PHONY : CMakeFiles/prg_lowmc_test.dir/build + +CMakeFiles/prg_lowmc_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/prg_lowmc_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/prg_lowmc_test.dir/clean + +CMakeFiles/prg_lowmc_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/prg_lowmc_test.dir/DependInfo.cmake "--color=$(COLOR)" prg_lowmc_test +.PHONY : CMakeFiles/prg_lowmc_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/prg_lowmc_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..34b58d0 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/prg_lowmc_test.dir/link.d" + "CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o" + "CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o.d" + "bin/prg_lowmc_test" + "bin/prg_lowmc_test.pdb" + "prg_lowmc_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/prg_lowmc_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/prg_lowmc_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/compiler_depend.make new file mode 100644 index 0000000..9d356ea --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for prg_lowmc_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/prg_lowmc_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/compiler_depend.ts new file mode 100644 index 0000000..404658f --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for prg_lowmc_test. diff --git a/test/build-asan/CMakeFiles/prg_lowmc_test.dir/depend.make b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/depend.make new file mode 100644 index 0000000..ff82bfa --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for prg_lowmc_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/prg_lowmc_test.dir/flags.make b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/prg_lowmc_test.dir/link.txt b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/link.txt new file mode 100644 index 0000000..2d2f784 --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/prg_lowmc_test.dir/link.d CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o -o bin/prg_lowmc_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/prg_lowmc_test.dir/progress.make b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/progress.make new file mode 100644 index 0000000..b04406c --- /dev/null +++ b/test/build-asan/CMakeFiles/prg_lowmc_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 74 + diff --git a/test/build-asan/CMakeFiles/principal_lut_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/principal_lut_test.dir/DependInfo.cmake new file mode 100644 index 0000000..ae8c6db --- /dev/null +++ b/test/build-asan/CMakeFiles/principal_lut_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/principal_lut_test.cpp" "CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o" "gcc" "CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o.d" + "" "bin/principal_lut_test" "gcc" "CMakeFiles/principal_lut_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/principal_lut_test.dir/build.make b/test/build-asan/CMakeFiles/principal_lut_test.dir/build.make new file mode 100644 index 0000000..4329f38 --- /dev/null +++ b/test/build-asan/CMakeFiles/principal_lut_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/principal_lut_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/principal_lut_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/principal_lut_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/principal_lut_test.dir/flags.make + +CMakeFiles/principal_lut_test.dir/codegen: +.PHONY : CMakeFiles/principal_lut_test.dir/codegen + +CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o: CMakeFiles/principal_lut_test.dir/flags.make +CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/principal_lut_test.cpp +CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o: CMakeFiles/principal_lut_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o -MF CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o.d -o CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/principal_lut_test.cpp + +CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/principal_lut_test.cpp > CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.i + +CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/principal_lut_test.cpp -o CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.s + +# Object files for target principal_lut_test +principal_lut_test_OBJECTS = \ +"CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o" + +# External object files for target principal_lut_test +principal_lut_test_EXTERNAL_OBJECTS = + +bin/principal_lut_test: CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o +bin/principal_lut_test: CMakeFiles/principal_lut_test.dir/build.make +bin/principal_lut_test: CMakeFiles/principal_lut_test.dir/compiler_depend.ts +bin/principal_lut_test: lib/libgtest_main.a +bin/principal_lut_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/principal_lut_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/principal_lut_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/principal_lut_test: lib/libgtest.a +bin/principal_lut_test: CMakeFiles/principal_lut_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/principal_lut_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/principal_lut_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=principal_lut_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/principal_lut_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=principal_lut_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/principal_lut_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/principal_lut_test.dir/build: bin/principal_lut_test +.PHONY : CMakeFiles/principal_lut_test.dir/build + +CMakeFiles/principal_lut_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/principal_lut_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/principal_lut_test.dir/clean + +CMakeFiles/principal_lut_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/principal_lut_test.dir/DependInfo.cmake "--color=$(COLOR)" principal_lut_test +.PHONY : CMakeFiles/principal_lut_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/principal_lut_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/principal_lut_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..205ff2a --- /dev/null +++ b/test/build-asan/CMakeFiles/principal_lut_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/principal_lut_test.dir/link.d" + "CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o" + "CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o.d" + "bin/principal_lut_test" + "bin/principal_lut_test.pdb" + "principal_lut_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/principal_lut_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/principal_lut_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/principal_lut_test.dir/compiler_depend.make new file mode 100644 index 0000000..6fbf3fd --- /dev/null +++ b/test/build-asan/CMakeFiles/principal_lut_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for principal_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/principal_lut_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/principal_lut_test.dir/compiler_depend.ts new file mode 100644 index 0000000..567a290 --- /dev/null +++ b/test/build-asan/CMakeFiles/principal_lut_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for principal_lut_test. diff --git a/test/build-asan/CMakeFiles/principal_lut_test.dir/depend.make b/test/build-asan/CMakeFiles/principal_lut_test.dir/depend.make new file mode 100644 index 0000000..b51ccf9 --- /dev/null +++ b/test/build-asan/CMakeFiles/principal_lut_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for principal_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/principal_lut_test.dir/flags.make b/test/build-asan/CMakeFiles/principal_lut_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/principal_lut_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/principal_lut_test.dir/link.txt b/test/build-asan/CMakeFiles/principal_lut_test.dir/link.txt new file mode 100644 index 0000000..ab321ad --- /dev/null +++ b/test/build-asan/CMakeFiles/principal_lut_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/principal_lut_test.dir/link.d CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o -o bin/principal_lut_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/principal_lut_test.dir/progress.make b/test/build-asan/CMakeFiles/principal_lut_test.dir/progress.make new file mode 100644 index 0000000..98725d7 --- /dev/null +++ b/test/build-asan/CMakeFiles/principal_lut_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 75 + diff --git a/test/build-asan/CMakeFiles/profile_eval.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/profile_eval.dir/DependInfo.cmake new file mode 100644 index 0000000..4ad95d4 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_eval.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/profile/eval_profile.cpp" "CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o" "gcc" "CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o.d" + "" "bin/profile_eval" "gcc" "CMakeFiles/profile_eval.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/profile_eval.dir/build.make b/test/build-asan/CMakeFiles/profile_eval.dir/build.make new file mode 100644 index 0000000..7cb7514 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_eval.dir/build.make @@ -0,0 +1,119 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/profile_eval.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/profile_eval.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/profile_eval.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/profile_eval.dir/flags.make + +CMakeFiles/profile_eval.dir/codegen: +.PHONY : CMakeFiles/profile_eval.dir/codegen + +CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o: CMakeFiles/profile_eval.dir/flags.make +CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/profile/eval_profile.cpp +CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o: CMakeFiles/profile_eval.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o -MF CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o.d -o CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/profile/eval_profile.cpp + +CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/profile/eval_profile.cpp > CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.i + +CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/profile/eval_profile.cpp -o CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.s + +# Object files for target profile_eval +profile_eval_OBJECTS = \ +"CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o" + +# External object files for target profile_eval +profile_eval_EXTERNAL_OBJECTS = + +bin/profile_eval: CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o +bin/profile_eval: CMakeFiles/profile_eval.dir/build.make +bin/profile_eval: CMakeFiles/profile_eval.dir/compiler_depend.ts +bin/profile_eval: lib/libgtest_main.a +bin/profile_eval: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/profile_eval: /usr/lib/x86_64-linux-gnu/libssl.so +bin/profile_eval: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/profile_eval: lib/libgtest.a +bin/profile_eval: CMakeFiles/profile_eval.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/profile_eval" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/profile_eval.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +CMakeFiles/profile_eval.dir/build: bin/profile_eval +.PHONY : CMakeFiles/profile_eval.dir/build + +CMakeFiles/profile_eval.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/profile_eval.dir/cmake_clean.cmake +.PHONY : CMakeFiles/profile_eval.dir/clean + +CMakeFiles/profile_eval.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/profile_eval.dir/DependInfo.cmake "--color=$(COLOR)" profile_eval +.PHONY : CMakeFiles/profile_eval.dir/depend + diff --git a/test/build-asan/CMakeFiles/profile_eval.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/profile_eval.dir/cmake_clean.cmake new file mode 100644 index 0000000..2859d73 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_eval.dir/cmake_clean.cmake @@ -0,0 +1,12 @@ +file(REMOVE_RECURSE + "CMakeFiles/profile_eval.dir/link.d" + "CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o" + "CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o.d" + "bin/profile_eval" + "bin/profile_eval.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/profile_eval.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/profile_eval.dir/compiler_depend.make b/test/build-asan/CMakeFiles/profile_eval.dir/compiler_depend.make new file mode 100644 index 0000000..95f95cd --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_eval.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for profile_eval. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/profile_eval.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/profile_eval.dir/compiler_depend.ts new file mode 100644 index 0000000..3078574 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_eval.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for profile_eval. diff --git a/test/build-asan/CMakeFiles/profile_eval.dir/depend.make b/test/build-asan/CMakeFiles/profile_eval.dir/depend.make new file mode 100644 index 0000000..051bc0e --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_eval.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for profile_eval. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/profile_eval.dir/flags.make b/test/build-asan/CMakeFiles/profile_eval.dir/flags.make new file mode 100644 index 0000000..0edafc2 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_eval.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result -O3 -fno-omit-frame-pointer + diff --git a/test/build-asan/CMakeFiles/profile_eval.dir/link.txt b/test/build-asan/CMakeFiles/profile_eval.dir/link.txt new file mode 100644 index 0000000..4a1dddc --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_eval.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/profile_eval.dir/link.d CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o -o bin/profile_eval lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/profile_eval.dir/progress.make b/test/build-asan/CMakeFiles/profile_eval.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_eval.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/profile_grotto.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/profile_grotto.dir/DependInfo.cmake new file mode 100644 index 0000000..f6244cd --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_grotto.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/profile/grotto_profile.cpp" "CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o" "gcc" "CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o.d" + "" "bin/profile_grotto" "gcc" "CMakeFiles/profile_grotto.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/profile_grotto.dir/build.make b/test/build-asan/CMakeFiles/profile_grotto.dir/build.make new file mode 100644 index 0000000..5da61c7 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_grotto.dir/build.make @@ -0,0 +1,119 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/profile_grotto.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/profile_grotto.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/profile_grotto.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/profile_grotto.dir/flags.make + +CMakeFiles/profile_grotto.dir/codegen: +.PHONY : CMakeFiles/profile_grotto.dir/codegen + +CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o: CMakeFiles/profile_grotto.dir/flags.make +CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/profile/grotto_profile.cpp +CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o: CMakeFiles/profile_grotto.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o -MF CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o.d -o CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/profile/grotto_profile.cpp + +CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/profile/grotto_profile.cpp > CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.i + +CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/profile/grotto_profile.cpp -o CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.s + +# Object files for target profile_grotto +profile_grotto_OBJECTS = \ +"CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o" + +# External object files for target profile_grotto +profile_grotto_EXTERNAL_OBJECTS = + +bin/profile_grotto: CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o +bin/profile_grotto: CMakeFiles/profile_grotto.dir/build.make +bin/profile_grotto: CMakeFiles/profile_grotto.dir/compiler_depend.ts +bin/profile_grotto: lib/libgtest_main.a +bin/profile_grotto: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/profile_grotto: /usr/lib/x86_64-linux-gnu/libssl.so +bin/profile_grotto: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/profile_grotto: lib/libgtest.a +bin/profile_grotto: CMakeFiles/profile_grotto.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/profile_grotto" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/profile_grotto.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +CMakeFiles/profile_grotto.dir/build: bin/profile_grotto +.PHONY : CMakeFiles/profile_grotto.dir/build + +CMakeFiles/profile_grotto.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/profile_grotto.dir/cmake_clean.cmake +.PHONY : CMakeFiles/profile_grotto.dir/clean + +CMakeFiles/profile_grotto.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/profile_grotto.dir/DependInfo.cmake "--color=$(COLOR)" profile_grotto +.PHONY : CMakeFiles/profile_grotto.dir/depend + diff --git a/test/build-asan/CMakeFiles/profile_grotto.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/profile_grotto.dir/cmake_clean.cmake new file mode 100644 index 0000000..2a0fb1d --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_grotto.dir/cmake_clean.cmake @@ -0,0 +1,12 @@ +file(REMOVE_RECURSE + "CMakeFiles/profile_grotto.dir/link.d" + "CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o" + "CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o.d" + "bin/profile_grotto" + "bin/profile_grotto.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/profile_grotto.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/profile_grotto.dir/compiler_depend.make b/test/build-asan/CMakeFiles/profile_grotto.dir/compiler_depend.make new file mode 100644 index 0000000..bd2b0b7 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_grotto.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for profile_grotto. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/profile_grotto.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/profile_grotto.dir/compiler_depend.ts new file mode 100644 index 0000000..da3b36d --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_grotto.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for profile_grotto. diff --git a/test/build-asan/CMakeFiles/profile_grotto.dir/depend.make b/test/build-asan/CMakeFiles/profile_grotto.dir/depend.make new file mode 100644 index 0000000..c37e3af --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_grotto.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for profile_grotto. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/profile_grotto.dir/flags.make b/test/build-asan/CMakeFiles/profile_grotto.dir/flags.make new file mode 100644 index 0000000..0edafc2 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_grotto.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result -O3 -fno-omit-frame-pointer + diff --git a/test/build-asan/CMakeFiles/profile_grotto.dir/link.txt b/test/build-asan/CMakeFiles/profile_grotto.dir/link.txt new file mode 100644 index 0000000..3c8c106 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_grotto.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/profile_grotto.dir/link.d CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o -o bin/profile_grotto lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/profile_grotto.dir/progress.make b/test/build-asan/CMakeFiles/profile_grotto.dir/progress.make new file mode 100644 index 0000000..f49bd4c --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_grotto.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 76 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/profile_party.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/profile_party.dir/DependInfo.cmake new file mode 100644 index 0000000..8cb75f6 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_party.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/profile/party_profile.cpp" "CMakeFiles/profile_party.dir/profile/party_profile.cpp.o" "gcc" "CMakeFiles/profile_party.dir/profile/party_profile.cpp.o.d" + "" "bin/profile_party" "gcc" "CMakeFiles/profile_party.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/profile_party.dir/build.make b/test/build-asan/CMakeFiles/profile_party.dir/build.make new file mode 100644 index 0000000..497eb5b --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_party.dir/build.make @@ -0,0 +1,124 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/profile_party.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/profile_party.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/profile_party.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/profile_party.dir/flags.make + +CMakeFiles/profile_party.dir/codegen: +.PHONY : CMakeFiles/profile_party.dir/codegen + +CMakeFiles/profile_party.dir/profile/party_profile.cpp.o: CMakeFiles/profile_party.dir/flags.make +CMakeFiles/profile_party.dir/profile/party_profile.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/profile/party_profile.cpp +CMakeFiles/profile_party.dir/profile/party_profile.cpp.o: CMakeFiles/profile_party.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/profile_party.dir/profile/party_profile.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/profile_party.dir/profile/party_profile.cpp.o -MF CMakeFiles/profile_party.dir/profile/party_profile.cpp.o.d -o CMakeFiles/profile_party.dir/profile/party_profile.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/profile/party_profile.cpp + +CMakeFiles/profile_party.dir/profile/party_profile.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/profile_party.dir/profile/party_profile.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/profile/party_profile.cpp > CMakeFiles/profile_party.dir/profile/party_profile.cpp.i + +CMakeFiles/profile_party.dir/profile/party_profile.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/profile_party.dir/profile/party_profile.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/profile/party_profile.cpp -o CMakeFiles/profile_party.dir/profile/party_profile.cpp.s + +# Object files for target profile_party +profile_party_OBJECTS = \ +"CMakeFiles/profile_party.dir/profile/party_profile.cpp.o" + +# External object files for target profile_party +profile_party_EXTERNAL_OBJECTS = + +bin/profile_party: CMakeFiles/profile_party.dir/profile/party_profile.cpp.o +bin/profile_party: CMakeFiles/profile_party.dir/build.make +bin/profile_party: CMakeFiles/profile_party.dir/compiler_depend.ts +bin/profile_party: lib/libgtest_main.a +bin/profile_party: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/profile_party: /usr/lib/x86_64-linux-gnu/libssl.so +bin/profile_party: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/profile_party: libparty_flows.a +bin/profile_party: lib/libgtest_main.a +bin/profile_party: lib/libgtest.a +bin/profile_party: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/profile_party: /usr/lib/x86_64-linux-gnu/libssl.so +bin/profile_party: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/profile_party: CMakeFiles/profile_party.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/profile_party" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/profile_party.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +CMakeFiles/profile_party.dir/build: bin/profile_party +.PHONY : CMakeFiles/profile_party.dir/build + +CMakeFiles/profile_party.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/profile_party.dir/cmake_clean.cmake +.PHONY : CMakeFiles/profile_party.dir/clean + +CMakeFiles/profile_party.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/profile_party.dir/DependInfo.cmake "--color=$(COLOR)" profile_party +.PHONY : CMakeFiles/profile_party.dir/depend + diff --git a/test/build-asan/CMakeFiles/profile_party.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/profile_party.dir/cmake_clean.cmake new file mode 100644 index 0000000..e22af5c --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_party.dir/cmake_clean.cmake @@ -0,0 +1,12 @@ +file(REMOVE_RECURSE + "CMakeFiles/profile_party.dir/link.d" + "CMakeFiles/profile_party.dir/profile/party_profile.cpp.o" + "CMakeFiles/profile_party.dir/profile/party_profile.cpp.o.d" + "bin/profile_party" + "bin/profile_party.pdb" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/profile_party.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/profile_party.dir/compiler_depend.make b/test/build-asan/CMakeFiles/profile_party.dir/compiler_depend.make new file mode 100644 index 0000000..8305380 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_party.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for profile_party. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/profile_party.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/profile_party.dir/compiler_depend.ts new file mode 100644 index 0000000..cddd2b5 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_party.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for profile_party. diff --git a/test/build-asan/CMakeFiles/profile_party.dir/depend.make b/test/build-asan/CMakeFiles/profile_party.dir/depend.make new file mode 100644 index 0000000..90b8af3 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_party.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for profile_party. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/profile_party.dir/flags.make b/test/build-asan/CMakeFiles/profile_party.dir/flags.make new file mode 100644 index 0000000..0a8a5dc --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_party.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" -DLIBDPF_HAS_ASIO -DLIBDPF_HAS_NLOHMANN_JSON -DLIBDPF_PARTY_BIN_DIR=\"/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../party -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/json/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result -O3 -fno-omit-frame-pointer + diff --git a/test/build-asan/CMakeFiles/profile_party.dir/link.txt b/test/build-asan/CMakeFiles/profile_party.dir/link.txt new file mode 100644 index 0000000..387eb1e --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_party.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/profile_party.dir/link.d CMakeFiles/profile_party.dir/profile/party_profile.cpp.o -o bin/profile_party lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so libparty_flows.a lib/libgtest_main.a lib/libgtest.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so -lpthread diff --git a/test/build-asan/CMakeFiles/profile_party.dir/progress.make b/test/build-asan/CMakeFiles/profile_party.dir/progress.make new file mode 100644 index 0000000..4ef80b2 --- /dev/null +++ b/test/build-asan/CMakeFiles/profile_party.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 77 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/progress.marks b/test/build-asan/CMakeFiles/progress.marks new file mode 100644 index 0000000..29d6383 --- /dev/null +++ b/test/build-asan/CMakeFiles/progress.marks @@ -0,0 +1 @@ +100 diff --git a/test/build-asan/CMakeFiles/protocol_batch_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/protocol_batch_test.dir/DependInfo.cmake new file mode 100644 index 0000000..9d2a212 --- /dev/null +++ b/test/build-asan/CMakeFiles/protocol_batch_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/protocol_batch_test.cpp" "CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o" "gcc" "CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o.d" + "" "bin/protocol_batch_test" "gcc" "CMakeFiles/protocol_batch_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/protocol_batch_test.dir/build.make b/test/build-asan/CMakeFiles/protocol_batch_test.dir/build.make new file mode 100644 index 0000000..1ec0153 --- /dev/null +++ b/test/build-asan/CMakeFiles/protocol_batch_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/protocol_batch_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/protocol_batch_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/protocol_batch_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/protocol_batch_test.dir/flags.make + +CMakeFiles/protocol_batch_test.dir/codegen: +.PHONY : CMakeFiles/protocol_batch_test.dir/codegen + +CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o: CMakeFiles/protocol_batch_test.dir/flags.make +CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/protocol_batch_test.cpp +CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o: CMakeFiles/protocol_batch_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o -MF CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o.d -o CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/protocol_batch_test.cpp + +CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/protocol_batch_test.cpp > CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.i + +CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/protocol_batch_test.cpp -o CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.s + +# Object files for target protocol_batch_test +protocol_batch_test_OBJECTS = \ +"CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o" + +# External object files for target protocol_batch_test +protocol_batch_test_EXTERNAL_OBJECTS = + +bin/protocol_batch_test: CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o +bin/protocol_batch_test: CMakeFiles/protocol_batch_test.dir/build.make +bin/protocol_batch_test: CMakeFiles/protocol_batch_test.dir/compiler_depend.ts +bin/protocol_batch_test: lib/libgtest_main.a +bin/protocol_batch_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/protocol_batch_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/protocol_batch_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/protocol_batch_test: lib/libgtest.a +bin/protocol_batch_test: CMakeFiles/protocol_batch_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/protocol_batch_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/protocol_batch_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=protocol_batch_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/protocol_batch_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=protocol_batch_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/protocol_batch_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/protocol_batch_test.dir/build: bin/protocol_batch_test +.PHONY : CMakeFiles/protocol_batch_test.dir/build + +CMakeFiles/protocol_batch_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/protocol_batch_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/protocol_batch_test.dir/clean + +CMakeFiles/protocol_batch_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/protocol_batch_test.dir/DependInfo.cmake "--color=$(COLOR)" protocol_batch_test +.PHONY : CMakeFiles/protocol_batch_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/protocol_batch_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/protocol_batch_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..2948e8e --- /dev/null +++ b/test/build-asan/CMakeFiles/protocol_batch_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/protocol_batch_test.dir/link.d" + "CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o" + "CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o.d" + "bin/protocol_batch_test" + "bin/protocol_batch_test.pdb" + "protocol_batch_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/protocol_batch_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/protocol_batch_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/protocol_batch_test.dir/compiler_depend.make new file mode 100644 index 0000000..651d2cb --- /dev/null +++ b/test/build-asan/CMakeFiles/protocol_batch_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for protocol_batch_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/protocol_batch_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/protocol_batch_test.dir/compiler_depend.ts new file mode 100644 index 0000000..bcbe528 --- /dev/null +++ b/test/build-asan/CMakeFiles/protocol_batch_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for protocol_batch_test. diff --git a/test/build-asan/CMakeFiles/protocol_batch_test.dir/depend.make b/test/build-asan/CMakeFiles/protocol_batch_test.dir/depend.make new file mode 100644 index 0000000..b761d1c --- /dev/null +++ b/test/build-asan/CMakeFiles/protocol_batch_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for protocol_batch_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/protocol_batch_test.dir/flags.make b/test/build-asan/CMakeFiles/protocol_batch_test.dir/flags.make new file mode 100644 index 0000000..96f7b96 --- /dev/null +++ b/test/build-asan/CMakeFiles/protocol_batch_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../party -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/protocol_batch_test.dir/link.txt b/test/build-asan/CMakeFiles/protocol_batch_test.dir/link.txt new file mode 100644 index 0000000..2a3fcd1 --- /dev/null +++ b/test/build-asan/CMakeFiles/protocol_batch_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/protocol_batch_test.dir/link.d CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o -o bin/protocol_batch_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/protocol_batch_test.dir/progress.make b/test/build-asan/CMakeFiles/protocol_batch_test.dir/progress.make new file mode 100644 index 0000000..3a909bb --- /dev/null +++ b/test/build-asan/CMakeFiles/protocol_batch_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 78 + diff --git a/test/build-asan/CMakeFiles/random_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/random_test.dir/DependInfo.cmake new file mode 100644 index 0000000..0bf610d --- /dev/null +++ b/test/build-asan/CMakeFiles/random_test.dir/DependInfo.cmake @@ -0,0 +1,25 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/random_odr_tu.cpp" "CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o" "gcc" "CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o.d" + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/random_test.cpp" "CMakeFiles/random_test.dir/tests/random_test.cpp.o" "gcc" "CMakeFiles/random_test.dir/tests/random_test.cpp.o.d" + "" "bin/random_test" "gcc" "CMakeFiles/random_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/random_test.dir/build.make b/test/build-asan/CMakeFiles/random_test.dir/build.make new file mode 100644 index 0000000..d6ceb22 --- /dev/null +++ b/test/build-asan/CMakeFiles/random_test.dir/build.make @@ -0,0 +1,136 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/random_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/random_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/random_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/random_test.dir/flags.make + +CMakeFiles/random_test.dir/codegen: +.PHONY : CMakeFiles/random_test.dir/codegen + +CMakeFiles/random_test.dir/tests/random_test.cpp.o: CMakeFiles/random_test.dir/flags.make +CMakeFiles/random_test.dir/tests/random_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/random_test.cpp +CMakeFiles/random_test.dir/tests/random_test.cpp.o: CMakeFiles/random_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/random_test.dir/tests/random_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/random_test.dir/tests/random_test.cpp.o -MF CMakeFiles/random_test.dir/tests/random_test.cpp.o.d -o CMakeFiles/random_test.dir/tests/random_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/random_test.cpp + +CMakeFiles/random_test.dir/tests/random_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/random_test.dir/tests/random_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/random_test.cpp > CMakeFiles/random_test.dir/tests/random_test.cpp.i + +CMakeFiles/random_test.dir/tests/random_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/random_test.dir/tests/random_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/random_test.cpp -o CMakeFiles/random_test.dir/tests/random_test.cpp.s + +CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o: CMakeFiles/random_test.dir/flags.make +CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/random_odr_tu.cpp +CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o: CMakeFiles/random_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Building CXX object CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o -MF CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o.d -o CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/random_odr_tu.cpp + +CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/random_odr_tu.cpp > CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.i + +CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/random_odr_tu.cpp -o CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.s + +# Object files for target random_test +random_test_OBJECTS = \ +"CMakeFiles/random_test.dir/tests/random_test.cpp.o" \ +"CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o" + +# External object files for target random_test +random_test_EXTERNAL_OBJECTS = + +bin/random_test: CMakeFiles/random_test.dir/tests/random_test.cpp.o +bin/random_test: CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o +bin/random_test: CMakeFiles/random_test.dir/build.make +bin/random_test: CMakeFiles/random_test.dir/compiler_depend.ts +bin/random_test: lib/libgtest_main.a +bin/random_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/random_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/random_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/random_test: lib/libgtest.a +bin/random_test: CMakeFiles/random_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_3) "Linking CXX executable bin/random_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/random_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=random_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/random_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=random_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/random_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/random_test.dir/build: bin/random_test +.PHONY : CMakeFiles/random_test.dir/build + +CMakeFiles/random_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/random_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/random_test.dir/clean + +CMakeFiles/random_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/random_test.dir/DependInfo.cmake "--color=$(COLOR)" random_test +.PHONY : CMakeFiles/random_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/random_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/random_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..f67393d --- /dev/null +++ b/test/build-asan/CMakeFiles/random_test.dir/cmake_clean.cmake @@ -0,0 +1,15 @@ +file(REMOVE_RECURSE + "CMakeFiles/random_test.dir/link.d" + "CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o" + "CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o.d" + "CMakeFiles/random_test.dir/tests/random_test.cpp.o" + "CMakeFiles/random_test.dir/tests/random_test.cpp.o.d" + "bin/random_test" + "bin/random_test.pdb" + "random_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/random_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/random_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/random_test.dir/compiler_depend.make new file mode 100644 index 0000000..358f522 --- /dev/null +++ b/test/build-asan/CMakeFiles/random_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for random_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/random_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/random_test.dir/compiler_depend.ts new file mode 100644 index 0000000..f609c75 --- /dev/null +++ b/test/build-asan/CMakeFiles/random_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for random_test. diff --git a/test/build-asan/CMakeFiles/random_test.dir/depend.make b/test/build-asan/CMakeFiles/random_test.dir/depend.make new file mode 100644 index 0000000..25bbb21 --- /dev/null +++ b/test/build-asan/CMakeFiles/random_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for random_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/random_test.dir/flags.make b/test/build-asan/CMakeFiles/random_test.dir/flags.make new file mode 100644 index 0000000..7f7c033 --- /dev/null +++ b/test/build-asan/CMakeFiles/random_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result -ftrapv + diff --git a/test/build-asan/CMakeFiles/random_test.dir/link.txt b/test/build-asan/CMakeFiles/random_test.dir/link.txt new file mode 100644 index 0000000..de29df3 --- /dev/null +++ b/test/build-asan/CMakeFiles/random_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/random_test.dir/link.d CMakeFiles/random_test.dir/tests/random_test.cpp.o CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o -o bin/random_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/random_test.dir/progress.make b/test/build-asan/CMakeFiles/random_test.dir/progress.make new file mode 100644 index 0000000..12e8c01 --- /dev/null +++ b/test/build-asan/CMakeFiles/random_test.dir/progress.make @@ -0,0 +1,4 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 79 +CMAKE_PROGRESS_3 = + diff --git a/test/build-asan/CMakeFiles/range_lut_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/range_lut_test.dir/DependInfo.cmake new file mode 100644 index 0000000..776cc12 --- /dev/null +++ b/test/build-asan/CMakeFiles/range_lut_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/range_lut_test.cpp" "CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o" "gcc" "CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o.d" + "" "bin/range_lut_test" "gcc" "CMakeFiles/range_lut_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/range_lut_test.dir/build.make b/test/build-asan/CMakeFiles/range_lut_test.dir/build.make new file mode 100644 index 0000000..45101c9 --- /dev/null +++ b/test/build-asan/CMakeFiles/range_lut_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/range_lut_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/range_lut_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/range_lut_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/range_lut_test.dir/flags.make + +CMakeFiles/range_lut_test.dir/codegen: +.PHONY : CMakeFiles/range_lut_test.dir/codegen + +CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o: CMakeFiles/range_lut_test.dir/flags.make +CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/range_lut_test.cpp +CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o: CMakeFiles/range_lut_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o -MF CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o.d -o CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/range_lut_test.cpp + +CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/range_lut_test.cpp > CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.i + +CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/range_lut_test.cpp -o CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.s + +# Object files for target range_lut_test +range_lut_test_OBJECTS = \ +"CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o" + +# External object files for target range_lut_test +range_lut_test_EXTERNAL_OBJECTS = + +bin/range_lut_test: CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o +bin/range_lut_test: CMakeFiles/range_lut_test.dir/build.make +bin/range_lut_test: CMakeFiles/range_lut_test.dir/compiler_depend.ts +bin/range_lut_test: lib/libgtest_main.a +bin/range_lut_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/range_lut_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/range_lut_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/range_lut_test: lib/libgtest.a +bin/range_lut_test: CMakeFiles/range_lut_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/range_lut_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/range_lut_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=range_lut_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/range_lut_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=range_lut_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/range_lut_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/range_lut_test.dir/build: bin/range_lut_test +.PHONY : CMakeFiles/range_lut_test.dir/build + +CMakeFiles/range_lut_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/range_lut_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/range_lut_test.dir/clean + +CMakeFiles/range_lut_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/range_lut_test.dir/DependInfo.cmake "--color=$(COLOR)" range_lut_test +.PHONY : CMakeFiles/range_lut_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/range_lut_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/range_lut_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..6ed0d60 --- /dev/null +++ b/test/build-asan/CMakeFiles/range_lut_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/range_lut_test.dir/link.d" + "CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o" + "CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o.d" + "bin/range_lut_test" + "bin/range_lut_test.pdb" + "range_lut_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/range_lut_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/range_lut_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/range_lut_test.dir/compiler_depend.make new file mode 100644 index 0000000..0480dc5 --- /dev/null +++ b/test/build-asan/CMakeFiles/range_lut_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for range_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/range_lut_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/range_lut_test.dir/compiler_depend.ts new file mode 100644 index 0000000..9de65f5 --- /dev/null +++ b/test/build-asan/CMakeFiles/range_lut_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for range_lut_test. diff --git a/test/build-asan/CMakeFiles/range_lut_test.dir/depend.make b/test/build-asan/CMakeFiles/range_lut_test.dir/depend.make new file mode 100644 index 0000000..4b117b6 --- /dev/null +++ b/test/build-asan/CMakeFiles/range_lut_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for range_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/range_lut_test.dir/flags.make b/test/build-asan/CMakeFiles/range_lut_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/range_lut_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/range_lut_test.dir/link.txt b/test/build-asan/CMakeFiles/range_lut_test.dir/link.txt new file mode 100644 index 0000000..4214550 --- /dev/null +++ b/test/build-asan/CMakeFiles/range_lut_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/range_lut_test.dir/link.d CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o -o bin/range_lut_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/range_lut_test.dir/progress.make b/test/build-asan/CMakeFiles/range_lut_test.dir/progress.make new file mode 100644 index 0000000..72c44be --- /dev/null +++ b/test/build-asan/CMakeFiles/range_lut_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 80 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/ring_switch_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/ring_switch_test.dir/DependInfo.cmake new file mode 100644 index 0000000..da972d3 --- /dev/null +++ b/test/build-asan/CMakeFiles/ring_switch_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/ring_switch_test.cpp" "CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o" "gcc" "CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o.d" + "" "bin/ring_switch_test" "gcc" "CMakeFiles/ring_switch_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/ring_switch_test.dir/build.make b/test/build-asan/CMakeFiles/ring_switch_test.dir/build.make new file mode 100644 index 0000000..538e4d0 --- /dev/null +++ b/test/build-asan/CMakeFiles/ring_switch_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/ring_switch_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/ring_switch_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/ring_switch_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/ring_switch_test.dir/flags.make + +CMakeFiles/ring_switch_test.dir/codegen: +.PHONY : CMakeFiles/ring_switch_test.dir/codegen + +CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o: CMakeFiles/ring_switch_test.dir/flags.make +CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/ring_switch_test.cpp +CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o: CMakeFiles/ring_switch_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o -MF CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o.d -o CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/ring_switch_test.cpp + +CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/ring_switch_test.cpp > CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.i + +CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/ring_switch_test.cpp -o CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.s + +# Object files for target ring_switch_test +ring_switch_test_OBJECTS = \ +"CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o" + +# External object files for target ring_switch_test +ring_switch_test_EXTERNAL_OBJECTS = + +bin/ring_switch_test: CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o +bin/ring_switch_test: CMakeFiles/ring_switch_test.dir/build.make +bin/ring_switch_test: CMakeFiles/ring_switch_test.dir/compiler_depend.ts +bin/ring_switch_test: lib/libgtest_main.a +bin/ring_switch_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/ring_switch_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/ring_switch_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/ring_switch_test: lib/libgtest.a +bin/ring_switch_test: CMakeFiles/ring_switch_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/ring_switch_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/ring_switch_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=ring_switch_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ring_switch_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=ring_switch_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/ring_switch_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/ring_switch_test.dir/build: bin/ring_switch_test +.PHONY : CMakeFiles/ring_switch_test.dir/build + +CMakeFiles/ring_switch_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/ring_switch_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/ring_switch_test.dir/clean + +CMakeFiles/ring_switch_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/ring_switch_test.dir/DependInfo.cmake "--color=$(COLOR)" ring_switch_test +.PHONY : CMakeFiles/ring_switch_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/ring_switch_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/ring_switch_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..e4bdfe3 --- /dev/null +++ b/test/build-asan/CMakeFiles/ring_switch_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/ring_switch_test.dir/link.d" + "CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o" + "CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o.d" + "bin/ring_switch_test" + "bin/ring_switch_test.pdb" + "ring_switch_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/ring_switch_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/ring_switch_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/ring_switch_test.dir/compiler_depend.make new file mode 100644 index 0000000..3bb5920 --- /dev/null +++ b/test/build-asan/CMakeFiles/ring_switch_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for ring_switch_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/ring_switch_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/ring_switch_test.dir/compiler_depend.ts new file mode 100644 index 0000000..e0ad6f9 --- /dev/null +++ b/test/build-asan/CMakeFiles/ring_switch_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for ring_switch_test. diff --git a/test/build-asan/CMakeFiles/ring_switch_test.dir/depend.make b/test/build-asan/CMakeFiles/ring_switch_test.dir/depend.make new file mode 100644 index 0000000..8158dff --- /dev/null +++ b/test/build-asan/CMakeFiles/ring_switch_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for ring_switch_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/ring_switch_test.dir/flags.make b/test/build-asan/CMakeFiles/ring_switch_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/ring_switch_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/ring_switch_test.dir/link.txt b/test/build-asan/CMakeFiles/ring_switch_test.dir/link.txt new file mode 100644 index 0000000..39059ab --- /dev/null +++ b/test/build-asan/CMakeFiles/ring_switch_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/ring_switch_test.dir/link.d CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o -o bin/ring_switch_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/ring_switch_test.dir/progress.make b/test/build-asan/CMakeFiles/ring_switch_test.dir/progress.make new file mode 100644 index 0000000..48151de --- /dev/null +++ b/test/build-asan/CMakeFiles/ring_switch_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 81 + diff --git a/test/build-asan/CMakeFiles/secret_share_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/secret_share_test.dir/DependInfo.cmake new file mode 100644 index 0000000..47417f7 --- /dev/null +++ b/test/build-asan/CMakeFiles/secret_share_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/secret_share_test.cpp" "CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o" "gcc" "CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o.d" + "" "bin/secret_share_test" "gcc" "CMakeFiles/secret_share_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/secret_share_test.dir/build.make b/test/build-asan/CMakeFiles/secret_share_test.dir/build.make new file mode 100644 index 0000000..b79a245 --- /dev/null +++ b/test/build-asan/CMakeFiles/secret_share_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/secret_share_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/secret_share_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/secret_share_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/secret_share_test.dir/flags.make + +CMakeFiles/secret_share_test.dir/codegen: +.PHONY : CMakeFiles/secret_share_test.dir/codegen + +CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o: CMakeFiles/secret_share_test.dir/flags.make +CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/secret_share_test.cpp +CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o: CMakeFiles/secret_share_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o -MF CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o.d -o CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/secret_share_test.cpp + +CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/secret_share_test.cpp > CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.i + +CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/secret_share_test.cpp -o CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.s + +# Object files for target secret_share_test +secret_share_test_OBJECTS = \ +"CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o" + +# External object files for target secret_share_test +secret_share_test_EXTERNAL_OBJECTS = + +bin/secret_share_test: CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o +bin/secret_share_test: CMakeFiles/secret_share_test.dir/build.make +bin/secret_share_test: CMakeFiles/secret_share_test.dir/compiler_depend.ts +bin/secret_share_test: lib/libgtest_main.a +bin/secret_share_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/secret_share_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/secret_share_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/secret_share_test: lib/libgtest.a +bin/secret_share_test: CMakeFiles/secret_share_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/secret_share_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/secret_share_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=secret_share_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/secret_share_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=secret_share_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/secret_share_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/secret_share_test.dir/build: bin/secret_share_test +.PHONY : CMakeFiles/secret_share_test.dir/build + +CMakeFiles/secret_share_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/secret_share_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/secret_share_test.dir/clean + +CMakeFiles/secret_share_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/secret_share_test.dir/DependInfo.cmake "--color=$(COLOR)" secret_share_test +.PHONY : CMakeFiles/secret_share_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/secret_share_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/secret_share_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..1a37f9a --- /dev/null +++ b/test/build-asan/CMakeFiles/secret_share_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/secret_share_test.dir/link.d" + "CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o" + "CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o.d" + "bin/secret_share_test" + "bin/secret_share_test.pdb" + "secret_share_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/secret_share_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/secret_share_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/secret_share_test.dir/compiler_depend.make new file mode 100644 index 0000000..947c452 --- /dev/null +++ b/test/build-asan/CMakeFiles/secret_share_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for secret_share_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/secret_share_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/secret_share_test.dir/compiler_depend.ts new file mode 100644 index 0000000..bd72b29 --- /dev/null +++ b/test/build-asan/CMakeFiles/secret_share_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for secret_share_test. diff --git a/test/build-asan/CMakeFiles/secret_share_test.dir/depend.make b/test/build-asan/CMakeFiles/secret_share_test.dir/depend.make new file mode 100644 index 0000000..ac7a8a9 --- /dev/null +++ b/test/build-asan/CMakeFiles/secret_share_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for secret_share_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/secret_share_test.dir/flags.make b/test/build-asan/CMakeFiles/secret_share_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/secret_share_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/secret_share_test.dir/link.txt b/test/build-asan/CMakeFiles/secret_share_test.dir/link.txt new file mode 100644 index 0000000..1b46b06 --- /dev/null +++ b/test/build-asan/CMakeFiles/secret_share_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/secret_share_test.dir/link.d CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o -o bin/secret_share_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/secret_share_test.dir/progress.make b/test/build-asan/CMakeFiles/secret_share_test.dir/progress.make new file mode 100644 index 0000000..f21a792 --- /dev/null +++ b/test/build-asan/CMakeFiles/secret_share_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 82 + diff --git a/test/build-asan/CMakeFiles/security_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/security_test.dir/DependInfo.cmake new file mode 100644 index 0000000..80036be --- /dev/null +++ b/test/build-asan/CMakeFiles/security_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp" "CMakeFiles/security_test.dir/tests/security_test.cpp.o" "gcc" "CMakeFiles/security_test.dir/tests/security_test.cpp.o.d" + "" "bin/security_test" "gcc" "CMakeFiles/security_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/security_test.dir/build.make b/test/build-asan/CMakeFiles/security_test.dir/build.make new file mode 100644 index 0000000..2dff5af --- /dev/null +++ b/test/build-asan/CMakeFiles/security_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/security_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/security_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/security_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/security_test.dir/flags.make + +CMakeFiles/security_test.dir/codegen: +.PHONY : CMakeFiles/security_test.dir/codegen + +CMakeFiles/security_test.dir/tests/security_test.cpp.o: CMakeFiles/security_test.dir/flags.make +CMakeFiles/security_test.dir/tests/security_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp +CMakeFiles/security_test.dir/tests/security_test.cpp.o: CMakeFiles/security_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/security_test.dir/tests/security_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/security_test.dir/tests/security_test.cpp.o -MF CMakeFiles/security_test.dir/tests/security_test.cpp.o.d -o CMakeFiles/security_test.dir/tests/security_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp + +CMakeFiles/security_test.dir/tests/security_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/security_test.dir/tests/security_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp > CMakeFiles/security_test.dir/tests/security_test.cpp.i + +CMakeFiles/security_test.dir/tests/security_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/security_test.dir/tests/security_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp -o CMakeFiles/security_test.dir/tests/security_test.cpp.s + +# Object files for target security_test +security_test_OBJECTS = \ +"CMakeFiles/security_test.dir/tests/security_test.cpp.o" + +# External object files for target security_test +security_test_EXTERNAL_OBJECTS = + +bin/security_test: CMakeFiles/security_test.dir/tests/security_test.cpp.o +bin/security_test: CMakeFiles/security_test.dir/build.make +bin/security_test: CMakeFiles/security_test.dir/compiler_depend.ts +bin/security_test: lib/libgtest_main.a +bin/security_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/security_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/security_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/security_test: lib/libgtest.a +bin/security_test: CMakeFiles/security_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/security_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/security_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=security_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=security_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/security_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/security_test.dir/build: bin/security_test +.PHONY : CMakeFiles/security_test.dir/build + +CMakeFiles/security_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/security_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/security_test.dir/clean + +CMakeFiles/security_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/security_test.dir/DependInfo.cmake "--color=$(COLOR)" security_test +.PHONY : CMakeFiles/security_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/security_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/security_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..cc20f23 --- /dev/null +++ b/test/build-asan/CMakeFiles/security_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/security_test.dir/link.d" + "CMakeFiles/security_test.dir/tests/security_test.cpp.o" + "CMakeFiles/security_test.dir/tests/security_test.cpp.o.d" + "bin/security_test" + "bin/security_test.pdb" + "security_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/security_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/security_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/security_test.dir/compiler_depend.make new file mode 100644 index 0000000..05766d2 --- /dev/null +++ b/test/build-asan/CMakeFiles/security_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for security_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/security_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/security_test.dir/compiler_depend.ts new file mode 100644 index 0000000..d68c396 --- /dev/null +++ b/test/build-asan/CMakeFiles/security_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for security_test. diff --git a/test/build-asan/CMakeFiles/security_test.dir/depend.make b/test/build-asan/CMakeFiles/security_test.dir/depend.make new file mode 100644 index 0000000..63a4385 --- /dev/null +++ b/test/build-asan/CMakeFiles/security_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for security_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/security_test.dir/flags.make b/test/build-asan/CMakeFiles/security_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/security_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/security_test.dir/link.txt b/test/build-asan/CMakeFiles/security_test.dir/link.txt new file mode 100644 index 0000000..d2e4bcb --- /dev/null +++ b/test/build-asan/CMakeFiles/security_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/security_test.dir/link.d CMakeFiles/security_test.dir/tests/security_test.cpp.o -o bin/security_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/security_test.dir/progress.make b/test/build-asan/CMakeFiles/security_test.dir/progress.make new file mode 100644 index 0000000..30ddd1d --- /dev/null +++ b/test/build-asan/CMakeFiles/security_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 83 + diff --git a/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/DependInfo.cmake new file mode 100644 index 0000000..95cfbbc --- /dev/null +++ b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/setbit_index_iterable_test.cpp" "CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o" "gcc" "CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o.d" + "" "bin/setbit_index_iterable_test" "gcc" "CMakeFiles/setbit_index_iterable_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/build.make b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/build.make new file mode 100644 index 0000000..b6984a7 --- /dev/null +++ b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/setbit_index_iterable_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/setbit_index_iterable_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/setbit_index_iterable_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/setbit_index_iterable_test.dir/flags.make + +CMakeFiles/setbit_index_iterable_test.dir/codegen: +.PHONY : CMakeFiles/setbit_index_iterable_test.dir/codegen + +CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o: CMakeFiles/setbit_index_iterable_test.dir/flags.make +CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/setbit_index_iterable_test.cpp +CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o: CMakeFiles/setbit_index_iterable_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o -MF CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o.d -o CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/setbit_index_iterable_test.cpp + +CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/setbit_index_iterable_test.cpp > CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.i + +CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/setbit_index_iterable_test.cpp -o CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.s + +# Object files for target setbit_index_iterable_test +setbit_index_iterable_test_OBJECTS = \ +"CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o" + +# External object files for target setbit_index_iterable_test +setbit_index_iterable_test_EXTERNAL_OBJECTS = + +bin/setbit_index_iterable_test: CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o +bin/setbit_index_iterable_test: CMakeFiles/setbit_index_iterable_test.dir/build.make +bin/setbit_index_iterable_test: CMakeFiles/setbit_index_iterable_test.dir/compiler_depend.ts +bin/setbit_index_iterable_test: lib/libgtest_main.a +bin/setbit_index_iterable_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/setbit_index_iterable_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/setbit_index_iterable_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/setbit_index_iterable_test: lib/libgtest.a +bin/setbit_index_iterable_test: CMakeFiles/setbit_index_iterable_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/setbit_index_iterable_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/setbit_index_iterable_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=setbit_index_iterable_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/setbit_index_iterable_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=setbit_index_iterable_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/setbit_index_iterable_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/setbit_index_iterable_test.dir/build: bin/setbit_index_iterable_test +.PHONY : CMakeFiles/setbit_index_iterable_test.dir/build + +CMakeFiles/setbit_index_iterable_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/setbit_index_iterable_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/setbit_index_iterable_test.dir/clean + +CMakeFiles/setbit_index_iterable_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/DependInfo.cmake "--color=$(COLOR)" setbit_index_iterable_test +.PHONY : CMakeFiles/setbit_index_iterable_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..f5c2bf7 --- /dev/null +++ b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/setbit_index_iterable_test.dir/link.d" + "CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o" + "CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o.d" + "bin/setbit_index_iterable_test" + "bin/setbit_index_iterable_test.pdb" + "setbit_index_iterable_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/setbit_index_iterable_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/compiler_depend.make new file mode 100644 index 0000000..e9f9909 --- /dev/null +++ b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for setbit_index_iterable_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/compiler_depend.ts new file mode 100644 index 0000000..45ff02b --- /dev/null +++ b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for setbit_index_iterable_test. diff --git a/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/depend.make b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/depend.make new file mode 100644 index 0000000..b244d94 --- /dev/null +++ b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for setbit_index_iterable_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/flags.make b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/link.txt b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/link.txt new file mode 100644 index 0000000..84b9e92 --- /dev/null +++ b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/setbit_index_iterable_test.dir/link.d CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o -o bin/setbit_index_iterable_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/progress.make b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/setbit_index_iterable_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/sfss_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/sfss_test.dir/DependInfo.cmake new file mode 100644 index 0000000..7e76526 --- /dev/null +++ b/test/build-asan/CMakeFiles/sfss_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/sfss_test.cpp" "CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o" "gcc" "CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o.d" + "" "bin/sfss_test" "gcc" "CMakeFiles/sfss_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/sfss_test.dir/build.make b/test/build-asan/CMakeFiles/sfss_test.dir/build.make new file mode 100644 index 0000000..240c568 --- /dev/null +++ b/test/build-asan/CMakeFiles/sfss_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/sfss_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/sfss_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/sfss_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/sfss_test.dir/flags.make + +CMakeFiles/sfss_test.dir/codegen: +.PHONY : CMakeFiles/sfss_test.dir/codegen + +CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o: CMakeFiles/sfss_test.dir/flags.make +CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/sfss_test.cpp +CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o: CMakeFiles/sfss_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o -MF CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o.d -o CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/sfss_test.cpp + +CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/sfss_test.cpp > CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.i + +CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/sfss_test.cpp -o CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.s + +# Object files for target sfss_test +sfss_test_OBJECTS = \ +"CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o" + +# External object files for target sfss_test +sfss_test_EXTERNAL_OBJECTS = + +bin/sfss_test: CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o +bin/sfss_test: CMakeFiles/sfss_test.dir/build.make +bin/sfss_test: CMakeFiles/sfss_test.dir/compiler_depend.ts +bin/sfss_test: lib/libgtest_main.a +bin/sfss_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/sfss_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/sfss_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/sfss_test: lib/libgtest.a +bin/sfss_test: CMakeFiles/sfss_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/sfss_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/sfss_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=sfss_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/sfss_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=sfss_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/sfss_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/sfss_test.dir/build: bin/sfss_test +.PHONY : CMakeFiles/sfss_test.dir/build + +CMakeFiles/sfss_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/sfss_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/sfss_test.dir/clean + +CMakeFiles/sfss_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/sfss_test.dir/DependInfo.cmake "--color=$(COLOR)" sfss_test +.PHONY : CMakeFiles/sfss_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/sfss_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/sfss_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..83c7933 --- /dev/null +++ b/test/build-asan/CMakeFiles/sfss_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/sfss_test.dir/link.d" + "CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o" + "CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o.d" + "bin/sfss_test" + "bin/sfss_test.pdb" + "sfss_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/sfss_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/sfss_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/sfss_test.dir/compiler_depend.make new file mode 100644 index 0000000..00e5e66 --- /dev/null +++ b/test/build-asan/CMakeFiles/sfss_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for sfss_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/sfss_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/sfss_test.dir/compiler_depend.ts new file mode 100644 index 0000000..ea4f005 --- /dev/null +++ b/test/build-asan/CMakeFiles/sfss_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for sfss_test. diff --git a/test/build-asan/CMakeFiles/sfss_test.dir/depend.make b/test/build-asan/CMakeFiles/sfss_test.dir/depend.make new file mode 100644 index 0000000..fa69cc2 --- /dev/null +++ b/test/build-asan/CMakeFiles/sfss_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for sfss_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/sfss_test.dir/flags.make b/test/build-asan/CMakeFiles/sfss_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/sfss_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/sfss_test.dir/link.txt b/test/build-asan/CMakeFiles/sfss_test.dir/link.txt new file mode 100644 index 0000000..d35990f --- /dev/null +++ b/test/build-asan/CMakeFiles/sfss_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/sfss_test.dir/link.d CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o -o bin/sfss_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/sfss_test.dir/progress.make b/test/build-asan/CMakeFiles/sfss_test.dir/progress.make new file mode 100644 index 0000000..7b8681c --- /dev/null +++ b/test/build-asan/CMakeFiles/sfss_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 84 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/DependInfo.cmake new file mode 100644 index 0000000..dfc905f --- /dev/null +++ b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/shamir_adversarial_test.cpp" "CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o" "gcc" "CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o.d" + "" "bin/shamir_adversarial_test" "gcc" "CMakeFiles/shamir_adversarial_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/build.make b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/build.make new file mode 100644 index 0000000..79aba41 --- /dev/null +++ b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/shamir_adversarial_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/shamir_adversarial_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/shamir_adversarial_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/shamir_adversarial_test.dir/flags.make + +CMakeFiles/shamir_adversarial_test.dir/codegen: +.PHONY : CMakeFiles/shamir_adversarial_test.dir/codegen + +CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o: CMakeFiles/shamir_adversarial_test.dir/flags.make +CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/shamir_adversarial_test.cpp +CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o: CMakeFiles/shamir_adversarial_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o -MF CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o.d -o CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/shamir_adversarial_test.cpp + +CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/shamir_adversarial_test.cpp > CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.i + +CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/shamir_adversarial_test.cpp -o CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.s + +# Object files for target shamir_adversarial_test +shamir_adversarial_test_OBJECTS = \ +"CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o" + +# External object files for target shamir_adversarial_test +shamir_adversarial_test_EXTERNAL_OBJECTS = + +bin/shamir_adversarial_test: CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o +bin/shamir_adversarial_test: CMakeFiles/shamir_adversarial_test.dir/build.make +bin/shamir_adversarial_test: CMakeFiles/shamir_adversarial_test.dir/compiler_depend.ts +bin/shamir_adversarial_test: lib/libgtest_main.a +bin/shamir_adversarial_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/shamir_adversarial_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/shamir_adversarial_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/shamir_adversarial_test: lib/libgtest.a +bin/shamir_adversarial_test: CMakeFiles/shamir_adversarial_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/shamir_adversarial_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/shamir_adversarial_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=shamir_adversarial_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/shamir_adversarial_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=shamir_adversarial_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/shamir_adversarial_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/shamir_adversarial_test.dir/build: bin/shamir_adversarial_test +.PHONY : CMakeFiles/shamir_adversarial_test.dir/build + +CMakeFiles/shamir_adversarial_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/shamir_adversarial_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/shamir_adversarial_test.dir/clean + +CMakeFiles/shamir_adversarial_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/DependInfo.cmake "--color=$(COLOR)" shamir_adversarial_test +.PHONY : CMakeFiles/shamir_adversarial_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..d87ae86 --- /dev/null +++ b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/shamir_adversarial_test.dir/link.d" + "CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o" + "CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o.d" + "bin/shamir_adversarial_test" + "bin/shamir_adversarial_test.pdb" + "shamir_adversarial_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/shamir_adversarial_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/compiler_depend.make new file mode 100644 index 0000000..e9883e4 --- /dev/null +++ b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for shamir_adversarial_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/compiler_depend.ts new file mode 100644 index 0000000..a500989 --- /dev/null +++ b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for shamir_adversarial_test. diff --git a/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/depend.make b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/depend.make new file mode 100644 index 0000000..8c9e5d4 --- /dev/null +++ b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for shamir_adversarial_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/flags.make b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/link.txt b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/link.txt new file mode 100644 index 0000000..6702795 --- /dev/null +++ b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/shamir_adversarial_test.dir/link.d CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o -o bin/shamir_adversarial_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/progress.make b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/progress.make new file mode 100644 index 0000000..57fa75e --- /dev/null +++ b/test/build-asan/CMakeFiles/shamir_adversarial_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 85 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/share_runtime_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/share_runtime_test.dir/DependInfo.cmake new file mode 100644 index 0000000..b866290 --- /dev/null +++ b/test/build-asan/CMakeFiles/share_runtime_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp" "CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o" "gcc" "CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o.d" + "" "bin/share_runtime_test" "gcc" "CMakeFiles/share_runtime_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/share_runtime_test.dir/build.make b/test/build-asan/CMakeFiles/share_runtime_test.dir/build.make new file mode 100644 index 0000000..35cb059 --- /dev/null +++ b/test/build-asan/CMakeFiles/share_runtime_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/share_runtime_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/share_runtime_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/share_runtime_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/share_runtime_test.dir/flags.make + +CMakeFiles/share_runtime_test.dir/codegen: +.PHONY : CMakeFiles/share_runtime_test.dir/codegen + +CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o: CMakeFiles/share_runtime_test.dir/flags.make +CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp +CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o: CMakeFiles/share_runtime_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o -MF CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o.d -o CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp + +CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp > CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.i + +CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp -o CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.s + +# Object files for target share_runtime_test +share_runtime_test_OBJECTS = \ +"CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o" + +# External object files for target share_runtime_test +share_runtime_test_EXTERNAL_OBJECTS = + +bin/share_runtime_test: CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o +bin/share_runtime_test: CMakeFiles/share_runtime_test.dir/build.make +bin/share_runtime_test: CMakeFiles/share_runtime_test.dir/compiler_depend.ts +bin/share_runtime_test: lib/libgtest_main.a +bin/share_runtime_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/share_runtime_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/share_runtime_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/share_runtime_test: lib/libgtest.a +bin/share_runtime_test: CMakeFiles/share_runtime_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/share_runtime_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/share_runtime_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=share_runtime_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=share_runtime_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/share_runtime_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/share_runtime_test.dir/build: bin/share_runtime_test +.PHONY : CMakeFiles/share_runtime_test.dir/build + +CMakeFiles/share_runtime_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/share_runtime_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/share_runtime_test.dir/clean + +CMakeFiles/share_runtime_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/share_runtime_test.dir/DependInfo.cmake "--color=$(COLOR)" share_runtime_test +.PHONY : CMakeFiles/share_runtime_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/share_runtime_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/share_runtime_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..09bd36a --- /dev/null +++ b/test/build-asan/CMakeFiles/share_runtime_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/share_runtime_test.dir/link.d" + "CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o" + "CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o.d" + "bin/share_runtime_test" + "bin/share_runtime_test.pdb" + "share_runtime_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/share_runtime_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/share_runtime_test.dir/compiler_depend.internal b/test/build-asan/CMakeFiles/share_runtime_test.dir/compiler_depend.internal new file mode 100644 index 0000000..cf111fa --- /dev/null +++ b/test/build-asan/CMakeFiles/share_runtime_test.dir/compiler_depend.internal @@ -0,0 +1,1224 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o + /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/aligned_allocator.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_flow.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_plans.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_runtime.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/async_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/beaver.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit_array.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit_inject.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bitstring.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/blob.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/buffered_prg.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/circuit.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/compose.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/compose_async.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/cost_pass.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/edabit.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/experiment.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/experiment_note.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/factory_gadgets.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/factory_tapes.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/fixed_share.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/fp61.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/gilboa.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/leaf_arithmetic.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/leaf_node.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/literals.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/log.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/matmul.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/mesh_apps.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/modint.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/asio_ns.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_round_sink.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_sctp_stream_array.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_stream_array.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/buffer_pool.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/channel.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/connect.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/dealer_cursor.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/edge_mesh.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/io_pool.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/link_log.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/memory_sink.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/party_session.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/policy.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/round_lane.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/round_sink.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/sink_exchange.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/socket_tune.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_array.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_edge_mesh.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_mesh.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/tcp_mesh.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/nyble.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/online_session.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/ot_pack.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/packed_lane.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/packed_lane_arithmetic.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/pad_graphs.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/party_run.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/party_runner.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/placement.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prep_source.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_aes.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_aes_ccr.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_chacha.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_count.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_dummy.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_lowmc.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol_factory.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol_roles.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/random.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/revealing.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/rss_seed.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/run_config.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/run_log.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/schedule_streams.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/secret_share.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/session_host.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/shamir.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/share_cmp.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/share_expr.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/share_vec.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/shuffle.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/trunc.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/twiddle.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/twobit.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/uint256_t.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/utils.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/verifiable.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/wildcard.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/xor_wrapper.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/grotto/fixedpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/include/grotto/fixedpoint_mul.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_completion_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_completion_handler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_io_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/append.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/as_tuple.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_allocator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_cancellation_slot.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_immediate_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/async_result.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/awaitable.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_datagram_socket.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_deadline_timer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_file.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_io_object.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_random_access_file.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_raw_socket.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_readable_pipe.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_seq_packet_socket.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_serial_port.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_signal_set.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_acceptor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_iostream.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_streambuf.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_stream_file.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_stream_socket.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_streambuf.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_streambuf_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_waitable_timer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_writable_pipe.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_allocator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_cancellation_slot.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_immediate_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffer_registration.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_read_stream.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_read_stream_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_stream.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_stream_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_write_stream.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_write_stream_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffers_iterator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_signal.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_state.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_type.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/co_spawn.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/completion_condition.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/compose.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/connect.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/connect_pipe.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/consign.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/coroutine.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/deadline_timer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/defer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/deferred.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detached.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/array.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/array_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/assert.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/atomic_count.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/base_from_cancellation_state.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/base_from_completion_cond.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/bind_handler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/blocking_executor_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffer_resize_guard.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffer_sequence_adapter.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffered_stream_storage.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/bulk_executor_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/call_stack.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/chrono.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/chrono_time_traits.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/completion_handler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/composed_work.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/concurrency_hint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/conditionally_enabled_event.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/conditionally_enabled_mutex.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/config.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/consuming_buffers.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/cstddef.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/cstdint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/date_time_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/deadline_timer_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/dependent_type.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_ops.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_read_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_write_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/epoll_reactor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/event.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/eventfd_select_interrupter.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/executor_function.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/executor_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/fenced_block.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/functional.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/future.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/global.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_alloc_helpers.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_cont_helpers.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_invoke_helpers.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_tracking.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_type_requirements.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_work.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/descriptor_ops.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/epoll_reactor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/epoll_reactor.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/eventfd_select_interrupter.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/handler_tracking.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/null_event.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_event.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_mutex.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_serial_port_service.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_thread.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/reactive_descriptor_service.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/reactive_socket_service_base.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/resolver_service_base.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/scheduler.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/service_registry.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/service_registry.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/signal_set_service.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/socket_ops.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_executor_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_executor_service.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_service.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/thread_context.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/throw_error.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/timer_queue_set.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_defer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_dispatch.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_post.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/io_control.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/io_object_impl.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/is_buffer_sequence.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/is_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/keyword_tss_ptr.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/limits.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/local_free_on_block_exit.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/memory.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/mutex.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/non_const_lvalue.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/noncopyable.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/null_event.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/object_pool.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/op_queue.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/operation.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/pop_options.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_event.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_global.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_mutex.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_serial_port_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_signal_blocker.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_static_mutex.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_thread.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/push_options.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_descriptor_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_null_buffers_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_accept_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_connect_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recv_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recvfrom_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recvmsg_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_send_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_sendto_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_service_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_wait_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactor_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/recycling_allocator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/regex_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_endpoint_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_query_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolver_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolver_service_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_operation.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_task.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_thread_info.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scoped_lock.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scoped_ptr.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/select_interrupter.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/service_registry.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_blocker.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_handler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_set_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_holder.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_ops.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_option.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_types.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/static_mutex.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/std_fenced_block.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/strand_executor_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/strand_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/string_view.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_group.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_info_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/throw_error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/throw_exception.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_ptime.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_set.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_scheduler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_scheduler_fwd.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/tss_ptr.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/type_traits.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/utility.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/variadic_templates.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wait_handler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wait_op.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/winsock_init.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/work_dispatcher.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wrapped_handler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/dispatch.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/error_code.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/allocator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/any_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bad_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/blocking.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/blocking_adaptation.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bulk_execute.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bulk_guarantee.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/connect.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/context_as.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_invocable.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_operation.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_receiver.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/bulk_sender.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/submit_receiver.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/void_receiver.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/execute.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/impl/bad_executor.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/impl/receiver_invocation_error.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/invocable_archetype.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/mapping.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/occupancy.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/operation_state.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/outstanding_work.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/prefer_only.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/receiver.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/receiver_invocation_error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/relationship.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/schedule.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/scheduler.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/sender.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_done.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_value.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/start.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/submit.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/executor_work_guard.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/file_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/basic_endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/datagram_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/detail/endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/detail/impl/endpoint.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/raw_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/seq_packet_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/stream_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_alloc_hook.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_continuation_hook.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_invoke_hook.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/high_resolution_timer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/any_completion_executor.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/any_io_executor.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/append.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/as_tuple.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/buffered_read_stream.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/buffered_write_stream.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/cancellation_signal.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect_pipe.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect_pipe.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/consign.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/deferred.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/detached.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/error.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/error_code.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/execution_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/execution_context.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/executor.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/handler_alloc_hook.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/io_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/io_context.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/multiple_exceptions.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/prepend.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read_at.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read_until.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/redirect_error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/serial_port_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/serial_port_base.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_context.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/thread_pool.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/thread_pool.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/use_future.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/write.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/write_at.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_context_strand.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_service.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_service_strand.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4_iterator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4_range.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6_iterator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6_range.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/bad_address_cast.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_entry.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_iterator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_query.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_results.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/impl/endpoint.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/socket_option.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/host_name.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/icmp.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v4.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v4.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v6.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v6.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/basic_endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/host_name.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v4.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v4.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v6.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v6.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/multicast.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/network_v4.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/network_v6.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/resolver_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/resolver_query_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/tcp.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/udp.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/unicast.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/v6_only.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_applicable_property.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_contiguous_iterator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_read_buffered.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_write_buffered.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/basic_endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/connect_pair.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/datagram_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/detail/endpoint.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/detail/impl/endpoint.ipp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/seq_packet_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/stream_protocol.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/multiple_exceptions.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/packaged_task.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/placeholders.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/basic_descriptor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/basic_stream_descriptor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/descriptor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/descriptor_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/stream_descriptor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/post.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/prefer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/prepend.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/query.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/random_access_file.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read_at.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read_until.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/readable_pipe.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/recycling_allocator.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/redirect_error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/registered_buffer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/require.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/require_concept.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/serial_port.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/serial_port_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/signal_set.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/signal_set_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/socket_base.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/static_thread_pool.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/steady_timer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/strand.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/stream_file.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/streambuf.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_context.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_error.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_timer.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/this_coro.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/thread.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/thread_pool.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/time_traits.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/bulk_execute_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/bulk_execute_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/connect_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/connect_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/equality_comparable.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/execute_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/execute_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/prefer_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/prefer_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_static_constexpr_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_concept_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_concept_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/schedule_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/schedule_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_done_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_done_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_error_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_error_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_value_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_value_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/start_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/start_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_query.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_require.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_require_concept.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/submit_free.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/submit_member.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/use_awaitable.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/use_future.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/uses_executor.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/version.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/wait_traits.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_object_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_overlapped_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_random_access_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_stream_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/object_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/overlapped_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/overlapped_ptr.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/random_access_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/stream_handle.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/writable_pipe.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/write.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/write_at.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/libutil.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/stdio.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/stdlib.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/unistd.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/hash-library/sha256.cpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/hash-library/sha256.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/hedley/hedley.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/lowmc/LowMC.cpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/lowmc/LowMC.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/builtin/builtin.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/endian/endian.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/exact-int/exact-int.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/check.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/debug-trap.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/hedley.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-align.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-arch.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-common.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-constify.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-detect-clang.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-diagnostic.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-f16.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-features.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-math.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/avx.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/avx2.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/mmx.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse2.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse3.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse4.1.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse4.2.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/ssse3.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/endianness.h + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/uint128_t.hpp + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/uint256_t.hpp + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-assertion-result.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-death-test.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-matchers.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-message.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-param-test.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-printers.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-test-part.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-typed-test.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_pred_impl.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_prod.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-port.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-printers.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-filepath.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-internal.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-param-util.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port-arch.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-string.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-type-util.h + /usr/include/alloca.h + /usr/include/arpa/inet.h + /usr/include/asm-generic/bitsperlong.h + /usr/include/asm-generic/errno-base.h + /usr/include/asm-generic/errno.h + /usr/include/asm-generic/int-ll64.h + /usr/include/asm-generic/ioctl.h + /usr/include/asm-generic/ioctls.h + /usr/include/asm-generic/posix_types.h + /usr/include/asm-generic/socket.h + /usr/include/asm-generic/sockios.h + /usr/include/asm-generic/types.h + /usr/include/assert.h + /usr/include/c++/15/algorithm + /usr/include/c++/15/any + /usr/include/c++/15/array + /usr/include/c++/15/atomic + /usr/include/c++/15/backward/auto_ptr.h + /usr/include/c++/15/backward/binders.h + /usr/include/c++/15/bit + /usr/include/c++/15/bits/algorithmfwd.h + /usr/include/c++/15/bits/align.h + /usr/include/c++/15/bits/alloc_traits.h + /usr/include/c++/15/bits/allocated_ptr.h + /usr/include/c++/15/bits/allocator.h + /usr/include/c++/15/bits/atomic_base.h + /usr/include/c++/15/bits/atomic_futex.h + /usr/include/c++/15/bits/atomic_lockfree_defines.h + /usr/include/c++/15/bits/basic_ios.h + /usr/include/c++/15/bits/basic_ios.tcc + /usr/include/c++/15/bits/basic_string.h + /usr/include/c++/15/bits/basic_string.tcc + /usr/include/c++/15/bits/char_traits.h + /usr/include/c++/15/bits/charconv.h + /usr/include/c++/15/bits/chrono.h + /usr/include/c++/15/bits/codecvt.h + /usr/include/c++/15/bits/concept_check.h + /usr/include/c++/15/bits/cpp_type_traits.h + /usr/include/c++/15/bits/cxxabi_forced.h + /usr/include/c++/15/bits/cxxabi_init_exception.h + /usr/include/c++/15/bits/deque.tcc + /usr/include/c++/15/bits/enable_special_members.h + /usr/include/c++/15/bits/erase_if.h + /usr/include/c++/15/bits/exception.h + /usr/include/c++/15/bits/exception_defines.h + /usr/include/c++/15/bits/exception_ptr.h + /usr/include/c++/15/bits/fstream.tcc + /usr/include/c++/15/bits/functexcept.h + /usr/include/c++/15/bits/functional_hash.h + /usr/include/c++/15/bits/hash_bytes.h + /usr/include/c++/15/bits/hashtable.h + /usr/include/c++/15/bits/hashtable_policy.h + /usr/include/c++/15/bits/invoke.h + /usr/include/c++/15/bits/ios_base.h + /usr/include/c++/15/bits/istream.tcc + /usr/include/c++/15/bits/locale_classes.h + /usr/include/c++/15/bits/locale_classes.tcc + /usr/include/c++/15/bits/locale_conv.h + /usr/include/c++/15/bits/locale_facets.h + /usr/include/c++/15/bits/locale_facets.tcc + /usr/include/c++/15/bits/locale_facets_nonio.h + /usr/include/c++/15/bits/locale_facets_nonio.tcc + /usr/include/c++/15/bits/localefwd.h + /usr/include/c++/15/bits/memory_resource.h + /usr/include/c++/15/bits/memoryfwd.h + /usr/include/c++/15/bits/monostate.h + /usr/include/c++/15/bits/move.h + /usr/include/c++/15/bits/nested_exception.h + /usr/include/c++/15/bits/new_allocator.h + /usr/include/c++/15/bits/node_handle.h + /usr/include/c++/15/bits/ostream.h + /usr/include/c++/15/bits/ostream.tcc + /usr/include/c++/15/bits/ostream_insert.h + /usr/include/c++/15/bits/parse_numbers.h + /usr/include/c++/15/bits/postypes.h + /usr/include/c++/15/bits/predefined_ops.h + /usr/include/c++/15/bits/ptr_traits.h + /usr/include/c++/15/bits/quoted_string.h + /usr/include/c++/15/bits/random.h + /usr/include/c++/15/bits/random.tcc + /usr/include/c++/15/bits/range_access.h + /usr/include/c++/15/bits/refwrap.h + /usr/include/c++/15/bits/requires_hosted.h + /usr/include/c++/15/bits/shared_ptr.h + /usr/include/c++/15/bits/shared_ptr_atomic.h + /usr/include/c++/15/bits/shared_ptr_base.h + /usr/include/c++/15/bits/specfun.h + /usr/include/c++/15/bits/sstream.tcc + /usr/include/c++/15/bits/std_abs.h + /usr/include/c++/15/bits/std_function.h + /usr/include/c++/15/bits/std_mutex.h + /usr/include/c++/15/bits/std_thread.h + /usr/include/c++/15/bits/stl_algo.h + /usr/include/c++/15/bits/stl_algobase.h + /usr/include/c++/15/bits/stl_bvector.h + /usr/include/c++/15/bits/stl_construct.h + /usr/include/c++/15/bits/stl_deque.h + /usr/include/c++/15/bits/stl_function.h + /usr/include/c++/15/bits/stl_heap.h + /usr/include/c++/15/bits/stl_iterator.h + /usr/include/c++/15/bits/stl_iterator_base_funcs.h + /usr/include/c++/15/bits/stl_iterator_base_types.h + /usr/include/c++/15/bits/stl_map.h + /usr/include/c++/15/bits/stl_multimap.h + /usr/include/c++/15/bits/stl_multiset.h + /usr/include/c++/15/bits/stl_numeric.h + /usr/include/c++/15/bits/stl_pair.h + /usr/include/c++/15/bits/stl_raw_storage_iter.h + /usr/include/c++/15/bits/stl_relops.h + /usr/include/c++/15/bits/stl_set.h + /usr/include/c++/15/bits/stl_tempbuf.h + /usr/include/c++/15/bits/stl_tree.h + /usr/include/c++/15/bits/stl_uninitialized.h + /usr/include/c++/15/bits/stl_vector.h + /usr/include/c++/15/bits/stream_iterator.h + /usr/include/c++/15/bits/streambuf.tcc + /usr/include/c++/15/bits/streambuf_iterator.h + /usr/include/c++/15/bits/string_view.tcc + /usr/include/c++/15/bits/stringfwd.h + /usr/include/c++/15/bits/this_thread_sleep.h + /usr/include/c++/15/bits/uniform_int_dist.h + /usr/include/c++/15/bits/unique_lock.h + /usr/include/c++/15/bits/unique_ptr.h + /usr/include/c++/15/bits/unordered_map.h + /usr/include/c++/15/bits/uses_allocator.h + /usr/include/c++/15/bits/uses_allocator_args.h + /usr/include/c++/15/bits/utility.h + /usr/include/c++/15/bits/vector.tcc + /usr/include/c++/15/bits/version.h + /usr/include/c++/15/bitset + /usr/include/c++/15/cassert + /usr/include/c++/15/cctype + /usr/include/c++/15/cerrno + /usr/include/c++/15/cfenv + /usr/include/c++/15/chrono + /usr/include/c++/15/cinttypes + /usr/include/c++/15/climits + /usr/include/c++/15/clocale + /usr/include/c++/15/cmath + /usr/include/c++/15/compare + /usr/include/c++/15/concepts + /usr/include/c++/15/condition_variable + /usr/include/c++/15/csignal + /usr/include/c++/15/cstddef + /usr/include/c++/15/cstdint + /usr/include/c++/15/cstdio + /usr/include/c++/15/cstdlib + /usr/include/c++/15/cstring + /usr/include/c++/15/ctime + /usr/include/c++/15/cwchar + /usr/include/c++/15/cwctype + /usr/include/c++/15/cxxabi.h + /usr/include/c++/15/debug/assertions.h + /usr/include/c++/15/debug/debug.h + /usr/include/c++/15/deque + /usr/include/c++/15/exception + /usr/include/c++/15/ext/aligned_buffer.h + /usr/include/c++/15/ext/alloc_traits.h + /usr/include/c++/15/ext/atomicity.h + /usr/include/c++/15/ext/concurrence.h + /usr/include/c++/15/ext/numeric_traits.h + /usr/include/c++/15/ext/string_conversions.h + /usr/include/c++/15/ext/type_traits.h + /usr/include/c++/15/fenv.h + /usr/include/c++/15/fstream + /usr/include/c++/15/functional + /usr/include/c++/15/future + /usr/include/c++/15/initializer_list + /usr/include/c++/15/iomanip + /usr/include/c++/15/ios + /usr/include/c++/15/iosfwd + /usr/include/c++/15/iostream + /usr/include/c++/15/istream + /usr/include/c++/15/iterator + /usr/include/c++/15/limits + /usr/include/c++/15/locale + /usr/include/c++/15/map + /usr/include/c++/15/memory + /usr/include/c++/15/mutex + /usr/include/c++/15/new + /usr/include/c++/15/numeric + /usr/include/c++/15/optional + /usr/include/c++/15/ostream + /usr/include/c++/15/pstl/execution_defs.h + /usr/include/c++/15/pstl/glue_algorithm_defs.h + /usr/include/c++/15/pstl/glue_memory_defs.h + /usr/include/c++/15/pstl/glue_numeric_defs.h + /usr/include/c++/15/pstl/pstl_config.h + /usr/include/c++/15/random + /usr/include/c++/15/ratio + /usr/include/c++/15/set + /usr/include/c++/15/sstream + /usr/include/c++/15/stdexcept + /usr/include/c++/15/stdlib.h + /usr/include/c++/15/streambuf + /usr/include/c++/15/string + /usr/include/c++/15/string_view + /usr/include/c++/15/system_error + /usr/include/c++/15/thread + /usr/include/c++/15/tr1/bessel_function.tcc + /usr/include/c++/15/tr1/beta_function.tcc + /usr/include/c++/15/tr1/ell_integral.tcc + /usr/include/c++/15/tr1/exp_integral.tcc + /usr/include/c++/15/tr1/gamma.tcc + /usr/include/c++/15/tr1/hypergeometric.tcc + /usr/include/c++/15/tr1/legendre_function.tcc + /usr/include/c++/15/tr1/modified_bessel_func.tcc + /usr/include/c++/15/tr1/poly_hermite.tcc + /usr/include/c++/15/tr1/poly_laguerre.tcc + /usr/include/c++/15/tr1/riemann_zeta.tcc + /usr/include/c++/15/tr1/special_function_util.h + /usr/include/c++/15/tuple + /usr/include/c++/15/type_traits + /usr/include/c++/15/typeindex + /usr/include/c++/15/typeinfo + /usr/include/c++/15/unordered_map + /usr/include/c++/15/utility + /usr/include/c++/15/variant + /usr/include/c++/15/vector + /usr/include/c++/15/version + /usr/include/ctype.h + /usr/include/endian.h + /usr/include/errno.h + /usr/include/fcntl.h + /usr/include/features-time64.h + /usr/include/features.h + /usr/include/fenv.h + /usr/include/ifaddrs.h + /usr/include/inttypes.h + /usr/include/libintl.h + /usr/include/limits.h + /usr/include/linux/close_range.h + /usr/include/linux/errno.h + /usr/include/linux/falloc.h + /usr/include/linux/ioctl.h + /usr/include/linux/limits.h + /usr/include/linux/openat2.h + /usr/include/linux/posix_types.h + /usr/include/linux/sched/types.h + /usr/include/linux/sctp.h + /usr/include/linux/socket.h + /usr/include/linux/sockios.h + /usr/include/linux/stat.h + /usr/include/linux/stddef.h + /usr/include/linux/types.h + /usr/include/linux/version.h + /usr/include/locale.h + /usr/include/math.h + /usr/include/net/if.h + /usr/include/netdb.h + /usr/include/netinet/in.h + /usr/include/netinet/sctp.h + /usr/include/netinet/tcp.h + /usr/include/poll.h + /usr/include/pthread.h + /usr/include/regex.h + /usr/include/rpc/netdb.h + /usr/include/sched.h + /usr/include/signal.h + /usr/include/stdc-predef.h + /usr/include/stdint.h + /usr/include/stdio.h + /usr/include/stdlib.h + /usr/include/string.h + /usr/include/strings.h + /usr/include/syslog.h + /usr/include/termios.h + /usr/include/time.h + /usr/include/unistd.h + /usr/include/wchar.h + /usr/include/wctype.h + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h + /usr/include/x86_64-linux-gnu/asm/errno.h + /usr/include/x86_64-linux-gnu/asm/ioctl.h + /usr/include/x86_64-linux-gnu/asm/ioctls.h + /usr/include/x86_64-linux-gnu/asm/posix_types.h + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h + /usr/include/x86_64-linux-gnu/asm/socket.h + /usr/include/x86_64-linux-gnu/asm/sockios.h + /usr/include/x86_64-linux-gnu/asm/types.h + /usr/include/x86_64-linux-gnu/asm/unistd.h + /usr/include/x86_64-linux-gnu/asm/unistd_64.h + /usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h + /usr/include/x86_64-linux-gnu/bits/byteswap.h + /usr/include/x86_64-linux-gnu/bits/confname.h + /usr/include/x86_64-linux-gnu/bits/cpu-set.h + /usr/include/x86_64-linux-gnu/bits/endian.h + /usr/include/x86_64-linux-gnu/bits/endianness.h + /usr/include/x86_64-linux-gnu/bits/environments.h + /usr/include/x86_64-linux-gnu/bits/epoll.h + /usr/include/x86_64-linux-gnu/bits/errno.h + /usr/include/x86_64-linux-gnu/bits/eventfd.h + /usr/include/x86_64-linux-gnu/bits/fcntl-linux-fortify.h + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h + /usr/include/x86_64-linux-gnu/bits/fcntl.h + /usr/include/x86_64-linux-gnu/bits/fcntl2.h + /usr/include/x86_64-linux-gnu/bits/fenv.h + /usr/include/x86_64-linux-gnu/bits/floatn-common.h + /usr/include/x86_64-linux-gnu/bits/floatn.h + /usr/include/x86_64-linux-gnu/bits/flt-eval-method.h + /usr/include/x86_64-linux-gnu/bits/fp-fast.h + /usr/include/x86_64-linux-gnu/bits/fp-logb.h + /usr/include/x86_64-linux-gnu/bits/getopt_core.h + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h + /usr/include/x86_64-linux-gnu/bits/in.h + /usr/include/x86_64-linux-gnu/bits/inet-fortified-decl.h + /usr/include/x86_64-linux-gnu/bits/inet-fortified.h + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h + /usr/include/x86_64-linux-gnu/bits/ioctls.h + /usr/include/x86_64-linux-gnu/bits/iscanonical.h + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h + /usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h + /usr/include/x86_64-linux-gnu/bits/local_lim.h + /usr/include/x86_64-linux-gnu/bits/locale.h + /usr/include/x86_64-linux-gnu/bits/long-double.h + /usr/include/x86_64-linux-gnu/bits/math-vector.h + /usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h + /usr/include/x86_64-linux-gnu/bits/mathcalls-macros.h + /usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h + /usr/include/x86_64-linux-gnu/bits/mathcalls.h + /usr/include/x86_64-linux-gnu/bits/netdb.h + /usr/include/x86_64-linux-gnu/bits/openat2.h + /usr/include/x86_64-linux-gnu/bits/poll.h + /usr/include/x86_64-linux-gnu/bits/poll2.h + /usr/include/x86_64-linux-gnu/bits/posix1_lim.h + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h + /usr/include/x86_64-linux-gnu/bits/posix_opt.h + /usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h + /usr/include/x86_64-linux-gnu/bits/sched.h + /usr/include/x86_64-linux-gnu/bits/select-decl.h + /usr/include/x86_64-linux-gnu/bits/select.h + /usr/include/x86_64-linux-gnu/bits/select2.h + /usr/include/x86_64-linux-gnu/bits/setjmp.h + /usr/include/x86_64-linux-gnu/bits/sigaction.h + /usr/include/x86_64-linux-gnu/bits/sigcontext.h + /usr/include/x86_64-linux-gnu/bits/sigevent-consts.h + /usr/include/x86_64-linux-gnu/bits/siginfo-arch.h + /usr/include/x86_64-linux-gnu/bits/siginfo-consts-arch.h + /usr/include/x86_64-linux-gnu/bits/siginfo-consts.h + /usr/include/x86_64-linux-gnu/bits/signal_ext.h + /usr/include/x86_64-linux-gnu/bits/signum-arch.h + /usr/include/x86_64-linux-gnu/bits/signum-generic.h + /usr/include/x86_64-linux-gnu/bits/sigstack.h + /usr/include/x86_64-linux-gnu/bits/sigstksz.h + /usr/include/x86_64-linux-gnu/bits/sigthread.h + /usr/include/x86_64-linux-gnu/bits/sockaddr.h + /usr/include/x86_64-linux-gnu/bits/socket.h + /usr/include/x86_64-linux-gnu/bits/socket2.h + /usr/include/x86_64-linux-gnu/bits/socket_type.h + /usr/include/x86_64-linux-gnu/bits/ss_flags.h + /usr/include/x86_64-linux-gnu/bits/stat.h + /usr/include/x86_64-linux-gnu/bits/statx-generic.h + /usr/include/x86_64-linux-gnu/bits/statx.h + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h + /usr/include/x86_64-linux-gnu/bits/stdint-least.h + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h + /usr/include/x86_64-linux-gnu/bits/stdio.h + /usr/include/x86_64-linux-gnu/bits/stdio2-decl.h + /usr/include/x86_64-linux-gnu/bits/stdio2.h + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h + /usr/include/x86_64-linux-gnu/bits/stdlib.h + /usr/include/x86_64-linux-gnu/bits/string_fortified.h + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h + /usr/include/x86_64-linux-gnu/bits/struct_stat.h + /usr/include/x86_64-linux-gnu/bits/syscall.h + /usr/include/x86_64-linux-gnu/bits/syslog-decl.h + /usr/include/x86_64-linux-gnu/bits/syslog-path.h + /usr/include/x86_64-linux-gnu/bits/syslog.h + /usr/include/x86_64-linux-gnu/bits/termios-baud.h + /usr/include/x86_64-linux-gnu/bits/termios-c_cc.h + /usr/include/x86_64-linux-gnu/bits/termios-c_cflag.h + /usr/include/x86_64-linux-gnu/bits/termios-c_iflag.h + /usr/include/x86_64-linux-gnu/bits/termios-c_lflag.h + /usr/include/x86_64-linux-gnu/bits/termios-c_oflag.h + /usr/include/x86_64-linux-gnu/bits/termios-cbaud.h + /usr/include/x86_64-linux-gnu/bits/termios-misc.h + /usr/include/x86_64-linux-gnu/bits/termios-struct.h + /usr/include/x86_64-linux-gnu/bits/termios-tcflow.h + /usr/include/x86_64-linux-gnu/bits/termios.h + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h + /usr/include/x86_64-linux-gnu/bits/time.h + /usr/include/x86_64-linux-gnu/bits/time64.h + /usr/include/x86_64-linux-gnu/bits/timerfd.h + /usr/include/x86_64-linux-gnu/bits/timesize.h + /usr/include/x86_64-linux-gnu/bits/timex.h + /usr/include/x86_64-linux-gnu/bits/types.h + /usr/include/x86_64-linux-gnu/bits/types/FILE.h + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h + /usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h + /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h + /usr/include/x86_64-linux-gnu/bits/types/error_t.h + /usr/include/x86_64-linux-gnu/bits/types/idtype_t.h + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h + /usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h + /usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigval_t.h + /usr/include/x86_64-linux-gnu/bits/types/stack_t.h + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h + /usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h + /usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h + /usr/include/x86_64-linux-gnu/bits/types/struct_statx.h + /usr/include/x86_64-linux-gnu/bits/types/struct_statx_timestamp.h + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h + /usr/include/x86_64-linux-gnu/bits/types/time_t.h + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h + /usr/include/x86_64-linux-gnu/bits/types/wint_t.h + /usr/include/x86_64-linux-gnu/bits/typesizes.h + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h + /usr/include/x86_64-linux-gnu/bits/uio-ext.h + /usr/include/x86_64-linux-gnu/bits/uio_lim.h + /usr/include/x86_64-linux-gnu/bits/unistd-decl.h + /usr/include/x86_64-linux-gnu/bits/unistd.h + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h + /usr/include/x86_64-linux-gnu/bits/utsname.h + /usr/include/x86_64-linux-gnu/bits/waitflags.h + /usr/include/x86_64-linux-gnu/bits/waitstatus.h + /usr/include/x86_64-linux-gnu/bits/wchar.h + /usr/include/x86_64-linux-gnu/bits/wchar2-decl.h + /usr/include/x86_64-linux-gnu/bits/wchar2.h + /usr/include/x86_64-linux-gnu/bits/wctype-wchar.h + /usr/include/x86_64-linux-gnu/bits/wordsize.h + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h + /usr/include/x86_64-linux-gnu/c++/15/bits/atomic_word.h + /usr/include/x86_64-linux-gnu/c++/15/bits/basic_file.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++allocator.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++config.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++io.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++locale.h + /usr/include/x86_64-linux-gnu/c++/15/bits/cpu_defines.h + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_base.h + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_inline.h + /usr/include/x86_64-linux-gnu/c++/15/bits/cxxabi_tweaks.h + /usr/include/x86_64-linux-gnu/c++/15/bits/error_constants.h + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr-default.h + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr.h + /usr/include/x86_64-linux-gnu/c++/15/bits/messages_members.h + /usr/include/x86_64-linux-gnu/c++/15/bits/opt_random.h + /usr/include/x86_64-linux-gnu/c++/15/bits/os_defines.h + /usr/include/x86_64-linux-gnu/c++/15/bits/time_members.h + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h + /usr/include/x86_64-linux-gnu/gnu/stubs.h + /usr/include/x86_64-linux-gnu/sys/cdefs.h + /usr/include/x86_64-linux-gnu/sys/epoll.h + /usr/include/x86_64-linux-gnu/sys/eventfd.h + /usr/include/x86_64-linux-gnu/sys/ioctl.h + /usr/include/x86_64-linux-gnu/sys/poll.h + /usr/include/x86_64-linux-gnu/sys/select.h + /usr/include/x86_64-linux-gnu/sys/single_threaded.h + /usr/include/x86_64-linux-gnu/sys/socket.h + /usr/include/x86_64-linux-gnu/sys/stat.h + /usr/include/x86_64-linux-gnu/sys/syscall.h + /usr/include/x86_64-linux-gnu/sys/syslog.h + /usr/include/x86_64-linux-gnu/sys/timerfd.h + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h + /usr/include/x86_64-linux-gnu/sys/types.h + /usr/include/x86_64-linux-gnu/sys/ucontext.h + /usr/include/x86_64-linux-gnu/sys/uio.h + /usr/include/x86_64-linux-gnu/sys/un.h + /usr/include/x86_64-linux-gnu/sys/utsname.h + /usr/include/x86_64-linux-gnu/sys/wait.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/adxintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/ammintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxavx512intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxbf16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxcomplexintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxfp16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxfp8intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxint8intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxmovrsintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxtf32intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxtileintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxtransposeintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512bf16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512convertintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512mediaintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512minmaxintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512satcvtintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2bf16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2convertintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2copyintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2mediaintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2minmaxintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2satcvtintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx2intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bf16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bf16vlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bitalgintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bitalgvlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bwintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512cdintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512dqintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fp16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fp16vlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512ifmaintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512ifmavlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmi2intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmi2vlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmiintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmivlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vlbwintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vldqintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vnniintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vnnivlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vp2intersectintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vp2intersectvlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vpopcntdqintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vpopcntdqvlintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxifmaintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxneconvertintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniint16intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniint8intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/bmi2intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/bmiintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/cetintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/cldemoteintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/clflushoptintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/clwbintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/clzerointrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/cmpccxaddintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/emmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/enqcmdintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/f16cintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/float.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/fma4intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/fmaintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/fxsrintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/gfniintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/hresetintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/ia32intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/immintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/keylockerintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/limits.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/lwpintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/lzcntintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/mm3dnow.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/mm_malloc.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/mmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/movdirintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/movrsintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/mwaitintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/mwaitxintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/pconfigintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/pkuintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/pmmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/popcntintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/prfchiintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/prfchwintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/raointintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/rdseedintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/rtmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/serializeintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/sgxintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/sha512intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/shaintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/sm3intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/sm4intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/smmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdarg.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/syslimits.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/tbmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/tmmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/tsxldtrkintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/uintrintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/usermsrintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/vaesintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/vpclmulqdqintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/waitpkgintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/wbnoinvdintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/wmmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/x86gprintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/x86intrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xmmintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xopintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsavecintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsaveintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsaveoptintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsavesintrin.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/xtestintrin.h + diff --git a/test/build-asan/CMakeFiles/share_runtime_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/share_runtime_test.dir/compiler_depend.make new file mode 100644 index 0000000..9f0b8c9 --- /dev/null +++ b/test/build-asan/CMakeFiles/share_runtime_test.dir/compiler_depend.make @@ -0,0 +1,3661 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/aligned_allocator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_flow.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_plans.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_runtime.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/async_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/beaver.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit_array.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit_inject.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/bitstring.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/blob.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/buffered_prg.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/circuit.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/compose.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/compose_async.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/cost_pass.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/edabit.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/experiment.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/experiment_note.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/factory_gadgets.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/factory_tapes.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/fixed_share.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/fp61.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/gilboa.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/leaf_arithmetic.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/leaf_node.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/literals.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/log.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/matmul.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/mesh_apps.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/modint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/asio_ns.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_round_sink.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_sctp_stream_array.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_stream_array.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/buffer_pool.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/channel.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/connect.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/dealer_cursor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/edge_mesh.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/io_pool.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/link_log.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/memory_sink.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/party_session.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/policy.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/round_lane.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/round_sink.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/sink_exchange.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/socket_tune.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_array.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_edge_mesh.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_mesh.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/tcp_mesh.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/nyble.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/online_session.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/ot_pack.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/packed_lane.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/packed_lane_arithmetic.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/pad_graphs.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/party_run.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/party_runner.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/placement.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prep_source.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_aes.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_aes_ccr.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_chacha.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_count.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_dummy.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_lowmc.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol_factory.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol_roles.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/random.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/revealing.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/rss_seed.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/run_config.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/run_log.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/schedule_streams.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/secret_share.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/session_host.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/shamir.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/share_cmp.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/share_expr.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/share_vec.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/shuffle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/trunc.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/twiddle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/twobit.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/uint256_t.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/utils.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/verifiable.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/wildcard.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/dpf/xor_wrapper.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/grotto/fixedpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/include/grotto/fixedpoint_mul.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_completion_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_completion_handler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_io_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/append.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/as_tuple.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_allocator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_cancellation_slot.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_immediate_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/async_result.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/awaitable.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_datagram_socket.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_deadline_timer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_file.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_io_object.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_random_access_file.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_raw_socket.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_readable_pipe.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_seq_packet_socket.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_serial_port.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_signal_set.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_acceptor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_iostream.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_streambuf.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_stream_file.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_stream_socket.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_streambuf.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_streambuf_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_waitable_timer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_writable_pipe.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_allocator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_cancellation_slot.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_immediate_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffer_registration.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_read_stream.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_read_stream_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_stream.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_stream_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_write_stream.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_write_stream_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffers_iterator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_signal.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_state.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_type.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/co_spawn.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/completion_condition.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/compose.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/connect.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/connect_pipe.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/consign.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/coroutine.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/deadline_timer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/defer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/deferred.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detached.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/array.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/array_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/assert.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/atomic_count.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/base_from_cancellation_state.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/base_from_completion_cond.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/bind_handler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/blocking_executor_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffer_resize_guard.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffer_sequence_adapter.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffered_stream_storage.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/bulk_executor_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/call_stack.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/chrono.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/chrono_time_traits.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/completion_handler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/composed_work.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/concurrency_hint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/conditionally_enabled_event.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/conditionally_enabled_mutex.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/config.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/consuming_buffers.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/cstddef.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/cstdint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/date_time_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/deadline_timer_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/dependent_type.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_ops.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_read_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_write_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/epoll_reactor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/event.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/eventfd_select_interrupter.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/executor_function.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/executor_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/fenced_block.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/functional.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/future.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/global.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_alloc_helpers.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_cont_helpers.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_invoke_helpers.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_tracking.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_type_requirements.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_work.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/descriptor_ops.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/epoll_reactor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/epoll_reactor.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/eventfd_select_interrupter.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/handler_tracking.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/null_event.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_event.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_mutex.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_serial_port_service.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_thread.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/reactive_descriptor_service.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/reactive_socket_service_base.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/resolver_service_base.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/scheduler.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/service_registry.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/service_registry.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/signal_set_service.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/socket_ops.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_executor_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_executor_service.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_service.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/thread_context.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/throw_error.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/timer_queue_set.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_defer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_dispatch.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_post.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/io_control.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/io_object_impl.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/is_buffer_sequence.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/is_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/keyword_tss_ptr.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/limits.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/local_free_on_block_exit.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/memory.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/mutex.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/non_const_lvalue.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/noncopyable.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/null_event.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/object_pool.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/op_queue.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/operation.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/pop_options.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_event.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_global.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_mutex.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_serial_port_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_signal_blocker.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_static_mutex.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_thread.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/push_options.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_descriptor_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_null_buffers_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_accept_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_connect_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recv_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recvfrom_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recvmsg_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_send_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_sendto_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_service_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_wait_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactor_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/recycling_allocator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/regex_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_endpoint_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_query_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolver_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolver_service_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_operation.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_task.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_thread_info.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scoped_lock.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scoped_ptr.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/select_interrupter.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/service_registry.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_blocker.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_handler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_set_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_holder.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_ops.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_option.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_types.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/static_mutex.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/std_fenced_block.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/strand_executor_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/strand_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/string_view.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_group.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_info_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/throw_error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/throw_exception.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_ptime.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_set.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_scheduler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_scheduler_fwd.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/tss_ptr.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/type_traits.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/utility.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/variadic_templates.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wait_handler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wait_op.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/winsock_init.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/work_dispatcher.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wrapped_handler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/dispatch.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/error_code.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/allocator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/any_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bad_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/blocking.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/blocking_adaptation.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bulk_execute.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bulk_guarantee.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/connect.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/context_as.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_invocable.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_operation.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_receiver.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/bulk_sender.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/submit_receiver.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/void_receiver.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/execute.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/impl/bad_executor.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/impl/receiver_invocation_error.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/invocable_archetype.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/mapping.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/occupancy.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/operation_state.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/outstanding_work.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/prefer_only.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/receiver.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/receiver_invocation_error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/relationship.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/schedule.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/scheduler.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/sender.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_done.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_value.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/start.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/submit.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/executor_work_guard.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/file_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/basic_endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/datagram_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/detail/endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/detail/impl/endpoint.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/raw_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/seq_packet_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/stream_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_alloc_hook.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_continuation_hook.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_invoke_hook.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/high_resolution_timer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/any_completion_executor.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/any_io_executor.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/append.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/as_tuple.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/buffered_read_stream.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/buffered_write_stream.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/cancellation_signal.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect_pipe.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect_pipe.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/consign.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/deferred.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/detached.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/error.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/error_code.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/execution_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/execution_context.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/executor.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/handler_alloc_hook.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/io_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/io_context.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/multiple_exceptions.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/prepend.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read_at.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read_until.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/redirect_error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/serial_port_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/serial_port_base.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_context.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/thread_pool.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/thread_pool.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/use_future.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/write.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/write_at.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_context_strand.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_service.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_service_strand.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4_iterator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4_range.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6_iterator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6_range.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/bad_address_cast.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_entry.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_iterator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_query.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_results.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/impl/endpoint.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/socket_option.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/host_name.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/icmp.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v4.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v4.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v6.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v6.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/basic_endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/host_name.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v4.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v4.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v6.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v6.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/multicast.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/network_v4.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/network_v6.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/resolver_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/resolver_query_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/tcp.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/udp.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/unicast.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/v6_only.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_applicable_property.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_contiguous_iterator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_read_buffered.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_write_buffered.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/basic_endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/connect_pair.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/datagram_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/detail/endpoint.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/detail/impl/endpoint.ipp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/seq_packet_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/stream_protocol.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/multiple_exceptions.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/packaged_task.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/placeholders.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/basic_descriptor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/basic_stream_descriptor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/descriptor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/descriptor_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/stream_descriptor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/post.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/prefer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/prepend.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/query.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/random_access_file.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read_at.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read_until.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/readable_pipe.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/recycling_allocator.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/redirect_error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/registered_buffer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/require.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/require_concept.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/serial_port.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/serial_port_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/signal_set.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/signal_set_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/socket_base.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/static_thread_pool.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/steady_timer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/strand.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/stream_file.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/streambuf.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_context.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_error.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_timer.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/this_coro.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/thread.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/thread_pool.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/time_traits.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/bulk_execute_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/bulk_execute_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/connect_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/connect_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/equality_comparable.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/execute_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/execute_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/prefer_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/prefer_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_static_constexpr_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_concept_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_concept_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/schedule_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/schedule_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_done_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_done_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_error_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_error_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_value_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_value_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/start_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/start_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_query.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_require.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_require_concept.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/submit_free.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/submit_member.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/use_awaitable.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/use_future.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/uses_executor.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/version.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/wait_traits.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_object_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_overlapped_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_random_access_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_stream_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/object_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/overlapped_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/overlapped_ptr.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/random_access_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/stream_handle.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/writable_pipe.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/write.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/write_at.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/libutil.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/stdio.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/stdlib.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/unistd.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/hash-library/sha256.cpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/hash-library/sha256.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/hedley/hedley.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/lowmc/LowMC.cpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/lowmc/LowMC.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/builtin/builtin.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/endian/endian.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/exact-int/exact-int.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/check.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/debug-trap.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/hedley.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-align.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-arch.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-common.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-constify.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-detect-clang.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-diagnostic.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-f16.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-features.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-math.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/avx.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/avx2.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/mmx.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse2.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse3.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse4.1.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse4.2.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/ssse3.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/endianness.h \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/uint128_t.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/uint256_t.hpp \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-assertion-result.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-death-test.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-matchers.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-message.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-param-test.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-printers.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-test-part.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-typed-test.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_pred_impl.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_prod.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-port.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-printers.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-filepath.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-internal.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-param-util.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port-arch.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-string.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-type-util.h \ + /usr/include/alloca.h \ + /usr/include/arpa/inet.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/asm-generic/errno-base.h \ + /usr/include/asm-generic/errno.h \ + /usr/include/asm-generic/int-ll64.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/asm-generic/ioctls.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/asm-generic/types.h \ + /usr/include/assert.h \ + /usr/include/c++/15/algorithm \ + /usr/include/c++/15/any \ + /usr/include/c++/15/array \ + /usr/include/c++/15/atomic \ + /usr/include/c++/15/backward/auto_ptr.h \ + /usr/include/c++/15/backward/binders.h \ + /usr/include/c++/15/bit \ + /usr/include/c++/15/bits/algorithmfwd.h \ + /usr/include/c++/15/bits/align.h \ + /usr/include/c++/15/bits/alloc_traits.h \ + /usr/include/c++/15/bits/allocated_ptr.h \ + /usr/include/c++/15/bits/allocator.h \ + /usr/include/c++/15/bits/atomic_base.h \ + /usr/include/c++/15/bits/atomic_futex.h \ + /usr/include/c++/15/bits/atomic_lockfree_defines.h \ + /usr/include/c++/15/bits/basic_ios.h \ + /usr/include/c++/15/bits/basic_ios.tcc \ + /usr/include/c++/15/bits/basic_string.h \ + /usr/include/c++/15/bits/basic_string.tcc \ + /usr/include/c++/15/bits/char_traits.h \ + /usr/include/c++/15/bits/charconv.h \ + /usr/include/c++/15/bits/chrono.h \ + /usr/include/c++/15/bits/codecvt.h \ + /usr/include/c++/15/bits/concept_check.h \ + /usr/include/c++/15/bits/cpp_type_traits.h \ + /usr/include/c++/15/bits/cxxabi_forced.h \ + /usr/include/c++/15/bits/cxxabi_init_exception.h \ + /usr/include/c++/15/bits/deque.tcc \ + /usr/include/c++/15/bits/enable_special_members.h \ + /usr/include/c++/15/bits/erase_if.h \ + /usr/include/c++/15/bits/exception.h \ + /usr/include/c++/15/bits/exception_defines.h \ + /usr/include/c++/15/bits/exception_ptr.h \ + /usr/include/c++/15/bits/fstream.tcc \ + /usr/include/c++/15/bits/functexcept.h \ + /usr/include/c++/15/bits/functional_hash.h \ + /usr/include/c++/15/bits/hash_bytes.h \ + /usr/include/c++/15/bits/hashtable.h \ + /usr/include/c++/15/bits/hashtable_policy.h \ + /usr/include/c++/15/bits/invoke.h \ + /usr/include/c++/15/bits/ios_base.h \ + /usr/include/c++/15/bits/istream.tcc \ + /usr/include/c++/15/bits/locale_classes.h \ + /usr/include/c++/15/bits/locale_classes.tcc \ + /usr/include/c++/15/bits/locale_conv.h \ + /usr/include/c++/15/bits/locale_facets.h \ + /usr/include/c++/15/bits/locale_facets.tcc \ + /usr/include/c++/15/bits/locale_facets_nonio.h \ + /usr/include/c++/15/bits/locale_facets_nonio.tcc \ + /usr/include/c++/15/bits/localefwd.h \ + /usr/include/c++/15/bits/memory_resource.h \ + /usr/include/c++/15/bits/memoryfwd.h \ + /usr/include/c++/15/bits/monostate.h \ + /usr/include/c++/15/bits/move.h \ + /usr/include/c++/15/bits/nested_exception.h \ + /usr/include/c++/15/bits/new_allocator.h \ + /usr/include/c++/15/bits/node_handle.h \ + /usr/include/c++/15/bits/ostream.h \ + /usr/include/c++/15/bits/ostream.tcc \ + /usr/include/c++/15/bits/ostream_insert.h \ + /usr/include/c++/15/bits/parse_numbers.h \ + /usr/include/c++/15/bits/postypes.h \ + /usr/include/c++/15/bits/predefined_ops.h \ + /usr/include/c++/15/bits/ptr_traits.h \ + /usr/include/c++/15/bits/quoted_string.h \ + /usr/include/c++/15/bits/random.h \ + /usr/include/c++/15/bits/random.tcc \ + /usr/include/c++/15/bits/range_access.h \ + /usr/include/c++/15/bits/refwrap.h \ + /usr/include/c++/15/bits/requires_hosted.h \ + /usr/include/c++/15/bits/shared_ptr.h \ + /usr/include/c++/15/bits/shared_ptr_atomic.h \ + /usr/include/c++/15/bits/shared_ptr_base.h \ + /usr/include/c++/15/bits/specfun.h \ + /usr/include/c++/15/bits/sstream.tcc \ + /usr/include/c++/15/bits/std_abs.h \ + /usr/include/c++/15/bits/std_function.h \ + /usr/include/c++/15/bits/std_mutex.h \ + /usr/include/c++/15/bits/std_thread.h \ + /usr/include/c++/15/bits/stl_algo.h \ + /usr/include/c++/15/bits/stl_algobase.h \ + /usr/include/c++/15/bits/stl_bvector.h \ + /usr/include/c++/15/bits/stl_construct.h \ + /usr/include/c++/15/bits/stl_deque.h \ + /usr/include/c++/15/bits/stl_function.h \ + /usr/include/c++/15/bits/stl_heap.h \ + /usr/include/c++/15/bits/stl_iterator.h \ + /usr/include/c++/15/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/15/bits/stl_iterator_base_types.h \ + /usr/include/c++/15/bits/stl_map.h \ + /usr/include/c++/15/bits/stl_multimap.h \ + /usr/include/c++/15/bits/stl_multiset.h \ + /usr/include/c++/15/bits/stl_numeric.h \ + /usr/include/c++/15/bits/stl_pair.h \ + /usr/include/c++/15/bits/stl_raw_storage_iter.h \ + /usr/include/c++/15/bits/stl_relops.h \ + /usr/include/c++/15/bits/stl_set.h \ + /usr/include/c++/15/bits/stl_tempbuf.h \ + /usr/include/c++/15/bits/stl_tree.h \ + /usr/include/c++/15/bits/stl_uninitialized.h \ + /usr/include/c++/15/bits/stl_vector.h \ + /usr/include/c++/15/bits/stream_iterator.h \ + /usr/include/c++/15/bits/streambuf.tcc \ + /usr/include/c++/15/bits/streambuf_iterator.h \ + /usr/include/c++/15/bits/string_view.tcc \ + /usr/include/c++/15/bits/stringfwd.h \ + /usr/include/c++/15/bits/this_thread_sleep.h \ + /usr/include/c++/15/bits/uniform_int_dist.h \ + /usr/include/c++/15/bits/unique_lock.h \ + /usr/include/c++/15/bits/unique_ptr.h \ + /usr/include/c++/15/bits/unordered_map.h \ + /usr/include/c++/15/bits/uses_allocator.h \ + /usr/include/c++/15/bits/uses_allocator_args.h \ + /usr/include/c++/15/bits/utility.h \ + /usr/include/c++/15/bits/vector.tcc \ + /usr/include/c++/15/bits/version.h \ + /usr/include/c++/15/bitset \ + /usr/include/c++/15/cassert \ + /usr/include/c++/15/cctype \ + /usr/include/c++/15/cerrno \ + /usr/include/c++/15/cfenv \ + /usr/include/c++/15/chrono \ + /usr/include/c++/15/cinttypes \ + /usr/include/c++/15/climits \ + /usr/include/c++/15/clocale \ + /usr/include/c++/15/cmath \ + /usr/include/c++/15/compare \ + /usr/include/c++/15/concepts \ + /usr/include/c++/15/condition_variable \ + /usr/include/c++/15/csignal \ + /usr/include/c++/15/cstddef \ + /usr/include/c++/15/cstdint \ + /usr/include/c++/15/cstdio \ + /usr/include/c++/15/cstdlib \ + /usr/include/c++/15/cstring \ + /usr/include/c++/15/ctime \ + /usr/include/c++/15/cwchar \ + /usr/include/c++/15/cwctype \ + /usr/include/c++/15/cxxabi.h \ + /usr/include/c++/15/debug/assertions.h \ + /usr/include/c++/15/debug/debug.h \ + /usr/include/c++/15/deque \ + /usr/include/c++/15/exception \ + /usr/include/c++/15/ext/aligned_buffer.h \ + /usr/include/c++/15/ext/alloc_traits.h \ + /usr/include/c++/15/ext/atomicity.h \ + /usr/include/c++/15/ext/concurrence.h \ + /usr/include/c++/15/ext/numeric_traits.h \ + /usr/include/c++/15/ext/string_conversions.h \ + /usr/include/c++/15/ext/type_traits.h \ + /usr/include/c++/15/fenv.h \ + /usr/include/c++/15/fstream \ + /usr/include/c++/15/functional \ + /usr/include/c++/15/future \ + /usr/include/c++/15/initializer_list \ + /usr/include/c++/15/iomanip \ + /usr/include/c++/15/ios \ + /usr/include/c++/15/iosfwd \ + /usr/include/c++/15/iostream \ + /usr/include/c++/15/istream \ + /usr/include/c++/15/iterator \ + /usr/include/c++/15/limits \ + /usr/include/c++/15/locale \ + /usr/include/c++/15/map \ + /usr/include/c++/15/memory \ + /usr/include/c++/15/mutex \ + /usr/include/c++/15/new \ + /usr/include/c++/15/numeric \ + /usr/include/c++/15/optional \ + /usr/include/c++/15/ostream \ + /usr/include/c++/15/pstl/execution_defs.h \ + /usr/include/c++/15/pstl/glue_algorithm_defs.h \ + /usr/include/c++/15/pstl/glue_memory_defs.h \ + /usr/include/c++/15/pstl/glue_numeric_defs.h \ + /usr/include/c++/15/pstl/pstl_config.h \ + /usr/include/c++/15/random \ + /usr/include/c++/15/ratio \ + /usr/include/c++/15/set \ + /usr/include/c++/15/sstream \ + /usr/include/c++/15/stdexcept \ + /usr/include/c++/15/stdlib.h \ + /usr/include/c++/15/streambuf \ + /usr/include/c++/15/string \ + /usr/include/c++/15/string_view \ + /usr/include/c++/15/system_error \ + /usr/include/c++/15/thread \ + /usr/include/c++/15/tr1/bessel_function.tcc \ + /usr/include/c++/15/tr1/beta_function.tcc \ + /usr/include/c++/15/tr1/ell_integral.tcc \ + /usr/include/c++/15/tr1/exp_integral.tcc \ + /usr/include/c++/15/tr1/gamma.tcc \ + /usr/include/c++/15/tr1/hypergeometric.tcc \ + /usr/include/c++/15/tr1/legendre_function.tcc \ + /usr/include/c++/15/tr1/modified_bessel_func.tcc \ + /usr/include/c++/15/tr1/poly_hermite.tcc \ + /usr/include/c++/15/tr1/poly_laguerre.tcc \ + /usr/include/c++/15/tr1/riemann_zeta.tcc \ + /usr/include/c++/15/tr1/special_function_util.h \ + /usr/include/c++/15/tuple \ + /usr/include/c++/15/type_traits \ + /usr/include/c++/15/typeindex \ + /usr/include/c++/15/typeinfo \ + /usr/include/c++/15/unordered_map \ + /usr/include/c++/15/utility \ + /usr/include/c++/15/variant \ + /usr/include/c++/15/vector \ + /usr/include/c++/15/version \ + /usr/include/ctype.h \ + /usr/include/endian.h \ + /usr/include/errno.h \ + /usr/include/fcntl.h \ + /usr/include/features-time64.h \ + /usr/include/features.h \ + /usr/include/fenv.h \ + /usr/include/ifaddrs.h \ + /usr/include/inttypes.h \ + /usr/include/libintl.h \ + /usr/include/limits.h \ + /usr/include/linux/close_range.h \ + /usr/include/linux/errno.h \ + /usr/include/linux/falloc.h \ + /usr/include/linux/ioctl.h \ + /usr/include/linux/limits.h \ + /usr/include/linux/openat2.h \ + /usr/include/linux/posix_types.h \ + /usr/include/linux/sched/types.h \ + /usr/include/linux/sctp.h \ + /usr/include/linux/socket.h \ + /usr/include/linux/sockios.h \ + /usr/include/linux/stat.h \ + /usr/include/linux/stddef.h \ + /usr/include/linux/types.h \ + /usr/include/linux/version.h \ + /usr/include/locale.h \ + /usr/include/math.h \ + /usr/include/net/if.h \ + /usr/include/netdb.h \ + /usr/include/netinet/in.h \ + /usr/include/netinet/sctp.h \ + /usr/include/netinet/tcp.h \ + /usr/include/poll.h \ + /usr/include/pthread.h \ + /usr/include/regex.h \ + /usr/include/rpc/netdb.h \ + /usr/include/sched.h \ + /usr/include/signal.h \ + /usr/include/stdc-predef.h \ + /usr/include/stdint.h \ + /usr/include/stdio.h \ + /usr/include/stdlib.h \ + /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/syslog.h \ + /usr/include/termios.h \ + /usr/include/time.h \ + /usr/include/unistd.h \ + /usr/include/wchar.h \ + /usr/include/wctype.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/x86_64-linux-gnu/asm/unistd.h \ + /usr/include/x86_64-linux-gnu/asm/unistd_64.h \ + /usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/epoll.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/x86_64-linux-gnu/bits/eventfd.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux-fortify.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl2.h \ + /usr/include/x86_64-linux-gnu/bits/fenv.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/flt-eval-method.h \ + /usr/include/x86_64-linux-gnu/bits/fp-fast.h \ + /usr/include/x86_64-linux-gnu/bits/fp-logb.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/in.h \ + /usr/include/x86_64-linux-gnu/bits/inet-fortified-decl.h \ + /usr/include/x86_64-linux-gnu/bits/inet-fortified.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/bits/iscanonical.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/bits/math-vector.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls-macros.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/openat2.h \ + /usr/include/x86_64-linux-gnu/bits/poll.h \ + /usr/include/x86_64-linux-gnu/bits/poll2.h \ + /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/select-decl.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigevent-consts.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-arch.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-consts-arch.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-consts.h \ + /usr/include/x86_64-linux-gnu/bits/signal_ext.h \ + /usr/include/x86_64-linux-gnu/bits/signum-arch.h \ + /usr/include/x86_64-linux-gnu/bits/signum-generic.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/sigstksz.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/ss_flags.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h \ + /usr/include/x86_64-linux-gnu/bits/statx-generic.h \ + /usr/include/x86_64-linux-gnu/bits/statx.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2-decl.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/struct_stat.h \ + /usr/include/x86_64-linux-gnu/bits/syscall.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-decl.h \ + /usr/include/x86_64-linux-gnu/bits/syslog-path.h \ + /usr/include/x86_64-linux-gnu/bits/syslog.h \ + /usr/include/x86_64-linux-gnu/bits/termios-baud.h \ + /usr/include/x86_64-linux-gnu/bits/termios-c_cc.h \ + /usr/include/x86_64-linux-gnu/bits/termios-c_cflag.h \ + /usr/include/x86_64-linux-gnu/bits/termios-c_iflag.h \ + /usr/include/x86_64-linux-gnu/bits/termios-c_lflag.h \ + /usr/include/x86_64-linux-gnu/bits/termios-c_oflag.h \ + /usr/include/x86_64-linux-gnu/bits/termios-cbaud.h \ + /usr/include/x86_64-linux-gnu/bits/termios-misc.h \ + /usr/include/x86_64-linux-gnu/bits/termios-struct.h \ + /usr/include/x86_64-linux-gnu/bits/termios-tcflow.h \ + /usr/include/x86_64-linux-gnu/bits/termios.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/timerfd.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/error_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/idtype_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/stack_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_statx.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_statx_timestamp.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/wint_t.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/bits/uio-ext.h \ + /usr/include/x86_64-linux-gnu/bits/uio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/unistd-decl.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h \ + /usr/include/x86_64-linux-gnu/bits/utsname.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2-decl.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2.h \ + /usr/include/x86_64-linux-gnu/bits/wctype-wchar.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/atomic_word.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/basic_file.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++allocator.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++config.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++io.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++locale.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/cpu_defines.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_base.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_inline.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/cxxabi_tweaks.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/error_constants.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr-default.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/messages_members.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/opt_random.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/os_defines.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/time_members.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/sys/epoll.h \ + /usr/include/x86_64-linux-gnu/sys/eventfd.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/sys/poll.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/sys/single_threaded.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/syscall.h \ + /usr/include/x86_64-linux-gnu/sys/syslog.h \ + /usr/include/x86_64-linux-gnu/sys/timerfd.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/sys/uio.h \ + /usr/include/x86_64-linux-gnu/sys/un.h \ + /usr/include/x86_64-linux-gnu/sys/utsname.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/adxintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/ammintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxavx512intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxbf16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxcomplexintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxfp16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxfp8intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxint8intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxmovrsintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxtf32intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxtileintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/amxtransposeintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512bf16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512convertintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512mediaintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512minmaxintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512satcvtintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2bf16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2convertintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2copyintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2mediaintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2minmaxintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2satcvtintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx2intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bf16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bf16vlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bitalgintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bitalgvlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bwintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512cdintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512dqintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fp16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fp16vlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512ifmaintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512ifmavlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmi2intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmi2vlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmiintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmivlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vlbwintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vldqintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vnniintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vnnivlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vp2intersectintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vp2intersectvlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vpopcntdqintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vpopcntdqvlintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxifmaintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxneconvertintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniint16intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniint8intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/bmi2intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/bmiintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/cetintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/cldemoteintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/clflushoptintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/clwbintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/clzerointrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/cmpccxaddintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/emmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/enqcmdintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/f16cintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/float.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/fma4intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/fmaintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/fxsrintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/gfniintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/hresetintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/ia32intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/immintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/keylockerintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/lwpintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/lzcntintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/mm3dnow.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/mm_malloc.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/mmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/movdirintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/movrsintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/mwaitintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/mwaitxintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/pconfigintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/pkuintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/pmmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/popcntintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/prfchiintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/prfchwintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/raointintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/rdseedintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/rtmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/serializeintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/sgxintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/sha512intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/shaintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/sm3intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/sm4intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/smmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdarg.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/syslimits.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/tbmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/tmmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/tsxldtrkintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/uintrintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/usermsrintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/vaesintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/vpclmulqdqintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/waitpkgintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/wbnoinvdintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/wmmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/x86gprintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/x86intrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xmmintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xopintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsavecintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsaveintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsaveoptintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xsavesintrin.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/xtestintrin.h + + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xtestintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xsaveoptintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xsaveintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xopintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xmmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/x86intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/x86gprintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/wmmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/wbnoinvdintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/vaesintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/usermsrintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/tsxldtrkintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/tmmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/tbmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/syslimits.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/smmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/sm3intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/shaintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/serializeintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/rdseedintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/raointintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/prfchwintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/prfchiintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/popcntintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/pconfigintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/mwaitxintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/mwaitintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/movrsintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/movdirintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/mm_malloc.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/keylockerintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/immintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/ia32intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/gfniintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/fxsrintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/fmaintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/enqcmdintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/emmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/cmpccxaddintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/clzerointrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/cetintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/bmiintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avxifmaintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vpopcntdqvlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vp2intersectvlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vnnivlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmiintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmi2vlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmi2intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512ifmavlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512ifmaintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fp16vlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fp16intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/rtmintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512cdintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bwintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bitalgvlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bf16vlintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bf16intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2minmaxintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2convertintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2bf16intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512minmaxintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512mediaintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_require.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-common.h: + +/usr/include/x86_64-linux-gnu/bits/flt-eval-method.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/schedule_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_value_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_concept_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/bulk_execute_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/time_traits.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_timer.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/execute_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_ptime.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_error.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/signal_set.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_context.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/waitpkgintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/string_view.hpp: + +/usr/include/c++/15/concepts: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/serial_port.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/require_concept.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/registered_buffer.hpp: + +/usr/include/c++/15/tr1/poly_laguerre.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/random_access_file.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/multicast.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/descriptor_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/basic_descriptor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_concept_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/detail/impl/endpoint.ipp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2mediaintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_applicable_property.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/clflushoptintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/v6_only.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/fp61.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v4.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v4.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v4.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit_inject.hpp: + +/usr/include/linux/types.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_waitable_timer.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_prod.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/icmp.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/socket_option.hpp: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/mm3dnow.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/impl/endpoint.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/connect_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4_range.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4.hpp: + +/usr/include/c++/15/tr1/riemann_zeta.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/lowmc/LowMC.cpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/prefer_member.hpp: + +/usr/include/x86_64-linux-gnu/bits/fp-logb.h: + +/usr/include/x86_64-linux-gnu/bits/types/idtype_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_endpoint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/write.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/use_future.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_set_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/thread_pool.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_option.hpp: + +/usr/include/linux/close_range.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/overlapped_handle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/serial_port_base.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/serial_port_base.hpp: + +/usr/include/c++/15/bits/stl_multiset.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read_until.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512fintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/handler_alloc_hook.ipp: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/c++/15/bits/unordered_map.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/error_code.ipp: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/detached.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/stdarg.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-port.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/buffered_read_stream.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512satcvtintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/as_tuple.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/socket_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/thread.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/any_io_executor.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/timer_queue_set.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/any_completion_executor.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_invoke_hook.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/write_at.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_receiver.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/factory_gadgets.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/write.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/stream_protocol.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/select_interrupter.hpp: + +/usr/include/c++/15/string: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/sha512intrin.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/bmi2intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/asio_ns.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse2.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/redirect_error.hpp: + +/usr/include/c++/15/typeindex: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/datagram_protocol.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/system_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/basic_endpoint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/file_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/connect_pair.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/bitstring.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_value.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/executor_work_guard.hpp: + +/usr/include/c++/15/locale: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_error.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_event.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/set_done.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/prefer.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/float.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-path.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/schedule.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/receiver_invocation_error.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/prefer_only.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/connect_member.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/uintrintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/outstanding_work.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/exact-int/exact-int.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/operation_state.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/occupancy.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/experiment.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/mapping.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/invocable_archetype.hpp: + +/usr/include/linux/stat.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/impl/bad_executor.ipp: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/executor.hpp: + +/usr/include/regex.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/sm4intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_query.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/execute.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/detail/endpoint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_context.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/submit_receiver.hpp: + +/usr/include/c++/15/cstdio: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/connect.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/stream_protocol.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bulk_guarantee.hpp: + +/usr/include/netinet/sctp.h: + +/usr/include/c++/15/tr1/bessel_function.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6_iterator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-printers.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bad_executor.hpp: + +/usr/include/c++/15/bits/streambuf_iterator.h: + +/usr/include/poll.h: + +/usr/include/x86_64-linux-gnu/bits/types/error_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/io_context.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/any_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/allocator.hpp: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/work_dispatcher.hpp: + +/usr/include/linux/socket.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/scheduler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detached.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_stream_handle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wait_handler.hpp: + +/usr/include/c++/15/iostream: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_runtime.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/udp.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/utility.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/f16cintrin.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/network_v6.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/tss_ptr.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_datagram_socket.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_scheduler_fwd.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2copyintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/packed_lane.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/object_handle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_scheduler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_set.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/fixed_share.hpp: + +/usr/include/assert.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/completion_handler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/timer_queue.hpp: + +/usr/include/c++/15/typeinfo: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/future.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avxneconvertintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_info_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/error.hpp: + +/usr/include/x86_64-linux-gnu/bits/statx.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_context.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/multiple_exceptions.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/execution_context.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/stdlib.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/context_as.hpp: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/hresetintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/static_thread_pool.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/throw_exception.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/circuit.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_ops.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read_at.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-death-test.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_blocker.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scoped_ptr.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_immediate_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_endpoint_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/regex_fwd.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/read_at.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse4.2.h: + +/usr/include/c++/15/bits/stl_set.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/void_receiver.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wait_op.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniint16intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactor_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/consign.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/dispatch.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_wait_op.hpp: + +/usr/include/x86_64-linux-gnu/bits/iscanonical.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_send_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recvmsg_op.hpp: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/static_require_concept.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_round_sink.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recvfrom_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/error_code.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/completion_condition.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_recv_op.hpp: + +/usr/include/x86_64-linux-gnu/bits/poll.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_done_free.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512convertintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_stream_file.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xsavecintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/bulk_sender.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/uint256_t.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/limits.hpp: + +/usr/include/c++/15/bits/stringfwd.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_pred_impl.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/execute_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolver_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/executor.ipp: + +/usr/include/c++/15/bits/stl_tempbuf.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/beaver.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_signal_set.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/functional.hpp: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/bits/fp-fast.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_results.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_seq_packet_socket.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_write_stream_fwd.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_aes_ccr.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/descriptor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/handler_tracking.ipp: + +/usr/include/c++/15/bits/stl_deque.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/lzcntintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_file.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v6.ipp: + +/usr/include/c++/15/bits/std_thread.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxfp8intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffers_iterator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/as_tuple.hpp: + +/usr/include/c++/15/bits/vector.tcc: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/c++/15/climits: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/atomic_count.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/post.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/prepend.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_value_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_executor.hpp: + +/usr/include/c++/15/type_traits: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffer_registration.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_io_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_types.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/host_name.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_immediate_executor.hpp: + +/usr/include/c++/15/ext/aligned_buffer.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxcomplexintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_completion_handler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/assert.hpp: + +/usr/include/c++/15/algorithm: + +/home/cryptolicious/hushmap-specified/libdpf/include/grotto/fixedpoint_mul.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/eventfd_select_interrupter.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scoped_lock.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_mesh.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vlintrin.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigval_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/bad_address_cast.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/grotto/fixedpoint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/compose.hpp: + +/usr/include/c++/15/bits/allocated_ptr.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_stream_socket.hpp: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/locale.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/address_v6.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/twiddle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/defer.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/session_host.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/config.hpp: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/verifiable.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/round_sink.hpp: + +/usr/include/x86_64-linux-gnu/bits/mathcalls-macros.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/awaitable.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_service_strand.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v4.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/rss_seed.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/variadic_templates.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_sendto_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/executor_function.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/random.hpp: + +/usr/include/wctype.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/share_expr.hpp: + +/usr/include/c++/15/ctime: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_cancellation_slot.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/context.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_contiguous_iterator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/scheduler.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_chacha.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_global.hpp: + +/usr/include/net/if.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/aligned_allocator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-f16.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/pmmintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_raw_socket.hpp: + +/usr/include/c++/15/bits/locale_facets.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/epoll_reactor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/party_run.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/epoll_reactor.ipp: + +/usr/include/c++/15/bits/codecvt.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/unicast.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_static_constexpr_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v6.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/eventfd_select_interrupter.ipp: + +/usr/include/c++/15/bits/predefined_ops.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/secret_share.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/shamir.hpp: + +/usr/include/x86_64-linux-gnu/bits/sigstksz.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/serial_port_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/network_v6.ipp: + +/usr/include/linux/stddef.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/share_vec.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v4_iterator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution_context.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/network_v4.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/signal_handler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/socket_holder.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/dependent_type.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/connect_pipe.hpp: + +/usr/include/c++/15/bits/alloc_traits.h: + +/usr/include/x86_64-linux-gnu/bits/termios-tcflow.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++allocator.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_query.hpp: + +/usr/include/ctype.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/party_runner.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/global.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_write_stream.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vbmivlintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_invocable.hpp: + +/usr/include/c++/15/cstring: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/strand_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_read_stream_fwd.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/compose.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/winsock_init.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associator.hpp: + +/usr/include/c++/15/stdexcept: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/ammintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/use_awaitable.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_lowmc.hpp: + +/usr/include/stdio.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/gilboa.hpp: + +/usr/include/c++/15/bits/move.h: + +/usr/include/c++/15/bits/unique_ptr.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_null_buffers_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/writable_pipe.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_cancellation_slot.hpp: + +/usr/include/c++/15/set: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/cstddef.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_flow.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/xsavesintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_edge_mesh.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/mutex.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/buffered_write_stream.hpp: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/signal_set_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/receiver.hpp: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/throw_error.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/factory_tapes.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/streambuf.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/bulk_execute_free.hpp: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/relationship.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_query_op.hpp: + +/usr/include/ifaddrs.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/utils.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/datagram_protocol.hpp: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/host_name.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/blob.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/stream_handle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/conditionally_enabled_mutex.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/deferred.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/dealer_cursor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_operation.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_post.hpp: + +/usr/include/x86_64-linux-gnu/bits/signum-arch.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/log.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/buffered_prg.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/ot_pack.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_serial_port_service.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/version.hpp: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_signal.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/type_traits.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/app_plans.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/literals.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/base_from_cancellation_state.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/chrono.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/append.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/channel.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_error_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/execution_context.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/high_resolution_timer.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/fenced_block.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/detail/impl/endpoint.ipp: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/blocking.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/wrapped_handler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/resolver_service_base.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_read_stream.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/nyble.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/leaf_arithmetic.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/party_session.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/memory_sink.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_task.hpp: + +/usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/noncopyable.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/require.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/query_free.hpp: + +/usr/include/c++/15/bits/shared_ptr_atomic.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/buffer_pool.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/multiple_exceptions.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/pad_graphs.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prep_source.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/matmul.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_dispatch.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/thread_pool.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/static_mutex.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/stream_descriptor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_acceptor.hpp: + +/usr/include/errno.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/schedule_streams.hpp: + +/usr/include/x86_64-linux-gnu/bits/wchar2.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/sink_exchange.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_readable_pipe.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/uint128_t.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_cont_helpers.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/cost_pass.hpp: + +/usr/include/x86_64-linux-gnu/bits/termios-c_cc.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/socket_ops.ipp: + +/usr/include/features-time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/mesh_apps.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/event.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/os_defines.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/policy.hpp: + +/usr/include/c++/15/functional: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread.hpp: + +/usr/include/c++/15/bits/version.h: + +/usr/include/c++/15/bits/node_handle.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/is_buffer_sequence.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/avx2.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_streambuf.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/placement.hpp: + +/usr/include/c++/15/thread: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/libintl.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/lwpintrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vp2intersectintrin.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_entry.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_service.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/share_cmp.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/seq_packet_protocol.hpp: + +/usr/include/c++/15/bits/ostream_insert.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/io_object_impl.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/memory.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-filepath.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/compose_async.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/strand_executor_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect_pipe.ipp: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/append.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avxintrin.h: + +/usr/include/c++/15/fenv.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_stream_array.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/basic_endpoint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/deferred.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/call_stack.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_descriptor_service.hpp: + +/usr/include/c++/15/limits: + +/usr/include/x86_64-linux-gnu/asm/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_stream.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/run_log.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/experiment_note.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/impl/receiver_invocation_error.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/query.hpp: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-internal.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_statx_timestamp.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/push_options.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_accept_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/edabit.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_context.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/wildcard.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-assertion-result.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_dummy.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_random_access_file.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/cldemoteintrin.h: + +/usr/include/linux/posix_types.h: + +/usr/include/x86_64-linux-gnu/bits/openat2.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_streambuf_fwd.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/readable_pipe.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/async_protocol.hpp: + +/usr/include/c++/15/bits/locale_facets.tcc: + +/usr/include/stdlib.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/connect_pipe.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/blocking_adaptation.hpp: + +/usr/include/x86_64-linux-gnu/bits/syslog.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/base_from_completion_cond.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolve_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/twobit.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_writable_pipe.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/async_sctp_stream_array.hpp: + +/usr/include/c++/15/bits/stl_vector.h: + +/usr/include/linux/openat2.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_count.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/online_session.hpp: + +/usr/include/c++/15/cwchar: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/read_until.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_deadline_timer.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/revealing.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/date_time_fwd.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/edge_mesh.hpp: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/basic_file.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/connect.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/redirect_error.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/bit_array.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/hash-library/sha256.h: + +/usr/include/c++/15/bits/atomic_futex.h: + +/usr/include/c++/15/initializer_list: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_service_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_thread.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver_iterator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/cstdint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/initiate_defer.hpp: + +/usr/include/c++/15/bits/uses_allocator_args.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/consign.hpp: + +/usr/include/c++/15/iosfwd: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/any_completion_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/submit_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/tcp_mesh.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/array_fwd.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/hedley.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/blocking_executor_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/is_executor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_mutex.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_static_mutex.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_socket_iostream.hpp: + +/usr/include/c++/15/bits/invoke.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-arch.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/bulk_executor_op.hpp: + +/usr/include/c++/15/bits/sstream.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_serial_port.hpp: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/schedule_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/concurrency_hint.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/conditionally_enabled_event.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/stream_array.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/reactive_descriptor_service.ipp: + +/usr/include/x86_64-linux-gnu/bits/termios-struct.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/consuming_buffers.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/operation.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/null_event.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/connect.hpp: + +/usr/include/x86_64-linux-gnu/bits/wctype-wchar.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/check.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/mmx.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/scheduler_thread_info.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/modint.hpp: + +/usr/include/netinet/in.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_write_buffered.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/deadline_timer_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/io_control.hpp: + +/usr/include/x86_64-linux-gnu/bits/stdint-least.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/tcp.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port-arch.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_read_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/epoll_reactor.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_alloc_helpers.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_io_object.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-matchers.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/trunc.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_tracking.hpp: + +/usr/include/alloca.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_type_requirements.hpp: + +/usr/include/x86_64-linux-gnu/bits/inet-fortified-decl.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/stream_file.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/shuffle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/io_pool.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/bind_handler.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++locale.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/descriptor_ops.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_state.hpp: + +/usr/include/c++/15/iomanip: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/sender.hpp: + +/usr/include/c++/15/bits/chrono.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/executor_op.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/resolver_service_base.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/unistd.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/recycling_allocator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/object_pool.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/use_future.hpp: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/reactive_socket_service_base.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/require_member.hpp: + +/usr/include/c++/15/bits/ostream.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/write_at.hpp: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/pkuintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/prefer_free.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/pop_options.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/service_registry.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_service.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/thread_context.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/keyword_tss_ptr.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/op_queue.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/local_free_on_block_exit.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/composed_work.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/non_const_lvalue.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/raw_protocol.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffered_stream_storage.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-detect-clang.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/cancellation_signal.ipp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_done_member.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/null_event.ipp: + +/usr/include/asm-generic/bitsperlong.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_event.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/uses_executor.hpp: + +/usr/include/c++/15/bits/ptr_traits.h: + +/usr/include/x86_64-linux-gnu/bits/unistd-decl.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/wait_traits.hpp: + +/usr/include/x86_64-linux-gnu/bits/termios-c_lflag.h: + +/usr/include/c++/15/optional: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vlbwintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/coroutine.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_object_handle.hpp: + +/usr/include/endian.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/cancellation_type.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_overlapped_handle.hpp: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/bits/wchar2-decl.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_work.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/overlapped_ptr.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/random_access_handle.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/libutil.h: + +/usr/include/c++/15/string_view: + +/usr/include/c++/15/bits/basic_string.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/signal_set_service.ipp: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/hash-library/sha256.cpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/hedley/hedley.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxfp16intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/run_config.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/lowmc/LowMC.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/debug-trap.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-constify.h: + +/usr/include/c++/15/bitset: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-diagnostic.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-features.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-math.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/avx.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse3.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/link_log.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/sse4.1.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/x86/ssse3.h: + +/usr/include/x86_64-linux-gnu/sys/single_threaded.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/endianness.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/uint256_t/uint256_t.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_signal_blocker.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/cpu_defines.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/fma4intrin.h: + +/usr/include/fenv.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-param-test.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/equality_comparable.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-test-part.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/async_result.hpp: + +/usr/include/inttypes.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-typed-test.h: + +/usr/include/c++/15/backward/auto_ptr.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_alloc_hook.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-param-util.h: + +/usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/start_member.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++io.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/packed_lane_arithmetic.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-type-util.h: + +/usr/include/arpa/inet.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/asm-generic/errno.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/service_registry.hpp: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/c++/15/csignal: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/asm-generic/socket.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/simde/simde/simde-align.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vnniintrin.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/asm-generic/types.h: + +/usr/include/c++/15/any: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/xor_wrapper.hpp: + +/usr/include/c++/15/atomic: + +/usr/include/c++/15/backward/binders.h: + +/usr/include/c++/15/exception: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/posix/basic_stream_descriptor.hpp: + +/usr/include/c++/15/bits/algorithmfwd.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/std_fenced_block.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-message.h: + +/usr/include/c++/15/bits/align.h: + +/usr/include/x86_64-linux-gnu/sys/syscall.h: + +/usr/include/c++/15/bits/allocator.h: + +/usr/include/c++/15/bits/atomic_base.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/vpclmulqdqintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-string.h: + +/usr/include/c++/15/bits/basic_ios.h: + +/usr/include/c++/15/variant: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/resolver_base.hpp: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxtransposeintrin.h: + +/usr/include/c++/15/bits/basic_ios.tcc: + +/usr/include/c++/15/pstl/pstl_config.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_service.hpp: + +/usr/include/c++/15/bits/basic_string.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/c++/15/ostream: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_executor_service.hpp: + +/usr/include/c++/15/bits/char_traits.h: + +/usr/include/x86_64-linux-gnu/bits/termios-cbaud.h: + +/usr/include/c++/15/bits/charconv.h: + +/usr/include/c++/15/bits/concept_check.h: + +/usr/include/x86_64-linux-gnu/sys/uio.h: + +/usr/include/c++/15/bits/cpp_type_traits.h: + +/usr/include/c++/15/bits/cxxabi_forced.h: + +/usr/include/c++/15/bits/cxxabi_init_exception.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/this_coro.hpp: + +/usr/include/c++/15/bits/enable_special_members.h: + +/usr/include/c++/15/bits/erase_if.h: + +/usr/include/c++/15/cctype: + +/usr/include/c++/15/bits/std_mutex.h: + +/usr/include/c++/15/bits/exception.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_serial_port_service.hpp: + +/usr/include/c++/15/bits/exception_defines.h: + +/usr/include/c++/15/bits/exception_ptr.h: + +/usr/include/c++/15/bits/fstream.tcc: + +/usr/include/c++/15/bits/functexcept.h: + +/usr/include/c++/15/bits/functional_hash.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/socket_tune.hpp: + +/usr/include/c++/15/bits/hash_bytes.h: + +/usr/include/c++/15/bits/hashtable.h: + +/usr/include/c++/15/bits/hashtable_policy.h: + +/usr/include/c++/15/bits/ios_base.h: + +/usr/include/c++/15/bits/istream.tcc: + +/usr/include/c++/15/bits/locale_classes.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/c++/15/bits/locale_classes.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/endian/endian.h: + +/usr/include/c++/15/bits/locale_conv.h: + +/usr/include/c++/15/bits/locale_facets_nonio.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/array.hpp: + +/usr/include/c++/15/bits/memory_resource.h: + +/usr/include/c++/15/bits/stl_function.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/is_read_buffered.hpp: + +/usr/include/c++/15/bits/memoryfwd.h: + +/usr/include/c++/15/bits/monostate.h: + +/usr/include/c++/15/bits/new_allocator.h: + +/usr/include/c++/15/bits/ostream.h: + +/usr/include/c++/15/bits/stl_raw_storage_iter.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/io_context_strand.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/start.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffer.hpp: + +/usr/include/c++/15/bits/parse_numbers.h: + +/usr/include/c++/15/bits/postypes.h: + +/usr/include/c++/15/bits/quoted_string.h: + +/usr/include/c++/15/bits/random.h: + +/usr/include/c++/15/bits/random.tcc: + +/usr/include/c++/15/bits/stl_relops.h: + +/usr/include/c++/15/bits/range_access.h: + +/usr/include/c++/15/map: + +/usr/include/c++/15/bits/requires_hosted.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/buffered_stream_fwd.hpp: + +/usr/include/c++/15/bits/shared_ptr_base.h: + +/usr/include/c++/15/bits/std_abs.h: + +/usr/include/c++/15/ios: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/system_context.hpp: + +/usr/include/c++/15/bits/nested_exception.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h: + +/usr/include/netinet/tcp.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/c++/15/bits/std_function.h: + +/usr/include/c++/15/bits/stl_algo.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/placeholders.hpp: + +/usr/include/c++/15/random: + +/usr/include/c++/15/array: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/generic/detail/endpoint.hpp: + +/usr/include/c++/15/bits/stl_bvector.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2-decl.h: + +/usr/include/c++/15/bits/stl_construct.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/chrono_time_traits.hpp: + +/usr/include/c++/15/bits/stl_heap.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/net/round_lane.hpp: + +/usr/include/c++/15/bits/stream_iterator.h: + +/usr/include/c++/15/bits/stl_iterator.h: + +/usr/include/x86_64-linux-gnu/sys/epoll.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/associated_allocator.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/reactive_socket_connect_op.hpp: + +/usr/include/c++/15/bits/stl_iterator_base_types.h: + +/usr/include/c++/15/bits/stl_map.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/start_free.hpp: + +/usr/include/c++/15/ratio: + +/usr/include/c++/15/bits/stl_multimap.h: + +/usr/include/x86_64-linux-gnu/bits/fenv.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/bsd/stdio.h: + +/usr/include/c++/15/bits/stl_numeric.h: + +/usr/include/c++/15/bits/stl_pair.h: + +/usr/include/c++/15/bits/shared_ptr.h: + +/usr/include/c++/15/cstdint: + +/usr/include/c++/15/bits/stl_tree.h: + +/usr/include/string.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/throw_error.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxint8intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/handler_continuation_hook.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxtileintrin.h: + +/usr/include/c++/15/bits/stl_uninitialized.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/portable-snippets/builtin/builtin.h: + +/usr/include/x86_64-linux-gnu/bits/poll2.h: + +/usr/include/c++/15/bits/string_view.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/co_spawn.hpp: + +/usr/include/c++/15/bits/this_thread_sleep.h: + +/usr/include/c++/15/bits/uniform_int_dist.h: + +/usr/include/c++/15/bits/unique_lock.h: + +/usr/include/c++/15/bits/uses_allocator.h: + +/usr/include/c++/15/bits/utility.h: + +/usr/include/c++/15/cassert: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/sgxintrin.h: + +/usr/include/c++/15/cerrno: + +/usr/include/c++/15/cfenv: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/posix_thread.hpp: + +/usr/include/c++/15/tr1/ell_integral.tcc: + +/usr/include/stdc-predef.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/error.ipp: + +/usr/include/c++/15/chrono: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/windows/basic_random_access_handle.hpp: + +/usr/include/c++/15/cinttypes: + +/usr/include/math.h: + +/usr/include/c++/15/clocale: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxmovrsintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/impl/basic_endpoint.hpp: + +/usr/include/c++/15/condition_variable: + +/usr/include/linux/falloc.h: + +/usr/include/c++/15/cstddef: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffer_resize_guard.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/recycling_allocator.hpp: + +/usr/include/c++/15/cstdlib: + +/usr/include/c++/15/cwctype: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/c++/15/debug/assertions.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/submit_free.hpp: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/bits/ss_flags.h: + +/usr/include/c++/15/debug/debug.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/c++/15/deque: + +/usr/include/c++/15/bits/locale_facets_nonio.h: + +/usr/include/c++/15/ext/alloc_traits.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/c++/15/ext/concurrence.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512dqintrin.h: + +/usr/include/c++/15/ext/numeric_traits.h: + +/usr/include/c++/15/ext/string_conversions.h: + +/usr/include/c++/15/ext/type_traits.h: + +/usr/include/c++/15/fstream: + +/usr/include/c++/15/istream: + +/usr/include/c++/15/iterator: + +/usr/include/x86_64-linux-gnu/bits/epoll.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution.hpp: + +/usr/include/x86_64-linux-gnu/bits/types/stack_t.h: + +/usr/include/c++/15/memory: + +/usr/include/c++/15/mutex: + +/usr/include/c++/15/new: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/c++/15/numeric: + +/usr/include/c++/15/pstl/execution_defs.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/bind_allocator.hpp: + +/usr/include/c++/15/pstl/glue_algorithm_defs.h: + +/usr/include/c++/15/ext/atomicity.h: + +/usr/include/c++/15/pstl/glue_memory_defs.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/posix_mutex.ipp: + +/usr/include/c++/15/pstl/glue_numeric_defs.h: + +/usr/include/c++/15/stdlib.h: + +/usr/include/c++/15/streambuf: + +/usr/include/c++/15/system_error: + +/usr/include/c++/15/tr1/beta_function.tcc: + +/usr/include/c++/15/tr1/exp_integral.tcc: + +/usr/include/c++/15/sstream: + +/usr/include/c++/15/tr1/gamma.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/thread_pool.hpp: + +/usr/include/limits.h: + +/usr/include/c++/15/tr1/hypergeometric.tcc: + +/usr/include/time.h: + +/usr/include/c++/15/future: + +/usr/include/c++/15/tr1/legendre_function.tcc: + +/usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h: + +/usr/include/c++/15/tr1/modified_bessel_func.tcc: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/uio-ext.h: + +/usr/include/x86_64-linux-gnu/sys/poll.h: + +/usr/include/c++/15/tr1/special_function_util.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/clwbintrin.h: + +/usr/include/c++/15/unordered_map: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/prepend.hpp: + +/usr/include/c++/15/utility: + +/usr/include/c++/15/vector: + +/usr/include/c++/15/compare: + +/usr/include/c++/15/version: + +/usr/include/features.h: + +/usr/include/c++/15/bits/deque.tcc: + +/usr/include/c++/15/bits/streambuf.tcc: + +/usr/include/linux/ioctl.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/leaf_node.hpp: + +/usr/include/linux/sched/types.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/thread_group.hpp: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vpopcntdqintrin.h: + +/usr/include/linux/sctp.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/basic_streambuf.hpp: + +/usr/include/linux/sockios.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/handler_invoke_helpers.hpp: + +/usr/include/linux/version.h: + +/usr/include/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h: + +/usr/include/sched.h: + +/usr/include/pthread.h: + +/usr/include/rpc/netdb.h: + +/usr/include/signal.h: + +/usr/include/c++/15/bits/stl_iterator_base_funcs.h: + +/usr/include/x86_64-linux-gnu/bits/struct_stat.h: + +/usr/include/x86_64-linux-gnu/bits/types/wint_t.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/mmintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_write_op.hpp: + +/usr/include/stdint.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/steady_timer.hpp: + +/usr/include/strings.h: + +/usr/include/syslog.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/prg_aes.hpp: + +/usr/include/termios.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/ctype_inline.h: + +/usr/include/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/statx-generic.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/c++/15/bits/specfun.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++config.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avxvnniint8intrin.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/x86_64-linux-gnu/asm/unistd_64.h: + +/usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/local/seq_packet_protocol.hpp: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/descriptor_ops.hpp: + +/usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx2intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/traits/set_error_member.hpp: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512bitalgintrin.h: + +/usr/include/c++/15/bits/localefwd.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls.h: + +/usr/include/x86_64-linux-gnu/bits/eventfd.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/detail/endpoint.hpp: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux-fortify.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl2.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/strand_executor_service.ipp: + +/usr/include/x86_64-linux-gnu/bits/inet-fortified.h: + +/usr/include/c++/15/cmath: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol_roles.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/cxxabi_tweaks.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-printers.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/math-vector.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/resolver_query_base.hpp: + +/usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/x86_64-linux-gnu/bits/select-decl.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigevent-consts.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-arch.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-consts-arch.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-consts.h: + +/usr/include/x86_64-linux-gnu/bits/signal_ext.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/executor.hpp: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/strand.hpp: + +/usr/include/x86_64-linux-gnu/bits/signum-generic.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/sys/eventfd.h: + +/usr/include/x86_64-linux-gnu/bits/syscall.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx512vldqintrin.h: + +/usr/include/x86_64-linux-gnu/bits/syslog-decl.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/impl/service_registry.hpp: + +/usr/include/x86_64-linux-gnu/bits/termios-baud.h: + +/usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/termios-c_cflag.h: + +/usr/include/x86_64-linux-gnu/bits/termios-c_iflag.h: + +/usr/include/c++/15/tr1/poly_hermite.tcc: + +/usr/include/x86_64-linux-gnu/bits/termios-c_oflag.h: + +/usr/include/x86_64-linux-gnu/bits/termios-misc.h: + +/usr/include/x86_64-linux-gnu/bits/termios.h: + +/usr/include/c++/15/bits/atomic_lockfree_defines.h: + +/usr/include/x86_64-linux-gnu/bits/timerfd.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/detail/buffer_sequence_adapter.hpp: + +/usr/include/c++/15/bits/refwrap.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/impl/io_context.hpp: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/basic_resolver.hpp: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/c++/15/bit: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/adxintrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/bulk_execute.hpp: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_statx.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/packaged_task.hpp: + +/usr/include/x86_64-linux-gnu/bits/uio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/utsname.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/home/cryptolicious/hushmap-specified/libdpf/include/dpf/protocol_factory.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/atomic_word.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/submit.hpp: + +/usr/include/x86_64-linux-gnu/c++/15/bits/ctype_base.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/error_constants.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/gthr-default.h: + +/usr/include/c++/15/bits/stl_algobase.h: + +/usr/include/x86_64-linux-gnu/sys/un.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2satcvtintrin.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/gthr.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/messages_members.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/opt_random.h: + +/usr/include/c++/15/tuple: + +/usr/include/x86_64-linux-gnu/c++/15/bits/time_members.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/ip/address_v6_range.hpp: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/c++/15/cxxabi.h: + +/usr/include/x86_64-linux-gnu/sys/syslog.h: + +/usr/include/x86_64-linux-gnu/sys/timerfd.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/x86_64-linux-gnu/sys/utsname.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxavx512intrin.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxbf16intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/deadline_timer.hpp: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/amxtf32intrin.h: + +/home/cryptolicious/hushmap-specified/libdpf/thirdparty/asio/asio/include/asio/execution/detail/as_operation.hpp: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/avx10_2-512bf16intrin.h: diff --git a/test/build-asan/CMakeFiles/share_runtime_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/share_runtime_test.dir/compiler_depend.ts new file mode 100644 index 0000000..06cd1d6 --- /dev/null +++ b/test/build-asan/CMakeFiles/share_runtime_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for share_runtime_test. diff --git a/test/build-asan/CMakeFiles/share_runtime_test.dir/depend.make b/test/build-asan/CMakeFiles/share_runtime_test.dir/depend.make new file mode 100644 index 0000000..2c31ad1 --- /dev/null +++ b/test/build-asan/CMakeFiles/share_runtime_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for share_runtime_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/share_runtime_test.dir/flags.make b/test/build-asan/CMakeFiles/share_runtime_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/share_runtime_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/share_runtime_test.dir/link.txt b/test/build-asan/CMakeFiles/share_runtime_test.dir/link.txt new file mode 100644 index 0000000..bc2585a --- /dev/null +++ b/test/build-asan/CMakeFiles/share_runtime_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/share_runtime_test.dir/link.d CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o -o bin/share_runtime_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/share_runtime_test.dir/progress.make b/test/build-asan/CMakeFiles/share_runtime_test.dir/progress.make new file mode 100644 index 0000000..f87199e --- /dev/null +++ b/test/build-asan/CMakeFiles/share_runtime_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 86 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/shared_and_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/shared_and_test.dir/DependInfo.cmake new file mode 100644 index 0000000..697d444 --- /dev/null +++ b/test/build-asan/CMakeFiles/shared_and_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/shared_and_test.cpp" "CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o" "gcc" "CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o.d" + "" "bin/shared_and_test" "gcc" "CMakeFiles/shared_and_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/shared_and_test.dir/build.make b/test/build-asan/CMakeFiles/shared_and_test.dir/build.make new file mode 100644 index 0000000..cc1dd8e --- /dev/null +++ b/test/build-asan/CMakeFiles/shared_and_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/shared_and_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/shared_and_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/shared_and_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/shared_and_test.dir/flags.make + +CMakeFiles/shared_and_test.dir/codegen: +.PHONY : CMakeFiles/shared_and_test.dir/codegen + +CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o: CMakeFiles/shared_and_test.dir/flags.make +CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/shared_and_test.cpp +CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o: CMakeFiles/shared_and_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o -MF CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o.d -o CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/shared_and_test.cpp + +CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/shared_and_test.cpp > CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.i + +CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/shared_and_test.cpp -o CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.s + +# Object files for target shared_and_test +shared_and_test_OBJECTS = \ +"CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o" + +# External object files for target shared_and_test +shared_and_test_EXTERNAL_OBJECTS = + +bin/shared_and_test: CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o +bin/shared_and_test: CMakeFiles/shared_and_test.dir/build.make +bin/shared_and_test: CMakeFiles/shared_and_test.dir/compiler_depend.ts +bin/shared_and_test: lib/libgtest_main.a +bin/shared_and_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/shared_and_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/shared_and_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/shared_and_test: lib/libgtest.a +bin/shared_and_test: CMakeFiles/shared_and_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/shared_and_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/shared_and_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=shared_and_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/shared_and_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=shared_and_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/shared_and_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/shared_and_test.dir/build: bin/shared_and_test +.PHONY : CMakeFiles/shared_and_test.dir/build + +CMakeFiles/shared_and_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/shared_and_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/shared_and_test.dir/clean + +CMakeFiles/shared_and_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/shared_and_test.dir/DependInfo.cmake "--color=$(COLOR)" shared_and_test +.PHONY : CMakeFiles/shared_and_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/shared_and_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/shared_and_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..93ba673 --- /dev/null +++ b/test/build-asan/CMakeFiles/shared_and_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/shared_and_test.dir/link.d" + "CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o" + "CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o.d" + "bin/shared_and_test" + "bin/shared_and_test.pdb" + "shared_and_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/shared_and_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/shared_and_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/shared_and_test.dir/compiler_depend.make new file mode 100644 index 0000000..a31db6f --- /dev/null +++ b/test/build-asan/CMakeFiles/shared_and_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for shared_and_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/shared_and_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/shared_and_test.dir/compiler_depend.ts new file mode 100644 index 0000000..dac1102 --- /dev/null +++ b/test/build-asan/CMakeFiles/shared_and_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for shared_and_test. diff --git a/test/build-asan/CMakeFiles/shared_and_test.dir/depend.make b/test/build-asan/CMakeFiles/shared_and_test.dir/depend.make new file mode 100644 index 0000000..7dc4323 --- /dev/null +++ b/test/build-asan/CMakeFiles/shared_and_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for shared_and_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/shared_and_test.dir/flags.make b/test/build-asan/CMakeFiles/shared_and_test.dir/flags.make new file mode 100644 index 0000000..96f7b96 --- /dev/null +++ b/test/build-asan/CMakeFiles/shared_and_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../party -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/shared_and_test.dir/link.txt b/test/build-asan/CMakeFiles/shared_and_test.dir/link.txt new file mode 100644 index 0000000..174cc61 --- /dev/null +++ b/test/build-asan/CMakeFiles/shared_and_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/shared_and_test.dir/link.d CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o -o bin/shared_and_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/shared_and_test.dir/progress.make b/test/build-asan/CMakeFiles/shared_and_test.dir/progress.make new file mode 100644 index 0000000..a958dd7 --- /dev/null +++ b/test/build-asan/CMakeFiles/shared_and_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 87 + diff --git a/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/DependInfo.cmake new file mode 100644 index 0000000..510203a --- /dev/null +++ b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/shuffle_hidden_test.cpp" "CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o" "gcc" "CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o.d" + "" "bin/shuffle_hidden_test" "gcc" "CMakeFiles/shuffle_hidden_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/build.make b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/build.make new file mode 100644 index 0000000..852b8f9 --- /dev/null +++ b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/shuffle_hidden_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/shuffle_hidden_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/shuffle_hidden_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/shuffle_hidden_test.dir/flags.make + +CMakeFiles/shuffle_hidden_test.dir/codegen: +.PHONY : CMakeFiles/shuffle_hidden_test.dir/codegen + +CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o: CMakeFiles/shuffle_hidden_test.dir/flags.make +CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/shuffle_hidden_test.cpp +CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o: CMakeFiles/shuffle_hidden_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o -MF CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o.d -o CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/shuffle_hidden_test.cpp + +CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/shuffle_hidden_test.cpp > CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.i + +CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/shuffle_hidden_test.cpp -o CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.s + +# Object files for target shuffle_hidden_test +shuffle_hidden_test_OBJECTS = \ +"CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o" + +# External object files for target shuffle_hidden_test +shuffle_hidden_test_EXTERNAL_OBJECTS = + +bin/shuffle_hidden_test: CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o +bin/shuffle_hidden_test: CMakeFiles/shuffle_hidden_test.dir/build.make +bin/shuffle_hidden_test: CMakeFiles/shuffle_hidden_test.dir/compiler_depend.ts +bin/shuffle_hidden_test: lib/libgtest_main.a +bin/shuffle_hidden_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/shuffle_hidden_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/shuffle_hidden_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/shuffle_hidden_test: lib/libgtest.a +bin/shuffle_hidden_test: CMakeFiles/shuffle_hidden_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/shuffle_hidden_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/shuffle_hidden_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=shuffle_hidden_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/shuffle_hidden_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=shuffle_hidden_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/shuffle_hidden_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/shuffle_hidden_test.dir/build: bin/shuffle_hidden_test +.PHONY : CMakeFiles/shuffle_hidden_test.dir/build + +CMakeFiles/shuffle_hidden_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/shuffle_hidden_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/shuffle_hidden_test.dir/clean + +CMakeFiles/shuffle_hidden_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/DependInfo.cmake "--color=$(COLOR)" shuffle_hidden_test +.PHONY : CMakeFiles/shuffle_hidden_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..cc18420 --- /dev/null +++ b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/shuffle_hidden_test.dir/link.d" + "CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o" + "CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o.d" + "bin/shuffle_hidden_test" + "bin/shuffle_hidden_test.pdb" + "shuffle_hidden_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/shuffle_hidden_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/compiler_depend.make new file mode 100644 index 0000000..bafd872 --- /dev/null +++ b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for shuffle_hidden_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/compiler_depend.ts new file mode 100644 index 0000000..a2ba709 --- /dev/null +++ b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for shuffle_hidden_test. diff --git a/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/depend.make b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/depend.make new file mode 100644 index 0000000..ecd04de --- /dev/null +++ b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for shuffle_hidden_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/flags.make b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/link.txt b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/link.txt new file mode 100644 index 0000000..244bfcf --- /dev/null +++ b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/shuffle_hidden_test.dir/link.d CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o -o bin/shuffle_hidden_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/progress.make b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/progress.make new file mode 100644 index 0000000..3890e59 --- /dev/null +++ b/test/build-asan/CMakeFiles/shuffle_hidden_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 88 + diff --git a/test/build-asan/CMakeFiles/signed_prefix_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/signed_prefix_test.dir/DependInfo.cmake new file mode 100644 index 0000000..401bd69 --- /dev/null +++ b/test/build-asan/CMakeFiles/signed_prefix_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/signed_prefix_test.cpp" "CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o" "gcc" "CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o.d" + "" "bin/signed_prefix_test" "gcc" "CMakeFiles/signed_prefix_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/signed_prefix_test.dir/build.make b/test/build-asan/CMakeFiles/signed_prefix_test.dir/build.make new file mode 100644 index 0000000..43af52b --- /dev/null +++ b/test/build-asan/CMakeFiles/signed_prefix_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/signed_prefix_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/signed_prefix_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/signed_prefix_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/signed_prefix_test.dir/flags.make + +CMakeFiles/signed_prefix_test.dir/codegen: +.PHONY : CMakeFiles/signed_prefix_test.dir/codegen + +CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o: CMakeFiles/signed_prefix_test.dir/flags.make +CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/signed_prefix_test.cpp +CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o: CMakeFiles/signed_prefix_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o -MF CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o.d -o CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/signed_prefix_test.cpp + +CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/signed_prefix_test.cpp > CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.i + +CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/signed_prefix_test.cpp -o CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.s + +# Object files for target signed_prefix_test +signed_prefix_test_OBJECTS = \ +"CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o" + +# External object files for target signed_prefix_test +signed_prefix_test_EXTERNAL_OBJECTS = + +bin/signed_prefix_test: CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o +bin/signed_prefix_test: CMakeFiles/signed_prefix_test.dir/build.make +bin/signed_prefix_test: CMakeFiles/signed_prefix_test.dir/compiler_depend.ts +bin/signed_prefix_test: lib/libgtest_main.a +bin/signed_prefix_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/signed_prefix_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/signed_prefix_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/signed_prefix_test: lib/libgtest.a +bin/signed_prefix_test: CMakeFiles/signed_prefix_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/signed_prefix_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/signed_prefix_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=signed_prefix_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/signed_prefix_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=signed_prefix_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/signed_prefix_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/signed_prefix_test.dir/build: bin/signed_prefix_test +.PHONY : CMakeFiles/signed_prefix_test.dir/build + +CMakeFiles/signed_prefix_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/signed_prefix_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/signed_prefix_test.dir/clean + +CMakeFiles/signed_prefix_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/signed_prefix_test.dir/DependInfo.cmake "--color=$(COLOR)" signed_prefix_test +.PHONY : CMakeFiles/signed_prefix_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/signed_prefix_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/signed_prefix_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..7eac771 --- /dev/null +++ b/test/build-asan/CMakeFiles/signed_prefix_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/signed_prefix_test.dir/link.d" + "CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o" + "CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o.d" + "bin/signed_prefix_test" + "bin/signed_prefix_test.pdb" + "signed_prefix_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/signed_prefix_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/signed_prefix_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/signed_prefix_test.dir/compiler_depend.make new file mode 100644 index 0000000..743f12c --- /dev/null +++ b/test/build-asan/CMakeFiles/signed_prefix_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for signed_prefix_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/signed_prefix_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/signed_prefix_test.dir/compiler_depend.ts new file mode 100644 index 0000000..a75fee9 --- /dev/null +++ b/test/build-asan/CMakeFiles/signed_prefix_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for signed_prefix_test. diff --git a/test/build-asan/CMakeFiles/signed_prefix_test.dir/depend.make b/test/build-asan/CMakeFiles/signed_prefix_test.dir/depend.make new file mode 100644 index 0000000..ceabbe0 --- /dev/null +++ b/test/build-asan/CMakeFiles/signed_prefix_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for signed_prefix_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/signed_prefix_test.dir/flags.make b/test/build-asan/CMakeFiles/signed_prefix_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/signed_prefix_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/signed_prefix_test.dir/link.txt b/test/build-asan/CMakeFiles/signed_prefix_test.dir/link.txt new file mode 100644 index 0000000..303de68 --- /dev/null +++ b/test/build-asan/CMakeFiles/signed_prefix_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/signed_prefix_test.dir/link.d CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o -o bin/signed_prefix_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/signed_prefix_test.dir/progress.make b/test/build-asan/CMakeFiles/signed_prefix_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/signed_prefix_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/stress_scenarios_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/DependInfo.cmake new file mode 100644 index 0000000..88f825c --- /dev/null +++ b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp" "CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o" "gcc" "CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o.d" + "" "bin/stress_scenarios_test" "gcc" "CMakeFiles/stress_scenarios_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/stress_scenarios_test.dir/build.make b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/build.make new file mode 100644 index 0000000..6cf0ee0 --- /dev/null +++ b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/stress_scenarios_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/stress_scenarios_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/stress_scenarios_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/stress_scenarios_test.dir/flags.make + +CMakeFiles/stress_scenarios_test.dir/codegen: +.PHONY : CMakeFiles/stress_scenarios_test.dir/codegen + +CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o: CMakeFiles/stress_scenarios_test.dir/flags.make +CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp +CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o: CMakeFiles/stress_scenarios_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o -MF CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o.d -o CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp + +CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp > CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.i + +CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp -o CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.s + +# Object files for target stress_scenarios_test +stress_scenarios_test_OBJECTS = \ +"CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o" + +# External object files for target stress_scenarios_test +stress_scenarios_test_EXTERNAL_OBJECTS = + +bin/stress_scenarios_test: CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o +bin/stress_scenarios_test: CMakeFiles/stress_scenarios_test.dir/build.make +bin/stress_scenarios_test: CMakeFiles/stress_scenarios_test.dir/compiler_depend.ts +bin/stress_scenarios_test: lib/libgtest_main.a +bin/stress_scenarios_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/stress_scenarios_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/stress_scenarios_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/stress_scenarios_test: lib/libgtest.a +bin/stress_scenarios_test: CMakeFiles/stress_scenarios_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/stress_scenarios_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/stress_scenarios_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=stress_scenarios_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=stress_scenarios_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/stress_scenarios_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/stress_scenarios_test.dir/build: bin/stress_scenarios_test +.PHONY : CMakeFiles/stress_scenarios_test.dir/build + +CMakeFiles/stress_scenarios_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/stress_scenarios_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/stress_scenarios_test.dir/clean + +CMakeFiles/stress_scenarios_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/stress_scenarios_test.dir/DependInfo.cmake "--color=$(COLOR)" stress_scenarios_test +.PHONY : CMakeFiles/stress_scenarios_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/stress_scenarios_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..df8fb60 --- /dev/null +++ b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/stress_scenarios_test.dir/link.d" + "CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o" + "CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o.d" + "bin/stress_scenarios_test" + "bin/stress_scenarios_test.pdb" + "stress_scenarios_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/stress_scenarios_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/stress_scenarios_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/compiler_depend.make new file mode 100644 index 0000000..be3ac9f --- /dev/null +++ b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for stress_scenarios_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/stress_scenarios_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/compiler_depend.ts new file mode 100644 index 0000000..80d4ecf --- /dev/null +++ b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for stress_scenarios_test. diff --git a/test/build-asan/CMakeFiles/stress_scenarios_test.dir/depend.make b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/depend.make new file mode 100644 index 0000000..14e1898 --- /dev/null +++ b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for stress_scenarios_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/stress_scenarios_test.dir/flags.make b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/stress_scenarios_test.dir/link.txt b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/link.txt new file mode 100644 index 0000000..5930392 --- /dev/null +++ b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/stress_scenarios_test.dir/link.d CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o -o bin/stress_scenarios_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/stress_scenarios_test.dir/progress.make b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/progress.make new file mode 100644 index 0000000..3d8fb39 --- /dev/null +++ b/test/build-asan/CMakeFiles/stress_scenarios_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 89 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/types_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/types_test.dir/DependInfo.cmake new file mode 100644 index 0000000..8b1215e --- /dev/null +++ b/test/build-asan/CMakeFiles/types_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/types_test.cpp" "CMakeFiles/types_test.dir/tests/types_test.cpp.o" "gcc" "CMakeFiles/types_test.dir/tests/types_test.cpp.o.d" + "" "bin/types_test" "gcc" "CMakeFiles/types_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/types_test.dir/build.make b/test/build-asan/CMakeFiles/types_test.dir/build.make new file mode 100644 index 0000000..1a64d8b --- /dev/null +++ b/test/build-asan/CMakeFiles/types_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/types_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/types_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/types_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/types_test.dir/flags.make + +CMakeFiles/types_test.dir/codegen: +.PHONY : CMakeFiles/types_test.dir/codegen + +CMakeFiles/types_test.dir/tests/types_test.cpp.o: CMakeFiles/types_test.dir/flags.make +CMakeFiles/types_test.dir/tests/types_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/types_test.cpp +CMakeFiles/types_test.dir/tests/types_test.cpp.o: CMakeFiles/types_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/types_test.dir/tests/types_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/types_test.dir/tests/types_test.cpp.o -MF CMakeFiles/types_test.dir/tests/types_test.cpp.o.d -o CMakeFiles/types_test.dir/tests/types_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/types_test.cpp + +CMakeFiles/types_test.dir/tests/types_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/types_test.dir/tests/types_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/types_test.cpp > CMakeFiles/types_test.dir/tests/types_test.cpp.i + +CMakeFiles/types_test.dir/tests/types_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/types_test.dir/tests/types_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/types_test.cpp -o CMakeFiles/types_test.dir/tests/types_test.cpp.s + +# Object files for target types_test +types_test_OBJECTS = \ +"CMakeFiles/types_test.dir/tests/types_test.cpp.o" + +# External object files for target types_test +types_test_EXTERNAL_OBJECTS = + +bin/types_test: CMakeFiles/types_test.dir/tests/types_test.cpp.o +bin/types_test: CMakeFiles/types_test.dir/build.make +bin/types_test: CMakeFiles/types_test.dir/compiler_depend.ts +bin/types_test: lib/libgtest_main.a +bin/types_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/types_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/types_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/types_test: lib/libgtest.a +bin/types_test: CMakeFiles/types_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/types_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/types_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=types_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/types_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=types_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/types_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/types_test.dir/build: bin/types_test +.PHONY : CMakeFiles/types_test.dir/build + +CMakeFiles/types_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/types_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/types_test.dir/clean + +CMakeFiles/types_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/types_test.dir/DependInfo.cmake "--color=$(COLOR)" types_test +.PHONY : CMakeFiles/types_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/types_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/types_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..f99d9ef --- /dev/null +++ b/test/build-asan/CMakeFiles/types_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/types_test.dir/link.d" + "CMakeFiles/types_test.dir/tests/types_test.cpp.o" + "CMakeFiles/types_test.dir/tests/types_test.cpp.o.d" + "bin/types_test" + "bin/types_test.pdb" + "types_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/types_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/types_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/types_test.dir/compiler_depend.make new file mode 100644 index 0000000..9825c0e --- /dev/null +++ b/test/build-asan/CMakeFiles/types_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for types_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/types_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/types_test.dir/compiler_depend.ts new file mode 100644 index 0000000..2d17548 --- /dev/null +++ b/test/build-asan/CMakeFiles/types_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for types_test. diff --git a/test/build-asan/CMakeFiles/types_test.dir/depend.make b/test/build-asan/CMakeFiles/types_test.dir/depend.make new file mode 100644 index 0000000..9246a7b --- /dev/null +++ b/test/build-asan/CMakeFiles/types_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for types_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/types_test.dir/flags.make b/test/build-asan/CMakeFiles/types_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/types_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/types_test.dir/link.txt b/test/build-asan/CMakeFiles/types_test.dir/link.txt new file mode 100644 index 0000000..30d745c --- /dev/null +++ b/test/build-asan/CMakeFiles/types_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/types_test.dir/link.d CMakeFiles/types_test.dir/tests/types_test.cpp.o -o bin/types_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/types_test.dir/progress.make b/test/build-asan/CMakeFiles/types_test.dir/progress.make new file mode 100644 index 0000000..37a7596 --- /dev/null +++ b/test/build-asan/CMakeFiles/types_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 90 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/DependInfo.cmake new file mode 100644 index 0000000..dc2ee23 --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/vdpf_adversarial_test.cpp" "CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o" "gcc" "CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o.d" + "" "bin/vdpf_adversarial_test" "gcc" "CMakeFiles/vdpf_adversarial_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/build.make b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/build.make new file mode 100644 index 0000000..23a5288 --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/vdpf_adversarial_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/vdpf_adversarial_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/vdpf_adversarial_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/vdpf_adversarial_test.dir/flags.make + +CMakeFiles/vdpf_adversarial_test.dir/codegen: +.PHONY : CMakeFiles/vdpf_adversarial_test.dir/codegen + +CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o: CMakeFiles/vdpf_adversarial_test.dir/flags.make +CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/vdpf_adversarial_test.cpp +CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o: CMakeFiles/vdpf_adversarial_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o -MF CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o.d -o CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/vdpf_adversarial_test.cpp + +CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/vdpf_adversarial_test.cpp > CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.i + +CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/vdpf_adversarial_test.cpp -o CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.s + +# Object files for target vdpf_adversarial_test +vdpf_adversarial_test_OBJECTS = \ +"CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o" + +# External object files for target vdpf_adversarial_test +vdpf_adversarial_test_EXTERNAL_OBJECTS = + +bin/vdpf_adversarial_test: CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o +bin/vdpf_adversarial_test: CMakeFiles/vdpf_adversarial_test.dir/build.make +bin/vdpf_adversarial_test: CMakeFiles/vdpf_adversarial_test.dir/compiler_depend.ts +bin/vdpf_adversarial_test: lib/libgtest_main.a +bin/vdpf_adversarial_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/vdpf_adversarial_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/vdpf_adversarial_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/vdpf_adversarial_test: lib/libgtest.a +bin/vdpf_adversarial_test: CMakeFiles/vdpf_adversarial_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/vdpf_adversarial_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/vdpf_adversarial_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=vdpf_adversarial_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/vdpf_adversarial_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=vdpf_adversarial_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/vdpf_adversarial_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/vdpf_adversarial_test.dir/build: bin/vdpf_adversarial_test +.PHONY : CMakeFiles/vdpf_adversarial_test.dir/build + +CMakeFiles/vdpf_adversarial_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/vdpf_adversarial_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/vdpf_adversarial_test.dir/clean + +CMakeFiles/vdpf_adversarial_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/DependInfo.cmake "--color=$(COLOR)" vdpf_adversarial_test +.PHONY : CMakeFiles/vdpf_adversarial_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..c8fc71f --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/vdpf_adversarial_test.dir/link.d" + "CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o" + "CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o.d" + "bin/vdpf_adversarial_test" + "bin/vdpf_adversarial_test.pdb" + "vdpf_adversarial_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/vdpf_adversarial_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/compiler_depend.make new file mode 100644 index 0000000..2e7c25d --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for vdpf_adversarial_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/compiler_depend.ts new file mode 100644 index 0000000..3dd7781 --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for vdpf_adversarial_test. diff --git a/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/depend.make b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/depend.make new file mode 100644 index 0000000..eddad3c --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for vdpf_adversarial_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/flags.make b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/link.txt b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/link.txt new file mode 100644 index 0000000..2a4821c --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/vdpf_adversarial_test.dir/link.d CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o -o bin/vdpf_adversarial_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/progress.make b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/progress.make new file mode 100644 index 0000000..8dea22a --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_adversarial_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 91 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/vdpf_regression_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/DependInfo.cmake new file mode 100644 index 0000000..ad05f9c --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/vdpf_regression_test.cpp" "CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o" "gcc" "CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o.d" + "" "bin/vdpf_regression_test" "gcc" "CMakeFiles/vdpf_regression_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/vdpf_regression_test.dir/build.make b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/build.make new file mode 100644 index 0000000..cb0dc2d --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/vdpf_regression_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/vdpf_regression_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/vdpf_regression_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/vdpf_regression_test.dir/flags.make + +CMakeFiles/vdpf_regression_test.dir/codegen: +.PHONY : CMakeFiles/vdpf_regression_test.dir/codegen + +CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o: CMakeFiles/vdpf_regression_test.dir/flags.make +CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/vdpf_regression_test.cpp +CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o: CMakeFiles/vdpf_regression_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o -MF CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o.d -o CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/vdpf_regression_test.cpp + +CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/vdpf_regression_test.cpp > CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.i + +CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/vdpf_regression_test.cpp -o CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.s + +# Object files for target vdpf_regression_test +vdpf_regression_test_OBJECTS = \ +"CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o" + +# External object files for target vdpf_regression_test +vdpf_regression_test_EXTERNAL_OBJECTS = + +bin/vdpf_regression_test: CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o +bin/vdpf_regression_test: CMakeFiles/vdpf_regression_test.dir/build.make +bin/vdpf_regression_test: CMakeFiles/vdpf_regression_test.dir/compiler_depend.ts +bin/vdpf_regression_test: lib/libgtest_main.a +bin/vdpf_regression_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/vdpf_regression_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/vdpf_regression_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/vdpf_regression_test: lib/libgtest.a +bin/vdpf_regression_test: CMakeFiles/vdpf_regression_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/vdpf_regression_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/vdpf_regression_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=vdpf_regression_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/vdpf_regression_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=vdpf_regression_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/vdpf_regression_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/vdpf_regression_test.dir/build: bin/vdpf_regression_test +.PHONY : CMakeFiles/vdpf_regression_test.dir/build + +CMakeFiles/vdpf_regression_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/vdpf_regression_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/vdpf_regression_test.dir/clean + +CMakeFiles/vdpf_regression_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/vdpf_regression_test.dir/DependInfo.cmake "--color=$(COLOR)" vdpf_regression_test +.PHONY : CMakeFiles/vdpf_regression_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/vdpf_regression_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..ad33c19 --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/vdpf_regression_test.dir/link.d" + "CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o" + "CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o.d" + "bin/vdpf_regression_test" + "bin/vdpf_regression_test.pdb" + "vdpf_regression_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/vdpf_regression_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/vdpf_regression_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/compiler_depend.make new file mode 100644 index 0000000..b6a3b6c --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for vdpf_regression_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/vdpf_regression_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/compiler_depend.ts new file mode 100644 index 0000000..9bbbb33 --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for vdpf_regression_test. diff --git a/test/build-asan/CMakeFiles/vdpf_regression_test.dir/depend.make b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/depend.make new file mode 100644 index 0000000..35cbc87 --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for vdpf_regression_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/vdpf_regression_test.dir/flags.make b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/vdpf_regression_test.dir/link.txt b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/link.txt new file mode 100644 index 0000000..0ed459e --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/vdpf_regression_test.dir/link.d CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o -o bin/vdpf_regression_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/vdpf_regression_test.dir/progress.make b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/progress.make new file mode 100644 index 0000000..9063d23 --- /dev/null +++ b/test/build-asan/CMakeFiles/vdpf_regression_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 92 + diff --git a/test/build-asan/CMakeFiles/verifiable_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/verifiable_test.dir/DependInfo.cmake new file mode 100644 index 0000000..9ffccf8 --- /dev/null +++ b/test/build-asan/CMakeFiles/verifiable_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/verifiable_test.cpp" "CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o" "gcc" "CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o.d" + "" "bin/verifiable_test" "gcc" "CMakeFiles/verifiable_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/verifiable_test.dir/build.make b/test/build-asan/CMakeFiles/verifiable_test.dir/build.make new file mode 100644 index 0000000..e4a3d02 --- /dev/null +++ b/test/build-asan/CMakeFiles/verifiable_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/verifiable_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/verifiable_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/verifiable_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/verifiable_test.dir/flags.make + +CMakeFiles/verifiable_test.dir/codegen: +.PHONY : CMakeFiles/verifiable_test.dir/codegen + +CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o: CMakeFiles/verifiable_test.dir/flags.make +CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/verifiable_test.cpp +CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o: CMakeFiles/verifiable_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o -MF CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o.d -o CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/verifiable_test.cpp + +CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/verifiable_test.cpp > CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.i + +CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/verifiable_test.cpp -o CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.s + +# Object files for target verifiable_test +verifiable_test_OBJECTS = \ +"CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o" + +# External object files for target verifiable_test +verifiable_test_EXTERNAL_OBJECTS = + +bin/verifiable_test: CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o +bin/verifiable_test: CMakeFiles/verifiable_test.dir/build.make +bin/verifiable_test: CMakeFiles/verifiable_test.dir/compiler_depend.ts +bin/verifiable_test: lib/libgtest_main.a +bin/verifiable_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/verifiable_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/verifiable_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/verifiable_test: lib/libgtest.a +bin/verifiable_test: CMakeFiles/verifiable_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/verifiable_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/verifiable_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=verifiable_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/verifiable_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=verifiable_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/verifiable_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/verifiable_test.dir/build: bin/verifiable_test +.PHONY : CMakeFiles/verifiable_test.dir/build + +CMakeFiles/verifiable_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/verifiable_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/verifiable_test.dir/clean + +CMakeFiles/verifiable_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/verifiable_test.dir/DependInfo.cmake "--color=$(COLOR)" verifiable_test +.PHONY : CMakeFiles/verifiable_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/verifiable_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/verifiable_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..63b04e9 --- /dev/null +++ b/test/build-asan/CMakeFiles/verifiable_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/verifiable_test.dir/link.d" + "CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o" + "CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o.d" + "bin/verifiable_test" + "bin/verifiable_test.pdb" + "verifiable_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/verifiable_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/verifiable_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/verifiable_test.dir/compiler_depend.make new file mode 100644 index 0000000..b24a682 --- /dev/null +++ b/test/build-asan/CMakeFiles/verifiable_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for verifiable_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/verifiable_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/verifiable_test.dir/compiler_depend.ts new file mode 100644 index 0000000..95b6974 --- /dev/null +++ b/test/build-asan/CMakeFiles/verifiable_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for verifiable_test. diff --git a/test/build-asan/CMakeFiles/verifiable_test.dir/depend.make b/test/build-asan/CMakeFiles/verifiable_test.dir/depend.make new file mode 100644 index 0000000..f335ce9 --- /dev/null +++ b/test/build-asan/CMakeFiles/verifiable_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for verifiable_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/verifiable_test.dir/flags.make b/test/build-asan/CMakeFiles/verifiable_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/verifiable_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/verifiable_test.dir/link.txt b/test/build-asan/CMakeFiles/verifiable_test.dir/link.txt new file mode 100644 index 0000000..9b85fd4 --- /dev/null +++ b/test/build-asan/CMakeFiles/verifiable_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/verifiable_test.dir/link.d CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o -o bin/verifiable_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/verifiable_test.dir/progress.make b/test/build-asan/CMakeFiles/verifiable_test.dir/progress.make new file mode 100644 index 0000000..7614da1 --- /dev/null +++ b/test/build-asan/CMakeFiles/verifiable_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 93 + diff --git a/test/build-asan/CMakeFiles/walk_helpers_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/walk_helpers_test.dir/DependInfo.cmake new file mode 100644 index 0000000..68923ba --- /dev/null +++ b/test/build-asan/CMakeFiles/walk_helpers_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/walk_helpers_test.cpp" "CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o" "gcc" "CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o.d" + "" "bin/walk_helpers_test" "gcc" "CMakeFiles/walk_helpers_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/walk_helpers_test.dir/build.make b/test/build-asan/CMakeFiles/walk_helpers_test.dir/build.make new file mode 100644 index 0000000..c8234ea --- /dev/null +++ b/test/build-asan/CMakeFiles/walk_helpers_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/walk_helpers_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/walk_helpers_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/walk_helpers_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/walk_helpers_test.dir/flags.make + +CMakeFiles/walk_helpers_test.dir/codegen: +.PHONY : CMakeFiles/walk_helpers_test.dir/codegen + +CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o: CMakeFiles/walk_helpers_test.dir/flags.make +CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/walk_helpers_test.cpp +CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o: CMakeFiles/walk_helpers_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o -MF CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o.d -o CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/walk_helpers_test.cpp + +CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/walk_helpers_test.cpp > CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.i + +CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/walk_helpers_test.cpp -o CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.s + +# Object files for target walk_helpers_test +walk_helpers_test_OBJECTS = \ +"CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o" + +# External object files for target walk_helpers_test +walk_helpers_test_EXTERNAL_OBJECTS = + +bin/walk_helpers_test: CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o +bin/walk_helpers_test: CMakeFiles/walk_helpers_test.dir/build.make +bin/walk_helpers_test: CMakeFiles/walk_helpers_test.dir/compiler_depend.ts +bin/walk_helpers_test: lib/libgtest_main.a +bin/walk_helpers_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/walk_helpers_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/walk_helpers_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/walk_helpers_test: lib/libgtest.a +bin/walk_helpers_test: CMakeFiles/walk_helpers_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/walk_helpers_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/walk_helpers_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=walk_helpers_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/walk_helpers_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=walk_helpers_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/walk_helpers_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/walk_helpers_test.dir/build: bin/walk_helpers_test +.PHONY : CMakeFiles/walk_helpers_test.dir/build + +CMakeFiles/walk_helpers_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/walk_helpers_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/walk_helpers_test.dir/clean + +CMakeFiles/walk_helpers_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/walk_helpers_test.dir/DependInfo.cmake "--color=$(COLOR)" walk_helpers_test +.PHONY : CMakeFiles/walk_helpers_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/walk_helpers_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/walk_helpers_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..7a1e18c --- /dev/null +++ b/test/build-asan/CMakeFiles/walk_helpers_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/walk_helpers_test.dir/link.d" + "CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o" + "CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o.d" + "bin/walk_helpers_test" + "bin/walk_helpers_test.pdb" + "walk_helpers_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/walk_helpers_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/walk_helpers_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/walk_helpers_test.dir/compiler_depend.make new file mode 100644 index 0000000..ef5764d --- /dev/null +++ b/test/build-asan/CMakeFiles/walk_helpers_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for walk_helpers_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/walk_helpers_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/walk_helpers_test.dir/compiler_depend.ts new file mode 100644 index 0000000..7b3297c --- /dev/null +++ b/test/build-asan/CMakeFiles/walk_helpers_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for walk_helpers_test. diff --git a/test/build-asan/CMakeFiles/walk_helpers_test.dir/depend.make b/test/build-asan/CMakeFiles/walk_helpers_test.dir/depend.make new file mode 100644 index 0000000..4a16ac3 --- /dev/null +++ b/test/build-asan/CMakeFiles/walk_helpers_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for walk_helpers_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/walk_helpers_test.dir/flags.make b/test/build-asan/CMakeFiles/walk_helpers_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/walk_helpers_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/walk_helpers_test.dir/link.txt b/test/build-asan/CMakeFiles/walk_helpers_test.dir/link.txt new file mode 100644 index 0000000..fb7b665 --- /dev/null +++ b/test/build-asan/CMakeFiles/walk_helpers_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/walk_helpers_test.dir/link.d CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o -o bin/walk_helpers_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/walk_helpers_test.dir/progress.make b/test/build-asan/CMakeFiles/walk_helpers_test.dir/progress.make new file mode 100644 index 0000000..2c3143a --- /dev/null +++ b/test/build-asan/CMakeFiles/walk_helpers_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 94 + diff --git a/test/build-asan/CMakeFiles/wide_payload_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/wide_payload_test.dir/DependInfo.cmake new file mode 100644 index 0000000..47cdda7 --- /dev/null +++ b/test/build-asan/CMakeFiles/wide_payload_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/wide_payload_test.cpp" "CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o" "gcc" "CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o.d" + "" "bin/wide_payload_test" "gcc" "CMakeFiles/wide_payload_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/wide_payload_test.dir/build.make b/test/build-asan/CMakeFiles/wide_payload_test.dir/build.make new file mode 100644 index 0000000..5b74fd4 --- /dev/null +++ b/test/build-asan/CMakeFiles/wide_payload_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/wide_payload_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/wide_payload_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/wide_payload_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/wide_payload_test.dir/flags.make + +CMakeFiles/wide_payload_test.dir/codegen: +.PHONY : CMakeFiles/wide_payload_test.dir/codegen + +CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o: CMakeFiles/wide_payload_test.dir/flags.make +CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/wide_payload_test.cpp +CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o: CMakeFiles/wide_payload_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o -MF CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o.d -o CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/wide_payload_test.cpp + +CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/wide_payload_test.cpp > CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.i + +CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/wide_payload_test.cpp -o CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.s + +# Object files for target wide_payload_test +wide_payload_test_OBJECTS = \ +"CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o" + +# External object files for target wide_payload_test +wide_payload_test_EXTERNAL_OBJECTS = + +bin/wide_payload_test: CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o +bin/wide_payload_test: CMakeFiles/wide_payload_test.dir/build.make +bin/wide_payload_test: CMakeFiles/wide_payload_test.dir/compiler_depend.ts +bin/wide_payload_test: lib/libgtest_main.a +bin/wide_payload_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/wide_payload_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/wide_payload_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/wide_payload_test: lib/libgtest.a +bin/wide_payload_test: CMakeFiles/wide_payload_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/wide_payload_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/wide_payload_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=wide_payload_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/wide_payload_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=wide_payload_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/wide_payload_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/wide_payload_test.dir/build: bin/wide_payload_test +.PHONY : CMakeFiles/wide_payload_test.dir/build + +CMakeFiles/wide_payload_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/wide_payload_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/wide_payload_test.dir/clean + +CMakeFiles/wide_payload_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/wide_payload_test.dir/DependInfo.cmake "--color=$(COLOR)" wide_payload_test +.PHONY : CMakeFiles/wide_payload_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/wide_payload_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/wide_payload_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..dab5f0e --- /dev/null +++ b/test/build-asan/CMakeFiles/wide_payload_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/wide_payload_test.dir/link.d" + "CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o" + "CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o.d" + "bin/wide_payload_test" + "bin/wide_payload_test.pdb" + "wide_payload_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/wide_payload_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/wide_payload_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/wide_payload_test.dir/compiler_depend.make new file mode 100644 index 0000000..6a9ee4d --- /dev/null +++ b/test/build-asan/CMakeFiles/wide_payload_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for wide_payload_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/wide_payload_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/wide_payload_test.dir/compiler_depend.ts new file mode 100644 index 0000000..e3f5518 --- /dev/null +++ b/test/build-asan/CMakeFiles/wide_payload_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for wide_payload_test. diff --git a/test/build-asan/CMakeFiles/wide_payload_test.dir/depend.make b/test/build-asan/CMakeFiles/wide_payload_test.dir/depend.make new file mode 100644 index 0000000..4bf792d --- /dev/null +++ b/test/build-asan/CMakeFiles/wide_payload_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for wide_payload_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/wide_payload_test.dir/flags.make b/test/build-asan/CMakeFiles/wide_payload_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/wide_payload_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/wide_payload_test.dir/link.txt b/test/build-asan/CMakeFiles/wide_payload_test.dir/link.txt new file mode 100644 index 0000000..4b0e837 --- /dev/null +++ b/test/build-asan/CMakeFiles/wide_payload_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/wide_payload_test.dir/link.d CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o -o bin/wide_payload_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/wide_payload_test.dir/progress.make b/test/build-asan/CMakeFiles/wide_payload_test.dir/progress.make new file mode 100644 index 0000000..6c287f1 --- /dev/null +++ b/test/build-asan/CMakeFiles/wide_payload_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/wildcard_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/wildcard_test.dir/DependInfo.cmake new file mode 100644 index 0000000..7083133 --- /dev/null +++ b/test/build-asan/CMakeFiles/wildcard_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/wildcard_test.cpp" "CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o" "gcc" "CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o.d" + "" "bin/wildcard_test" "gcc" "CMakeFiles/wildcard_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/wildcard_test.dir/build.make b/test/build-asan/CMakeFiles/wildcard_test.dir/build.make new file mode 100644 index 0000000..376eefb --- /dev/null +++ b/test/build-asan/CMakeFiles/wildcard_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/wildcard_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/wildcard_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/wildcard_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/wildcard_test.dir/flags.make + +CMakeFiles/wildcard_test.dir/codegen: +.PHONY : CMakeFiles/wildcard_test.dir/codegen + +CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o: CMakeFiles/wildcard_test.dir/flags.make +CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/wildcard_test.cpp +CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o: CMakeFiles/wildcard_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o -MF CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o.d -o CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/wildcard_test.cpp + +CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/wildcard_test.cpp > CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.i + +CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/wildcard_test.cpp -o CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.s + +# Object files for target wildcard_test +wildcard_test_OBJECTS = \ +"CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o" + +# External object files for target wildcard_test +wildcard_test_EXTERNAL_OBJECTS = + +bin/wildcard_test: CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o +bin/wildcard_test: CMakeFiles/wildcard_test.dir/build.make +bin/wildcard_test: CMakeFiles/wildcard_test.dir/compiler_depend.ts +bin/wildcard_test: lib/libgtest_main.a +bin/wildcard_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/wildcard_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/wildcard_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/wildcard_test: lib/libgtest.a +bin/wildcard_test: CMakeFiles/wildcard_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/wildcard_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/wildcard_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=wildcard_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/wildcard_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=wildcard_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/wildcard_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/wildcard_test.dir/build: bin/wildcard_test +.PHONY : CMakeFiles/wildcard_test.dir/build + +CMakeFiles/wildcard_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/wildcard_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/wildcard_test.dir/clean + +CMakeFiles/wildcard_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/wildcard_test.dir/DependInfo.cmake "--color=$(COLOR)" wildcard_test +.PHONY : CMakeFiles/wildcard_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/wildcard_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/wildcard_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..a69f8b1 --- /dev/null +++ b/test/build-asan/CMakeFiles/wildcard_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/wildcard_test.dir/link.d" + "CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o" + "CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o.d" + "bin/wildcard_test" + "bin/wildcard_test.pdb" + "wildcard_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/wildcard_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/wildcard_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/wildcard_test.dir/compiler_depend.make new file mode 100644 index 0000000..a1a71b4 --- /dev/null +++ b/test/build-asan/CMakeFiles/wildcard_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for wildcard_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/wildcard_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/wildcard_test.dir/compiler_depend.ts new file mode 100644 index 0000000..099375b --- /dev/null +++ b/test/build-asan/CMakeFiles/wildcard_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for wildcard_test. diff --git a/test/build-asan/CMakeFiles/wildcard_test.dir/depend.make b/test/build-asan/CMakeFiles/wildcard_test.dir/depend.make new file mode 100644 index 0000000..3d13ec3 --- /dev/null +++ b/test/build-asan/CMakeFiles/wildcard_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for wildcard_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/wildcard_test.dir/flags.make b/test/build-asan/CMakeFiles/wildcard_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/wildcard_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/wildcard_test.dir/link.txt b/test/build-asan/CMakeFiles/wildcard_test.dir/link.txt new file mode 100644 index 0000000..26f8528 --- /dev/null +++ b/test/build-asan/CMakeFiles/wildcard_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/wildcard_test.dir/link.d CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o -o bin/wildcard_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/wildcard_test.dir/progress.make b/test/build-asan/CMakeFiles/wildcard_test.dir/progress.make new file mode 100644 index 0000000..c16f3dd --- /dev/null +++ b/test/build-asan/CMakeFiles/wildcard_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 95 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/window_lut_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/window_lut_test.dir/DependInfo.cmake new file mode 100644 index 0000000..e41b7be --- /dev/null +++ b/test/build-asan/CMakeFiles/window_lut_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/window_lut_test.cpp" "CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o" "gcc" "CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o.d" + "" "bin/window_lut_test" "gcc" "CMakeFiles/window_lut_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/window_lut_test.dir/build.make b/test/build-asan/CMakeFiles/window_lut_test.dir/build.make new file mode 100644 index 0000000..7df09ed --- /dev/null +++ b/test/build-asan/CMakeFiles/window_lut_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/window_lut_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/window_lut_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/window_lut_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/window_lut_test.dir/flags.make + +CMakeFiles/window_lut_test.dir/codegen: +.PHONY : CMakeFiles/window_lut_test.dir/codegen + +CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o: CMakeFiles/window_lut_test.dir/flags.make +CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/window_lut_test.cpp +CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o: CMakeFiles/window_lut_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o -MF CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o.d -o CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/window_lut_test.cpp + +CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/window_lut_test.cpp > CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.i + +CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/window_lut_test.cpp -o CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.s + +# Object files for target window_lut_test +window_lut_test_OBJECTS = \ +"CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o" + +# External object files for target window_lut_test +window_lut_test_EXTERNAL_OBJECTS = + +bin/window_lut_test: CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o +bin/window_lut_test: CMakeFiles/window_lut_test.dir/build.make +bin/window_lut_test: CMakeFiles/window_lut_test.dir/compiler_depend.ts +bin/window_lut_test: lib/libgtest_main.a +bin/window_lut_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/window_lut_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/window_lut_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/window_lut_test: lib/libgtest.a +bin/window_lut_test: CMakeFiles/window_lut_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/window_lut_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/window_lut_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=window_lut_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/window_lut_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=window_lut_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/window_lut_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/window_lut_test.dir/build: bin/window_lut_test +.PHONY : CMakeFiles/window_lut_test.dir/build + +CMakeFiles/window_lut_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/window_lut_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/window_lut_test.dir/clean + +CMakeFiles/window_lut_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/window_lut_test.dir/DependInfo.cmake "--color=$(COLOR)" window_lut_test +.PHONY : CMakeFiles/window_lut_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/window_lut_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/window_lut_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..c81d9e3 --- /dev/null +++ b/test/build-asan/CMakeFiles/window_lut_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/window_lut_test.dir/link.d" + "CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o" + "CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o.d" + "bin/window_lut_test" + "bin/window_lut_test.pdb" + "window_lut_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/window_lut_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/window_lut_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/window_lut_test.dir/compiler_depend.make new file mode 100644 index 0000000..59c1c91 --- /dev/null +++ b/test/build-asan/CMakeFiles/window_lut_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for window_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/window_lut_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/window_lut_test.dir/compiler_depend.ts new file mode 100644 index 0000000..bf80c0e --- /dev/null +++ b/test/build-asan/CMakeFiles/window_lut_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for window_lut_test. diff --git a/test/build-asan/CMakeFiles/window_lut_test.dir/depend.make b/test/build-asan/CMakeFiles/window_lut_test.dir/depend.make new file mode 100644 index 0000000..cea898b --- /dev/null +++ b/test/build-asan/CMakeFiles/window_lut_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for window_lut_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/window_lut_test.dir/flags.make b/test/build-asan/CMakeFiles/window_lut_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/window_lut_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/window_lut_test.dir/link.txt b/test/build-asan/CMakeFiles/window_lut_test.dir/link.txt new file mode 100644 index 0000000..6f29484 --- /dev/null +++ b/test/build-asan/CMakeFiles/window_lut_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/window_lut_test.dir/link.d CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o -o bin/window_lut_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/window_lut_test.dir/progress.make b/test/build-asan/CMakeFiles/window_lut_test.dir/progress.make new file mode 100644 index 0000000..761d6c5 --- /dev/null +++ b/test/build-asan/CMakeFiles/window_lut_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 96 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/DependInfo.cmake new file mode 100644 index 0000000..6bc9f88 --- /dev/null +++ b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/wrap_and_rotate_test.cpp" "CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o" "gcc" "CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o.d" + "" "bin/wrap_and_rotate_test" "gcc" "CMakeFiles/wrap_and_rotate_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/build.make b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/build.make new file mode 100644 index 0000000..d44ca4f --- /dev/null +++ b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/wrap_and_rotate_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/wrap_and_rotate_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/wrap_and_rotate_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/wrap_and_rotate_test.dir/flags.make + +CMakeFiles/wrap_and_rotate_test.dir/codegen: +.PHONY : CMakeFiles/wrap_and_rotate_test.dir/codegen + +CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o: CMakeFiles/wrap_and_rotate_test.dir/flags.make +CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/wrap_and_rotate_test.cpp +CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o: CMakeFiles/wrap_and_rotate_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o -MF CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o.d -o CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/wrap_and_rotate_test.cpp + +CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/wrap_and_rotate_test.cpp > CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.i + +CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/wrap_and_rotate_test.cpp -o CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.s + +# Object files for target wrap_and_rotate_test +wrap_and_rotate_test_OBJECTS = \ +"CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o" + +# External object files for target wrap_and_rotate_test +wrap_and_rotate_test_EXTERNAL_OBJECTS = + +bin/wrap_and_rotate_test: CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o +bin/wrap_and_rotate_test: CMakeFiles/wrap_and_rotate_test.dir/build.make +bin/wrap_and_rotate_test: CMakeFiles/wrap_and_rotate_test.dir/compiler_depend.ts +bin/wrap_and_rotate_test: lib/libgtest_main.a +bin/wrap_and_rotate_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/wrap_and_rotate_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/wrap_and_rotate_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/wrap_and_rotate_test: lib/libgtest.a +bin/wrap_and_rotate_test: CMakeFiles/wrap_and_rotate_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/wrap_and_rotate_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/wrap_and_rotate_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=wrap_and_rotate_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/wrap_and_rotate_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=wrap_and_rotate_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/wrap_and_rotate_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/wrap_and_rotate_test.dir/build: bin/wrap_and_rotate_test +.PHONY : CMakeFiles/wrap_and_rotate_test.dir/build + +CMakeFiles/wrap_and_rotate_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/wrap_and_rotate_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/wrap_and_rotate_test.dir/clean + +CMakeFiles/wrap_and_rotate_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/DependInfo.cmake "--color=$(COLOR)" wrap_and_rotate_test +.PHONY : CMakeFiles/wrap_and_rotate_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..94d63c2 --- /dev/null +++ b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/wrap_and_rotate_test.dir/link.d" + "CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o" + "CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o.d" + "bin/wrap_and_rotate_test" + "bin/wrap_and_rotate_test.pdb" + "wrap_and_rotate_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/wrap_and_rotate_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/compiler_depend.make new file mode 100644 index 0000000..da20451 --- /dev/null +++ b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for wrap_and_rotate_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/compiler_depend.ts new file mode 100644 index 0000000..2ef038c --- /dev/null +++ b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for wrap_and_rotate_test. diff --git a/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/depend.make b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/depend.make new file mode 100644 index 0000000..cd4b40c --- /dev/null +++ b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for wrap_and_rotate_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/flags.make b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/link.txt b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/link.txt new file mode 100644 index 0000000..b0ed8b1 --- /dev/null +++ b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/wrap_and_rotate_test.dir/link.d CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o -o bin/wrap_and_rotate_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/progress.make b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/progress.make new file mode 100644 index 0000000..cf90e91 --- /dev/null +++ b/test/build-asan/CMakeFiles/wrap_and_rotate_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = 97 +CMAKE_PROGRESS_2 = + diff --git a/test/build-asan/CMakeFiles/yao_share_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/yao_share_test.dir/DependInfo.cmake new file mode 100644 index 0000000..6a8ac4b --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_share_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_share_test.cpp" "CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o" "gcc" "CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o.d" + "" "bin/yao_share_test" "gcc" "CMakeFiles/yao_share_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/yao_share_test.dir/build.make b/test/build-asan/CMakeFiles/yao_share_test.dir/build.make new file mode 100644 index 0000000..358a2b3 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_share_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/yao_share_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/yao_share_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/yao_share_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/yao_share_test.dir/flags.make + +CMakeFiles/yao_share_test.dir/codegen: +.PHONY : CMakeFiles/yao_share_test.dir/codegen + +CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o: CMakeFiles/yao_share_test.dir/flags.make +CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_share_test.cpp +CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o: CMakeFiles/yao_share_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o -MF CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o.d -o CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_share_test.cpp + +CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_share_test.cpp > CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.i + +CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_share_test.cpp -o CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.s + +# Object files for target yao_share_test +yao_share_test_OBJECTS = \ +"CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o" + +# External object files for target yao_share_test +yao_share_test_EXTERNAL_OBJECTS = + +bin/yao_share_test: CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o +bin/yao_share_test: CMakeFiles/yao_share_test.dir/build.make +bin/yao_share_test: CMakeFiles/yao_share_test.dir/compiler_depend.ts +bin/yao_share_test: lib/libgtest_main.a +bin/yao_share_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/yao_share_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/yao_share_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/yao_share_test: lib/libgtest.a +bin/yao_share_test: CMakeFiles/yao_share_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/yao_share_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/yao_share_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=yao_share_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/yao_share_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=yao_share_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/yao_share_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/yao_share_test.dir/build: bin/yao_share_test +.PHONY : CMakeFiles/yao_share_test.dir/build + +CMakeFiles/yao_share_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/yao_share_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/yao_share_test.dir/clean + +CMakeFiles/yao_share_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/yao_share_test.dir/DependInfo.cmake "--color=$(COLOR)" yao_share_test +.PHONY : CMakeFiles/yao_share_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/yao_share_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/yao_share_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..09a7892 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_share_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/yao_share_test.dir/link.d" + "CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o" + "CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o.d" + "bin/yao_share_test" + "bin/yao_share_test.pdb" + "yao_share_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/yao_share_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/yao_share_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/yao_share_test.dir/compiler_depend.make new file mode 100644 index 0000000..db7d5de --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_share_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for yao_share_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/yao_share_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/yao_share_test.dir/compiler_depend.ts new file mode 100644 index 0000000..0b27075 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_share_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for yao_share_test. diff --git a/test/build-asan/CMakeFiles/yao_share_test.dir/depend.make b/test/build-asan/CMakeFiles/yao_share_test.dir/depend.make new file mode 100644 index 0000000..89e7ac1 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_share_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for yao_share_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/yao_share_test.dir/flags.make b/test/build-asan/CMakeFiles/yao_share_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_share_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/yao_share_test.dir/link.txt b/test/build-asan/CMakeFiles/yao_share_test.dir/link.txt new file mode 100644 index 0000000..fca148e --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_share_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/yao_share_test.dir/link.d CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o -o bin/yao_share_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/yao_share_test.dir/progress.make b/test/build-asan/CMakeFiles/yao_share_test.dir/progress.make new file mode 100644 index 0000000..0d87696 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_share_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 98 + diff --git a/test/build-asan/CMakeFiles/yao_stack_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/yao_stack_test.dir/DependInfo.cmake new file mode 100644 index 0000000..a0cabb9 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_stack_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_stack_test.cpp" "CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o" "gcc" "CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o.d" + "" "bin/yao_stack_test" "gcc" "CMakeFiles/yao_stack_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/yao_stack_test.dir/build.make b/test/build-asan/CMakeFiles/yao_stack_test.dir/build.make new file mode 100644 index 0000000..43a95d1 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_stack_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/yao_stack_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/yao_stack_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/yao_stack_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/yao_stack_test.dir/flags.make + +CMakeFiles/yao_stack_test.dir/codegen: +.PHONY : CMakeFiles/yao_stack_test.dir/codegen + +CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o: CMakeFiles/yao_stack_test.dir/flags.make +CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_stack_test.cpp +CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o: CMakeFiles/yao_stack_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o -MF CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o.d -o CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_stack_test.cpp + +CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_stack_test.cpp > CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.i + +CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_stack_test.cpp -o CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.s + +# Object files for target yao_stack_test +yao_stack_test_OBJECTS = \ +"CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o" + +# External object files for target yao_stack_test +yao_stack_test_EXTERNAL_OBJECTS = + +bin/yao_stack_test: CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o +bin/yao_stack_test: CMakeFiles/yao_stack_test.dir/build.make +bin/yao_stack_test: CMakeFiles/yao_stack_test.dir/compiler_depend.ts +bin/yao_stack_test: lib/libgtest_main.a +bin/yao_stack_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/yao_stack_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/yao_stack_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/yao_stack_test: lib/libgtest.a +bin/yao_stack_test: CMakeFiles/yao_stack_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/yao_stack_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/yao_stack_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=yao_stack_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/yao_stack_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=yao_stack_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/yao_stack_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/yao_stack_test.dir/build: bin/yao_stack_test +.PHONY : CMakeFiles/yao_stack_test.dir/build + +CMakeFiles/yao_stack_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/yao_stack_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/yao_stack_test.dir/clean + +CMakeFiles/yao_stack_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/yao_stack_test.dir/DependInfo.cmake "--color=$(COLOR)" yao_stack_test +.PHONY : CMakeFiles/yao_stack_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/yao_stack_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/yao_stack_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..65ce87e --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_stack_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/yao_stack_test.dir/link.d" + "CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o" + "CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o.d" + "bin/yao_stack_test" + "bin/yao_stack_test.pdb" + "yao_stack_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/yao_stack_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/yao_stack_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/yao_stack_test.dir/compiler_depend.make new file mode 100644 index 0000000..33df794 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_stack_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for yao_stack_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/yao_stack_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/yao_stack_test.dir/compiler_depend.ts new file mode 100644 index 0000000..fcd5288 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_stack_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for yao_stack_test. diff --git a/test/build-asan/CMakeFiles/yao_stack_test.dir/depend.make b/test/build-asan/CMakeFiles/yao_stack_test.dir/depend.make new file mode 100644 index 0000000..5f09f84 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_stack_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for yao_stack_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/yao_stack_test.dir/flags.make b/test/build-asan/CMakeFiles/yao_stack_test.dir/flags.make new file mode 100644 index 0000000..449ed82 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_stack_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result + diff --git a/test/build-asan/CMakeFiles/yao_stack_test.dir/link.txt b/test/build-asan/CMakeFiles/yao_stack_test.dir/link.txt new file mode 100644 index 0000000..2667cb5 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_stack_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/yao_stack_test.dir/link.d CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o -o bin/yao_stack_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/yao_stack_test.dir/progress.make b/test/build-asan/CMakeFiles/yao_stack_test.dir/progress.make new file mode 100644 index 0000000..f4a80ec --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_stack_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 99 + diff --git a/test/build-asan/CMakeFiles/yao_test.dir/DependInfo.cmake b/test/build-asan/CMakeFiles/yao_test.dir/DependInfo.cmake new file mode 100644 index 0000000..41be535 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_test.dir/DependInfo.cmake @@ -0,0 +1,24 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_test.cpp" "CMakeFiles/yao_test.dir/tests/yao_test.cpp.o" "gcc" "CMakeFiles/yao_test.dir/tests/yao_test.cpp.o.d" + "" "bin/yao_test" "gcc" "CMakeFiles/yao_test.dir/link.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/CMakeFiles/yao_test.dir/build.make b/test/build-asan/CMakeFiles/yao_test.dir/build.make new file mode 100644 index 0000000..c9d0010 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_test.dir/build.make @@ -0,0 +1,120 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include CMakeFiles/yao_test.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include CMakeFiles/yao_test.dir/compiler_depend.make + +# Include the progress variables for this target. +include CMakeFiles/yao_test.dir/progress.make + +# Include the compile flags for this target's objects. +include CMakeFiles/yao_test.dir/flags.make + +CMakeFiles/yao_test.dir/codegen: +.PHONY : CMakeFiles/yao_test.dir/codegen + +CMakeFiles/yao_test.dir/tests/yao_test.cpp.o: CMakeFiles/yao_test.dir/flags.make +CMakeFiles/yao_test.dir/tests/yao_test.cpp.o: /home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_test.cpp +CMakeFiles/yao_test.dir/tests/yao_test.cpp.o: CMakeFiles/yao_test.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object CMakeFiles/yao_test.dir/tests/yao_test.cpp.o" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT CMakeFiles/yao_test.dir/tests/yao_test.cpp.o -MF CMakeFiles/yao_test.dir/tests/yao_test.cpp.o.d -o CMakeFiles/yao_test.dir/tests/yao_test.cpp.o -c /home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_test.cpp + +CMakeFiles/yao_test.dir/tests/yao_test.cpp.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/yao_test.dir/tests/yao_test.cpp.i" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_test.cpp > CMakeFiles/yao_test.dir/tests/yao_test.cpp.i + +CMakeFiles/yao_test.dir/tests/yao_test.cpp.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/yao_test.dir/tests/yao_test.cpp.s" + /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/tests/yao_test.cpp -o CMakeFiles/yao_test.dir/tests/yao_test.cpp.s + +# Object files for target yao_test +yao_test_OBJECTS = \ +"CMakeFiles/yao_test.dir/tests/yao_test.cpp.o" + +# External object files for target yao_test +yao_test_EXTERNAL_OBJECTS = + +bin/yao_test: CMakeFiles/yao_test.dir/tests/yao_test.cpp.o +bin/yao_test: CMakeFiles/yao_test.dir/build.make +bin/yao_test: CMakeFiles/yao_test.dir/compiler_depend.ts +bin/yao_test: lib/libgtest_main.a +bin/yao_test: /usr/lib/x86_64-linux-gnu/libsctp.so +bin/yao_test: /usr/lib/x86_64-linux-gnu/libssl.so +bin/yao_test: /usr/lib/x86_64-linux-gnu/libcrypto.so +bin/yao_test: lib/libgtest.a +bin/yao_test: CMakeFiles/yao_test.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable bin/yao_test" + $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/yao_test.dir/link.txt --verbose=$(VERBOSE) + /usr/bin/cmake -D TEST_TARGET=yao_test -D TEST_EXECUTABLE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/yao_test -D TEST_EXECUTOR= -D TEST_WORKING_DIR=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_FILTER= -D NO_PRETTY_TYPES=FALSE -D NO_PRETTY_VALUES=FALSE -D TEST_LIST=yao_test_TESTS -D CTEST_FILE=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/yao_test[1]_tests.cmake -D TEST_DISCOVERY_TIMEOUT=5 -D TEST_DISCOVERY_EXTRA_ARGS= -D TEST_XML_OUTPUT_DIR= -P /usr/share/cmake-4.2/Modules/GoogleTestAddTests.cmake + +# Rule to build all files generated by this target. +CMakeFiles/yao_test.dir/build: bin/yao_test +.PHONY : CMakeFiles/yao_test.dir/build + +CMakeFiles/yao_test.dir/clean: + $(CMAKE_COMMAND) -P CMakeFiles/yao_test.dir/cmake_clean.cmake +.PHONY : CMakeFiles/yao_test.dir/clean + +CMakeFiles/yao_test.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles/yao_test.dir/DependInfo.cmake "--color=$(COLOR)" yao_test +.PHONY : CMakeFiles/yao_test.dir/depend + diff --git a/test/build-asan/CMakeFiles/yao_test.dir/cmake_clean.cmake b/test/build-asan/CMakeFiles/yao_test.dir/cmake_clean.cmake new file mode 100644 index 0000000..31f855d --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_test.dir/cmake_clean.cmake @@ -0,0 +1,13 @@ +file(REMOVE_RECURSE + "CMakeFiles/yao_test.dir/link.d" + "CMakeFiles/yao_test.dir/tests/yao_test.cpp.o" + "CMakeFiles/yao_test.dir/tests/yao_test.cpp.o.d" + "bin/yao_test" + "bin/yao_test.pdb" + "yao_test[1]_tests.cmake" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/yao_test.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/CMakeFiles/yao_test.dir/compiler_depend.make b/test/build-asan/CMakeFiles/yao_test.dir/compiler_depend.make new file mode 100644 index 0000000..ae2524e --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_test.dir/compiler_depend.make @@ -0,0 +1,2 @@ +# Empty compiler generated dependencies file for yao_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/yao_test.dir/compiler_depend.ts b/test/build-asan/CMakeFiles/yao_test.dir/compiler_depend.ts new file mode 100644 index 0000000..befe26a --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_test.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for yao_test. diff --git a/test/build-asan/CMakeFiles/yao_test.dir/depend.make b/test/build-asan/CMakeFiles/yao_test.dir/depend.make new file mode 100644 index 0000000..37b551b --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_test.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for yao_test. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/CMakeFiles/yao_test.dir/flags.make b/test/build-asan/CMakeFiles/yao_test.dir/flags.make new file mode 100644 index 0000000..1a3a08d --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_test.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = -DLIBDPF_GIT_REV=\"695f8e84f7f4-dirty\" + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/../include -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty -I/home/cryptolicious/hushmap-specified/libdpf/test/../thirdparty/asio/asio/include -I/home/cryptolicious/hushmap-specified/libdpf/test/../party -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=gnu++17 -march=native -Wall -Wextra -Wpedantic -Wno-pedantic -Wno-dangling-else -Wno-ignored-attributes -Wno-stringop-overflow -Wno-unused-result -O2 + diff --git a/test/build-asan/CMakeFiles/yao_test.dir/link.txt b/test/build-asan/CMakeFiles/yao_test.dir/link.txt new file mode 100644 index 0000000..6f23ba0 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_test.dir/link.txt @@ -0,0 +1 @@ +/usr/bin/c++ -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -fsanitize=address,undefined -Wl,--dependency-file=CMakeFiles/yao_test.dir/link.d CMakeFiles/yao_test.dir/tests/yao_test.cpp.o -o bin/yao_test lib/libgtest_main.a -lbsd /usr/lib/x86_64-linux-gnu/libsctp.so /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so -lpthread lib/libgtest.a diff --git a/test/build-asan/CMakeFiles/yao_test.dir/progress.make b/test/build-asan/CMakeFiles/yao_test.dir/progress.make new file mode 100644 index 0000000..1f1e9c2 --- /dev/null +++ b/test/build-asan/CMakeFiles/yao_test.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 100 + diff --git a/test/build-asan/CTestTestfile.cmake b/test/build-asan/CTestTestfile.cmake new file mode 100644 index 0000000..8695423 --- /dev/null +++ b/test/build-asan/CTestTestfile.cmake @@ -0,0 +1,113 @@ +# CMake generated Testfile for +# Source directory: /home/cryptolicious/hushmap-specified/libdpf/test +# Build directory: /home/cryptolicious/hushmap-specified/libdpf/test/build-asan +# +# This file includes the relevant testing commands required for +# testing this directory and lists subdirectories to be tested as well. +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/yao_share_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/yao_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/yao_stack_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/arith_garble_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/flute_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/shuffle_hidden_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bench_cell_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/iknp_party_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dpf_key_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/wildcard_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_point_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_interval_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_full_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_sequence_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_point_multi_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_interval_multi_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_full_multi_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_sequence_multi_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/advice_bit_iterable_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bit_array_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/parallel_bit_iterable_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/setbit_index_iterable_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/incremental_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/path_recipe_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/blocked_dcf_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/geneval_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/stress_scenarios_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/incremental_json_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/keyword2_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/types_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/packed_lane_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bitmore_mod_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/lane_blast_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/context_blast_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/random_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/prg_lowmc_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/prg_chacha_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/prg_aes_ccr_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/half_tree_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/constrained_cmp_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/fp61_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/field_output_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/gf2_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/gf2_adversarial_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/arith_payload_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/verifiable_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/vdpf_adversarial_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/shamir_adversarial_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/vdpf_regression_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/opt_in_malicious_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/multipoint_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dpf3_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_inner_product_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/shared_and_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/cohort_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/interleave_leaves_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/secret_share_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/beaver_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/share_runtime_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/net_control_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/security_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/protocol_batch_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/compose_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/experiment_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/log_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/beaver_party_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/constant_lut_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/signed_prefix_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/easy_lut_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dyadic_lut_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/nmod_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/exact_steps_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/closed_form_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/principal_lut_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/range_lut_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/window_lut_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dwt_lut_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_horner_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_poly_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/lut_union_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_jet_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_repr_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_twist_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/ring_switch_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/ic_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/wide_payload_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/corner_gaps_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/carry_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/fixedpoint_beaver_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/class_sweep_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/extractable_full_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/walk_helpers_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/domain128_point_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/blob_leaf_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/growing_idpf_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/pprf_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/ppvc_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/leaf_later_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/caller_fold_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/defer_eval_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/wrap_and_rotate_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/sfss_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/path_sketch_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_until_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/idpf_agg_test[1]_include.cmake") +include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/it_dpf3_test[1]_include.cmake") +subdirs("googletest") diff --git a/test/build-asan/Makefile b/test/build-asan/Makefile new file mode 100644 index 0000000..41d0b2e --- /dev/null +++ b/test/build-asan/Makefile @@ -0,0 +1,4948 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +# Allow only one "make -f Makefile2" at a time, but pass parallelism. +.NOTPARALLEL: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target test +test: + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running tests..." + /usr/bin/ctest $(ARGS) +.PHONY : test + +# Special rule for the target test +test/fast: test +.PHONY : test/fast + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "No interactive CMake dialog available..." + /usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available. +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# The main all target +all: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles /home/cryptolicious/hushmap-specified/libdpf/test/build-asan//CMakeFiles/progress.marks + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +#============================================================================= +# Target rules for targets named all_test + +# Build rule for target. +all_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all_test +.PHONY : all_test + +# fast build rule for target. +all_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/all_test.dir/build.make CMakeFiles/all_test.dir/build +.PHONY : all_test/fast + +#============================================================================= +# Target rules for targets named dpf_key_test + +# Build rule for target. +dpf_key_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 dpf_key_test +.PHONY : dpf_key_test + +# fast build rule for target. +dpf_key_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf_key_test.dir/build.make CMakeFiles/dpf_key_test.dir/build +.PHONY : dpf_key_test/fast + +#============================================================================= +# Target rules for targets named wildcard_test + +# Build rule for target. +wildcard_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 wildcard_test +.PHONY : wildcard_test + +# fast build rule for target. +wildcard_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wildcard_test.dir/build.make CMakeFiles/wildcard_test.dir/build +.PHONY : wildcard_test/fast + +#============================================================================= +# Target rules for targets named eval_point_test + +# Build rule for target. +eval_point_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 eval_point_test +.PHONY : eval_point_test + +# fast build rule for target. +eval_point_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_test.dir/build.make CMakeFiles/eval_point_test.dir/build +.PHONY : eval_point_test/fast + +#============================================================================= +# Target rules for targets named eval_interval_test + +# Build rule for target. +eval_interval_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 eval_interval_test +.PHONY : eval_interval_test + +# fast build rule for target. +eval_interval_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_test.dir/build.make CMakeFiles/eval_interval_test.dir/build +.PHONY : eval_interval_test/fast + +#============================================================================= +# Target rules for targets named eval_full_test + +# Build rule for target. +eval_full_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 eval_full_test +.PHONY : eval_full_test + +# fast build rule for target. +eval_full_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_test.dir/build.make CMakeFiles/eval_full_test.dir/build +.PHONY : eval_full_test/fast + +#============================================================================= +# Target rules for targets named eval_sequence_test + +# Build rule for target. +eval_sequence_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 eval_sequence_test +.PHONY : eval_sequence_test + +# fast build rule for target. +eval_sequence_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_test.dir/build.make CMakeFiles/eval_sequence_test.dir/build +.PHONY : eval_sequence_test/fast + +#============================================================================= +# Target rules for targets named eval_point_multi_test + +# Build rule for target. +eval_point_multi_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 eval_point_multi_test +.PHONY : eval_point_multi_test + +# fast build rule for target. +eval_point_multi_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_multi_test.dir/build.make CMakeFiles/eval_point_multi_test.dir/build +.PHONY : eval_point_multi_test/fast + +#============================================================================= +# Target rules for targets named eval_interval_multi_test + +# Build rule for target. +eval_interval_multi_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 eval_interval_multi_test +.PHONY : eval_interval_multi_test + +# fast build rule for target. +eval_interval_multi_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_multi_test.dir/build.make CMakeFiles/eval_interval_multi_test.dir/build +.PHONY : eval_interval_multi_test/fast + +#============================================================================= +# Target rules for targets named eval_full_multi_test + +# Build rule for target. +eval_full_multi_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 eval_full_multi_test +.PHONY : eval_full_multi_test + +# fast build rule for target. +eval_full_multi_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_multi_test.dir/build.make CMakeFiles/eval_full_multi_test.dir/build +.PHONY : eval_full_multi_test/fast + +#============================================================================= +# Target rules for targets named eval_sequence_multi_test + +# Build rule for target. +eval_sequence_multi_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 eval_sequence_multi_test +.PHONY : eval_sequence_multi_test + +# fast build rule for target. +eval_sequence_multi_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_multi_test.dir/build.make CMakeFiles/eval_sequence_multi_test.dir/build +.PHONY : eval_sequence_multi_test/fast + +#============================================================================= +# Target rules for targets named advice_bit_iterable_test + +# Build rule for target. +advice_bit_iterable_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 advice_bit_iterable_test +.PHONY : advice_bit_iterable_test + +# fast build rule for target. +advice_bit_iterable_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/advice_bit_iterable_test.dir/build.make CMakeFiles/advice_bit_iterable_test.dir/build +.PHONY : advice_bit_iterable_test/fast + +#============================================================================= +# Target rules for targets named bit_array_test + +# Build rule for target. +bit_array_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 bit_array_test +.PHONY : bit_array_test + +# fast build rule for target. +bit_array_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bit_array_test.dir/build.make CMakeFiles/bit_array_test.dir/build +.PHONY : bit_array_test/fast + +#============================================================================= +# Target rules for targets named parallel_bit_iterable_test + +# Build rule for target. +parallel_bit_iterable_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 parallel_bit_iterable_test +.PHONY : parallel_bit_iterable_test + +# fast build rule for target. +parallel_bit_iterable_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/parallel_bit_iterable_test.dir/build.make CMakeFiles/parallel_bit_iterable_test.dir/build +.PHONY : parallel_bit_iterable_test/fast + +#============================================================================= +# Target rules for targets named setbit_index_iterable_test + +# Build rule for target. +setbit_index_iterable_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 setbit_index_iterable_test +.PHONY : setbit_index_iterable_test + +# fast build rule for target. +setbit_index_iterable_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/setbit_index_iterable_test.dir/build.make CMakeFiles/setbit_index_iterable_test.dir/build +.PHONY : setbit_index_iterable_test/fast + +#============================================================================= +# Target rules for targets named incremental_test + +# Build rule for target. +incremental_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 incremental_test +.PHONY : incremental_test + +# fast build rule for target. +incremental_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_test.dir/build.make CMakeFiles/incremental_test.dir/build +.PHONY : incremental_test/fast + +#============================================================================= +# Target rules for targets named path_recipe_test + +# Build rule for target. +path_recipe_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 path_recipe_test +.PHONY : path_recipe_test + +# fast build rule for target. +path_recipe_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_recipe_test.dir/build.make CMakeFiles/path_recipe_test.dir/build +.PHONY : path_recipe_test/fast + +#============================================================================= +# Target rules for targets named blocked_dcf_test + +# Build rule for target. +blocked_dcf_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 blocked_dcf_test +.PHONY : blocked_dcf_test + +# fast build rule for target. +blocked_dcf_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/blocked_dcf_test.dir/build.make CMakeFiles/blocked_dcf_test.dir/build +.PHONY : blocked_dcf_test/fast + +#============================================================================= +# Target rules for targets named geneval_test + +# Build rule for target. +geneval_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 geneval_test +.PHONY : geneval_test + +# fast build rule for target. +geneval_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/geneval_test.dir/build.make CMakeFiles/geneval_test.dir/build +.PHONY : geneval_test/fast + +#============================================================================= +# Target rules for targets named stress_scenarios_test + +# Build rule for target. +stress_scenarios_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 stress_scenarios_test +.PHONY : stress_scenarios_test + +# fast build rule for target. +stress_scenarios_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/stress_scenarios_test.dir/build.make CMakeFiles/stress_scenarios_test.dir/build +.PHONY : stress_scenarios_test/fast + +#============================================================================= +# Target rules for targets named incremental_json_test + +# Build rule for target. +incremental_json_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 incremental_json_test +.PHONY : incremental_json_test + +# fast build rule for target. +incremental_json_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_json_test.dir/build.make CMakeFiles/incremental_json_test.dir/build +.PHONY : incremental_json_test/fast + +#============================================================================= +# Target rules for targets named keyword2_test + +# Build rule for target. +keyword2_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 keyword2_test +.PHONY : keyword2_test + +# fast build rule for target. +keyword2_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/keyword2_test.dir/build.make CMakeFiles/keyword2_test.dir/build +.PHONY : keyword2_test/fast + +#============================================================================= +# Target rules for targets named types_test + +# Build rule for target. +types_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 types_test +.PHONY : types_test + +# fast build rule for target. +types_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/types_test.dir/build.make CMakeFiles/types_test.dir/build +.PHONY : types_test/fast + +#============================================================================= +# Target rules for targets named packed_lane_test + +# Build rule for target. +packed_lane_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 packed_lane_test +.PHONY : packed_lane_test + +# fast build rule for target. +packed_lane_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/packed_lane_test.dir/build.make CMakeFiles/packed_lane_test.dir/build +.PHONY : packed_lane_test/fast + +#============================================================================= +# Target rules for targets named bitmore_mod_test + +# Build rule for target. +bitmore_mod_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 bitmore_mod_test +.PHONY : bitmore_mod_test + +# fast build rule for target. +bitmore_mod_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bitmore_mod_test.dir/build.make CMakeFiles/bitmore_mod_test.dir/build +.PHONY : bitmore_mod_test/fast + +#============================================================================= +# Target rules for targets named lane_blast_test + +# Build rule for target. +lane_blast_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 lane_blast_test +.PHONY : lane_blast_test + +# fast build rule for target. +lane_blast_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/lane_blast_test.dir/build.make CMakeFiles/lane_blast_test.dir/build +.PHONY : lane_blast_test/fast + +#============================================================================= +# Target rules for targets named context_blast_test + +# Build rule for target. +context_blast_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 context_blast_test +.PHONY : context_blast_test + +# fast build rule for target. +context_blast_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/context_blast_test.dir/build.make CMakeFiles/context_blast_test.dir/build +.PHONY : context_blast_test/fast + +#============================================================================= +# Target rules for targets named random_test + +# Build rule for target. +random_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 random_test +.PHONY : random_test + +# fast build rule for target. +random_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/random_test.dir/build.make CMakeFiles/random_test.dir/build +.PHONY : random_test/fast + +#============================================================================= +# Target rules for targets named prg_lowmc_test + +# Build rule for target. +prg_lowmc_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 prg_lowmc_test +.PHONY : prg_lowmc_test + +# fast build rule for target. +prg_lowmc_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_lowmc_test.dir/build.make CMakeFiles/prg_lowmc_test.dir/build +.PHONY : prg_lowmc_test/fast + +#============================================================================= +# Target rules for targets named prg_chacha_test + +# Build rule for target. +prg_chacha_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 prg_chacha_test +.PHONY : prg_chacha_test + +# fast build rule for target. +prg_chacha_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_chacha_test.dir/build.make CMakeFiles/prg_chacha_test.dir/build +.PHONY : prg_chacha_test/fast + +#============================================================================= +# Target rules for targets named prg_aes_ccr_test + +# Build rule for target. +prg_aes_ccr_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 prg_aes_ccr_test +.PHONY : prg_aes_ccr_test + +# fast build rule for target. +prg_aes_ccr_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_aes_ccr_test.dir/build.make CMakeFiles/prg_aes_ccr_test.dir/build +.PHONY : prg_aes_ccr_test/fast + +#============================================================================= +# Target rules for targets named half_tree_test + +# Build rule for target. +half_tree_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 half_tree_test +.PHONY : half_tree_test + +# fast build rule for target. +half_tree_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/half_tree_test.dir/build.make CMakeFiles/half_tree_test.dir/build +.PHONY : half_tree_test/fast + +#============================================================================= +# Target rules for targets named constrained_cmp_test + +# Build rule for target. +constrained_cmp_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 constrained_cmp_test +.PHONY : constrained_cmp_test + +# fast build rule for target. +constrained_cmp_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/constrained_cmp_test.dir/build.make CMakeFiles/constrained_cmp_test.dir/build +.PHONY : constrained_cmp_test/fast + +#============================================================================= +# Target rules for targets named fp61_test + +# Build rule for target. +fp61_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 fp61_test +.PHONY : fp61_test + +# fast build rule for target. +fp61_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/fp61_test.dir/build.make CMakeFiles/fp61_test.dir/build +.PHONY : fp61_test/fast + +#============================================================================= +# Target rules for targets named field_output_test + +# Build rule for target. +field_output_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 field_output_test +.PHONY : field_output_test + +# fast build rule for target. +field_output_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/field_output_test.dir/build.make CMakeFiles/field_output_test.dir/build +.PHONY : field_output_test/fast + +#============================================================================= +# Target rules for targets named gf2_test + +# Build rule for target. +gf2_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 gf2_test +.PHONY : gf2_test + +# fast build rule for target. +gf2_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_test.dir/build.make CMakeFiles/gf2_test.dir/build +.PHONY : gf2_test/fast + +#============================================================================= +# Target rules for targets named gf2_adversarial_test + +# Build rule for target. +gf2_adversarial_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 gf2_adversarial_test +.PHONY : gf2_adversarial_test + +# fast build rule for target. +gf2_adversarial_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_adversarial_test.dir/build.make CMakeFiles/gf2_adversarial_test.dir/build +.PHONY : gf2_adversarial_test/fast + +#============================================================================= +# Target rules for targets named arith_payload_test + +# Build rule for target. +arith_payload_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 arith_payload_test +.PHONY : arith_payload_test + +# fast build rule for target. +arith_payload_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_payload_test.dir/build.make CMakeFiles/arith_payload_test.dir/build +.PHONY : arith_payload_test/fast + +#============================================================================= +# Target rules for targets named verifiable_test + +# Build rule for target. +verifiable_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 verifiable_test +.PHONY : verifiable_test + +# fast build rule for target. +verifiable_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/verifiable_test.dir/build.make CMakeFiles/verifiable_test.dir/build +.PHONY : verifiable_test/fast + +#============================================================================= +# Target rules for targets named vdpf_adversarial_test + +# Build rule for target. +vdpf_adversarial_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 vdpf_adversarial_test +.PHONY : vdpf_adversarial_test + +# fast build rule for target. +vdpf_adversarial_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_adversarial_test.dir/build.make CMakeFiles/vdpf_adversarial_test.dir/build +.PHONY : vdpf_adversarial_test/fast + +#============================================================================= +# Target rules for targets named shamir_adversarial_test + +# Build rule for target. +shamir_adversarial_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 shamir_adversarial_test +.PHONY : shamir_adversarial_test + +# fast build rule for target. +shamir_adversarial_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shamir_adversarial_test.dir/build.make CMakeFiles/shamir_adversarial_test.dir/build +.PHONY : shamir_adversarial_test/fast + +#============================================================================= +# Target rules for targets named vdpf_regression_test + +# Build rule for target. +vdpf_regression_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 vdpf_regression_test +.PHONY : vdpf_regression_test + +# fast build rule for target. +vdpf_regression_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_regression_test.dir/build.make CMakeFiles/vdpf_regression_test.dir/build +.PHONY : vdpf_regression_test/fast + +#============================================================================= +# Target rules for targets named opt_in_malicious_test + +# Build rule for target. +opt_in_malicious_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 opt_in_malicious_test +.PHONY : opt_in_malicious_test + +# fast build rule for target. +opt_in_malicious_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/opt_in_malicious_test.dir/build.make CMakeFiles/opt_in_malicious_test.dir/build +.PHONY : opt_in_malicious_test/fast + +#============================================================================= +# Target rules for targets named multipoint_test + +# Build rule for target. +multipoint_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 multipoint_test +.PHONY : multipoint_test + +# fast build rule for target. +multipoint_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/multipoint_test.dir/build.make CMakeFiles/multipoint_test.dir/build +.PHONY : multipoint_test/fast + +#============================================================================= +# Target rules for targets named dpf3_test + +# Build rule for target. +dpf3_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 dpf3_test +.PHONY : dpf3_test + +# fast build rule for target. +dpf3_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf3_test.dir/build.make CMakeFiles/dpf3_test.dir/build +.PHONY : dpf3_test/fast + +#============================================================================= +# Target rules for targets named eval_inner_product_test + +# Build rule for target. +eval_inner_product_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 eval_inner_product_test +.PHONY : eval_inner_product_test + +# fast build rule for target. +eval_inner_product_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_inner_product_test.dir/build.make CMakeFiles/eval_inner_product_test.dir/build +.PHONY : eval_inner_product_test/fast + +#============================================================================= +# Target rules for targets named shared_and_test + +# Build rule for target. +shared_and_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 shared_and_test +.PHONY : shared_and_test + +# fast build rule for target. +shared_and_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shared_and_test.dir/build.make CMakeFiles/shared_and_test.dir/build +.PHONY : shared_and_test/fast + +#============================================================================= +# Target rules for targets named cohort_test + +# Build rule for target. +cohort_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 cohort_test +.PHONY : cohort_test + +# fast build rule for target. +cohort_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cohort_test.dir/build.make CMakeFiles/cohort_test.dir/build +.PHONY : cohort_test/fast + +#============================================================================= +# Target rules for targets named interleave_leaves_test + +# Build rule for target. +interleave_leaves_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 interleave_leaves_test +.PHONY : interleave_leaves_test + +# fast build rule for target. +interleave_leaves_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/interleave_leaves_test.dir/build.make CMakeFiles/interleave_leaves_test.dir/build +.PHONY : interleave_leaves_test/fast + +#============================================================================= +# Target rules for targets named secret_share_test + +# Build rule for target. +secret_share_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 secret_share_test +.PHONY : secret_share_test + +# fast build rule for target. +secret_share_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/secret_share_test.dir/build.make CMakeFiles/secret_share_test.dir/build +.PHONY : secret_share_test/fast + +#============================================================================= +# Target rules for targets named beaver_test + +# Build rule for target. +beaver_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 beaver_test +.PHONY : beaver_test + +# fast build rule for target. +beaver_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_test.dir/build.make CMakeFiles/beaver_test.dir/build +.PHONY : beaver_test/fast + +#============================================================================= +# Target rules for targets named share_runtime_test + +# Build rule for target. +share_runtime_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 share_runtime_test +.PHONY : share_runtime_test + +# fast build rule for target. +share_runtime_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/share_runtime_test.dir/build.make CMakeFiles/share_runtime_test.dir/build +.PHONY : share_runtime_test/fast + +#============================================================================= +# Target rules for targets named net_control_test + +# Build rule for target. +net_control_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 net_control_test +.PHONY : net_control_test + +# fast build rule for target. +net_control_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/net_control_test.dir/build.make CMakeFiles/net_control_test.dir/build +.PHONY : net_control_test/fast + +#============================================================================= +# Target rules for targets named security_test + +# Build rule for target. +security_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 security_test +.PHONY : security_test + +# fast build rule for target. +security_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/security_test.dir/build.make CMakeFiles/security_test.dir/build +.PHONY : security_test/fast + +#============================================================================= +# Target rules for targets named protocol_batch_test + +# Build rule for target. +protocol_batch_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 protocol_batch_test +.PHONY : protocol_batch_test + +# fast build rule for target. +protocol_batch_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/protocol_batch_test.dir/build.make CMakeFiles/protocol_batch_test.dir/build +.PHONY : protocol_batch_test/fast + +#============================================================================= +# Target rules for targets named compose_test + +# Build rule for target. +compose_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 compose_test +.PHONY : compose_test + +# fast build rule for target. +compose_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/compose_test.dir/build.make CMakeFiles/compose_test.dir/build +.PHONY : compose_test/fast + +#============================================================================= +# Target rules for targets named experiment_test + +# Build rule for target. +experiment_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 experiment_test +.PHONY : experiment_test + +# fast build rule for target. +experiment_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/experiment_test.dir/build.make CMakeFiles/experiment_test.dir/build +.PHONY : experiment_test/fast + +#============================================================================= +# Target rules for targets named log_test + +# Build rule for target. +log_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 log_test +.PHONY : log_test + +# fast build rule for target. +log_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/log_test.dir/build.make CMakeFiles/log_test.dir/build +.PHONY : log_test/fast + +#============================================================================= +# Target rules for targets named constant_lut_test + +# Build rule for target. +constant_lut_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 constant_lut_test +.PHONY : constant_lut_test + +# fast build rule for target. +constant_lut_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/constant_lut_test.dir/build.make CMakeFiles/constant_lut_test.dir/build +.PHONY : constant_lut_test/fast + +#============================================================================= +# Target rules for targets named signed_prefix_test + +# Build rule for target. +signed_prefix_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 signed_prefix_test +.PHONY : signed_prefix_test + +# fast build rule for target. +signed_prefix_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/signed_prefix_test.dir/build.make CMakeFiles/signed_prefix_test.dir/build +.PHONY : signed_prefix_test/fast + +#============================================================================= +# Target rules for targets named easy_lut_test + +# Build rule for target. +easy_lut_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 easy_lut_test +.PHONY : easy_lut_test + +# fast build rule for target. +easy_lut_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/easy_lut_test.dir/build.make CMakeFiles/easy_lut_test.dir/build +.PHONY : easy_lut_test/fast + +#============================================================================= +# Target rules for targets named dyadic_lut_test + +# Build rule for target. +dyadic_lut_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 dyadic_lut_test +.PHONY : dyadic_lut_test + +# fast build rule for target. +dyadic_lut_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dyadic_lut_test.dir/build.make CMakeFiles/dyadic_lut_test.dir/build +.PHONY : dyadic_lut_test/fast + +#============================================================================= +# Target rules for targets named nmod_test + +# Build rule for target. +nmod_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 nmod_test +.PHONY : nmod_test + +# fast build rule for target. +nmod_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/nmod_test.dir/build.make CMakeFiles/nmod_test.dir/build +.PHONY : nmod_test/fast + +#============================================================================= +# Target rules for targets named exact_steps_test + +# Build rule for target. +exact_steps_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 exact_steps_test +.PHONY : exact_steps_test + +# fast build rule for target. +exact_steps_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/exact_steps_test.dir/build.make CMakeFiles/exact_steps_test.dir/build +.PHONY : exact_steps_test/fast + +#============================================================================= +# Target rules for targets named closed_form_test + +# Build rule for target. +closed_form_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 closed_form_test +.PHONY : closed_form_test + +# fast build rule for target. +closed_form_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/closed_form_test.dir/build.make CMakeFiles/closed_form_test.dir/build +.PHONY : closed_form_test/fast + +#============================================================================= +# Target rules for targets named principal_lut_test + +# Build rule for target. +principal_lut_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 principal_lut_test +.PHONY : principal_lut_test + +# fast build rule for target. +principal_lut_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/principal_lut_test.dir/build.make CMakeFiles/principal_lut_test.dir/build +.PHONY : principal_lut_test/fast + +#============================================================================= +# Target rules for targets named range_lut_test + +# Build rule for target. +range_lut_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 range_lut_test +.PHONY : range_lut_test + +# fast build rule for target. +range_lut_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/range_lut_test.dir/build.make CMakeFiles/range_lut_test.dir/build +.PHONY : range_lut_test/fast + +#============================================================================= +# Target rules for targets named window_lut_test + +# Build rule for target. +window_lut_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 window_lut_test +.PHONY : window_lut_test + +# fast build rule for target. +window_lut_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/window_lut_test.dir/build.make CMakeFiles/window_lut_test.dir/build +.PHONY : window_lut_test/fast + +#============================================================================= +# Target rules for targets named dwt_lut_test + +# Build rule for target. +dwt_lut_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 dwt_lut_test +.PHONY : dwt_lut_test + +# fast build rule for target. +dwt_lut_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dwt_lut_test.dir/build.make CMakeFiles/dwt_lut_test.dir/build +.PHONY : dwt_lut_test/fast + +#============================================================================= +# Target rules for targets named offset_horner_test + +# Build rule for target. +offset_horner_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 offset_horner_test +.PHONY : offset_horner_test + +# fast build rule for target. +offset_horner_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_horner_test.dir/build.make CMakeFiles/offset_horner_test.dir/build +.PHONY : offset_horner_test/fast + +#============================================================================= +# Target rules for targets named offset_poly_test + +# Build rule for target. +offset_poly_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 offset_poly_test +.PHONY : offset_poly_test + +# fast build rule for target. +offset_poly_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_poly_test.dir/build.make CMakeFiles/offset_poly_test.dir/build +.PHONY : offset_poly_test/fast + +#============================================================================= +# Target rules for targets named lut_union_test + +# Build rule for target. +lut_union_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 lut_union_test +.PHONY : lut_union_test + +# fast build rule for target. +lut_union_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/lut_union_test.dir/build.make CMakeFiles/lut_union_test.dir/build +.PHONY : lut_union_test/fast + +#============================================================================= +# Target rules for targets named offset_jet_test + +# Build rule for target. +offset_jet_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 offset_jet_test +.PHONY : offset_jet_test + +# fast build rule for target. +offset_jet_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_jet_test.dir/build.make CMakeFiles/offset_jet_test.dir/build +.PHONY : offset_jet_test/fast + +#============================================================================= +# Target rules for targets named offset_repr_test + +# Build rule for target. +offset_repr_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 offset_repr_test +.PHONY : offset_repr_test + +# fast build rule for target. +offset_repr_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_repr_test.dir/build.make CMakeFiles/offset_repr_test.dir/build +.PHONY : offset_repr_test/fast + +#============================================================================= +# Target rules for targets named offset_twist_test + +# Build rule for target. +offset_twist_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 offset_twist_test +.PHONY : offset_twist_test + +# fast build rule for target. +offset_twist_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_twist_test.dir/build.make CMakeFiles/offset_twist_test.dir/build +.PHONY : offset_twist_test/fast + +#============================================================================= +# Target rules for targets named ring_switch_test + +# Build rule for target. +ring_switch_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ring_switch_test +.PHONY : ring_switch_test + +# fast build rule for target. +ring_switch_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ring_switch_test.dir/build.make CMakeFiles/ring_switch_test.dir/build +.PHONY : ring_switch_test/fast + +#============================================================================= +# Target rules for targets named corner_gaps_test + +# Build rule for target. +corner_gaps_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 corner_gaps_test +.PHONY : corner_gaps_test + +# fast build rule for target. +corner_gaps_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/corner_gaps_test.dir/build.make CMakeFiles/corner_gaps_test.dir/build +.PHONY : corner_gaps_test/fast + +#============================================================================= +# Target rules for targets named carry_test + +# Build rule for target. +carry_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 carry_test +.PHONY : carry_test + +# fast build rule for target. +carry_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/carry_test.dir/build.make CMakeFiles/carry_test.dir/build +.PHONY : carry_test/fast + +#============================================================================= +# Target rules for targets named fixedpoint_beaver_test + +# Build rule for target. +fixedpoint_beaver_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 fixedpoint_beaver_test +.PHONY : fixedpoint_beaver_test + +# fast build rule for target. +fixedpoint_beaver_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/fixedpoint_beaver_test.dir/build.make CMakeFiles/fixedpoint_beaver_test.dir/build +.PHONY : fixedpoint_beaver_test/fast + +#============================================================================= +# Target rules for targets named class_sweep_test + +# Build rule for target. +class_sweep_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 class_sweep_test +.PHONY : class_sweep_test + +# fast build rule for target. +class_sweep_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/class_sweep_test.dir/build.make CMakeFiles/class_sweep_test.dir/build +.PHONY : class_sweep_test/fast + +#============================================================================= +# Target rules for targets named extractable_full_test + +# Build rule for target. +extractable_full_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 extractable_full_test +.PHONY : extractable_full_test + +# fast build rule for target. +extractable_full_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/extractable_full_test.dir/build.make CMakeFiles/extractable_full_test.dir/build +.PHONY : extractable_full_test/fast + +#============================================================================= +# Target rules for targets named walk_helpers_test + +# Build rule for target. +walk_helpers_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 walk_helpers_test +.PHONY : walk_helpers_test + +# fast build rule for target. +walk_helpers_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/walk_helpers_test.dir/build.make CMakeFiles/walk_helpers_test.dir/build +.PHONY : walk_helpers_test/fast + +#============================================================================= +# Target rules for targets named domain128_point_test + +# Build rule for target. +domain128_point_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 domain128_point_test +.PHONY : domain128_point_test + +# fast build rule for target. +domain128_point_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/domain128_point_test.dir/build.make CMakeFiles/domain128_point_test.dir/build +.PHONY : domain128_point_test/fast + +#============================================================================= +# Target rules for targets named blob_leaf_test + +# Build rule for target. +blob_leaf_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 blob_leaf_test +.PHONY : blob_leaf_test + +# fast build rule for target. +blob_leaf_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/blob_leaf_test.dir/build.make CMakeFiles/blob_leaf_test.dir/build +.PHONY : blob_leaf_test/fast + +#============================================================================= +# Target rules for targets named growing_idpf_test + +# Build rule for target. +growing_idpf_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 growing_idpf_test +.PHONY : growing_idpf_test + +# fast build rule for target. +growing_idpf_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/growing_idpf_test.dir/build.make CMakeFiles/growing_idpf_test.dir/build +.PHONY : growing_idpf_test/fast + +#============================================================================= +# Target rules for targets named pprf_test + +# Build rule for target. +pprf_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 pprf_test +.PHONY : pprf_test + +# fast build rule for target. +pprf_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pprf_test.dir/build.make CMakeFiles/pprf_test.dir/build +.PHONY : pprf_test/fast + +#============================================================================= +# Target rules for targets named ppvc_test + +# Build rule for target. +ppvc_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ppvc_test +.PHONY : ppvc_test + +# fast build rule for target. +ppvc_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ppvc_test.dir/build.make CMakeFiles/ppvc_test.dir/build +.PHONY : ppvc_test/fast + +#============================================================================= +# Target rules for targets named leaf_later_test + +# Build rule for target. +leaf_later_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 leaf_later_test +.PHONY : leaf_later_test + +# fast build rule for target. +leaf_later_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/leaf_later_test.dir/build.make CMakeFiles/leaf_later_test.dir/build +.PHONY : leaf_later_test/fast + +#============================================================================= +# Target rules for targets named caller_fold_test + +# Build rule for target. +caller_fold_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 caller_fold_test +.PHONY : caller_fold_test + +# fast build rule for target. +caller_fold_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/caller_fold_test.dir/build.make CMakeFiles/caller_fold_test.dir/build +.PHONY : caller_fold_test/fast + +#============================================================================= +# Target rules for targets named defer_eval_test + +# Build rule for target. +defer_eval_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 defer_eval_test +.PHONY : defer_eval_test + +# fast build rule for target. +defer_eval_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/defer_eval_test.dir/build.make CMakeFiles/defer_eval_test.dir/build +.PHONY : defer_eval_test/fast + +#============================================================================= +# Target rules for targets named wrap_and_rotate_test + +# Build rule for target. +wrap_and_rotate_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 wrap_and_rotate_test +.PHONY : wrap_and_rotate_test + +# fast build rule for target. +wrap_and_rotate_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wrap_and_rotate_test.dir/build.make CMakeFiles/wrap_and_rotate_test.dir/build +.PHONY : wrap_and_rotate_test/fast + +#============================================================================= +# Target rules for targets named sfss_test + +# Build rule for target. +sfss_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 sfss_test +.PHONY : sfss_test + +# fast build rule for target. +sfss_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/sfss_test.dir/build.make CMakeFiles/sfss_test.dir/build +.PHONY : sfss_test/fast + +#============================================================================= +# Target rules for targets named path_sketch_test + +# Build rule for target. +path_sketch_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 path_sketch_test +.PHONY : path_sketch_test + +# fast build rule for target. +path_sketch_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_sketch_test.dir/build.make CMakeFiles/path_sketch_test.dir/build +.PHONY : path_sketch_test/fast + +#============================================================================= +# Target rules for targets named eval_until_test + +# Build rule for target. +eval_until_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 eval_until_test +.PHONY : eval_until_test + +# fast build rule for target. +eval_until_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_until_test.dir/build.make CMakeFiles/eval_until_test.dir/build +.PHONY : eval_until_test/fast + +#============================================================================= +# Target rules for targets named idpf_agg_test + +# Build rule for target. +idpf_agg_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 idpf_agg_test +.PHONY : idpf_agg_test + +# fast build rule for target. +idpf_agg_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/idpf_agg_test.dir/build.make CMakeFiles/idpf_agg_test.dir/build +.PHONY : idpf_agg_test/fast + +#============================================================================= +# Target rules for targets named it_dpf3_test + +# Build rule for target. +it_dpf3_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 it_dpf3_test +.PHONY : it_dpf3_test + +# fast build rule for target. +it_dpf3_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/it_dpf3_test.dir/build.make CMakeFiles/it_dpf3_test.dir/build +.PHONY : it_dpf3_test/fast + +#============================================================================= +# Target rules for targets named party_flows + +# Build rule for target. +party_flows: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 party_flows +.PHONY : party_flows + +# fast build rule for target. +party_flows/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_flows.dir/build.make CMakeFiles/party_flows.dir/build +.PHONY : party_flows/fast + +#============================================================================= +# Target rules for targets named p0 + +# Build rule for target. +p0: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 p0 +.PHONY : p0 + +# fast build rule for target. +p0/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p0.dir/build.make CMakeFiles/p0.dir/build +.PHONY : p0/fast + +#============================================================================= +# Target rules for targets named p1 + +# Build rule for target. +p1: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 p1 +.PHONY : p1 + +# fast build rule for target. +p1/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p1.dir/build.make CMakeFiles/p1.dir/build +.PHONY : p1/fast + +#============================================================================= +# Target rules for targets named p2 + +# Build rule for target. +p2: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 p2 +.PHONY : p2 + +# fast build rule for target. +p2/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p2.dir/build.make CMakeFiles/p2.dir/build +.PHONY : p2/fast + +#============================================================================= +# Target rules for targets named party_bench + +# Build rule for target. +party_bench: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 party_bench +.PHONY : party_bench + +# fast build rule for target. +party_bench/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_bench.dir/build.make CMakeFiles/party_bench.dir/build +.PHONY : party_bench/fast + +#============================================================================= +# Target rules for targets named profile_eval + +# Build rule for target. +profile_eval: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 profile_eval +.PHONY : profile_eval + +# fast build rule for target. +profile_eval/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_eval.dir/build.make CMakeFiles/profile_eval.dir/build +.PHONY : profile_eval/fast + +#============================================================================= +# Target rules for targets named profile_grotto + +# Build rule for target. +profile_grotto: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 profile_grotto +.PHONY : profile_grotto + +# fast build rule for target. +profile_grotto/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_grotto.dir/build.make CMakeFiles/profile_grotto.dir/build +.PHONY : profile_grotto/fast + +#============================================================================= +# Target rules for targets named profile_party + +# Build rule for target. +profile_party: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 profile_party +.PHONY : profile_party + +# fast build rule for target. +profile_party/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_party.dir/build.make CMakeFiles/profile_party.dir/build +.PHONY : profile_party/fast + +#============================================================================= +# Target rules for targets named yao_share_test + +# Build rule for target. +yao_share_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 yao_share_test +.PHONY : yao_share_test + +# fast build rule for target. +yao_share_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_share_test.dir/build.make CMakeFiles/yao_share_test.dir/build +.PHONY : yao_share_test/fast + +#============================================================================= +# Target rules for targets named yao_test + +# Build rule for target. +yao_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 yao_test +.PHONY : yao_test + +# fast build rule for target. +yao_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_test.dir/build.make CMakeFiles/yao_test.dir/build +.PHONY : yao_test/fast + +#============================================================================= +# Target rules for targets named yao_stack_test + +# Build rule for target. +yao_stack_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 yao_stack_test +.PHONY : yao_stack_test + +# fast build rule for target. +yao_stack_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_stack_test.dir/build.make CMakeFiles/yao_stack_test.dir/build +.PHONY : yao_stack_test/fast + +#============================================================================= +# Target rules for targets named arith_garble_test + +# Build rule for target. +arith_garble_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 arith_garble_test +.PHONY : arith_garble_test + +# fast build rule for target. +arith_garble_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_garble_test.dir/build.make CMakeFiles/arith_garble_test.dir/build +.PHONY : arith_garble_test/fast + +#============================================================================= +# Target rules for targets named flute_test + +# Build rule for target. +flute_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 flute_test +.PHONY : flute_test + +# fast build rule for target. +flute_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/flute_test.dir/build.make CMakeFiles/flute_test.dir/build +.PHONY : flute_test/fast + +#============================================================================= +# Target rules for targets named shuffle_hidden_test + +# Build rule for target. +shuffle_hidden_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 shuffle_hidden_test +.PHONY : shuffle_hidden_test + +# fast build rule for target. +shuffle_hidden_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shuffle_hidden_test.dir/build.make CMakeFiles/shuffle_hidden_test.dir/build +.PHONY : shuffle_hidden_test/fast + +#============================================================================= +# Target rules for targets named bench_cell_test + +# Build rule for target. +bench_cell_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 bench_cell_test +.PHONY : bench_cell_test + +# fast build rule for target. +bench_cell_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bench_cell_test.dir/build.make CMakeFiles/bench_cell_test.dir/build +.PHONY : bench_cell_test/fast + +#============================================================================= +# Target rules for targets named iknp_party_test + +# Build rule for target. +iknp_party_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 iknp_party_test +.PHONY : iknp_party_test + +# fast build rule for target. +iknp_party_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/iknp_party_test.dir/build.make CMakeFiles/iknp_party_test.dir/build +.PHONY : iknp_party_test/fast + +#============================================================================= +# Target rules for targets named beaver_party_test + +# Build rule for target. +beaver_party_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 beaver_party_test +.PHONY : beaver_party_test + +# fast build rule for target. +beaver_party_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_party_test.dir/build.make CMakeFiles/beaver_party_test.dir/build +.PHONY : beaver_party_test/fast + +#============================================================================= +# Target rules for targets named ic_test + +# Build rule for target. +ic_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 ic_test +.PHONY : ic_test + +# fast build rule for target. +ic_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ic_test.dir/build.make CMakeFiles/ic_test.dir/build +.PHONY : ic_test/fast + +#============================================================================= +# Target rules for targets named wide_payload_test + +# Build rule for target. +wide_payload_test: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 wide_payload_test +.PHONY : wide_payload_test + +# fast build rule for target. +wide_payload_test/fast: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wide_payload_test.dir/build.make CMakeFiles/wide_payload_test.dir/build +.PHONY : wide_payload_test/fast + +#============================================================================= +# Target rules for targets named gtest + +# Build rule for target. +gtest: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 gtest +.PHONY : gtest + +# fast build rule for target. +gtest/fast: + $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest.dir/build.make googletest/googletest/CMakeFiles/gtest.dir/build +.PHONY : gtest/fast + +#============================================================================= +# Target rules for targets named gtest_main + +# Build rule for target. +gtest_main: cmake_check_build_system + $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 gtest_main +.PHONY : gtest_main + +# fast build rule for target. +gtest_main/fast: + $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest_main.dir/build.make googletest/googletest/CMakeFiles/gtest_main.dir/build +.PHONY : gtest_main/fast + +home/cryptolicious/hushmap-specified/libdpf/party/p0.o: home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p0.o + +# target to build an object file +home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p0.dir/build.make CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.o + +home/cryptolicious/hushmap-specified/libdpf/party/p0.i: home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.i +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p0.i + +# target to preprocess a source file +home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p0.dir/build.make CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.i +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.i + +home/cryptolicious/hushmap-specified/libdpf/party/p0.s: home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.s +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p0.s + +# target to generate assembly for a file +home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p0.dir/build.make CMakeFiles/p0.dir/home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.s +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p0.cpp.s + +home/cryptolicious/hushmap-specified/libdpf/party/p1.o: home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p1.o + +# target to build an object file +home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p1.dir/build.make CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.o + +home/cryptolicious/hushmap-specified/libdpf/party/p1.i: home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.i +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p1.i + +# target to preprocess a source file +home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p1.dir/build.make CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.i +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.i + +home/cryptolicious/hushmap-specified/libdpf/party/p1.s: home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.s +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p1.s + +# target to generate assembly for a file +home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p1.dir/build.make CMakeFiles/p1.dir/home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.s +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p1.cpp.s + +home/cryptolicious/hushmap-specified/libdpf/party/p2.o: home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p2.o + +# target to build an object file +home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p2.dir/build.make CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.o + +home/cryptolicious/hushmap-specified/libdpf/party/p2.i: home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.i +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p2.i + +# target to preprocess a source file +home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p2.dir/build.make CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.i +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.i + +home/cryptolicious/hushmap-specified/libdpf/party/p2.s: home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.s +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p2.s + +# target to generate assembly for a file +home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/p2.dir/build.make CMakeFiles/p2.dir/home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.s +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/p2.cpp.s + +home/cryptolicious/hushmap-specified/libdpf/party/party_bench.o: home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/party_bench.o + +# target to build an object file +home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_bench.dir/build.make CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.o + +home/cryptolicious/hushmap-specified/libdpf/party/party_bench.i: home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.i +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/party_bench.i + +# target to preprocess a source file +home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_bench.dir/build.make CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.i +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.i + +home/cryptolicious/hushmap-specified/libdpf/party/party_bench.s: home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.s +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/party_bench.s + +# target to generate assembly for a file +home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_bench.dir/build.make CMakeFiles/party_bench.dir/home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.s +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/party_bench.cpp.s + +home/cryptolicious/hushmap-specified/libdpf/party/registry.o: home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/registry.o + +# target to build an object file +home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_flows.dir/build.make CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.o + +home/cryptolicious/hushmap-specified/libdpf/party/registry.i: home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.i +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/registry.i + +# target to preprocess a source file +home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_flows.dir/build.make CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.i +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.i + +home/cryptolicious/hushmap-specified/libdpf/party/registry.s: home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.s +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/registry.s + +# target to generate assembly for a file +home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_flows.dir/build.make CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.s +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/registry.cpp.s + +home/cryptolicious/hushmap-specified/libdpf/party/run.o: home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/run.o + +# target to build an object file +home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_flows.dir/build.make CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.o + +home/cryptolicious/hushmap-specified/libdpf/party/run.i: home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.i +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/run.i + +# target to preprocess a source file +home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_flows.dir/build.make CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.i +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.i + +home/cryptolicious/hushmap-specified/libdpf/party/run.s: home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.s +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/run.s + +# target to generate assembly for a file +home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/party_flows.dir/build.make CMakeFiles/party_flows.dir/home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.s +.PHONY : home/cryptolicious/hushmap-specified/libdpf/party/run.cpp.s + +profile/eval_profile.o: profile/eval_profile.cpp.o +.PHONY : profile/eval_profile.o + +# target to build an object file +profile/eval_profile.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_eval.dir/build.make CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.o +.PHONY : profile/eval_profile.cpp.o + +profile/eval_profile.i: profile/eval_profile.cpp.i +.PHONY : profile/eval_profile.i + +# target to preprocess a source file +profile/eval_profile.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_eval.dir/build.make CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.i +.PHONY : profile/eval_profile.cpp.i + +profile/eval_profile.s: profile/eval_profile.cpp.s +.PHONY : profile/eval_profile.s + +# target to generate assembly for a file +profile/eval_profile.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_eval.dir/build.make CMakeFiles/profile_eval.dir/profile/eval_profile.cpp.s +.PHONY : profile/eval_profile.cpp.s + +profile/grotto_profile.o: profile/grotto_profile.cpp.o +.PHONY : profile/grotto_profile.o + +# target to build an object file +profile/grotto_profile.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_grotto.dir/build.make CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.o +.PHONY : profile/grotto_profile.cpp.o + +profile/grotto_profile.i: profile/grotto_profile.cpp.i +.PHONY : profile/grotto_profile.i + +# target to preprocess a source file +profile/grotto_profile.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_grotto.dir/build.make CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.i +.PHONY : profile/grotto_profile.cpp.i + +profile/grotto_profile.s: profile/grotto_profile.cpp.s +.PHONY : profile/grotto_profile.s + +# target to generate assembly for a file +profile/grotto_profile.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_grotto.dir/build.make CMakeFiles/profile_grotto.dir/profile/grotto_profile.cpp.s +.PHONY : profile/grotto_profile.cpp.s + +profile/party_profile.o: profile/party_profile.cpp.o +.PHONY : profile/party_profile.o + +# target to build an object file +profile/party_profile.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_party.dir/build.make CMakeFiles/profile_party.dir/profile/party_profile.cpp.o +.PHONY : profile/party_profile.cpp.o + +profile/party_profile.i: profile/party_profile.cpp.i +.PHONY : profile/party_profile.i + +# target to preprocess a source file +profile/party_profile.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_party.dir/build.make CMakeFiles/profile_party.dir/profile/party_profile.cpp.i +.PHONY : profile/party_profile.cpp.i + +profile/party_profile.s: profile/party_profile.cpp.s +.PHONY : profile/party_profile.s + +# target to generate assembly for a file +profile/party_profile.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/profile_party.dir/build.make CMakeFiles/profile_party.dir/profile/party_profile.cpp.s +.PHONY : profile/party_profile.cpp.s + +tests/advice_bit_iterable_test.o: tests/advice_bit_iterable_test.cpp.o +.PHONY : tests/advice_bit_iterable_test.o + +# target to build an object file +tests/advice_bit_iterable_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/advice_bit_iterable_test.dir/build.make CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.o +.PHONY : tests/advice_bit_iterable_test.cpp.o + +tests/advice_bit_iterable_test.i: tests/advice_bit_iterable_test.cpp.i +.PHONY : tests/advice_bit_iterable_test.i + +# target to preprocess a source file +tests/advice_bit_iterable_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/advice_bit_iterable_test.dir/build.make CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.i +.PHONY : tests/advice_bit_iterable_test.cpp.i + +tests/advice_bit_iterable_test.s: tests/advice_bit_iterable_test.cpp.s +.PHONY : tests/advice_bit_iterable_test.s + +# target to generate assembly for a file +tests/advice_bit_iterable_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/advice_bit_iterable_test.dir/build.make CMakeFiles/advice_bit_iterable_test.dir/tests/advice_bit_iterable_test.cpp.s +.PHONY : tests/advice_bit_iterable_test.cpp.s + +tests/all_test.o: tests/all_test.cpp.o +.PHONY : tests/all_test.o + +# target to build an object file +tests/all_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/all_test.dir/build.make CMakeFiles/all_test.dir/tests/all_test.cpp.o +.PHONY : tests/all_test.cpp.o + +tests/all_test.i: tests/all_test.cpp.i +.PHONY : tests/all_test.i + +# target to preprocess a source file +tests/all_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/all_test.dir/build.make CMakeFiles/all_test.dir/tests/all_test.cpp.i +.PHONY : tests/all_test.cpp.i + +tests/all_test.s: tests/all_test.cpp.s +.PHONY : tests/all_test.s + +# target to generate assembly for a file +tests/all_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/all_test.dir/build.make CMakeFiles/all_test.dir/tests/all_test.cpp.s +.PHONY : tests/all_test.cpp.s + +tests/arith_garble_test.o: tests/arith_garble_test.cpp.o +.PHONY : tests/arith_garble_test.o + +# target to build an object file +tests/arith_garble_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_garble_test.dir/build.make CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.o +.PHONY : tests/arith_garble_test.cpp.o + +tests/arith_garble_test.i: tests/arith_garble_test.cpp.i +.PHONY : tests/arith_garble_test.i + +# target to preprocess a source file +tests/arith_garble_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_garble_test.dir/build.make CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.i +.PHONY : tests/arith_garble_test.cpp.i + +tests/arith_garble_test.s: tests/arith_garble_test.cpp.s +.PHONY : tests/arith_garble_test.s + +# target to generate assembly for a file +tests/arith_garble_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_garble_test.dir/build.make CMakeFiles/arith_garble_test.dir/tests/arith_garble_test.cpp.s +.PHONY : tests/arith_garble_test.cpp.s + +tests/arith_payload_test.o: tests/arith_payload_test.cpp.o +.PHONY : tests/arith_payload_test.o + +# target to build an object file +tests/arith_payload_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_payload_test.dir/build.make CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.o +.PHONY : tests/arith_payload_test.cpp.o + +tests/arith_payload_test.i: tests/arith_payload_test.cpp.i +.PHONY : tests/arith_payload_test.i + +# target to preprocess a source file +tests/arith_payload_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_payload_test.dir/build.make CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.i +.PHONY : tests/arith_payload_test.cpp.i + +tests/arith_payload_test.s: tests/arith_payload_test.cpp.s +.PHONY : tests/arith_payload_test.s + +# target to generate assembly for a file +tests/arith_payload_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/arith_payload_test.dir/build.make CMakeFiles/arith_payload_test.dir/tests/arith_payload_test.cpp.s +.PHONY : tests/arith_payload_test.cpp.s + +tests/beaver_party_test.o: tests/beaver_party_test.cpp.o +.PHONY : tests/beaver_party_test.o + +# target to build an object file +tests/beaver_party_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_party_test.dir/build.make CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.o +.PHONY : tests/beaver_party_test.cpp.o + +tests/beaver_party_test.i: tests/beaver_party_test.cpp.i +.PHONY : tests/beaver_party_test.i + +# target to preprocess a source file +tests/beaver_party_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_party_test.dir/build.make CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.i +.PHONY : tests/beaver_party_test.cpp.i + +tests/beaver_party_test.s: tests/beaver_party_test.cpp.s +.PHONY : tests/beaver_party_test.s + +# target to generate assembly for a file +tests/beaver_party_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_party_test.dir/build.make CMakeFiles/beaver_party_test.dir/tests/beaver_party_test.cpp.s +.PHONY : tests/beaver_party_test.cpp.s + +tests/beaver_test.o: tests/beaver_test.cpp.o +.PHONY : tests/beaver_test.o + +# target to build an object file +tests/beaver_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_test.dir/build.make CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.o +.PHONY : tests/beaver_test.cpp.o + +tests/beaver_test.i: tests/beaver_test.cpp.i +.PHONY : tests/beaver_test.i + +# target to preprocess a source file +tests/beaver_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_test.dir/build.make CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.i +.PHONY : tests/beaver_test.cpp.i + +tests/beaver_test.s: tests/beaver_test.cpp.s +.PHONY : tests/beaver_test.s + +# target to generate assembly for a file +tests/beaver_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/beaver_test.dir/build.make CMakeFiles/beaver_test.dir/tests/beaver_test.cpp.s +.PHONY : tests/beaver_test.cpp.s + +tests/bench_cell_test.o: tests/bench_cell_test.cpp.o +.PHONY : tests/bench_cell_test.o + +# target to build an object file +tests/bench_cell_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bench_cell_test.dir/build.make CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.o +.PHONY : tests/bench_cell_test.cpp.o + +tests/bench_cell_test.i: tests/bench_cell_test.cpp.i +.PHONY : tests/bench_cell_test.i + +# target to preprocess a source file +tests/bench_cell_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bench_cell_test.dir/build.make CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.i +.PHONY : tests/bench_cell_test.cpp.i + +tests/bench_cell_test.s: tests/bench_cell_test.cpp.s +.PHONY : tests/bench_cell_test.s + +# target to generate assembly for a file +tests/bench_cell_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bench_cell_test.dir/build.make CMakeFiles/bench_cell_test.dir/tests/bench_cell_test.cpp.s +.PHONY : tests/bench_cell_test.cpp.s + +tests/bit_array_test.o: tests/bit_array_test.cpp.o +.PHONY : tests/bit_array_test.o + +# target to build an object file +tests/bit_array_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bit_array_test.dir/build.make CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.o +.PHONY : tests/bit_array_test.cpp.o + +tests/bit_array_test.i: tests/bit_array_test.cpp.i +.PHONY : tests/bit_array_test.i + +# target to preprocess a source file +tests/bit_array_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bit_array_test.dir/build.make CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.i +.PHONY : tests/bit_array_test.cpp.i + +tests/bit_array_test.s: tests/bit_array_test.cpp.s +.PHONY : tests/bit_array_test.s + +# target to generate assembly for a file +tests/bit_array_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bit_array_test.dir/build.make CMakeFiles/bit_array_test.dir/tests/bit_array_test.cpp.s +.PHONY : tests/bit_array_test.cpp.s + +tests/bitmore_mod_test.o: tests/bitmore_mod_test.cpp.o +.PHONY : tests/bitmore_mod_test.o + +# target to build an object file +tests/bitmore_mod_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bitmore_mod_test.dir/build.make CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.o +.PHONY : tests/bitmore_mod_test.cpp.o + +tests/bitmore_mod_test.i: tests/bitmore_mod_test.cpp.i +.PHONY : tests/bitmore_mod_test.i + +# target to preprocess a source file +tests/bitmore_mod_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bitmore_mod_test.dir/build.make CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.i +.PHONY : tests/bitmore_mod_test.cpp.i + +tests/bitmore_mod_test.s: tests/bitmore_mod_test.cpp.s +.PHONY : tests/bitmore_mod_test.s + +# target to generate assembly for a file +tests/bitmore_mod_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/bitmore_mod_test.dir/build.make CMakeFiles/bitmore_mod_test.dir/tests/bitmore_mod_test.cpp.s +.PHONY : tests/bitmore_mod_test.cpp.s + +tests/blob_leaf_test.o: tests/blob_leaf_test.cpp.o +.PHONY : tests/blob_leaf_test.o + +# target to build an object file +tests/blob_leaf_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/blob_leaf_test.dir/build.make CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.o +.PHONY : tests/blob_leaf_test.cpp.o + +tests/blob_leaf_test.i: tests/blob_leaf_test.cpp.i +.PHONY : tests/blob_leaf_test.i + +# target to preprocess a source file +tests/blob_leaf_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/blob_leaf_test.dir/build.make CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.i +.PHONY : tests/blob_leaf_test.cpp.i + +tests/blob_leaf_test.s: tests/blob_leaf_test.cpp.s +.PHONY : tests/blob_leaf_test.s + +# target to generate assembly for a file +tests/blob_leaf_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/blob_leaf_test.dir/build.make CMakeFiles/blob_leaf_test.dir/tests/blob_leaf_test.cpp.s +.PHONY : tests/blob_leaf_test.cpp.s + +tests/blocked_dcf_test.o: tests/blocked_dcf_test.cpp.o +.PHONY : tests/blocked_dcf_test.o + +# target to build an object file +tests/blocked_dcf_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/blocked_dcf_test.dir/build.make CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.o +.PHONY : tests/blocked_dcf_test.cpp.o + +tests/blocked_dcf_test.i: tests/blocked_dcf_test.cpp.i +.PHONY : tests/blocked_dcf_test.i + +# target to preprocess a source file +tests/blocked_dcf_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/blocked_dcf_test.dir/build.make CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.i +.PHONY : tests/blocked_dcf_test.cpp.i + +tests/blocked_dcf_test.s: tests/blocked_dcf_test.cpp.s +.PHONY : tests/blocked_dcf_test.s + +# target to generate assembly for a file +tests/blocked_dcf_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/blocked_dcf_test.dir/build.make CMakeFiles/blocked_dcf_test.dir/tests/blocked_dcf_test.cpp.s +.PHONY : tests/blocked_dcf_test.cpp.s + +tests/caller_fold_test.o: tests/caller_fold_test.cpp.o +.PHONY : tests/caller_fold_test.o + +# target to build an object file +tests/caller_fold_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/caller_fold_test.dir/build.make CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.o +.PHONY : tests/caller_fold_test.cpp.o + +tests/caller_fold_test.i: tests/caller_fold_test.cpp.i +.PHONY : tests/caller_fold_test.i + +# target to preprocess a source file +tests/caller_fold_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/caller_fold_test.dir/build.make CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.i +.PHONY : tests/caller_fold_test.cpp.i + +tests/caller_fold_test.s: tests/caller_fold_test.cpp.s +.PHONY : tests/caller_fold_test.s + +# target to generate assembly for a file +tests/caller_fold_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/caller_fold_test.dir/build.make CMakeFiles/caller_fold_test.dir/tests/caller_fold_test.cpp.s +.PHONY : tests/caller_fold_test.cpp.s + +tests/carry_test.o: tests/carry_test.cpp.o +.PHONY : tests/carry_test.o + +# target to build an object file +tests/carry_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/carry_test.dir/build.make CMakeFiles/carry_test.dir/tests/carry_test.cpp.o +.PHONY : tests/carry_test.cpp.o + +tests/carry_test.i: tests/carry_test.cpp.i +.PHONY : tests/carry_test.i + +# target to preprocess a source file +tests/carry_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/carry_test.dir/build.make CMakeFiles/carry_test.dir/tests/carry_test.cpp.i +.PHONY : tests/carry_test.cpp.i + +tests/carry_test.s: tests/carry_test.cpp.s +.PHONY : tests/carry_test.s + +# target to generate assembly for a file +tests/carry_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/carry_test.dir/build.make CMakeFiles/carry_test.dir/tests/carry_test.cpp.s +.PHONY : tests/carry_test.cpp.s + +tests/class_sweep_test.o: tests/class_sweep_test.cpp.o +.PHONY : tests/class_sweep_test.o + +# target to build an object file +tests/class_sweep_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/class_sweep_test.dir/build.make CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.o +.PHONY : tests/class_sweep_test.cpp.o + +tests/class_sweep_test.i: tests/class_sweep_test.cpp.i +.PHONY : tests/class_sweep_test.i + +# target to preprocess a source file +tests/class_sweep_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/class_sweep_test.dir/build.make CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.i +.PHONY : tests/class_sweep_test.cpp.i + +tests/class_sweep_test.s: tests/class_sweep_test.cpp.s +.PHONY : tests/class_sweep_test.s + +# target to generate assembly for a file +tests/class_sweep_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/class_sweep_test.dir/build.make CMakeFiles/class_sweep_test.dir/tests/class_sweep_test.cpp.s +.PHONY : tests/class_sweep_test.cpp.s + +tests/closed_form_test.o: tests/closed_form_test.cpp.o +.PHONY : tests/closed_form_test.o + +# target to build an object file +tests/closed_form_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/closed_form_test.dir/build.make CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.o +.PHONY : tests/closed_form_test.cpp.o + +tests/closed_form_test.i: tests/closed_form_test.cpp.i +.PHONY : tests/closed_form_test.i + +# target to preprocess a source file +tests/closed_form_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/closed_form_test.dir/build.make CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.i +.PHONY : tests/closed_form_test.cpp.i + +tests/closed_form_test.s: tests/closed_form_test.cpp.s +.PHONY : tests/closed_form_test.s + +# target to generate assembly for a file +tests/closed_form_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/closed_form_test.dir/build.make CMakeFiles/closed_form_test.dir/tests/closed_form_test.cpp.s +.PHONY : tests/closed_form_test.cpp.s + +tests/cohort_test.o: tests/cohort_test.cpp.o +.PHONY : tests/cohort_test.o + +# target to build an object file +tests/cohort_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cohort_test.dir/build.make CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.o +.PHONY : tests/cohort_test.cpp.o + +tests/cohort_test.i: tests/cohort_test.cpp.i +.PHONY : tests/cohort_test.i + +# target to preprocess a source file +tests/cohort_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cohort_test.dir/build.make CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.i +.PHONY : tests/cohort_test.cpp.i + +tests/cohort_test.s: tests/cohort_test.cpp.s +.PHONY : tests/cohort_test.s + +# target to generate assembly for a file +tests/cohort_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/cohort_test.dir/build.make CMakeFiles/cohort_test.dir/tests/cohort_test.cpp.s +.PHONY : tests/cohort_test.cpp.s + +tests/compose_test.o: tests/compose_test.cpp.o +.PHONY : tests/compose_test.o + +# target to build an object file +tests/compose_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/compose_test.dir/build.make CMakeFiles/compose_test.dir/tests/compose_test.cpp.o +.PHONY : tests/compose_test.cpp.o + +tests/compose_test.i: tests/compose_test.cpp.i +.PHONY : tests/compose_test.i + +# target to preprocess a source file +tests/compose_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/compose_test.dir/build.make CMakeFiles/compose_test.dir/tests/compose_test.cpp.i +.PHONY : tests/compose_test.cpp.i + +tests/compose_test.s: tests/compose_test.cpp.s +.PHONY : tests/compose_test.s + +# target to generate assembly for a file +tests/compose_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/compose_test.dir/build.make CMakeFiles/compose_test.dir/tests/compose_test.cpp.s +.PHONY : tests/compose_test.cpp.s + +tests/constant_lut_test.o: tests/constant_lut_test.cpp.o +.PHONY : tests/constant_lut_test.o + +# target to build an object file +tests/constant_lut_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/constant_lut_test.dir/build.make CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.o +.PHONY : tests/constant_lut_test.cpp.o + +tests/constant_lut_test.i: tests/constant_lut_test.cpp.i +.PHONY : tests/constant_lut_test.i + +# target to preprocess a source file +tests/constant_lut_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/constant_lut_test.dir/build.make CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.i +.PHONY : tests/constant_lut_test.cpp.i + +tests/constant_lut_test.s: tests/constant_lut_test.cpp.s +.PHONY : tests/constant_lut_test.s + +# target to generate assembly for a file +tests/constant_lut_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/constant_lut_test.dir/build.make CMakeFiles/constant_lut_test.dir/tests/constant_lut_test.cpp.s +.PHONY : tests/constant_lut_test.cpp.s + +tests/constrained_cmp_test.o: tests/constrained_cmp_test.cpp.o +.PHONY : tests/constrained_cmp_test.o + +# target to build an object file +tests/constrained_cmp_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/constrained_cmp_test.dir/build.make CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.o +.PHONY : tests/constrained_cmp_test.cpp.o + +tests/constrained_cmp_test.i: tests/constrained_cmp_test.cpp.i +.PHONY : tests/constrained_cmp_test.i + +# target to preprocess a source file +tests/constrained_cmp_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/constrained_cmp_test.dir/build.make CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.i +.PHONY : tests/constrained_cmp_test.cpp.i + +tests/constrained_cmp_test.s: tests/constrained_cmp_test.cpp.s +.PHONY : tests/constrained_cmp_test.s + +# target to generate assembly for a file +tests/constrained_cmp_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/constrained_cmp_test.dir/build.make CMakeFiles/constrained_cmp_test.dir/tests/constrained_cmp_test.cpp.s +.PHONY : tests/constrained_cmp_test.cpp.s + +tests/context_blast_test.o: tests/context_blast_test.cpp.o +.PHONY : tests/context_blast_test.o + +# target to build an object file +tests/context_blast_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/context_blast_test.dir/build.make CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.o +.PHONY : tests/context_blast_test.cpp.o + +tests/context_blast_test.i: tests/context_blast_test.cpp.i +.PHONY : tests/context_blast_test.i + +# target to preprocess a source file +tests/context_blast_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/context_blast_test.dir/build.make CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.i +.PHONY : tests/context_blast_test.cpp.i + +tests/context_blast_test.s: tests/context_blast_test.cpp.s +.PHONY : tests/context_blast_test.s + +# target to generate assembly for a file +tests/context_blast_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/context_blast_test.dir/build.make CMakeFiles/context_blast_test.dir/tests/context_blast_test.cpp.s +.PHONY : tests/context_blast_test.cpp.s + +tests/corner_gaps_test.o: tests/corner_gaps_test.cpp.o +.PHONY : tests/corner_gaps_test.o + +# target to build an object file +tests/corner_gaps_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/corner_gaps_test.dir/build.make CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.o +.PHONY : tests/corner_gaps_test.cpp.o + +tests/corner_gaps_test.i: tests/corner_gaps_test.cpp.i +.PHONY : tests/corner_gaps_test.i + +# target to preprocess a source file +tests/corner_gaps_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/corner_gaps_test.dir/build.make CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.i +.PHONY : tests/corner_gaps_test.cpp.i + +tests/corner_gaps_test.s: tests/corner_gaps_test.cpp.s +.PHONY : tests/corner_gaps_test.s + +# target to generate assembly for a file +tests/corner_gaps_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/corner_gaps_test.dir/build.make CMakeFiles/corner_gaps_test.dir/tests/corner_gaps_test.cpp.s +.PHONY : tests/corner_gaps_test.cpp.s + +tests/defer_eval_test.o: tests/defer_eval_test.cpp.o +.PHONY : tests/defer_eval_test.o + +# target to build an object file +tests/defer_eval_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/defer_eval_test.dir/build.make CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.o +.PHONY : tests/defer_eval_test.cpp.o + +tests/defer_eval_test.i: tests/defer_eval_test.cpp.i +.PHONY : tests/defer_eval_test.i + +# target to preprocess a source file +tests/defer_eval_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/defer_eval_test.dir/build.make CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.i +.PHONY : tests/defer_eval_test.cpp.i + +tests/defer_eval_test.s: tests/defer_eval_test.cpp.s +.PHONY : tests/defer_eval_test.s + +# target to generate assembly for a file +tests/defer_eval_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/defer_eval_test.dir/build.make CMakeFiles/defer_eval_test.dir/tests/defer_eval_test.cpp.s +.PHONY : tests/defer_eval_test.cpp.s + +tests/domain128_point_test.o: tests/domain128_point_test.cpp.o +.PHONY : tests/domain128_point_test.o + +# target to build an object file +tests/domain128_point_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/domain128_point_test.dir/build.make CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.o +.PHONY : tests/domain128_point_test.cpp.o + +tests/domain128_point_test.i: tests/domain128_point_test.cpp.i +.PHONY : tests/domain128_point_test.i + +# target to preprocess a source file +tests/domain128_point_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/domain128_point_test.dir/build.make CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.i +.PHONY : tests/domain128_point_test.cpp.i + +tests/domain128_point_test.s: tests/domain128_point_test.cpp.s +.PHONY : tests/domain128_point_test.s + +# target to generate assembly for a file +tests/domain128_point_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/domain128_point_test.dir/build.make CMakeFiles/domain128_point_test.dir/tests/domain128_point_test.cpp.s +.PHONY : tests/domain128_point_test.cpp.s + +tests/dpf3_test.o: tests/dpf3_test.cpp.o +.PHONY : tests/dpf3_test.o + +# target to build an object file +tests/dpf3_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf3_test.dir/build.make CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.o +.PHONY : tests/dpf3_test.cpp.o + +tests/dpf3_test.i: tests/dpf3_test.cpp.i +.PHONY : tests/dpf3_test.i + +# target to preprocess a source file +tests/dpf3_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf3_test.dir/build.make CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.i +.PHONY : tests/dpf3_test.cpp.i + +tests/dpf3_test.s: tests/dpf3_test.cpp.s +.PHONY : tests/dpf3_test.s + +# target to generate assembly for a file +tests/dpf3_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf3_test.dir/build.make CMakeFiles/dpf3_test.dir/tests/dpf3_test.cpp.s +.PHONY : tests/dpf3_test.cpp.s + +tests/dpf_key_test.o: tests/dpf_key_test.cpp.o +.PHONY : tests/dpf_key_test.o + +# target to build an object file +tests/dpf_key_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf_key_test.dir/build.make CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.o +.PHONY : tests/dpf_key_test.cpp.o + +tests/dpf_key_test.i: tests/dpf_key_test.cpp.i +.PHONY : tests/dpf_key_test.i + +# target to preprocess a source file +tests/dpf_key_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf_key_test.dir/build.make CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.i +.PHONY : tests/dpf_key_test.cpp.i + +tests/dpf_key_test.s: tests/dpf_key_test.cpp.s +.PHONY : tests/dpf_key_test.s + +# target to generate assembly for a file +tests/dpf_key_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dpf_key_test.dir/build.make CMakeFiles/dpf_key_test.dir/tests/dpf_key_test.cpp.s +.PHONY : tests/dpf_key_test.cpp.s + +tests/dwt_lut_test.o: tests/dwt_lut_test.cpp.o +.PHONY : tests/dwt_lut_test.o + +# target to build an object file +tests/dwt_lut_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dwt_lut_test.dir/build.make CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.o +.PHONY : tests/dwt_lut_test.cpp.o + +tests/dwt_lut_test.i: tests/dwt_lut_test.cpp.i +.PHONY : tests/dwt_lut_test.i + +# target to preprocess a source file +tests/dwt_lut_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dwt_lut_test.dir/build.make CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.i +.PHONY : tests/dwt_lut_test.cpp.i + +tests/dwt_lut_test.s: tests/dwt_lut_test.cpp.s +.PHONY : tests/dwt_lut_test.s + +# target to generate assembly for a file +tests/dwt_lut_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dwt_lut_test.dir/build.make CMakeFiles/dwt_lut_test.dir/tests/dwt_lut_test.cpp.s +.PHONY : tests/dwt_lut_test.cpp.s + +tests/dyadic_lut_test.o: tests/dyadic_lut_test.cpp.o +.PHONY : tests/dyadic_lut_test.o + +# target to build an object file +tests/dyadic_lut_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dyadic_lut_test.dir/build.make CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.o +.PHONY : tests/dyadic_lut_test.cpp.o + +tests/dyadic_lut_test.i: tests/dyadic_lut_test.cpp.i +.PHONY : tests/dyadic_lut_test.i + +# target to preprocess a source file +tests/dyadic_lut_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dyadic_lut_test.dir/build.make CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.i +.PHONY : tests/dyadic_lut_test.cpp.i + +tests/dyadic_lut_test.s: tests/dyadic_lut_test.cpp.s +.PHONY : tests/dyadic_lut_test.s + +# target to generate assembly for a file +tests/dyadic_lut_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/dyadic_lut_test.dir/build.make CMakeFiles/dyadic_lut_test.dir/tests/dyadic_lut_test.cpp.s +.PHONY : tests/dyadic_lut_test.cpp.s + +tests/easy_lut_test.o: tests/easy_lut_test.cpp.o +.PHONY : tests/easy_lut_test.o + +# target to build an object file +tests/easy_lut_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/easy_lut_test.dir/build.make CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.o +.PHONY : tests/easy_lut_test.cpp.o + +tests/easy_lut_test.i: tests/easy_lut_test.cpp.i +.PHONY : tests/easy_lut_test.i + +# target to preprocess a source file +tests/easy_lut_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/easy_lut_test.dir/build.make CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.i +.PHONY : tests/easy_lut_test.cpp.i + +tests/easy_lut_test.s: tests/easy_lut_test.cpp.s +.PHONY : tests/easy_lut_test.s + +# target to generate assembly for a file +tests/easy_lut_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/easy_lut_test.dir/build.make CMakeFiles/easy_lut_test.dir/tests/easy_lut_test.cpp.s +.PHONY : tests/easy_lut_test.cpp.s + +tests/eval_full_multi_test.o: tests/eval_full_multi_test.cpp.o +.PHONY : tests/eval_full_multi_test.o + +# target to build an object file +tests/eval_full_multi_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_multi_test.dir/build.make CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.o +.PHONY : tests/eval_full_multi_test.cpp.o + +tests/eval_full_multi_test.i: tests/eval_full_multi_test.cpp.i +.PHONY : tests/eval_full_multi_test.i + +# target to preprocess a source file +tests/eval_full_multi_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_multi_test.dir/build.make CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.i +.PHONY : tests/eval_full_multi_test.cpp.i + +tests/eval_full_multi_test.s: tests/eval_full_multi_test.cpp.s +.PHONY : tests/eval_full_multi_test.s + +# target to generate assembly for a file +tests/eval_full_multi_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_multi_test.dir/build.make CMakeFiles/eval_full_multi_test.dir/tests/eval_full_multi_test.cpp.s +.PHONY : tests/eval_full_multi_test.cpp.s + +tests/eval_full_test.o: tests/eval_full_test.cpp.o +.PHONY : tests/eval_full_test.o + +# target to build an object file +tests/eval_full_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_test.dir/build.make CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.o +.PHONY : tests/eval_full_test.cpp.o + +tests/eval_full_test.i: tests/eval_full_test.cpp.i +.PHONY : tests/eval_full_test.i + +# target to preprocess a source file +tests/eval_full_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_test.dir/build.make CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.i +.PHONY : tests/eval_full_test.cpp.i + +tests/eval_full_test.s: tests/eval_full_test.cpp.s +.PHONY : tests/eval_full_test.s + +# target to generate assembly for a file +tests/eval_full_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_full_test.dir/build.make CMakeFiles/eval_full_test.dir/tests/eval_full_test.cpp.s +.PHONY : tests/eval_full_test.cpp.s + +tests/eval_inner_product_test.o: tests/eval_inner_product_test.cpp.o +.PHONY : tests/eval_inner_product_test.o + +# target to build an object file +tests/eval_inner_product_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_inner_product_test.dir/build.make CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.o +.PHONY : tests/eval_inner_product_test.cpp.o + +tests/eval_inner_product_test.i: tests/eval_inner_product_test.cpp.i +.PHONY : tests/eval_inner_product_test.i + +# target to preprocess a source file +tests/eval_inner_product_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_inner_product_test.dir/build.make CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.i +.PHONY : tests/eval_inner_product_test.cpp.i + +tests/eval_inner_product_test.s: tests/eval_inner_product_test.cpp.s +.PHONY : tests/eval_inner_product_test.s + +# target to generate assembly for a file +tests/eval_inner_product_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_inner_product_test.dir/build.make CMakeFiles/eval_inner_product_test.dir/tests/eval_inner_product_test.cpp.s +.PHONY : tests/eval_inner_product_test.cpp.s + +tests/eval_interval_multi_test.o: tests/eval_interval_multi_test.cpp.o +.PHONY : tests/eval_interval_multi_test.o + +# target to build an object file +tests/eval_interval_multi_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_multi_test.dir/build.make CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.o +.PHONY : tests/eval_interval_multi_test.cpp.o + +tests/eval_interval_multi_test.i: tests/eval_interval_multi_test.cpp.i +.PHONY : tests/eval_interval_multi_test.i + +# target to preprocess a source file +tests/eval_interval_multi_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_multi_test.dir/build.make CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.i +.PHONY : tests/eval_interval_multi_test.cpp.i + +tests/eval_interval_multi_test.s: tests/eval_interval_multi_test.cpp.s +.PHONY : tests/eval_interval_multi_test.s + +# target to generate assembly for a file +tests/eval_interval_multi_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_multi_test.dir/build.make CMakeFiles/eval_interval_multi_test.dir/tests/eval_interval_multi_test.cpp.s +.PHONY : tests/eval_interval_multi_test.cpp.s + +tests/eval_interval_test.o: tests/eval_interval_test.cpp.o +.PHONY : tests/eval_interval_test.o + +# target to build an object file +tests/eval_interval_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_test.dir/build.make CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.o +.PHONY : tests/eval_interval_test.cpp.o + +tests/eval_interval_test.i: tests/eval_interval_test.cpp.i +.PHONY : tests/eval_interval_test.i + +# target to preprocess a source file +tests/eval_interval_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_test.dir/build.make CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.i +.PHONY : tests/eval_interval_test.cpp.i + +tests/eval_interval_test.s: tests/eval_interval_test.cpp.s +.PHONY : tests/eval_interval_test.s + +# target to generate assembly for a file +tests/eval_interval_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_interval_test.dir/build.make CMakeFiles/eval_interval_test.dir/tests/eval_interval_test.cpp.s +.PHONY : tests/eval_interval_test.cpp.s + +tests/eval_point_multi_test.o: tests/eval_point_multi_test.cpp.o +.PHONY : tests/eval_point_multi_test.o + +# target to build an object file +tests/eval_point_multi_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_multi_test.dir/build.make CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.o +.PHONY : tests/eval_point_multi_test.cpp.o + +tests/eval_point_multi_test.i: tests/eval_point_multi_test.cpp.i +.PHONY : tests/eval_point_multi_test.i + +# target to preprocess a source file +tests/eval_point_multi_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_multi_test.dir/build.make CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.i +.PHONY : tests/eval_point_multi_test.cpp.i + +tests/eval_point_multi_test.s: tests/eval_point_multi_test.cpp.s +.PHONY : tests/eval_point_multi_test.s + +# target to generate assembly for a file +tests/eval_point_multi_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_multi_test.dir/build.make CMakeFiles/eval_point_multi_test.dir/tests/eval_point_multi_test.cpp.s +.PHONY : tests/eval_point_multi_test.cpp.s + +tests/eval_point_test.o: tests/eval_point_test.cpp.o +.PHONY : tests/eval_point_test.o + +# target to build an object file +tests/eval_point_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_test.dir/build.make CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.o +.PHONY : tests/eval_point_test.cpp.o + +tests/eval_point_test.i: tests/eval_point_test.cpp.i +.PHONY : tests/eval_point_test.i + +# target to preprocess a source file +tests/eval_point_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_test.dir/build.make CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.i +.PHONY : tests/eval_point_test.cpp.i + +tests/eval_point_test.s: tests/eval_point_test.cpp.s +.PHONY : tests/eval_point_test.s + +# target to generate assembly for a file +tests/eval_point_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_point_test.dir/build.make CMakeFiles/eval_point_test.dir/tests/eval_point_test.cpp.s +.PHONY : tests/eval_point_test.cpp.s + +tests/eval_sequence_multi_test.o: tests/eval_sequence_multi_test.cpp.o +.PHONY : tests/eval_sequence_multi_test.o + +# target to build an object file +tests/eval_sequence_multi_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_multi_test.dir/build.make CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.o +.PHONY : tests/eval_sequence_multi_test.cpp.o + +tests/eval_sequence_multi_test.i: tests/eval_sequence_multi_test.cpp.i +.PHONY : tests/eval_sequence_multi_test.i + +# target to preprocess a source file +tests/eval_sequence_multi_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_multi_test.dir/build.make CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.i +.PHONY : tests/eval_sequence_multi_test.cpp.i + +tests/eval_sequence_multi_test.s: tests/eval_sequence_multi_test.cpp.s +.PHONY : tests/eval_sequence_multi_test.s + +# target to generate assembly for a file +tests/eval_sequence_multi_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_multi_test.dir/build.make CMakeFiles/eval_sequence_multi_test.dir/tests/eval_sequence_multi_test.cpp.s +.PHONY : tests/eval_sequence_multi_test.cpp.s + +tests/eval_sequence_test.o: tests/eval_sequence_test.cpp.o +.PHONY : tests/eval_sequence_test.o + +# target to build an object file +tests/eval_sequence_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_test.dir/build.make CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.o +.PHONY : tests/eval_sequence_test.cpp.o + +tests/eval_sequence_test.i: tests/eval_sequence_test.cpp.i +.PHONY : tests/eval_sequence_test.i + +# target to preprocess a source file +tests/eval_sequence_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_test.dir/build.make CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.i +.PHONY : tests/eval_sequence_test.cpp.i + +tests/eval_sequence_test.s: tests/eval_sequence_test.cpp.s +.PHONY : tests/eval_sequence_test.s + +# target to generate assembly for a file +tests/eval_sequence_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_sequence_test.dir/build.make CMakeFiles/eval_sequence_test.dir/tests/eval_sequence_test.cpp.s +.PHONY : tests/eval_sequence_test.cpp.s + +tests/eval_until_test.o: tests/eval_until_test.cpp.o +.PHONY : tests/eval_until_test.o + +# target to build an object file +tests/eval_until_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_until_test.dir/build.make CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.o +.PHONY : tests/eval_until_test.cpp.o + +tests/eval_until_test.i: tests/eval_until_test.cpp.i +.PHONY : tests/eval_until_test.i + +# target to preprocess a source file +tests/eval_until_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_until_test.dir/build.make CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.i +.PHONY : tests/eval_until_test.cpp.i + +tests/eval_until_test.s: tests/eval_until_test.cpp.s +.PHONY : tests/eval_until_test.s + +# target to generate assembly for a file +tests/eval_until_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/eval_until_test.dir/build.make CMakeFiles/eval_until_test.dir/tests/eval_until_test.cpp.s +.PHONY : tests/eval_until_test.cpp.s + +tests/exact_steps_test.o: tests/exact_steps_test.cpp.o +.PHONY : tests/exact_steps_test.o + +# target to build an object file +tests/exact_steps_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/exact_steps_test.dir/build.make CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.o +.PHONY : tests/exact_steps_test.cpp.o + +tests/exact_steps_test.i: tests/exact_steps_test.cpp.i +.PHONY : tests/exact_steps_test.i + +# target to preprocess a source file +tests/exact_steps_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/exact_steps_test.dir/build.make CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.i +.PHONY : tests/exact_steps_test.cpp.i + +tests/exact_steps_test.s: tests/exact_steps_test.cpp.s +.PHONY : tests/exact_steps_test.s + +# target to generate assembly for a file +tests/exact_steps_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/exact_steps_test.dir/build.make CMakeFiles/exact_steps_test.dir/tests/exact_steps_test.cpp.s +.PHONY : tests/exact_steps_test.cpp.s + +tests/experiment_test.o: tests/experiment_test.cpp.o +.PHONY : tests/experiment_test.o + +# target to build an object file +tests/experiment_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/experiment_test.dir/build.make CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.o +.PHONY : tests/experiment_test.cpp.o + +tests/experiment_test.i: tests/experiment_test.cpp.i +.PHONY : tests/experiment_test.i + +# target to preprocess a source file +tests/experiment_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/experiment_test.dir/build.make CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.i +.PHONY : tests/experiment_test.cpp.i + +tests/experiment_test.s: tests/experiment_test.cpp.s +.PHONY : tests/experiment_test.s + +# target to generate assembly for a file +tests/experiment_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/experiment_test.dir/build.make CMakeFiles/experiment_test.dir/tests/experiment_test.cpp.s +.PHONY : tests/experiment_test.cpp.s + +tests/extractable_full_test.o: tests/extractable_full_test.cpp.o +.PHONY : tests/extractable_full_test.o + +# target to build an object file +tests/extractable_full_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/extractable_full_test.dir/build.make CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.o +.PHONY : tests/extractable_full_test.cpp.o + +tests/extractable_full_test.i: tests/extractable_full_test.cpp.i +.PHONY : tests/extractable_full_test.i + +# target to preprocess a source file +tests/extractable_full_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/extractable_full_test.dir/build.make CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.i +.PHONY : tests/extractable_full_test.cpp.i + +tests/extractable_full_test.s: tests/extractable_full_test.cpp.s +.PHONY : tests/extractable_full_test.s + +# target to generate assembly for a file +tests/extractable_full_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/extractable_full_test.dir/build.make CMakeFiles/extractable_full_test.dir/tests/extractable_full_test.cpp.s +.PHONY : tests/extractable_full_test.cpp.s + +tests/field_output_test.o: tests/field_output_test.cpp.o +.PHONY : tests/field_output_test.o + +# target to build an object file +tests/field_output_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/field_output_test.dir/build.make CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.o +.PHONY : tests/field_output_test.cpp.o + +tests/field_output_test.i: tests/field_output_test.cpp.i +.PHONY : tests/field_output_test.i + +# target to preprocess a source file +tests/field_output_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/field_output_test.dir/build.make CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.i +.PHONY : tests/field_output_test.cpp.i + +tests/field_output_test.s: tests/field_output_test.cpp.s +.PHONY : tests/field_output_test.s + +# target to generate assembly for a file +tests/field_output_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/field_output_test.dir/build.make CMakeFiles/field_output_test.dir/tests/field_output_test.cpp.s +.PHONY : tests/field_output_test.cpp.s + +tests/fixedpoint_beaver_test.o: tests/fixedpoint_beaver_test.cpp.o +.PHONY : tests/fixedpoint_beaver_test.o + +# target to build an object file +tests/fixedpoint_beaver_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/fixedpoint_beaver_test.dir/build.make CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.o +.PHONY : tests/fixedpoint_beaver_test.cpp.o + +tests/fixedpoint_beaver_test.i: tests/fixedpoint_beaver_test.cpp.i +.PHONY : tests/fixedpoint_beaver_test.i + +# target to preprocess a source file +tests/fixedpoint_beaver_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/fixedpoint_beaver_test.dir/build.make CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.i +.PHONY : tests/fixedpoint_beaver_test.cpp.i + +tests/fixedpoint_beaver_test.s: tests/fixedpoint_beaver_test.cpp.s +.PHONY : tests/fixedpoint_beaver_test.s + +# target to generate assembly for a file +tests/fixedpoint_beaver_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/fixedpoint_beaver_test.dir/build.make CMakeFiles/fixedpoint_beaver_test.dir/tests/fixedpoint_beaver_test.cpp.s +.PHONY : tests/fixedpoint_beaver_test.cpp.s + +tests/flute_test.o: tests/flute_test.cpp.o +.PHONY : tests/flute_test.o + +# target to build an object file +tests/flute_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/flute_test.dir/build.make CMakeFiles/flute_test.dir/tests/flute_test.cpp.o +.PHONY : tests/flute_test.cpp.o + +tests/flute_test.i: tests/flute_test.cpp.i +.PHONY : tests/flute_test.i + +# target to preprocess a source file +tests/flute_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/flute_test.dir/build.make CMakeFiles/flute_test.dir/tests/flute_test.cpp.i +.PHONY : tests/flute_test.cpp.i + +tests/flute_test.s: tests/flute_test.cpp.s +.PHONY : tests/flute_test.s + +# target to generate assembly for a file +tests/flute_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/flute_test.dir/build.make CMakeFiles/flute_test.dir/tests/flute_test.cpp.s +.PHONY : tests/flute_test.cpp.s + +tests/fp61_test.o: tests/fp61_test.cpp.o +.PHONY : tests/fp61_test.o + +# target to build an object file +tests/fp61_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/fp61_test.dir/build.make CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.o +.PHONY : tests/fp61_test.cpp.o + +tests/fp61_test.i: tests/fp61_test.cpp.i +.PHONY : tests/fp61_test.i + +# target to preprocess a source file +tests/fp61_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/fp61_test.dir/build.make CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.i +.PHONY : tests/fp61_test.cpp.i + +tests/fp61_test.s: tests/fp61_test.cpp.s +.PHONY : tests/fp61_test.s + +# target to generate assembly for a file +tests/fp61_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/fp61_test.dir/build.make CMakeFiles/fp61_test.dir/tests/fp61_test.cpp.s +.PHONY : tests/fp61_test.cpp.s + +tests/geneval_test.o: tests/geneval_test.cpp.o +.PHONY : tests/geneval_test.o + +# target to build an object file +tests/geneval_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/geneval_test.dir/build.make CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.o +.PHONY : tests/geneval_test.cpp.o + +tests/geneval_test.i: tests/geneval_test.cpp.i +.PHONY : tests/geneval_test.i + +# target to preprocess a source file +tests/geneval_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/geneval_test.dir/build.make CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.i +.PHONY : tests/geneval_test.cpp.i + +tests/geneval_test.s: tests/geneval_test.cpp.s +.PHONY : tests/geneval_test.s + +# target to generate assembly for a file +tests/geneval_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/geneval_test.dir/build.make CMakeFiles/geneval_test.dir/tests/geneval_test.cpp.s +.PHONY : tests/geneval_test.cpp.s + +tests/gf2_adversarial_test.o: tests/gf2_adversarial_test.cpp.o +.PHONY : tests/gf2_adversarial_test.o + +# target to build an object file +tests/gf2_adversarial_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_adversarial_test.dir/build.make CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.o +.PHONY : tests/gf2_adversarial_test.cpp.o + +tests/gf2_adversarial_test.i: tests/gf2_adversarial_test.cpp.i +.PHONY : tests/gf2_adversarial_test.i + +# target to preprocess a source file +tests/gf2_adversarial_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_adversarial_test.dir/build.make CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.i +.PHONY : tests/gf2_adversarial_test.cpp.i + +tests/gf2_adversarial_test.s: tests/gf2_adversarial_test.cpp.s +.PHONY : tests/gf2_adversarial_test.s + +# target to generate assembly for a file +tests/gf2_adversarial_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_adversarial_test.dir/build.make CMakeFiles/gf2_adversarial_test.dir/tests/gf2_adversarial_test.cpp.s +.PHONY : tests/gf2_adversarial_test.cpp.s + +tests/gf2_test.o: tests/gf2_test.cpp.o +.PHONY : tests/gf2_test.o + +# target to build an object file +tests/gf2_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_test.dir/build.make CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.o +.PHONY : tests/gf2_test.cpp.o + +tests/gf2_test.i: tests/gf2_test.cpp.i +.PHONY : tests/gf2_test.i + +# target to preprocess a source file +tests/gf2_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_test.dir/build.make CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.i +.PHONY : tests/gf2_test.cpp.i + +tests/gf2_test.s: tests/gf2_test.cpp.s +.PHONY : tests/gf2_test.s + +# target to generate assembly for a file +tests/gf2_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/gf2_test.dir/build.make CMakeFiles/gf2_test.dir/tests/gf2_test.cpp.s +.PHONY : tests/gf2_test.cpp.s + +tests/growing_idpf_test.o: tests/growing_idpf_test.cpp.o +.PHONY : tests/growing_idpf_test.o + +# target to build an object file +tests/growing_idpf_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/growing_idpf_test.dir/build.make CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.o +.PHONY : tests/growing_idpf_test.cpp.o + +tests/growing_idpf_test.i: tests/growing_idpf_test.cpp.i +.PHONY : tests/growing_idpf_test.i + +# target to preprocess a source file +tests/growing_idpf_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/growing_idpf_test.dir/build.make CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.i +.PHONY : tests/growing_idpf_test.cpp.i + +tests/growing_idpf_test.s: tests/growing_idpf_test.cpp.s +.PHONY : tests/growing_idpf_test.s + +# target to generate assembly for a file +tests/growing_idpf_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/growing_idpf_test.dir/build.make CMakeFiles/growing_idpf_test.dir/tests/growing_idpf_test.cpp.s +.PHONY : tests/growing_idpf_test.cpp.s + +tests/half_tree_test.o: tests/half_tree_test.cpp.o +.PHONY : tests/half_tree_test.o + +# target to build an object file +tests/half_tree_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/half_tree_test.dir/build.make CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.o +.PHONY : tests/half_tree_test.cpp.o + +tests/half_tree_test.i: tests/half_tree_test.cpp.i +.PHONY : tests/half_tree_test.i + +# target to preprocess a source file +tests/half_tree_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/half_tree_test.dir/build.make CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.i +.PHONY : tests/half_tree_test.cpp.i + +tests/half_tree_test.s: tests/half_tree_test.cpp.s +.PHONY : tests/half_tree_test.s + +# target to generate assembly for a file +tests/half_tree_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/half_tree_test.dir/build.make CMakeFiles/half_tree_test.dir/tests/half_tree_test.cpp.s +.PHONY : tests/half_tree_test.cpp.s + +tests/ic_test.o: tests/ic_test.cpp.o +.PHONY : tests/ic_test.o + +# target to build an object file +tests/ic_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ic_test.dir/build.make CMakeFiles/ic_test.dir/tests/ic_test.cpp.o +.PHONY : tests/ic_test.cpp.o + +tests/ic_test.i: tests/ic_test.cpp.i +.PHONY : tests/ic_test.i + +# target to preprocess a source file +tests/ic_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ic_test.dir/build.make CMakeFiles/ic_test.dir/tests/ic_test.cpp.i +.PHONY : tests/ic_test.cpp.i + +tests/ic_test.s: tests/ic_test.cpp.s +.PHONY : tests/ic_test.s + +# target to generate assembly for a file +tests/ic_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ic_test.dir/build.make CMakeFiles/ic_test.dir/tests/ic_test.cpp.s +.PHONY : tests/ic_test.cpp.s + +tests/idpf_agg_test.o: tests/idpf_agg_test.cpp.o +.PHONY : tests/idpf_agg_test.o + +# target to build an object file +tests/idpf_agg_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/idpf_agg_test.dir/build.make CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.o +.PHONY : tests/idpf_agg_test.cpp.o + +tests/idpf_agg_test.i: tests/idpf_agg_test.cpp.i +.PHONY : tests/idpf_agg_test.i + +# target to preprocess a source file +tests/idpf_agg_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/idpf_agg_test.dir/build.make CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.i +.PHONY : tests/idpf_agg_test.cpp.i + +tests/idpf_agg_test.s: tests/idpf_agg_test.cpp.s +.PHONY : tests/idpf_agg_test.s + +# target to generate assembly for a file +tests/idpf_agg_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/idpf_agg_test.dir/build.make CMakeFiles/idpf_agg_test.dir/tests/idpf_agg_test.cpp.s +.PHONY : tests/idpf_agg_test.cpp.s + +tests/iknp_party_test.o: tests/iknp_party_test.cpp.o +.PHONY : tests/iknp_party_test.o + +# target to build an object file +tests/iknp_party_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/iknp_party_test.dir/build.make CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.o +.PHONY : tests/iknp_party_test.cpp.o + +tests/iknp_party_test.i: tests/iknp_party_test.cpp.i +.PHONY : tests/iknp_party_test.i + +# target to preprocess a source file +tests/iknp_party_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/iknp_party_test.dir/build.make CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.i +.PHONY : tests/iknp_party_test.cpp.i + +tests/iknp_party_test.s: tests/iknp_party_test.cpp.s +.PHONY : tests/iknp_party_test.s + +# target to generate assembly for a file +tests/iknp_party_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/iknp_party_test.dir/build.make CMakeFiles/iknp_party_test.dir/tests/iknp_party_test.cpp.s +.PHONY : tests/iknp_party_test.cpp.s + +tests/incremental_json_test.o: tests/incremental_json_test.cpp.o +.PHONY : tests/incremental_json_test.o + +# target to build an object file +tests/incremental_json_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_json_test.dir/build.make CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.o +.PHONY : tests/incremental_json_test.cpp.o + +tests/incremental_json_test.i: tests/incremental_json_test.cpp.i +.PHONY : tests/incremental_json_test.i + +# target to preprocess a source file +tests/incremental_json_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_json_test.dir/build.make CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.i +.PHONY : tests/incremental_json_test.cpp.i + +tests/incremental_json_test.s: tests/incremental_json_test.cpp.s +.PHONY : tests/incremental_json_test.s + +# target to generate assembly for a file +tests/incremental_json_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_json_test.dir/build.make CMakeFiles/incremental_json_test.dir/tests/incremental_json_test.cpp.s +.PHONY : tests/incremental_json_test.cpp.s + +tests/incremental_test.o: tests/incremental_test.cpp.o +.PHONY : tests/incremental_test.o + +# target to build an object file +tests/incremental_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_test.dir/build.make CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.o +.PHONY : tests/incremental_test.cpp.o + +tests/incremental_test.i: tests/incremental_test.cpp.i +.PHONY : tests/incremental_test.i + +# target to preprocess a source file +tests/incremental_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_test.dir/build.make CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.i +.PHONY : tests/incremental_test.cpp.i + +tests/incremental_test.s: tests/incremental_test.cpp.s +.PHONY : tests/incremental_test.s + +# target to generate assembly for a file +tests/incremental_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/incremental_test.dir/build.make CMakeFiles/incremental_test.dir/tests/incremental_test.cpp.s +.PHONY : tests/incremental_test.cpp.s + +tests/interleave_leaves_test.o: tests/interleave_leaves_test.cpp.o +.PHONY : tests/interleave_leaves_test.o + +# target to build an object file +tests/interleave_leaves_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/interleave_leaves_test.dir/build.make CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.o +.PHONY : tests/interleave_leaves_test.cpp.o + +tests/interleave_leaves_test.i: tests/interleave_leaves_test.cpp.i +.PHONY : tests/interleave_leaves_test.i + +# target to preprocess a source file +tests/interleave_leaves_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/interleave_leaves_test.dir/build.make CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.i +.PHONY : tests/interleave_leaves_test.cpp.i + +tests/interleave_leaves_test.s: tests/interleave_leaves_test.cpp.s +.PHONY : tests/interleave_leaves_test.s + +# target to generate assembly for a file +tests/interleave_leaves_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/interleave_leaves_test.dir/build.make CMakeFiles/interleave_leaves_test.dir/tests/interleave_leaves_test.cpp.s +.PHONY : tests/interleave_leaves_test.cpp.s + +tests/it_dpf3_test.o: tests/it_dpf3_test.cpp.o +.PHONY : tests/it_dpf3_test.o + +# target to build an object file +tests/it_dpf3_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/it_dpf3_test.dir/build.make CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.o +.PHONY : tests/it_dpf3_test.cpp.o + +tests/it_dpf3_test.i: tests/it_dpf3_test.cpp.i +.PHONY : tests/it_dpf3_test.i + +# target to preprocess a source file +tests/it_dpf3_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/it_dpf3_test.dir/build.make CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.i +.PHONY : tests/it_dpf3_test.cpp.i + +tests/it_dpf3_test.s: tests/it_dpf3_test.cpp.s +.PHONY : tests/it_dpf3_test.s + +# target to generate assembly for a file +tests/it_dpf3_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/it_dpf3_test.dir/build.make CMakeFiles/it_dpf3_test.dir/tests/it_dpf3_test.cpp.s +.PHONY : tests/it_dpf3_test.cpp.s + +tests/keyword2_test.o: tests/keyword2_test.cpp.o +.PHONY : tests/keyword2_test.o + +# target to build an object file +tests/keyword2_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/keyword2_test.dir/build.make CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.o +.PHONY : tests/keyword2_test.cpp.o + +tests/keyword2_test.i: tests/keyword2_test.cpp.i +.PHONY : tests/keyword2_test.i + +# target to preprocess a source file +tests/keyword2_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/keyword2_test.dir/build.make CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.i +.PHONY : tests/keyword2_test.cpp.i + +tests/keyword2_test.s: tests/keyword2_test.cpp.s +.PHONY : tests/keyword2_test.s + +# target to generate assembly for a file +tests/keyword2_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/keyword2_test.dir/build.make CMakeFiles/keyword2_test.dir/tests/keyword2_test.cpp.s +.PHONY : tests/keyword2_test.cpp.s + +tests/lane_blast_test.o: tests/lane_blast_test.cpp.o +.PHONY : tests/lane_blast_test.o + +# target to build an object file +tests/lane_blast_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/lane_blast_test.dir/build.make CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.o +.PHONY : tests/lane_blast_test.cpp.o + +tests/lane_blast_test.i: tests/lane_blast_test.cpp.i +.PHONY : tests/lane_blast_test.i + +# target to preprocess a source file +tests/lane_blast_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/lane_blast_test.dir/build.make CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.i +.PHONY : tests/lane_blast_test.cpp.i + +tests/lane_blast_test.s: tests/lane_blast_test.cpp.s +.PHONY : tests/lane_blast_test.s + +# target to generate assembly for a file +tests/lane_blast_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/lane_blast_test.dir/build.make CMakeFiles/lane_blast_test.dir/tests/lane_blast_test.cpp.s +.PHONY : tests/lane_blast_test.cpp.s + +tests/leaf_later_test.o: tests/leaf_later_test.cpp.o +.PHONY : tests/leaf_later_test.o + +# target to build an object file +tests/leaf_later_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/leaf_later_test.dir/build.make CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.o +.PHONY : tests/leaf_later_test.cpp.o + +tests/leaf_later_test.i: tests/leaf_later_test.cpp.i +.PHONY : tests/leaf_later_test.i + +# target to preprocess a source file +tests/leaf_later_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/leaf_later_test.dir/build.make CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.i +.PHONY : tests/leaf_later_test.cpp.i + +tests/leaf_later_test.s: tests/leaf_later_test.cpp.s +.PHONY : tests/leaf_later_test.s + +# target to generate assembly for a file +tests/leaf_later_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/leaf_later_test.dir/build.make CMakeFiles/leaf_later_test.dir/tests/leaf_later_test.cpp.s +.PHONY : tests/leaf_later_test.cpp.s + +tests/log_test.o: tests/log_test.cpp.o +.PHONY : tests/log_test.o + +# target to build an object file +tests/log_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/log_test.dir/build.make CMakeFiles/log_test.dir/tests/log_test.cpp.o +.PHONY : tests/log_test.cpp.o + +tests/log_test.i: tests/log_test.cpp.i +.PHONY : tests/log_test.i + +# target to preprocess a source file +tests/log_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/log_test.dir/build.make CMakeFiles/log_test.dir/tests/log_test.cpp.i +.PHONY : tests/log_test.cpp.i + +tests/log_test.s: tests/log_test.cpp.s +.PHONY : tests/log_test.s + +# target to generate assembly for a file +tests/log_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/log_test.dir/build.make CMakeFiles/log_test.dir/tests/log_test.cpp.s +.PHONY : tests/log_test.cpp.s + +tests/lut_union_test.o: tests/lut_union_test.cpp.o +.PHONY : tests/lut_union_test.o + +# target to build an object file +tests/lut_union_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/lut_union_test.dir/build.make CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.o +.PHONY : tests/lut_union_test.cpp.o + +tests/lut_union_test.i: tests/lut_union_test.cpp.i +.PHONY : tests/lut_union_test.i + +# target to preprocess a source file +tests/lut_union_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/lut_union_test.dir/build.make CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.i +.PHONY : tests/lut_union_test.cpp.i + +tests/lut_union_test.s: tests/lut_union_test.cpp.s +.PHONY : tests/lut_union_test.s + +# target to generate assembly for a file +tests/lut_union_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/lut_union_test.dir/build.make CMakeFiles/lut_union_test.dir/tests/lut_union_test.cpp.s +.PHONY : tests/lut_union_test.cpp.s + +tests/multipoint_test.o: tests/multipoint_test.cpp.o +.PHONY : tests/multipoint_test.o + +# target to build an object file +tests/multipoint_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/multipoint_test.dir/build.make CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.o +.PHONY : tests/multipoint_test.cpp.o + +tests/multipoint_test.i: tests/multipoint_test.cpp.i +.PHONY : tests/multipoint_test.i + +# target to preprocess a source file +tests/multipoint_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/multipoint_test.dir/build.make CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.i +.PHONY : tests/multipoint_test.cpp.i + +tests/multipoint_test.s: tests/multipoint_test.cpp.s +.PHONY : tests/multipoint_test.s + +# target to generate assembly for a file +tests/multipoint_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/multipoint_test.dir/build.make CMakeFiles/multipoint_test.dir/tests/multipoint_test.cpp.s +.PHONY : tests/multipoint_test.cpp.s + +tests/net_control_test.o: tests/net_control_test.cpp.o +.PHONY : tests/net_control_test.o + +# target to build an object file +tests/net_control_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/net_control_test.dir/build.make CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.o +.PHONY : tests/net_control_test.cpp.o + +tests/net_control_test.i: tests/net_control_test.cpp.i +.PHONY : tests/net_control_test.i + +# target to preprocess a source file +tests/net_control_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/net_control_test.dir/build.make CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.i +.PHONY : tests/net_control_test.cpp.i + +tests/net_control_test.s: tests/net_control_test.cpp.s +.PHONY : tests/net_control_test.s + +# target to generate assembly for a file +tests/net_control_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/net_control_test.dir/build.make CMakeFiles/net_control_test.dir/tests/net_control_test.cpp.s +.PHONY : tests/net_control_test.cpp.s + +tests/nmod_test.o: tests/nmod_test.cpp.o +.PHONY : tests/nmod_test.o + +# target to build an object file +tests/nmod_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/nmod_test.dir/build.make CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.o +.PHONY : tests/nmod_test.cpp.o + +tests/nmod_test.i: tests/nmod_test.cpp.i +.PHONY : tests/nmod_test.i + +# target to preprocess a source file +tests/nmod_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/nmod_test.dir/build.make CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.i +.PHONY : tests/nmod_test.cpp.i + +tests/nmod_test.s: tests/nmod_test.cpp.s +.PHONY : tests/nmod_test.s + +# target to generate assembly for a file +tests/nmod_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/nmod_test.dir/build.make CMakeFiles/nmod_test.dir/tests/nmod_test.cpp.s +.PHONY : tests/nmod_test.cpp.s + +tests/offset_horner_test.o: tests/offset_horner_test.cpp.o +.PHONY : tests/offset_horner_test.o + +# target to build an object file +tests/offset_horner_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_horner_test.dir/build.make CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.o +.PHONY : tests/offset_horner_test.cpp.o + +tests/offset_horner_test.i: tests/offset_horner_test.cpp.i +.PHONY : tests/offset_horner_test.i + +# target to preprocess a source file +tests/offset_horner_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_horner_test.dir/build.make CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.i +.PHONY : tests/offset_horner_test.cpp.i + +tests/offset_horner_test.s: tests/offset_horner_test.cpp.s +.PHONY : tests/offset_horner_test.s + +# target to generate assembly for a file +tests/offset_horner_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_horner_test.dir/build.make CMakeFiles/offset_horner_test.dir/tests/offset_horner_test.cpp.s +.PHONY : tests/offset_horner_test.cpp.s + +tests/offset_jet_test.o: tests/offset_jet_test.cpp.o +.PHONY : tests/offset_jet_test.o + +# target to build an object file +tests/offset_jet_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_jet_test.dir/build.make CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.o +.PHONY : tests/offset_jet_test.cpp.o + +tests/offset_jet_test.i: tests/offset_jet_test.cpp.i +.PHONY : tests/offset_jet_test.i + +# target to preprocess a source file +tests/offset_jet_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_jet_test.dir/build.make CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.i +.PHONY : tests/offset_jet_test.cpp.i + +tests/offset_jet_test.s: tests/offset_jet_test.cpp.s +.PHONY : tests/offset_jet_test.s + +# target to generate assembly for a file +tests/offset_jet_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_jet_test.dir/build.make CMakeFiles/offset_jet_test.dir/tests/offset_jet_test.cpp.s +.PHONY : tests/offset_jet_test.cpp.s + +tests/offset_poly_test.o: tests/offset_poly_test.cpp.o +.PHONY : tests/offset_poly_test.o + +# target to build an object file +tests/offset_poly_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_poly_test.dir/build.make CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.o +.PHONY : tests/offset_poly_test.cpp.o + +tests/offset_poly_test.i: tests/offset_poly_test.cpp.i +.PHONY : tests/offset_poly_test.i + +# target to preprocess a source file +tests/offset_poly_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_poly_test.dir/build.make CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.i +.PHONY : tests/offset_poly_test.cpp.i + +tests/offset_poly_test.s: tests/offset_poly_test.cpp.s +.PHONY : tests/offset_poly_test.s + +# target to generate assembly for a file +tests/offset_poly_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_poly_test.dir/build.make CMakeFiles/offset_poly_test.dir/tests/offset_poly_test.cpp.s +.PHONY : tests/offset_poly_test.cpp.s + +tests/offset_repr_test.o: tests/offset_repr_test.cpp.o +.PHONY : tests/offset_repr_test.o + +# target to build an object file +tests/offset_repr_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_repr_test.dir/build.make CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.o +.PHONY : tests/offset_repr_test.cpp.o + +tests/offset_repr_test.i: tests/offset_repr_test.cpp.i +.PHONY : tests/offset_repr_test.i + +# target to preprocess a source file +tests/offset_repr_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_repr_test.dir/build.make CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.i +.PHONY : tests/offset_repr_test.cpp.i + +tests/offset_repr_test.s: tests/offset_repr_test.cpp.s +.PHONY : tests/offset_repr_test.s + +# target to generate assembly for a file +tests/offset_repr_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_repr_test.dir/build.make CMakeFiles/offset_repr_test.dir/tests/offset_repr_test.cpp.s +.PHONY : tests/offset_repr_test.cpp.s + +tests/offset_twist_test.o: tests/offset_twist_test.cpp.o +.PHONY : tests/offset_twist_test.o + +# target to build an object file +tests/offset_twist_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_twist_test.dir/build.make CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.o +.PHONY : tests/offset_twist_test.cpp.o + +tests/offset_twist_test.i: tests/offset_twist_test.cpp.i +.PHONY : tests/offset_twist_test.i + +# target to preprocess a source file +tests/offset_twist_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_twist_test.dir/build.make CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.i +.PHONY : tests/offset_twist_test.cpp.i + +tests/offset_twist_test.s: tests/offset_twist_test.cpp.s +.PHONY : tests/offset_twist_test.s + +# target to generate assembly for a file +tests/offset_twist_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/offset_twist_test.dir/build.make CMakeFiles/offset_twist_test.dir/tests/offset_twist_test.cpp.s +.PHONY : tests/offset_twist_test.cpp.s + +tests/opt_in_malicious_test.o: tests/opt_in_malicious_test.cpp.o +.PHONY : tests/opt_in_malicious_test.o + +# target to build an object file +tests/opt_in_malicious_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/opt_in_malicious_test.dir/build.make CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.o +.PHONY : tests/opt_in_malicious_test.cpp.o + +tests/opt_in_malicious_test.i: tests/opt_in_malicious_test.cpp.i +.PHONY : tests/opt_in_malicious_test.i + +# target to preprocess a source file +tests/opt_in_malicious_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/opt_in_malicious_test.dir/build.make CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.i +.PHONY : tests/opt_in_malicious_test.cpp.i + +tests/opt_in_malicious_test.s: tests/opt_in_malicious_test.cpp.s +.PHONY : tests/opt_in_malicious_test.s + +# target to generate assembly for a file +tests/opt_in_malicious_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/opt_in_malicious_test.dir/build.make CMakeFiles/opt_in_malicious_test.dir/tests/opt_in_malicious_test.cpp.s +.PHONY : tests/opt_in_malicious_test.cpp.s + +tests/packed_lane_test.o: tests/packed_lane_test.cpp.o +.PHONY : tests/packed_lane_test.o + +# target to build an object file +tests/packed_lane_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/packed_lane_test.dir/build.make CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.o +.PHONY : tests/packed_lane_test.cpp.o + +tests/packed_lane_test.i: tests/packed_lane_test.cpp.i +.PHONY : tests/packed_lane_test.i + +# target to preprocess a source file +tests/packed_lane_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/packed_lane_test.dir/build.make CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.i +.PHONY : tests/packed_lane_test.cpp.i + +tests/packed_lane_test.s: tests/packed_lane_test.cpp.s +.PHONY : tests/packed_lane_test.s + +# target to generate assembly for a file +tests/packed_lane_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/packed_lane_test.dir/build.make CMakeFiles/packed_lane_test.dir/tests/packed_lane_test.cpp.s +.PHONY : tests/packed_lane_test.cpp.s + +tests/parallel_bit_iterable_test.o: tests/parallel_bit_iterable_test.cpp.o +.PHONY : tests/parallel_bit_iterable_test.o + +# target to build an object file +tests/parallel_bit_iterable_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/parallel_bit_iterable_test.dir/build.make CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.o +.PHONY : tests/parallel_bit_iterable_test.cpp.o + +tests/parallel_bit_iterable_test.i: tests/parallel_bit_iterable_test.cpp.i +.PHONY : tests/parallel_bit_iterable_test.i + +# target to preprocess a source file +tests/parallel_bit_iterable_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/parallel_bit_iterable_test.dir/build.make CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.i +.PHONY : tests/parallel_bit_iterable_test.cpp.i + +tests/parallel_bit_iterable_test.s: tests/parallel_bit_iterable_test.cpp.s +.PHONY : tests/parallel_bit_iterable_test.s + +# target to generate assembly for a file +tests/parallel_bit_iterable_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/parallel_bit_iterable_test.dir/build.make CMakeFiles/parallel_bit_iterable_test.dir/tests/parallel_bit_iterable_test.cpp.s +.PHONY : tests/parallel_bit_iterable_test.cpp.s + +tests/path_recipe_test.o: tests/path_recipe_test.cpp.o +.PHONY : tests/path_recipe_test.o + +# target to build an object file +tests/path_recipe_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_recipe_test.dir/build.make CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.o +.PHONY : tests/path_recipe_test.cpp.o + +tests/path_recipe_test.i: tests/path_recipe_test.cpp.i +.PHONY : tests/path_recipe_test.i + +# target to preprocess a source file +tests/path_recipe_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_recipe_test.dir/build.make CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.i +.PHONY : tests/path_recipe_test.cpp.i + +tests/path_recipe_test.s: tests/path_recipe_test.cpp.s +.PHONY : tests/path_recipe_test.s + +# target to generate assembly for a file +tests/path_recipe_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_recipe_test.dir/build.make CMakeFiles/path_recipe_test.dir/tests/path_recipe_test.cpp.s +.PHONY : tests/path_recipe_test.cpp.s + +tests/path_sketch_test.o: tests/path_sketch_test.cpp.o +.PHONY : tests/path_sketch_test.o + +# target to build an object file +tests/path_sketch_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_sketch_test.dir/build.make CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.o +.PHONY : tests/path_sketch_test.cpp.o + +tests/path_sketch_test.i: tests/path_sketch_test.cpp.i +.PHONY : tests/path_sketch_test.i + +# target to preprocess a source file +tests/path_sketch_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_sketch_test.dir/build.make CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.i +.PHONY : tests/path_sketch_test.cpp.i + +tests/path_sketch_test.s: tests/path_sketch_test.cpp.s +.PHONY : tests/path_sketch_test.s + +# target to generate assembly for a file +tests/path_sketch_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/path_sketch_test.dir/build.make CMakeFiles/path_sketch_test.dir/tests/path_sketch_test.cpp.s +.PHONY : tests/path_sketch_test.cpp.s + +tests/pprf_test.o: tests/pprf_test.cpp.o +.PHONY : tests/pprf_test.o + +# target to build an object file +tests/pprf_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pprf_test.dir/build.make CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.o +.PHONY : tests/pprf_test.cpp.o + +tests/pprf_test.i: tests/pprf_test.cpp.i +.PHONY : tests/pprf_test.i + +# target to preprocess a source file +tests/pprf_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pprf_test.dir/build.make CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.i +.PHONY : tests/pprf_test.cpp.i + +tests/pprf_test.s: tests/pprf_test.cpp.s +.PHONY : tests/pprf_test.s + +# target to generate assembly for a file +tests/pprf_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/pprf_test.dir/build.make CMakeFiles/pprf_test.dir/tests/pprf_test.cpp.s +.PHONY : tests/pprf_test.cpp.s + +tests/ppvc_test.o: tests/ppvc_test.cpp.o +.PHONY : tests/ppvc_test.o + +# target to build an object file +tests/ppvc_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ppvc_test.dir/build.make CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.o +.PHONY : tests/ppvc_test.cpp.o + +tests/ppvc_test.i: tests/ppvc_test.cpp.i +.PHONY : tests/ppvc_test.i + +# target to preprocess a source file +tests/ppvc_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ppvc_test.dir/build.make CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.i +.PHONY : tests/ppvc_test.cpp.i + +tests/ppvc_test.s: tests/ppvc_test.cpp.s +.PHONY : tests/ppvc_test.s + +# target to generate assembly for a file +tests/ppvc_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ppvc_test.dir/build.make CMakeFiles/ppvc_test.dir/tests/ppvc_test.cpp.s +.PHONY : tests/ppvc_test.cpp.s + +tests/prg_aes_ccr_test.o: tests/prg_aes_ccr_test.cpp.o +.PHONY : tests/prg_aes_ccr_test.o + +# target to build an object file +tests/prg_aes_ccr_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_aes_ccr_test.dir/build.make CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.o +.PHONY : tests/prg_aes_ccr_test.cpp.o + +tests/prg_aes_ccr_test.i: tests/prg_aes_ccr_test.cpp.i +.PHONY : tests/prg_aes_ccr_test.i + +# target to preprocess a source file +tests/prg_aes_ccr_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_aes_ccr_test.dir/build.make CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.i +.PHONY : tests/prg_aes_ccr_test.cpp.i + +tests/prg_aes_ccr_test.s: tests/prg_aes_ccr_test.cpp.s +.PHONY : tests/prg_aes_ccr_test.s + +# target to generate assembly for a file +tests/prg_aes_ccr_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_aes_ccr_test.dir/build.make CMakeFiles/prg_aes_ccr_test.dir/tests/prg_aes_ccr_test.cpp.s +.PHONY : tests/prg_aes_ccr_test.cpp.s + +tests/prg_chacha_test.o: tests/prg_chacha_test.cpp.o +.PHONY : tests/prg_chacha_test.o + +# target to build an object file +tests/prg_chacha_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_chacha_test.dir/build.make CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.o +.PHONY : tests/prg_chacha_test.cpp.o + +tests/prg_chacha_test.i: tests/prg_chacha_test.cpp.i +.PHONY : tests/prg_chacha_test.i + +# target to preprocess a source file +tests/prg_chacha_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_chacha_test.dir/build.make CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.i +.PHONY : tests/prg_chacha_test.cpp.i + +tests/prg_chacha_test.s: tests/prg_chacha_test.cpp.s +.PHONY : tests/prg_chacha_test.s + +# target to generate assembly for a file +tests/prg_chacha_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_chacha_test.dir/build.make CMakeFiles/prg_chacha_test.dir/tests/prg_chacha_test.cpp.s +.PHONY : tests/prg_chacha_test.cpp.s + +tests/prg_lowmc_test.o: tests/prg_lowmc_test.cpp.o +.PHONY : tests/prg_lowmc_test.o + +# target to build an object file +tests/prg_lowmc_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_lowmc_test.dir/build.make CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.o +.PHONY : tests/prg_lowmc_test.cpp.o + +tests/prg_lowmc_test.i: tests/prg_lowmc_test.cpp.i +.PHONY : tests/prg_lowmc_test.i + +# target to preprocess a source file +tests/prg_lowmc_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_lowmc_test.dir/build.make CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.i +.PHONY : tests/prg_lowmc_test.cpp.i + +tests/prg_lowmc_test.s: tests/prg_lowmc_test.cpp.s +.PHONY : tests/prg_lowmc_test.s + +# target to generate assembly for a file +tests/prg_lowmc_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/prg_lowmc_test.dir/build.make CMakeFiles/prg_lowmc_test.dir/tests/prg_lowmc_test.cpp.s +.PHONY : tests/prg_lowmc_test.cpp.s + +tests/principal_lut_test.o: tests/principal_lut_test.cpp.o +.PHONY : tests/principal_lut_test.o + +# target to build an object file +tests/principal_lut_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/principal_lut_test.dir/build.make CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.o +.PHONY : tests/principal_lut_test.cpp.o + +tests/principal_lut_test.i: tests/principal_lut_test.cpp.i +.PHONY : tests/principal_lut_test.i + +# target to preprocess a source file +tests/principal_lut_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/principal_lut_test.dir/build.make CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.i +.PHONY : tests/principal_lut_test.cpp.i + +tests/principal_lut_test.s: tests/principal_lut_test.cpp.s +.PHONY : tests/principal_lut_test.s + +# target to generate assembly for a file +tests/principal_lut_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/principal_lut_test.dir/build.make CMakeFiles/principal_lut_test.dir/tests/principal_lut_test.cpp.s +.PHONY : tests/principal_lut_test.cpp.s + +tests/protocol_batch_test.o: tests/protocol_batch_test.cpp.o +.PHONY : tests/protocol_batch_test.o + +# target to build an object file +tests/protocol_batch_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/protocol_batch_test.dir/build.make CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.o +.PHONY : tests/protocol_batch_test.cpp.o + +tests/protocol_batch_test.i: tests/protocol_batch_test.cpp.i +.PHONY : tests/protocol_batch_test.i + +# target to preprocess a source file +tests/protocol_batch_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/protocol_batch_test.dir/build.make CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.i +.PHONY : tests/protocol_batch_test.cpp.i + +tests/protocol_batch_test.s: tests/protocol_batch_test.cpp.s +.PHONY : tests/protocol_batch_test.s + +# target to generate assembly for a file +tests/protocol_batch_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/protocol_batch_test.dir/build.make CMakeFiles/protocol_batch_test.dir/tests/protocol_batch_test.cpp.s +.PHONY : tests/protocol_batch_test.cpp.s + +tests/random_odr_tu.o: tests/random_odr_tu.cpp.o +.PHONY : tests/random_odr_tu.o + +# target to build an object file +tests/random_odr_tu.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/random_test.dir/build.make CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.o +.PHONY : tests/random_odr_tu.cpp.o + +tests/random_odr_tu.i: tests/random_odr_tu.cpp.i +.PHONY : tests/random_odr_tu.i + +# target to preprocess a source file +tests/random_odr_tu.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/random_test.dir/build.make CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.i +.PHONY : tests/random_odr_tu.cpp.i + +tests/random_odr_tu.s: tests/random_odr_tu.cpp.s +.PHONY : tests/random_odr_tu.s + +# target to generate assembly for a file +tests/random_odr_tu.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/random_test.dir/build.make CMakeFiles/random_test.dir/tests/random_odr_tu.cpp.s +.PHONY : tests/random_odr_tu.cpp.s + +tests/random_test.o: tests/random_test.cpp.o +.PHONY : tests/random_test.o + +# target to build an object file +tests/random_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/random_test.dir/build.make CMakeFiles/random_test.dir/tests/random_test.cpp.o +.PHONY : tests/random_test.cpp.o + +tests/random_test.i: tests/random_test.cpp.i +.PHONY : tests/random_test.i + +# target to preprocess a source file +tests/random_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/random_test.dir/build.make CMakeFiles/random_test.dir/tests/random_test.cpp.i +.PHONY : tests/random_test.cpp.i + +tests/random_test.s: tests/random_test.cpp.s +.PHONY : tests/random_test.s + +# target to generate assembly for a file +tests/random_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/random_test.dir/build.make CMakeFiles/random_test.dir/tests/random_test.cpp.s +.PHONY : tests/random_test.cpp.s + +tests/range_lut_test.o: tests/range_lut_test.cpp.o +.PHONY : tests/range_lut_test.o + +# target to build an object file +tests/range_lut_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/range_lut_test.dir/build.make CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.o +.PHONY : tests/range_lut_test.cpp.o + +tests/range_lut_test.i: tests/range_lut_test.cpp.i +.PHONY : tests/range_lut_test.i + +# target to preprocess a source file +tests/range_lut_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/range_lut_test.dir/build.make CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.i +.PHONY : tests/range_lut_test.cpp.i + +tests/range_lut_test.s: tests/range_lut_test.cpp.s +.PHONY : tests/range_lut_test.s + +# target to generate assembly for a file +tests/range_lut_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/range_lut_test.dir/build.make CMakeFiles/range_lut_test.dir/tests/range_lut_test.cpp.s +.PHONY : tests/range_lut_test.cpp.s + +tests/ring_switch_test.o: tests/ring_switch_test.cpp.o +.PHONY : tests/ring_switch_test.o + +# target to build an object file +tests/ring_switch_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ring_switch_test.dir/build.make CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.o +.PHONY : tests/ring_switch_test.cpp.o + +tests/ring_switch_test.i: tests/ring_switch_test.cpp.i +.PHONY : tests/ring_switch_test.i + +# target to preprocess a source file +tests/ring_switch_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ring_switch_test.dir/build.make CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.i +.PHONY : tests/ring_switch_test.cpp.i + +tests/ring_switch_test.s: tests/ring_switch_test.cpp.s +.PHONY : tests/ring_switch_test.s + +# target to generate assembly for a file +tests/ring_switch_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/ring_switch_test.dir/build.make CMakeFiles/ring_switch_test.dir/tests/ring_switch_test.cpp.s +.PHONY : tests/ring_switch_test.cpp.s + +tests/secret_share_test.o: tests/secret_share_test.cpp.o +.PHONY : tests/secret_share_test.o + +# target to build an object file +tests/secret_share_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/secret_share_test.dir/build.make CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.o +.PHONY : tests/secret_share_test.cpp.o + +tests/secret_share_test.i: tests/secret_share_test.cpp.i +.PHONY : tests/secret_share_test.i + +# target to preprocess a source file +tests/secret_share_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/secret_share_test.dir/build.make CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.i +.PHONY : tests/secret_share_test.cpp.i + +tests/secret_share_test.s: tests/secret_share_test.cpp.s +.PHONY : tests/secret_share_test.s + +# target to generate assembly for a file +tests/secret_share_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/secret_share_test.dir/build.make CMakeFiles/secret_share_test.dir/tests/secret_share_test.cpp.s +.PHONY : tests/secret_share_test.cpp.s + +tests/security_test.o: tests/security_test.cpp.o +.PHONY : tests/security_test.o + +# target to build an object file +tests/security_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/security_test.dir/build.make CMakeFiles/security_test.dir/tests/security_test.cpp.o +.PHONY : tests/security_test.cpp.o + +tests/security_test.i: tests/security_test.cpp.i +.PHONY : tests/security_test.i + +# target to preprocess a source file +tests/security_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/security_test.dir/build.make CMakeFiles/security_test.dir/tests/security_test.cpp.i +.PHONY : tests/security_test.cpp.i + +tests/security_test.s: tests/security_test.cpp.s +.PHONY : tests/security_test.s + +# target to generate assembly for a file +tests/security_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/security_test.dir/build.make CMakeFiles/security_test.dir/tests/security_test.cpp.s +.PHONY : tests/security_test.cpp.s + +tests/setbit_index_iterable_test.o: tests/setbit_index_iterable_test.cpp.o +.PHONY : tests/setbit_index_iterable_test.o + +# target to build an object file +tests/setbit_index_iterable_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/setbit_index_iterable_test.dir/build.make CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.o +.PHONY : tests/setbit_index_iterable_test.cpp.o + +tests/setbit_index_iterable_test.i: tests/setbit_index_iterable_test.cpp.i +.PHONY : tests/setbit_index_iterable_test.i + +# target to preprocess a source file +tests/setbit_index_iterable_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/setbit_index_iterable_test.dir/build.make CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.i +.PHONY : tests/setbit_index_iterable_test.cpp.i + +tests/setbit_index_iterable_test.s: tests/setbit_index_iterable_test.cpp.s +.PHONY : tests/setbit_index_iterable_test.s + +# target to generate assembly for a file +tests/setbit_index_iterable_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/setbit_index_iterable_test.dir/build.make CMakeFiles/setbit_index_iterable_test.dir/tests/setbit_index_iterable_test.cpp.s +.PHONY : tests/setbit_index_iterable_test.cpp.s + +tests/sfss_test.o: tests/sfss_test.cpp.o +.PHONY : tests/sfss_test.o + +# target to build an object file +tests/sfss_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/sfss_test.dir/build.make CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.o +.PHONY : tests/sfss_test.cpp.o + +tests/sfss_test.i: tests/sfss_test.cpp.i +.PHONY : tests/sfss_test.i + +# target to preprocess a source file +tests/sfss_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/sfss_test.dir/build.make CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.i +.PHONY : tests/sfss_test.cpp.i + +tests/sfss_test.s: tests/sfss_test.cpp.s +.PHONY : tests/sfss_test.s + +# target to generate assembly for a file +tests/sfss_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/sfss_test.dir/build.make CMakeFiles/sfss_test.dir/tests/sfss_test.cpp.s +.PHONY : tests/sfss_test.cpp.s + +tests/shamir_adversarial_test.o: tests/shamir_adversarial_test.cpp.o +.PHONY : tests/shamir_adversarial_test.o + +# target to build an object file +tests/shamir_adversarial_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shamir_adversarial_test.dir/build.make CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.o +.PHONY : tests/shamir_adversarial_test.cpp.o + +tests/shamir_adversarial_test.i: tests/shamir_adversarial_test.cpp.i +.PHONY : tests/shamir_adversarial_test.i + +# target to preprocess a source file +tests/shamir_adversarial_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shamir_adversarial_test.dir/build.make CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.i +.PHONY : tests/shamir_adversarial_test.cpp.i + +tests/shamir_adversarial_test.s: tests/shamir_adversarial_test.cpp.s +.PHONY : tests/shamir_adversarial_test.s + +# target to generate assembly for a file +tests/shamir_adversarial_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shamir_adversarial_test.dir/build.make CMakeFiles/shamir_adversarial_test.dir/tests/shamir_adversarial_test.cpp.s +.PHONY : tests/shamir_adversarial_test.cpp.s + +tests/share_runtime_test.o: tests/share_runtime_test.cpp.o +.PHONY : tests/share_runtime_test.o + +# target to build an object file +tests/share_runtime_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/share_runtime_test.dir/build.make CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.o +.PHONY : tests/share_runtime_test.cpp.o + +tests/share_runtime_test.i: tests/share_runtime_test.cpp.i +.PHONY : tests/share_runtime_test.i + +# target to preprocess a source file +tests/share_runtime_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/share_runtime_test.dir/build.make CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.i +.PHONY : tests/share_runtime_test.cpp.i + +tests/share_runtime_test.s: tests/share_runtime_test.cpp.s +.PHONY : tests/share_runtime_test.s + +# target to generate assembly for a file +tests/share_runtime_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/share_runtime_test.dir/build.make CMakeFiles/share_runtime_test.dir/tests/share_runtime_test.cpp.s +.PHONY : tests/share_runtime_test.cpp.s + +tests/shared_and_test.o: tests/shared_and_test.cpp.o +.PHONY : tests/shared_and_test.o + +# target to build an object file +tests/shared_and_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shared_and_test.dir/build.make CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.o +.PHONY : tests/shared_and_test.cpp.o + +tests/shared_and_test.i: tests/shared_and_test.cpp.i +.PHONY : tests/shared_and_test.i + +# target to preprocess a source file +tests/shared_and_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shared_and_test.dir/build.make CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.i +.PHONY : tests/shared_and_test.cpp.i + +tests/shared_and_test.s: tests/shared_and_test.cpp.s +.PHONY : tests/shared_and_test.s + +# target to generate assembly for a file +tests/shared_and_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shared_and_test.dir/build.make CMakeFiles/shared_and_test.dir/tests/shared_and_test.cpp.s +.PHONY : tests/shared_and_test.cpp.s + +tests/shuffle_hidden_test.o: tests/shuffle_hidden_test.cpp.o +.PHONY : tests/shuffle_hidden_test.o + +# target to build an object file +tests/shuffle_hidden_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shuffle_hidden_test.dir/build.make CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.o +.PHONY : tests/shuffle_hidden_test.cpp.o + +tests/shuffle_hidden_test.i: tests/shuffle_hidden_test.cpp.i +.PHONY : tests/shuffle_hidden_test.i + +# target to preprocess a source file +tests/shuffle_hidden_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shuffle_hidden_test.dir/build.make CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.i +.PHONY : tests/shuffle_hidden_test.cpp.i + +tests/shuffle_hidden_test.s: tests/shuffle_hidden_test.cpp.s +.PHONY : tests/shuffle_hidden_test.s + +# target to generate assembly for a file +tests/shuffle_hidden_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/shuffle_hidden_test.dir/build.make CMakeFiles/shuffle_hidden_test.dir/tests/shuffle_hidden_test.cpp.s +.PHONY : tests/shuffle_hidden_test.cpp.s + +tests/signed_prefix_test.o: tests/signed_prefix_test.cpp.o +.PHONY : tests/signed_prefix_test.o + +# target to build an object file +tests/signed_prefix_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/signed_prefix_test.dir/build.make CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.o +.PHONY : tests/signed_prefix_test.cpp.o + +tests/signed_prefix_test.i: tests/signed_prefix_test.cpp.i +.PHONY : tests/signed_prefix_test.i + +# target to preprocess a source file +tests/signed_prefix_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/signed_prefix_test.dir/build.make CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.i +.PHONY : tests/signed_prefix_test.cpp.i + +tests/signed_prefix_test.s: tests/signed_prefix_test.cpp.s +.PHONY : tests/signed_prefix_test.s + +# target to generate assembly for a file +tests/signed_prefix_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/signed_prefix_test.dir/build.make CMakeFiles/signed_prefix_test.dir/tests/signed_prefix_test.cpp.s +.PHONY : tests/signed_prefix_test.cpp.s + +tests/stress_scenarios_test.o: tests/stress_scenarios_test.cpp.o +.PHONY : tests/stress_scenarios_test.o + +# target to build an object file +tests/stress_scenarios_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/stress_scenarios_test.dir/build.make CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.o +.PHONY : tests/stress_scenarios_test.cpp.o + +tests/stress_scenarios_test.i: tests/stress_scenarios_test.cpp.i +.PHONY : tests/stress_scenarios_test.i + +# target to preprocess a source file +tests/stress_scenarios_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/stress_scenarios_test.dir/build.make CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.i +.PHONY : tests/stress_scenarios_test.cpp.i + +tests/stress_scenarios_test.s: tests/stress_scenarios_test.cpp.s +.PHONY : tests/stress_scenarios_test.s + +# target to generate assembly for a file +tests/stress_scenarios_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/stress_scenarios_test.dir/build.make CMakeFiles/stress_scenarios_test.dir/tests/stress_scenarios_test.cpp.s +.PHONY : tests/stress_scenarios_test.cpp.s + +tests/types_test.o: tests/types_test.cpp.o +.PHONY : tests/types_test.o + +# target to build an object file +tests/types_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/types_test.dir/build.make CMakeFiles/types_test.dir/tests/types_test.cpp.o +.PHONY : tests/types_test.cpp.o + +tests/types_test.i: tests/types_test.cpp.i +.PHONY : tests/types_test.i + +# target to preprocess a source file +tests/types_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/types_test.dir/build.make CMakeFiles/types_test.dir/tests/types_test.cpp.i +.PHONY : tests/types_test.cpp.i + +tests/types_test.s: tests/types_test.cpp.s +.PHONY : tests/types_test.s + +# target to generate assembly for a file +tests/types_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/types_test.dir/build.make CMakeFiles/types_test.dir/tests/types_test.cpp.s +.PHONY : tests/types_test.cpp.s + +tests/vdpf_adversarial_test.o: tests/vdpf_adversarial_test.cpp.o +.PHONY : tests/vdpf_adversarial_test.o + +# target to build an object file +tests/vdpf_adversarial_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_adversarial_test.dir/build.make CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.o +.PHONY : tests/vdpf_adversarial_test.cpp.o + +tests/vdpf_adversarial_test.i: tests/vdpf_adversarial_test.cpp.i +.PHONY : tests/vdpf_adversarial_test.i + +# target to preprocess a source file +tests/vdpf_adversarial_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_adversarial_test.dir/build.make CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.i +.PHONY : tests/vdpf_adversarial_test.cpp.i + +tests/vdpf_adversarial_test.s: tests/vdpf_adversarial_test.cpp.s +.PHONY : tests/vdpf_adversarial_test.s + +# target to generate assembly for a file +tests/vdpf_adversarial_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_adversarial_test.dir/build.make CMakeFiles/vdpf_adversarial_test.dir/tests/vdpf_adversarial_test.cpp.s +.PHONY : tests/vdpf_adversarial_test.cpp.s + +tests/vdpf_regression_test.o: tests/vdpf_regression_test.cpp.o +.PHONY : tests/vdpf_regression_test.o + +# target to build an object file +tests/vdpf_regression_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_regression_test.dir/build.make CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.o +.PHONY : tests/vdpf_regression_test.cpp.o + +tests/vdpf_regression_test.i: tests/vdpf_regression_test.cpp.i +.PHONY : tests/vdpf_regression_test.i + +# target to preprocess a source file +tests/vdpf_regression_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_regression_test.dir/build.make CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.i +.PHONY : tests/vdpf_regression_test.cpp.i + +tests/vdpf_regression_test.s: tests/vdpf_regression_test.cpp.s +.PHONY : tests/vdpf_regression_test.s + +# target to generate assembly for a file +tests/vdpf_regression_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/vdpf_regression_test.dir/build.make CMakeFiles/vdpf_regression_test.dir/tests/vdpf_regression_test.cpp.s +.PHONY : tests/vdpf_regression_test.cpp.s + +tests/verifiable_test.o: tests/verifiable_test.cpp.o +.PHONY : tests/verifiable_test.o + +# target to build an object file +tests/verifiable_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/verifiable_test.dir/build.make CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.o +.PHONY : tests/verifiable_test.cpp.o + +tests/verifiable_test.i: tests/verifiable_test.cpp.i +.PHONY : tests/verifiable_test.i + +# target to preprocess a source file +tests/verifiable_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/verifiable_test.dir/build.make CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.i +.PHONY : tests/verifiable_test.cpp.i + +tests/verifiable_test.s: tests/verifiable_test.cpp.s +.PHONY : tests/verifiable_test.s + +# target to generate assembly for a file +tests/verifiable_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/verifiable_test.dir/build.make CMakeFiles/verifiable_test.dir/tests/verifiable_test.cpp.s +.PHONY : tests/verifiable_test.cpp.s + +tests/walk_helpers_test.o: tests/walk_helpers_test.cpp.o +.PHONY : tests/walk_helpers_test.o + +# target to build an object file +tests/walk_helpers_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/walk_helpers_test.dir/build.make CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.o +.PHONY : tests/walk_helpers_test.cpp.o + +tests/walk_helpers_test.i: tests/walk_helpers_test.cpp.i +.PHONY : tests/walk_helpers_test.i + +# target to preprocess a source file +tests/walk_helpers_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/walk_helpers_test.dir/build.make CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.i +.PHONY : tests/walk_helpers_test.cpp.i + +tests/walk_helpers_test.s: tests/walk_helpers_test.cpp.s +.PHONY : tests/walk_helpers_test.s + +# target to generate assembly for a file +tests/walk_helpers_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/walk_helpers_test.dir/build.make CMakeFiles/walk_helpers_test.dir/tests/walk_helpers_test.cpp.s +.PHONY : tests/walk_helpers_test.cpp.s + +tests/wide_payload_test.o: tests/wide_payload_test.cpp.o +.PHONY : tests/wide_payload_test.o + +# target to build an object file +tests/wide_payload_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wide_payload_test.dir/build.make CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.o +.PHONY : tests/wide_payload_test.cpp.o + +tests/wide_payload_test.i: tests/wide_payload_test.cpp.i +.PHONY : tests/wide_payload_test.i + +# target to preprocess a source file +tests/wide_payload_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wide_payload_test.dir/build.make CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.i +.PHONY : tests/wide_payload_test.cpp.i + +tests/wide_payload_test.s: tests/wide_payload_test.cpp.s +.PHONY : tests/wide_payload_test.s + +# target to generate assembly for a file +tests/wide_payload_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wide_payload_test.dir/build.make CMakeFiles/wide_payload_test.dir/tests/wide_payload_test.cpp.s +.PHONY : tests/wide_payload_test.cpp.s + +tests/wildcard_test.o: tests/wildcard_test.cpp.o +.PHONY : tests/wildcard_test.o + +# target to build an object file +tests/wildcard_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wildcard_test.dir/build.make CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.o +.PHONY : tests/wildcard_test.cpp.o + +tests/wildcard_test.i: tests/wildcard_test.cpp.i +.PHONY : tests/wildcard_test.i + +# target to preprocess a source file +tests/wildcard_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wildcard_test.dir/build.make CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.i +.PHONY : tests/wildcard_test.cpp.i + +tests/wildcard_test.s: tests/wildcard_test.cpp.s +.PHONY : tests/wildcard_test.s + +# target to generate assembly for a file +tests/wildcard_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wildcard_test.dir/build.make CMakeFiles/wildcard_test.dir/tests/wildcard_test.cpp.s +.PHONY : tests/wildcard_test.cpp.s + +tests/window_lut_test.o: tests/window_lut_test.cpp.o +.PHONY : tests/window_lut_test.o + +# target to build an object file +tests/window_lut_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/window_lut_test.dir/build.make CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.o +.PHONY : tests/window_lut_test.cpp.o + +tests/window_lut_test.i: tests/window_lut_test.cpp.i +.PHONY : tests/window_lut_test.i + +# target to preprocess a source file +tests/window_lut_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/window_lut_test.dir/build.make CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.i +.PHONY : tests/window_lut_test.cpp.i + +tests/window_lut_test.s: tests/window_lut_test.cpp.s +.PHONY : tests/window_lut_test.s + +# target to generate assembly for a file +tests/window_lut_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/window_lut_test.dir/build.make CMakeFiles/window_lut_test.dir/tests/window_lut_test.cpp.s +.PHONY : tests/window_lut_test.cpp.s + +tests/wrap_and_rotate_test.o: tests/wrap_and_rotate_test.cpp.o +.PHONY : tests/wrap_and_rotate_test.o + +# target to build an object file +tests/wrap_and_rotate_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wrap_and_rotate_test.dir/build.make CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.o +.PHONY : tests/wrap_and_rotate_test.cpp.o + +tests/wrap_and_rotate_test.i: tests/wrap_and_rotate_test.cpp.i +.PHONY : tests/wrap_and_rotate_test.i + +# target to preprocess a source file +tests/wrap_and_rotate_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wrap_and_rotate_test.dir/build.make CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.i +.PHONY : tests/wrap_and_rotate_test.cpp.i + +tests/wrap_and_rotate_test.s: tests/wrap_and_rotate_test.cpp.s +.PHONY : tests/wrap_and_rotate_test.s + +# target to generate assembly for a file +tests/wrap_and_rotate_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/wrap_and_rotate_test.dir/build.make CMakeFiles/wrap_and_rotate_test.dir/tests/wrap_and_rotate_test.cpp.s +.PHONY : tests/wrap_and_rotate_test.cpp.s + +tests/yao_share_test.o: tests/yao_share_test.cpp.o +.PHONY : tests/yao_share_test.o + +# target to build an object file +tests/yao_share_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_share_test.dir/build.make CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.o +.PHONY : tests/yao_share_test.cpp.o + +tests/yao_share_test.i: tests/yao_share_test.cpp.i +.PHONY : tests/yao_share_test.i + +# target to preprocess a source file +tests/yao_share_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_share_test.dir/build.make CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.i +.PHONY : tests/yao_share_test.cpp.i + +tests/yao_share_test.s: tests/yao_share_test.cpp.s +.PHONY : tests/yao_share_test.s + +# target to generate assembly for a file +tests/yao_share_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_share_test.dir/build.make CMakeFiles/yao_share_test.dir/tests/yao_share_test.cpp.s +.PHONY : tests/yao_share_test.cpp.s + +tests/yao_stack_test.o: tests/yao_stack_test.cpp.o +.PHONY : tests/yao_stack_test.o + +# target to build an object file +tests/yao_stack_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_stack_test.dir/build.make CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.o +.PHONY : tests/yao_stack_test.cpp.o + +tests/yao_stack_test.i: tests/yao_stack_test.cpp.i +.PHONY : tests/yao_stack_test.i + +# target to preprocess a source file +tests/yao_stack_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_stack_test.dir/build.make CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.i +.PHONY : tests/yao_stack_test.cpp.i + +tests/yao_stack_test.s: tests/yao_stack_test.cpp.s +.PHONY : tests/yao_stack_test.s + +# target to generate assembly for a file +tests/yao_stack_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_stack_test.dir/build.make CMakeFiles/yao_stack_test.dir/tests/yao_stack_test.cpp.s +.PHONY : tests/yao_stack_test.cpp.s + +tests/yao_test.o: tests/yao_test.cpp.o +.PHONY : tests/yao_test.o + +# target to build an object file +tests/yao_test.cpp.o: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_test.dir/build.make CMakeFiles/yao_test.dir/tests/yao_test.cpp.o +.PHONY : tests/yao_test.cpp.o + +tests/yao_test.i: tests/yao_test.cpp.i +.PHONY : tests/yao_test.i + +# target to preprocess a source file +tests/yao_test.cpp.i: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_test.dir/build.make CMakeFiles/yao_test.dir/tests/yao_test.cpp.i +.PHONY : tests/yao_test.cpp.i + +tests/yao_test.s: tests/yao_test.cpp.s +.PHONY : tests/yao_test.s + +# target to generate assembly for a file +tests/yao_test.cpp.s: + $(MAKE) $(MAKESILENT) -f CMakeFiles/yao_test.dir/build.make CMakeFiles/yao_test.dir/tests/yao_test.cpp.s +.PHONY : tests/yao_test.cpp.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... rebuild_cache" + @echo "... test" + @echo "... advice_bit_iterable_test" + @echo "... all_test" + @echo "... arith_garble_test" + @echo "... arith_payload_test" + @echo "... beaver_party_test" + @echo "... beaver_test" + @echo "... bench_cell_test" + @echo "... bit_array_test" + @echo "... bitmore_mod_test" + @echo "... blob_leaf_test" + @echo "... blocked_dcf_test" + @echo "... caller_fold_test" + @echo "... carry_test" + @echo "... class_sweep_test" + @echo "... closed_form_test" + @echo "... cohort_test" + @echo "... compose_test" + @echo "... constant_lut_test" + @echo "... constrained_cmp_test" + @echo "... context_blast_test" + @echo "... corner_gaps_test" + @echo "... defer_eval_test" + @echo "... domain128_point_test" + @echo "... dpf3_test" + @echo "... dpf_key_test" + @echo "... dwt_lut_test" + @echo "... dyadic_lut_test" + @echo "... easy_lut_test" + @echo "... eval_full_multi_test" + @echo "... eval_full_test" + @echo "... eval_inner_product_test" + @echo "... eval_interval_multi_test" + @echo "... eval_interval_test" + @echo "... eval_point_multi_test" + @echo "... eval_point_test" + @echo "... eval_sequence_multi_test" + @echo "... eval_sequence_test" + @echo "... eval_until_test" + @echo "... exact_steps_test" + @echo "... experiment_test" + @echo "... extractable_full_test" + @echo "... field_output_test" + @echo "... fixedpoint_beaver_test" + @echo "... flute_test" + @echo "... fp61_test" + @echo "... geneval_test" + @echo "... gf2_adversarial_test" + @echo "... gf2_test" + @echo "... growing_idpf_test" + @echo "... gtest" + @echo "... gtest_main" + @echo "... half_tree_test" + @echo "... ic_test" + @echo "... idpf_agg_test" + @echo "... iknp_party_test" + @echo "... incremental_json_test" + @echo "... incremental_test" + @echo "... interleave_leaves_test" + @echo "... it_dpf3_test" + @echo "... keyword2_test" + @echo "... lane_blast_test" + @echo "... leaf_later_test" + @echo "... log_test" + @echo "... lut_union_test" + @echo "... multipoint_test" + @echo "... net_control_test" + @echo "... nmod_test" + @echo "... offset_horner_test" + @echo "... offset_jet_test" + @echo "... offset_poly_test" + @echo "... offset_repr_test" + @echo "... offset_twist_test" + @echo "... opt_in_malicious_test" + @echo "... p0" + @echo "... p1" + @echo "... p2" + @echo "... packed_lane_test" + @echo "... parallel_bit_iterable_test" + @echo "... party_bench" + @echo "... party_flows" + @echo "... path_recipe_test" + @echo "... path_sketch_test" + @echo "... pprf_test" + @echo "... ppvc_test" + @echo "... prg_aes_ccr_test" + @echo "... prg_chacha_test" + @echo "... prg_lowmc_test" + @echo "... principal_lut_test" + @echo "... profile_eval" + @echo "... profile_grotto" + @echo "... profile_party" + @echo "... protocol_batch_test" + @echo "... random_test" + @echo "... range_lut_test" + @echo "... ring_switch_test" + @echo "... secret_share_test" + @echo "... security_test" + @echo "... setbit_index_iterable_test" + @echo "... sfss_test" + @echo "... shamir_adversarial_test" + @echo "... share_runtime_test" + @echo "... shared_and_test" + @echo "... shuffle_hidden_test" + @echo "... signed_prefix_test" + @echo "... stress_scenarios_test" + @echo "... types_test" + @echo "... vdpf_adversarial_test" + @echo "... vdpf_regression_test" + @echo "... verifiable_test" + @echo "... walk_helpers_test" + @echo "... wide_payload_test" + @echo "... wildcard_test" + @echo "... window_lut_test" + @echo "... wrap_and_rotate_test" + @echo "... yao_share_test" + @echo "... yao_stack_test" + @echo "... yao_test" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/p0.o" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/p0.i" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/p0.s" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/p1.o" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/p1.i" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/p1.s" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/p2.o" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/p2.i" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/p2.s" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/party_bench.o" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/party_bench.i" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/party_bench.s" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/registry.o" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/registry.i" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/registry.s" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/run.o" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/run.i" + @echo "... home/cryptolicious/hushmap-specified/libdpf/party/run.s" + @echo "... profile/eval_profile.o" + @echo "... profile/eval_profile.i" + @echo "... profile/eval_profile.s" + @echo "... profile/grotto_profile.o" + @echo "... profile/grotto_profile.i" + @echo "... profile/grotto_profile.s" + @echo "... profile/party_profile.o" + @echo "... profile/party_profile.i" + @echo "... profile/party_profile.s" + @echo "... tests/advice_bit_iterable_test.o" + @echo "... tests/advice_bit_iterable_test.i" + @echo "... tests/advice_bit_iterable_test.s" + @echo "... tests/all_test.o" + @echo "... tests/all_test.i" + @echo "... tests/all_test.s" + @echo "... tests/arith_garble_test.o" + @echo "... tests/arith_garble_test.i" + @echo "... tests/arith_garble_test.s" + @echo "... tests/arith_payload_test.o" + @echo "... tests/arith_payload_test.i" + @echo "... tests/arith_payload_test.s" + @echo "... tests/beaver_party_test.o" + @echo "... tests/beaver_party_test.i" + @echo "... tests/beaver_party_test.s" + @echo "... tests/beaver_test.o" + @echo "... tests/beaver_test.i" + @echo "... tests/beaver_test.s" + @echo "... tests/bench_cell_test.o" + @echo "... tests/bench_cell_test.i" + @echo "... tests/bench_cell_test.s" + @echo "... tests/bit_array_test.o" + @echo "... tests/bit_array_test.i" + @echo "... tests/bit_array_test.s" + @echo "... tests/bitmore_mod_test.o" + @echo "... tests/bitmore_mod_test.i" + @echo "... tests/bitmore_mod_test.s" + @echo "... tests/blob_leaf_test.o" + @echo "... tests/blob_leaf_test.i" + @echo "... tests/blob_leaf_test.s" + @echo "... tests/blocked_dcf_test.o" + @echo "... tests/blocked_dcf_test.i" + @echo "... tests/blocked_dcf_test.s" + @echo "... tests/caller_fold_test.o" + @echo "... tests/caller_fold_test.i" + @echo "... tests/caller_fold_test.s" + @echo "... tests/carry_test.o" + @echo "... tests/carry_test.i" + @echo "... tests/carry_test.s" + @echo "... tests/class_sweep_test.o" + @echo "... tests/class_sweep_test.i" + @echo "... tests/class_sweep_test.s" + @echo "... tests/closed_form_test.o" + @echo "... tests/closed_form_test.i" + @echo "... tests/closed_form_test.s" + @echo "... tests/cohort_test.o" + @echo "... tests/cohort_test.i" + @echo "... tests/cohort_test.s" + @echo "... tests/compose_test.o" + @echo "... tests/compose_test.i" + @echo "... tests/compose_test.s" + @echo "... tests/constant_lut_test.o" + @echo "... tests/constant_lut_test.i" + @echo "... tests/constant_lut_test.s" + @echo "... tests/constrained_cmp_test.o" + @echo "... tests/constrained_cmp_test.i" + @echo "... tests/constrained_cmp_test.s" + @echo "... tests/context_blast_test.o" + @echo "... tests/context_blast_test.i" + @echo "... tests/context_blast_test.s" + @echo "... tests/corner_gaps_test.o" + @echo "... tests/corner_gaps_test.i" + @echo "... tests/corner_gaps_test.s" + @echo "... tests/defer_eval_test.o" + @echo "... tests/defer_eval_test.i" + @echo "... tests/defer_eval_test.s" + @echo "... tests/domain128_point_test.o" + @echo "... tests/domain128_point_test.i" + @echo "... tests/domain128_point_test.s" + @echo "... tests/dpf3_test.o" + @echo "... tests/dpf3_test.i" + @echo "... tests/dpf3_test.s" + @echo "... tests/dpf_key_test.o" + @echo "... tests/dpf_key_test.i" + @echo "... tests/dpf_key_test.s" + @echo "... tests/dwt_lut_test.o" + @echo "... tests/dwt_lut_test.i" + @echo "... tests/dwt_lut_test.s" + @echo "... tests/dyadic_lut_test.o" + @echo "... tests/dyadic_lut_test.i" + @echo "... tests/dyadic_lut_test.s" + @echo "... tests/easy_lut_test.o" + @echo "... tests/easy_lut_test.i" + @echo "... tests/easy_lut_test.s" + @echo "... tests/eval_full_multi_test.o" + @echo "... tests/eval_full_multi_test.i" + @echo "... tests/eval_full_multi_test.s" + @echo "... tests/eval_full_test.o" + @echo "... tests/eval_full_test.i" + @echo "... tests/eval_full_test.s" + @echo "... tests/eval_inner_product_test.o" + @echo "... tests/eval_inner_product_test.i" + @echo "... tests/eval_inner_product_test.s" + @echo "... tests/eval_interval_multi_test.o" + @echo "... tests/eval_interval_multi_test.i" + @echo "... tests/eval_interval_multi_test.s" + @echo "... tests/eval_interval_test.o" + @echo "... tests/eval_interval_test.i" + @echo "... tests/eval_interval_test.s" + @echo "... tests/eval_point_multi_test.o" + @echo "... tests/eval_point_multi_test.i" + @echo "... tests/eval_point_multi_test.s" + @echo "... tests/eval_point_test.o" + @echo "... tests/eval_point_test.i" + @echo "... tests/eval_point_test.s" + @echo "... tests/eval_sequence_multi_test.o" + @echo "... tests/eval_sequence_multi_test.i" + @echo "... tests/eval_sequence_multi_test.s" + @echo "... tests/eval_sequence_test.o" + @echo "... tests/eval_sequence_test.i" + @echo "... tests/eval_sequence_test.s" + @echo "... tests/eval_until_test.o" + @echo "... tests/eval_until_test.i" + @echo "... tests/eval_until_test.s" + @echo "... tests/exact_steps_test.o" + @echo "... tests/exact_steps_test.i" + @echo "... tests/exact_steps_test.s" + @echo "... tests/experiment_test.o" + @echo "... tests/experiment_test.i" + @echo "... tests/experiment_test.s" + @echo "... tests/extractable_full_test.o" + @echo "... tests/extractable_full_test.i" + @echo "... tests/extractable_full_test.s" + @echo "... tests/field_output_test.o" + @echo "... tests/field_output_test.i" + @echo "... tests/field_output_test.s" + @echo "... tests/fixedpoint_beaver_test.o" + @echo "... tests/fixedpoint_beaver_test.i" + @echo "... tests/fixedpoint_beaver_test.s" + @echo "... tests/flute_test.o" + @echo "... tests/flute_test.i" + @echo "... tests/flute_test.s" + @echo "... tests/fp61_test.o" + @echo "... tests/fp61_test.i" + @echo "... tests/fp61_test.s" + @echo "... tests/geneval_test.o" + @echo "... tests/geneval_test.i" + @echo "... tests/geneval_test.s" + @echo "... tests/gf2_adversarial_test.o" + @echo "... tests/gf2_adversarial_test.i" + @echo "... tests/gf2_adversarial_test.s" + @echo "... tests/gf2_test.o" + @echo "... tests/gf2_test.i" + @echo "... tests/gf2_test.s" + @echo "... tests/growing_idpf_test.o" + @echo "... tests/growing_idpf_test.i" + @echo "... tests/growing_idpf_test.s" + @echo "... tests/half_tree_test.o" + @echo "... tests/half_tree_test.i" + @echo "... tests/half_tree_test.s" + @echo "... tests/ic_test.o" + @echo "... tests/ic_test.i" + @echo "... tests/ic_test.s" + @echo "... tests/idpf_agg_test.o" + @echo "... tests/idpf_agg_test.i" + @echo "... tests/idpf_agg_test.s" + @echo "... tests/iknp_party_test.o" + @echo "... tests/iknp_party_test.i" + @echo "... tests/iknp_party_test.s" + @echo "... tests/incremental_json_test.o" + @echo "... tests/incremental_json_test.i" + @echo "... tests/incremental_json_test.s" + @echo "... tests/incremental_test.o" + @echo "... tests/incremental_test.i" + @echo "... tests/incremental_test.s" + @echo "... tests/interleave_leaves_test.o" + @echo "... tests/interleave_leaves_test.i" + @echo "... tests/interleave_leaves_test.s" + @echo "... tests/it_dpf3_test.o" + @echo "... tests/it_dpf3_test.i" + @echo "... tests/it_dpf3_test.s" + @echo "... tests/keyword2_test.o" + @echo "... tests/keyword2_test.i" + @echo "... tests/keyword2_test.s" + @echo "... tests/lane_blast_test.o" + @echo "... tests/lane_blast_test.i" + @echo "... tests/lane_blast_test.s" + @echo "... tests/leaf_later_test.o" + @echo "... tests/leaf_later_test.i" + @echo "... tests/leaf_later_test.s" + @echo "... tests/log_test.o" + @echo "... tests/log_test.i" + @echo "... tests/log_test.s" + @echo "... tests/lut_union_test.o" + @echo "... tests/lut_union_test.i" + @echo "... tests/lut_union_test.s" + @echo "... tests/multipoint_test.o" + @echo "... tests/multipoint_test.i" + @echo "... tests/multipoint_test.s" + @echo "... tests/net_control_test.o" + @echo "... tests/net_control_test.i" + @echo "... tests/net_control_test.s" + @echo "... tests/nmod_test.o" + @echo "... tests/nmod_test.i" + @echo "... tests/nmod_test.s" + @echo "... tests/offset_horner_test.o" + @echo "... tests/offset_horner_test.i" + @echo "... tests/offset_horner_test.s" + @echo "... tests/offset_jet_test.o" + @echo "... tests/offset_jet_test.i" + @echo "... tests/offset_jet_test.s" + @echo "... tests/offset_poly_test.o" + @echo "... tests/offset_poly_test.i" + @echo "... tests/offset_poly_test.s" + @echo "... tests/offset_repr_test.o" + @echo "... tests/offset_repr_test.i" + @echo "... tests/offset_repr_test.s" + @echo "... tests/offset_twist_test.o" + @echo "... tests/offset_twist_test.i" + @echo "... tests/offset_twist_test.s" + @echo "... tests/opt_in_malicious_test.o" + @echo "... tests/opt_in_malicious_test.i" + @echo "... tests/opt_in_malicious_test.s" + @echo "... tests/packed_lane_test.o" + @echo "... tests/packed_lane_test.i" + @echo "... tests/packed_lane_test.s" + @echo "... tests/parallel_bit_iterable_test.o" + @echo "... tests/parallel_bit_iterable_test.i" + @echo "... tests/parallel_bit_iterable_test.s" + @echo "... tests/path_recipe_test.o" + @echo "... tests/path_recipe_test.i" + @echo "... tests/path_recipe_test.s" + @echo "... tests/path_sketch_test.o" + @echo "... tests/path_sketch_test.i" + @echo "... tests/path_sketch_test.s" + @echo "... tests/pprf_test.o" + @echo "... tests/pprf_test.i" + @echo "... tests/pprf_test.s" + @echo "... tests/ppvc_test.o" + @echo "... tests/ppvc_test.i" + @echo "... tests/ppvc_test.s" + @echo "... tests/prg_aes_ccr_test.o" + @echo "... tests/prg_aes_ccr_test.i" + @echo "... tests/prg_aes_ccr_test.s" + @echo "... tests/prg_chacha_test.o" + @echo "... tests/prg_chacha_test.i" + @echo "... tests/prg_chacha_test.s" + @echo "... tests/prg_lowmc_test.o" + @echo "... tests/prg_lowmc_test.i" + @echo "... tests/prg_lowmc_test.s" + @echo "... tests/principal_lut_test.o" + @echo "... tests/principal_lut_test.i" + @echo "... tests/principal_lut_test.s" + @echo "... tests/protocol_batch_test.o" + @echo "... tests/protocol_batch_test.i" + @echo "... tests/protocol_batch_test.s" + @echo "... tests/random_odr_tu.o" + @echo "... tests/random_odr_tu.i" + @echo "... tests/random_odr_tu.s" + @echo "... tests/random_test.o" + @echo "... tests/random_test.i" + @echo "... tests/random_test.s" + @echo "... tests/range_lut_test.o" + @echo "... tests/range_lut_test.i" + @echo "... tests/range_lut_test.s" + @echo "... tests/ring_switch_test.o" + @echo "... tests/ring_switch_test.i" + @echo "... tests/ring_switch_test.s" + @echo "... tests/secret_share_test.o" + @echo "... tests/secret_share_test.i" + @echo "... tests/secret_share_test.s" + @echo "... tests/security_test.o" + @echo "... tests/security_test.i" + @echo "... tests/security_test.s" + @echo "... tests/setbit_index_iterable_test.o" + @echo "... tests/setbit_index_iterable_test.i" + @echo "... tests/setbit_index_iterable_test.s" + @echo "... tests/sfss_test.o" + @echo "... tests/sfss_test.i" + @echo "... tests/sfss_test.s" + @echo "... tests/shamir_adversarial_test.o" + @echo "... tests/shamir_adversarial_test.i" + @echo "... tests/shamir_adversarial_test.s" + @echo "... tests/share_runtime_test.o" + @echo "... tests/share_runtime_test.i" + @echo "... tests/share_runtime_test.s" + @echo "... tests/shared_and_test.o" + @echo "... tests/shared_and_test.i" + @echo "... tests/shared_and_test.s" + @echo "... tests/shuffle_hidden_test.o" + @echo "... tests/shuffle_hidden_test.i" + @echo "... tests/shuffle_hidden_test.s" + @echo "... tests/signed_prefix_test.o" + @echo "... tests/signed_prefix_test.i" + @echo "... tests/signed_prefix_test.s" + @echo "... tests/stress_scenarios_test.o" + @echo "... tests/stress_scenarios_test.i" + @echo "... tests/stress_scenarios_test.s" + @echo "... tests/types_test.o" + @echo "... tests/types_test.i" + @echo "... tests/types_test.s" + @echo "... tests/vdpf_adversarial_test.o" + @echo "... tests/vdpf_adversarial_test.i" + @echo "... tests/vdpf_adversarial_test.s" + @echo "... tests/vdpf_regression_test.o" + @echo "... tests/vdpf_regression_test.i" + @echo "... tests/vdpf_regression_test.s" + @echo "... tests/verifiable_test.o" + @echo "... tests/verifiable_test.i" + @echo "... tests/verifiable_test.s" + @echo "... tests/walk_helpers_test.o" + @echo "... tests/walk_helpers_test.i" + @echo "... tests/walk_helpers_test.s" + @echo "... tests/wide_payload_test.o" + @echo "... tests/wide_payload_test.i" + @echo "... tests/wide_payload_test.s" + @echo "... tests/wildcard_test.o" + @echo "... tests/wildcard_test.i" + @echo "... tests/wildcard_test.s" + @echo "... tests/window_lut_test.o" + @echo "... tests/window_lut_test.i" + @echo "... tests/window_lut_test.s" + @echo "... tests/wrap_and_rotate_test.o" + @echo "... tests/wrap_and_rotate_test.i" + @echo "... tests/wrap_and_rotate_test.s" + @echo "... tests/yao_share_test.o" + @echo "... tests/yao_share_test.i" + @echo "... tests/yao_share_test.s" + @echo "... tests/yao_stack_test.o" + @echo "... tests/yao_stack_test.i" + @echo "... tests/yao_stack_test.s" + @echo "... tests/yao_test.o" + @echo "... tests/yao_test.i" + @echo "... tests/yao_test.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/test/build-asan/advice_bit_iterable_test[1]_include.cmake b/test/build-asan/advice_bit_iterable_test[1]_include.cmake new file mode 100644 index 0000000..cddf937 --- /dev/null +++ b/test/build-asan/advice_bit_iterable_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/advice_bit_iterable_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/advice_bit_iterable_test[1]_tests.cmake") +else() + add_test(advice_bit_iterable_test_NOT_BUILT advice_bit_iterable_test_NOT_BUILT) +endif() diff --git a/test/build-asan/arith_garble_test[1]_include.cmake b/test/build-asan/arith_garble_test[1]_include.cmake new file mode 100644 index 0000000..719af3a --- /dev/null +++ b/test/build-asan/arith_garble_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/arith_garble_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/arith_garble_test[1]_tests.cmake") +else() + add_test(arith_garble_test_NOT_BUILT arith_garble_test_NOT_BUILT) +endif() diff --git a/test/build-asan/arith_payload_test[1]_include.cmake b/test/build-asan/arith_payload_test[1]_include.cmake new file mode 100644 index 0000000..620e6b6 --- /dev/null +++ b/test/build-asan/arith_payload_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/arith_payload_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/arith_payload_test[1]_tests.cmake") +else() + add_test(arith_payload_test_NOT_BUILT arith_payload_test_NOT_BUILT) +endif() diff --git a/test/build-asan/arith_payload_test[1]_tests.cmake b/test/build-asan/arith_payload_test[1]_tests.cmake new file mode 100644 index 0000000..9479bac --- /dev/null +++ b/test/build-asan/arith_payload_test[1]_tests.cmake @@ -0,0 +1,17 @@ +add_test([=[ArithPayload.DsXorIndexMatchesDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/arith_payload_test [==[--gtest_filter=ArithPayload.DsXorIndexMatchesDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ArithPayload.DsXorIndexMatchesDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp:62 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ArithPayload.DsArithIndexMatchesDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/arith_payload_test [==[--gtest_filter=ArithPayload.DsArithIndexMatchesDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ArithPayload.DsArithIndexMatchesDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp:111 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ArithPayload.GenevalXorSharedBeta]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/arith_payload_test [==[--gtest_filter=ArithPayload.GenevalXorSharedBeta]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ArithPayload.GenevalXorSharedBeta]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp:144 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ArithPayload.GenevalArithSharedBeta]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/arith_payload_test [==[--gtest_filter=ArithPayload.GenevalArithSharedBeta]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ArithPayload.GenevalArithSharedBeta]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp:172 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ArithPayload.XorWrapperSharesMatchDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/arith_payload_test [==[--gtest_filter=ArithPayload.XorWrapperSharesMatchDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ArithPayload.XorWrapperSharesMatchDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp:201 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ArithPayload.MultiBlockUint256MatchesDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/arith_payload_test [==[--gtest_filter=ArithPayload.MultiBlockUint256MatchesDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ArithPayload.MultiBlockUint256MatchesDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp:244 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ArithPayload.IncrementalMultiSlotArithBeta]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/arith_payload_test [==[--gtest_filter=ArithPayload.IncrementalMultiSlotArithBeta]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ArithPayload.IncrementalMultiSlotArithBeta]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp:284 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ArithPayload.MixedArithBetaAndWildcard]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/arith_payload_test [==[--gtest_filter=ArithPayload.MixedArithBetaAndWildcard]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ArithPayload.MixedArithBetaAndWildcard]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/arith_payload_test.cpp:334 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( arith_payload_test_TESTS ArithPayload.DsXorIndexMatchesDealer ArithPayload.DsArithIndexMatchesDealer ArithPayload.GenevalXorSharedBeta ArithPayload.GenevalArithSharedBeta ArithPayload.XorWrapperSharesMatchDealer ArithPayload.MultiBlockUint256MatchesDealer ArithPayload.IncrementalMultiSlotArithBeta ArithPayload.MixedArithBetaAndWildcard) diff --git a/test/build-asan/beaver_party_test[1]_include.cmake b/test/build-asan/beaver_party_test[1]_include.cmake new file mode 100644 index 0000000..6663a61 --- /dev/null +++ b/test/build-asan/beaver_party_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/beaver_party_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/beaver_party_test[1]_tests.cmake") +else() + add_test(beaver_party_test_NOT_BUILT beaver_party_test_NOT_BUILT) +endif() diff --git a/test/build-asan/beaver_test[1]_include.cmake b/test/build-asan/beaver_test[1]_include.cmake new file mode 100644 index 0000000..51b8374 --- /dev/null +++ b/test/build-asan/beaver_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/beaver_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/beaver_test[1]_tests.cmake") +else() + add_test(beaver_test_NOT_BUILT beaver_test_NOT_BUILT) +endif() diff --git a/test/build-asan/bench_cell_test[1]_include.cmake b/test/build-asan/bench_cell_test[1]_include.cmake new file mode 100644 index 0000000..502aac3 --- /dev/null +++ b/test/build-asan/bench_cell_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bench_cell_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bench_cell_test[1]_tests.cmake") +else() + add_test(bench_cell_test_NOT_BUILT bench_cell_test_NOT_BUILT) +endif() diff --git a/test/build-asan/bin/arith_payload_test b/test/build-asan/bin/arith_payload_test new file mode 100755 index 0000000..a8e9689 Binary files /dev/null and b/test/build-asan/bin/arith_payload_test differ diff --git a/test/build-asan/bin/blocked_dcf_test b/test/build-asan/bin/blocked_dcf_test new file mode 100755 index 0000000..fac3b90 Binary files /dev/null and b/test/build-asan/bin/blocked_dcf_test differ diff --git a/test/build-asan/bin/geneval_test b/test/build-asan/bin/geneval_test new file mode 100755 index 0000000..80cab64 Binary files /dev/null and b/test/build-asan/bin/geneval_test differ diff --git a/test/build-asan/bin/growing_idpf_test b/test/build-asan/bin/growing_idpf_test new file mode 100755 index 0000000..5a7b4ee Binary files /dev/null and b/test/build-asan/bin/growing_idpf_test differ diff --git a/test/build-asan/bin/half_tree_test b/test/build-asan/bin/half_tree_test new file mode 100755 index 0000000..45fdac3 Binary files /dev/null and b/test/build-asan/bin/half_tree_test differ diff --git a/test/build-asan/bin/ic_test b/test/build-asan/bin/ic_test new file mode 100755 index 0000000..a843060 Binary files /dev/null and b/test/build-asan/bin/ic_test differ diff --git a/test/build-asan/bin/incremental_test b/test/build-asan/bin/incremental_test new file mode 100755 index 0000000..bd0f31c Binary files /dev/null and b/test/build-asan/bin/incremental_test differ diff --git a/test/build-asan/bin/lane_blast_test b/test/build-asan/bin/lane_blast_test new file mode 100755 index 0000000..e6bfccf Binary files /dev/null and b/test/build-asan/bin/lane_blast_test differ diff --git a/test/build-asan/bin/net_control_test b/test/build-asan/bin/net_control_test new file mode 100755 index 0000000..d7d2d0a Binary files /dev/null and b/test/build-asan/bin/net_control_test differ diff --git a/test/build-asan/bin/offset_horner_test b/test/build-asan/bin/offset_horner_test new file mode 100755 index 0000000..976841e Binary files /dev/null and b/test/build-asan/bin/offset_horner_test differ diff --git a/test/build-asan/bin/p0 b/test/build-asan/bin/p0 new file mode 100755 index 0000000..e980fbd Binary files /dev/null and b/test/build-asan/bin/p0 differ diff --git a/test/build-asan/bin/p1 b/test/build-asan/bin/p1 new file mode 100755 index 0000000..813d349 Binary files /dev/null and b/test/build-asan/bin/p1 differ diff --git a/test/build-asan/bin/p2 b/test/build-asan/bin/p2 new file mode 100755 index 0000000..0d84e3e Binary files /dev/null and b/test/build-asan/bin/p2 differ diff --git a/test/build-asan/bin/party_bench b/test/build-asan/bin/party_bench new file mode 100755 index 0000000..8dc539f Binary files /dev/null and b/test/build-asan/bin/party_bench differ diff --git a/test/build-asan/bin/ppvc_test b/test/build-asan/bin/ppvc_test new file mode 100755 index 0000000..3c4e6b0 Binary files /dev/null and b/test/build-asan/bin/ppvc_test differ diff --git a/test/build-asan/bin/security_test b/test/build-asan/bin/security_test new file mode 100755 index 0000000..f039755 Binary files /dev/null and b/test/build-asan/bin/security_test differ diff --git a/test/build-asan/bin/share_runtime_test b/test/build-asan/bin/share_runtime_test new file mode 100755 index 0000000..d54c492 Binary files /dev/null and b/test/build-asan/bin/share_runtime_test differ diff --git a/test/build-asan/bin/signed_prefix_test b/test/build-asan/bin/signed_prefix_test new file mode 100755 index 0000000..7444dbe Binary files /dev/null and b/test/build-asan/bin/signed_prefix_test differ diff --git a/test/build-asan/bin/stress_scenarios_test b/test/build-asan/bin/stress_scenarios_test new file mode 100755 index 0000000..ee1231a Binary files /dev/null and b/test/build-asan/bin/stress_scenarios_test differ diff --git a/test/build-asan/bit_array_test[1]_include.cmake b/test/build-asan/bit_array_test[1]_include.cmake new file mode 100644 index 0000000..0d7c080 --- /dev/null +++ b/test/build-asan/bit_array_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bit_array_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bit_array_test[1]_tests.cmake") +else() + add_test(bit_array_test_NOT_BUILT bit_array_test_NOT_BUILT) +endif() diff --git a/test/build-asan/bitmore_mod_test[1]_include.cmake b/test/build-asan/bitmore_mod_test[1]_include.cmake new file mode 100644 index 0000000..77652df --- /dev/null +++ b/test/build-asan/bitmore_mod_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bitmore_mod_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bitmore_mod_test[1]_tests.cmake") +else() + add_test(bitmore_mod_test_NOT_BUILT bitmore_mod_test_NOT_BUILT) +endif() diff --git a/test/build-asan/blob_leaf_test[1]_include.cmake b/test/build-asan/blob_leaf_test[1]_include.cmake new file mode 100644 index 0000000..78aeeff --- /dev/null +++ b/test/build-asan/blob_leaf_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/blob_leaf_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/blob_leaf_test[1]_tests.cmake") +else() + add_test(blob_leaf_test_NOT_BUILT blob_leaf_test_NOT_BUILT) +endif() diff --git a/test/build-asan/blocked_dcf_test[1]_include.cmake b/test/build-asan/blocked_dcf_test[1]_include.cmake new file mode 100644 index 0000000..4338fa4 --- /dev/null +++ b/test/build-asan/blocked_dcf_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/blocked_dcf_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/blocked_dcf_test[1]_tests.cmake") +else() + add_test(blocked_dcf_test_NOT_BUILT blocked_dcf_test_NOT_BUILT) +endif() diff --git a/test/build-asan/blocked_dcf_test[1]_tests.cmake b/test/build-asan/blocked_dcf_test[1]_tests.cmake new file mode 100644 index 0000000..217d897 --- /dev/null +++ b/test/build-asan/blocked_dcf_test[1]_tests.cmake @@ -0,0 +1,31 @@ +add_test([=[BlockedDcf.ExhaustiveUint8AllWidths]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.ExhaustiveUint8AllWidths]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.ExhaustiveUint8AllWidths]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:91 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.KindsIfFalseAndPayloadWidths]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.KindsIfFalseAndPayloadWidths]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.KindsIfFalseAndPayloadWidths]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:104 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.Block1MatchesFunctionNotBytes]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.Block1MatchesFunctionNotBytes]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.Block1MatchesFunctionNotBytes]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:115 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.DeeperOutputForcesFullTree]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.DeeperOutputForcesFullTree]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.DeeperOutputForcesFullTree]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:132 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.ShallowerLeafKeepsTail]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.ShallowerLeafKeepsTail]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.ShallowerLeafKeepsTail]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:151 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.PointIntervalFullSequenceInnerProduct]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.PointIntervalFullSequenceInnerProduct]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.PointIntervalFullSequenceInnerProduct]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:164 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.DealerMatchesDoernerShelat]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.DealerMatchesDoernerShelat]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.DealerMatchesDoernerShelat]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:232 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.WildcardAssignMatchesConcrete]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.WildcardAssignMatchesConcrete]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.WildcardAssignMatchesConcrete]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:268 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.TrivialDomainEdges]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.TrivialDomainEdges]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.TrivialDomainEdges]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:295 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.JsonRoundTrip]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.JsonRoundTrip]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.JsonRoundTrip]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:310 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.GenevalOpensCheckpointWords]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.GenevalOpensCheckpointWords]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.GenevalOpensCheckpointWords]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:337 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.UnevenScheduleMatchesDenseComparison]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.UnevenScheduleMatchesDenseComparison]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.UnevenScheduleMatchesDenseComparison]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:360 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.WideCheckpointFrontierMatchesDense]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.WideCheckpointFrontierMatchesDense]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.WideCheckpointFrontierMatchesDense]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:390 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.PathRecipesStayOnThePerLevelChannel]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.PathRecipesStayOnThePerLevelChannel]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.PathRecipesStayOnThePerLevelChannel]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:422 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BlockedDcf.GrottoPrefixSegmentAndHorner]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/blocked_dcf_test [==[--gtest_filter=BlockedDcf.GrottoPrefixSegmentAndHorner]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BlockedDcf.GrottoPrefixSegmentAndHorner]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/blocked_dcf_test.cpp:439 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( blocked_dcf_test_TESTS BlockedDcf.ExhaustiveUint8AllWidths BlockedDcf.KindsIfFalseAndPayloadWidths BlockedDcf.Block1MatchesFunctionNotBytes BlockedDcf.DeeperOutputForcesFullTree BlockedDcf.ShallowerLeafKeepsTail BlockedDcf.PointIntervalFullSequenceInnerProduct BlockedDcf.DealerMatchesDoernerShelat BlockedDcf.WildcardAssignMatchesConcrete BlockedDcf.TrivialDomainEdges BlockedDcf.JsonRoundTrip BlockedDcf.GenevalOpensCheckpointWords BlockedDcf.UnevenScheduleMatchesDenseComparison BlockedDcf.WideCheckpointFrontierMatchesDense BlockedDcf.PathRecipesStayOnThePerLevelChannel BlockedDcf.GrottoPrefixSegmentAndHorner) diff --git a/test/build-asan/caller_fold_test[1]_include.cmake b/test/build-asan/caller_fold_test[1]_include.cmake new file mode 100644 index 0000000..11ef7c9 --- /dev/null +++ b/test/build-asan/caller_fold_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/caller_fold_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/caller_fold_test[1]_tests.cmake") +else() + add_test(caller_fold_test_NOT_BUILT caller_fold_test_NOT_BUILT) +endif() diff --git a/test/build-asan/carry_test[1]_include.cmake b/test/build-asan/carry_test[1]_include.cmake new file mode 100644 index 0000000..26b7be3 --- /dev/null +++ b/test/build-asan/carry_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/carry_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/carry_test[1]_tests.cmake") +else() + add_test(carry_test_NOT_BUILT carry_test_NOT_BUILT) +endif() diff --git a/test/build-asan/class_sweep_test[1]_include.cmake b/test/build-asan/class_sweep_test[1]_include.cmake new file mode 100644 index 0000000..b2157e4 --- /dev/null +++ b/test/build-asan/class_sweep_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/class_sweep_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/class_sweep_test[1]_tests.cmake") +else() + add_test(class_sweep_test_NOT_BUILT class_sweep_test_NOT_BUILT) +endif() diff --git a/test/build-asan/closed_form_test[1]_include.cmake b/test/build-asan/closed_form_test[1]_include.cmake new file mode 100644 index 0000000..d125ded --- /dev/null +++ b/test/build-asan/closed_form_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/closed_form_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/closed_form_test[1]_tests.cmake") +else() + add_test(closed_form_test_NOT_BUILT closed_form_test_NOT_BUILT) +endif() diff --git a/test/build-asan/cmake_install.cmake b/test/build-asan/cmake_install.cmake new file mode 100644 index 0000000..f8a59fb --- /dev/null +++ b/test/build-asan/cmake_install.cmake @@ -0,0 +1,72 @@ +# Install script for directory: /home/cryptolicious/hushmap-specified/libdpf/test + +# Set the install prefix +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "/usr/local") +endif() +string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + if(BUILD_TYPE) + string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + else() + set(CMAKE_INSTALL_CONFIG_NAME "Debug") + endif() + message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +endif() + +# Set the component getting installed. +if(NOT CMAKE_INSTALL_COMPONENT) + if(COMPONENT) + message(STATUS "Install component: \"${COMPONENT}\"") + set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + else() + set(CMAKE_INSTALL_COMPONENT) + endif() +endif() + +# Install shared libraries without execute permission? +if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + set(CMAKE_INSTALL_SO_NO_EXE "1") +endif() + +# Is this installation the result of a crosscompile? +if(NOT DEFINED CMAKE_CROSSCOMPILING) + set(CMAKE_CROSSCOMPILING "FALSE") +endif() + +# Set path to fallback-tool for dependency-resolution. +if(NOT DEFINED CMAKE_OBJDUMP) + set(CMAKE_OBJDUMP "/usr/bin/objdump") +endif() + +if(NOT CMAKE_INSTALL_LOCAL_ONLY) + # Include the install script for each subdirectory. + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/cmake_install.cmake") + +endif() + +string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT + "${CMAKE_INSTALL_MANIFEST_FILES}") +if(CMAKE_INSTALL_LOCAL_ONLY) + file(WRITE "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/install_local_manifest.txt" + "${CMAKE_INSTALL_MANIFEST_CONTENT}") +endif() +if(CMAKE_INSTALL_COMPONENT) + if(CMAKE_INSTALL_COMPONENT MATCHES "^[a-zA-Z0-9_.+-]+$") + set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt") + else() + string(MD5 CMAKE_INST_COMP_HASH "${CMAKE_INSTALL_COMPONENT}") + set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INST_COMP_HASH}.txt") + unset(CMAKE_INST_COMP_HASH) + endif() +else() + set(CMAKE_INSTALL_MANIFEST "install_manifest.txt") +endif() + +if(NOT CMAKE_INSTALL_LOCAL_ONLY) + file(WRITE "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/${CMAKE_INSTALL_MANIFEST}" + "${CMAKE_INSTALL_MANIFEST_CONTENT}") +endif() diff --git a/test/build-asan/cmake_test_discovery_018768cf5c.json b/test/build-asan/cmake_test_discovery_018768cf5c.json new file mode 100644 index 0000000..0d31e0e --- /dev/null +++ b/test/build-asan/cmake_test_discovery_018768cf5c.json @@ -0,0 +1,187 @@ +{ + "tests": 35, + "name": "AllTests", + "testsuites": [ + { + "name": "Geneval", + "tests": 35, + "testsuite": [ + { + "name": "PointOnTargetMatchesKeyAndEval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 121 + }, + { + "name": "PointDivergesAfterSharedPrefix", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 151 + }, + { + "name": "SameLeafDifferentLane", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 182 + }, + { + "name": "IntervalContainsTarget", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 212 + }, + { + "name": "IntervalMissesAfterSharedPrefix", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 249 + }, + { + "name": "SequenceOrderAndSharedTrie", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 279 + }, + { + "name": "FullDomainUint8", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 322 + }, + { + "name": "EmptySequence", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 358 + }, + { + "name": "ArithPointMatchesDealerAtQuery", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 372 + }, + { + "name": "ArithPointOnSecretIsFullKey", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 401 + }, + { + "name": "ArithIntervalAndSequence", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 427 + }, + { + "name": "ArithFullMatchesDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 477 + }, + { + "name": "DoernerShelatKeyAgreesOnLivePrefix", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 507 + }, + { + "name": "EdgesZeroMaxAndSinglePointShapesAgree", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 574 + }, + { + "name": "XorSplitAndPadStreamDoNotChangeLiveWords", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 624 + }, + { + "name": "IntervalLiveFollowsLongestPrefixNotTheFirstPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 661 + }, + { + "name": "PartialLeafExcludesTargetButKeepsItsWord", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 702 + }, + { + "name": "DepthOneBitOutput", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 735 + }, + { + "name": "FullMatchesWholeIntervalAndRejectsHugeDomain", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 776 + }, + { + "name": "SequencePermutationKeepsWordsAndDuplicates", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 809 + }, + { + "name": "SignedPointIntervalAndCrossZero", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 840 + }, + { + "name": "SignedFullAndArithFull", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 907 + }, + { + "name": "ArithShareOverflowAndWrappingInterval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 953 + }, + { + "name": "XorWrapperOutput", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 1007 + }, + { + "name": "SignedRegressionsFromTheCornerPass", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 1040 + }, + { + "name": "CmpEmptyRangeOpensNothing", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 1094 + }, + { + "name": "CmpMatchesDoernerShelatKeyAndGtPredicate", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 1106 + }, + { + "name": "CmpSignedPayloadAndDomainMax", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 1148 + }, + { + "name": "CmpLtIsTheComplementOfTheStrictUpperSet", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 1179 + }, + { + "name": "DoernerShelatOnTargetSharesMatch", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 1196 + }, + { + "name": "WideLiveFrontierMatchesDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 1224 + }, + { + "name": "CmpLeqGeqNonzeroElseAndDomainMin", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 1258 + }, + { + "name": "ArithSignedMsbAndCarryAcrossPowerOfTwo", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 1321 + }, + { + "name": "ArithDoernerShelatAndCmpMatchDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 1373 + }, + { + "name": "ArithCarryLeavesXorShares", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/geneval_test.cpp", + "line": 1410 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_39faf8c228.json b/test/build-asan/cmake_test_discovery_39faf8c228.json new file mode 100644 index 0000000..61e4ed3 --- /dev/null +++ b/test/build-asan/cmake_test_discovery_39faf8c228.json @@ -0,0 +1,192 @@ +{ + "tests": 36, + "name": "AllTests", + "testsuites": [ + { + "name": "OffsetHorner", + "tests": 36, + "testsuite": [ + { + "name": "BinomialAgreesWithPowerSum", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 176 + }, + { + "name": "HandCubicAtCenterPlusEta", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 195 + }, + { + "name": "MultiPieceSelectsWrappedInput", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 219 + }, + { + "name": "CarrySplitEvaluatesTheWrappedRepresentative", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 236 + }, + { + "name": "XPlusRWiring", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 271 + }, + { + "name": "DegreesZeroOneAndTwo", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 289 + }, + { + "name": "WholeDomainAndWrapPiece", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 324 + }, + { + "name": "CenterOrEtaZero", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 346 + }, + { + "name": "NegativeCoefficientsAndSignedDomain", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 363 + }, + { + "name": "ShiftedKnotsThatAreNotSortedStillSelect", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 393 + }, + { + "name": "RingOverflowDiffersFromWideInteger", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 415 + }, + { + "name": "WrapSharesHideThePayload", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 433 + }, + { + "name": "PowerKeysAreIndependentComparisons", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 448 + }, + { + "name": "DegreeZeroMatchesSignRespectingDot", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 467 + }, + { + "name": "AdviceBitSignIsNotACoefficientShare", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 500 + }, + { + "name": "SignRespectingOneHotIsNotTheShiftedCubic", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 551 + }, + { + "name": "PrefixIntoMatchesFixedArray", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 578 + }, + { + "name": "RejectsBadKnots", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 598 + }, + { + "name": "ManyPiecesAndRandomUint16", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 609 + }, + { + "name": "ExhaustiveUint8AgreesWithGoldAndCountsWraps", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 636 + }, + { + "name": "ExhaustiveInt8AgreesWithGoldAndCountsOverflows", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 685 + }, + { + "name": "GenevalXorSharesMatchTheDealerPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 730 + }, + { + "name": "GenevalFromAdditiveSharesOfXAndR", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 753 + }, + { + "name": "GenevalSignedSharesUseGenevalConvention", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 782 + }, + { + "name": "HornerOfOpenedCoefficientsMatchesValue", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 818 + }, + { + "name": "OpenedSharesAreNotHornerInputs", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 838 + }, + { + "name": "KnotsThatOmitZeroStillSplitTheCarry", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 902 + }, + { + "name": "SignedKnotsThatOmitTheMinimum", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 929 + }, + { + "name": "CarryThresholdLandsOnEveryKnotAndOnTheDomainEnds", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 955 + }, + { + "name": "DegreeZeroIsThePieceConstantOnBothSidesOfTheCarry", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 996 + }, + { + "name": "CubicAcrossUnsignedAndSignedCarryHasANegativeKappa", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 1023 + }, + { + "name": "ZeroPolynomialAndProperShares", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 1066 + }, + { + "name": "XPlusRMatchesTheWrappedSumOnAStride", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 1092 + }, + { + "name": "GenevalAgreesWithDealerAcrossCarryAndEdges", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 1126 + }, + { + "name": "WiderRandomDomainsMatchWrappedGold", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 1188 + }, + { + "name": "BiggerDomainsExerciseCarrySplitAndGeneval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/offset_horner_test.cpp", + "line": 1411 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_3a95693b1a.json b/test/build-asan/cmake_test_discovery_3a95693b1a.json new file mode 100644 index 0000000..5d40856 --- /dev/null +++ b/test/build-asan/cmake_test_discovery_3a95693b1a.json @@ -0,0 +1,108 @@ +{ + "tests": 18, + "name": "AllTests", + "testsuites": [ + { + "name": "GrowingIdpf", + "tests": 13, + "testsuite": [ + { + "name": "PrefixesOpenToOwnPayload", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 63 + }, + { + "name": "ExtendMatchesFullySpecified", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 94 + }, + { + "name": "AddOutputWildcardOnExistingLevel", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 140 + }, + { + "name": "DeepestPrefixMatchesClassicDpf", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 162 + }, + { + "name": "ChaChaPrgOpensThePrefix", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 189 + }, + { + "name": "MemoizerExtendMatchesRewalk", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 224 + }, + { + "name": "ExtendDsMatchesDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 255 + }, + { + "name": "AddOutputDsWildcard", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 284 + }, + { + "name": "ShallowMemoizerThrows", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 307 + }, + { + "name": "ExtendSaturatesEightBitDomain", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 356 + }, + { + "name": "ExhaustiveDomainAfterMemoGrow", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 421 + }, + { + "name": "DsAndDealerAgreeFullDomain", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 450 + }, + { + "name": "EmptyAddOutputThrows", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 482 + } + ] + }, + { + "name": "GrowingIdpfDeath", + "tests": 5, + "testsuite": [ + { + "name": "MismatchedKeyPairThrows", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 323 + }, + { + "name": "WrongPathBitThrows", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 334 + }, + { + "name": "SpecNotOnNewDepthThrows", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 345 + }, + { + "name": "MemoizerOnSiblingCorruptsNewSlot", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 371 + }, + { + "name": "DsWrongSharesDisagreeWithDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/growing_idpf_test.cpp", + "line": 396 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_4a0c11a00a.json b/test/build-asan/cmake_test_discovery_4a0c11a00a.json new file mode 100644 index 0000000..3769578 --- /dev/null +++ b/test/build-asan/cmake_test_discovery_4a0c11a00a.json @@ -0,0 +1,302 @@ +{ + "tests": 58, + "name": "AllTests", + "testsuites": [ + { + "name": "IncrementalDpfTest", + "tests": 58, + "testsuite": [ + { + "name": "ClassicPathByteIdentical", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 196 + }, + { + "name": "At10BitDepthAndLanes", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 216 + }, + { + "name": "SameWidthPackedInOneGroup", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 236 + }, + { + "name": "MixedWidthsSamePrefixSeparateGroups", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 263 + }, + { + "name": "ManyLevelsManyTypes", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 286 + }, + { + "name": "ManySameLevelGroupsHighPosBase", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 346 + }, + { + "name": "NinePlusGroupsScales", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 405 + }, + { + "name": "DealerMatchesDoernerShelat", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 435 + }, + { + "name": "IntermediateWildcardSameKey", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 477 + }, + { + "name": "EvalSweepAroundPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 511 + }, + { + "name": "SignedInput", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 546 + }, + { + "name": "FullDomainAtEqualsBare", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 560 + }, + { + "name": "DepthZeroLeaf", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 578 + }, + { + "name": "MemoizedPathEval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 592 + }, + { + "name": "DsEvalAgreesWithDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 615 + }, + { + "name": "SixteenUint8PackedOneLevel", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 646 + }, + { + "name": "EightUint16AndFourUint32Packed", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 682 + }, + { + "name": "ManyBitsOnePrefix", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 710 + }, + { + "name": "FixedpointIntermediateAndFullDomain", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 733 + }, + { + "name": "FixedpointMixedWithIntegralAndBit", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 768 + }, + { + "name": "FixedpointDealerMatchesDoernerShelat", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 792 + }, + { + "name": "DenseSameLevelManyGroups", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 832 + }, + { + "name": "TwelveBitPrefixesPlusFullDomain", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 886 + }, + { + "name": "TwoFullPackedNodesSameLevel", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 920 + }, + { + "name": "IntervalAtMatchesPointEval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 955 + }, + { + "name": "FullAtDeepestAndSequenceAt", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 992 + }, + { + "name": "LocalCwProtocolMatchesDsRandomness", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1021 + }, + { + "name": "DpfAndCmpSameKey", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1050 + }, + { + "name": "CmpPairAndRelations", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1081 + }, + { + "name": "EqSynonymAndEqAt", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1114 + }, + { + "name": "CmpWithDoernerShelat", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1148 + }, + { + "name": "CmpDealerMatchesDoernerShelat", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1164 + }, + { + "name": "CmpIntervalAndSequenceBuffers", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1211 + }, + { + "name": "CmpSharesPathMemoizerWithEvalAt", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1253 + }, + { + "name": "CmpOnlyZeroOutputs", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1277 + }, + { + "name": "CmpDomainEdgeTrivial", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1291 + }, + { + "name": "CmpValueCwGroupWidth", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1312 + }, + { + "name": "CmpValueCwGroupWidthDsParity", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1346 + }, + { + "name": "CmpPayloadHiddenOnKeys", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1382 + }, + { + "name": "UnifiedEvalTargetSurface", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1410 + }, + { + "name": "ClassicKeyHasSlotMetaAndOutEval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1472 + }, + { + "name": "CmpWildcardAssignMatchesConcrete", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1522 + }, + { + "name": "CmpWildcardPairAndGeqAndInterval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1571 + }, + { + "name": "CmpWildcardNarrowPayloadAndAt", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1611 + }, + { + "name": "DsWildcardCmpMatchesDealerThenAssign", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1638 + }, + { + "name": "DsWildcardCmpWithAtAndNarrowPayload", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1704 + }, + { + "name": "MultilevelInnerProductMatchesInterval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1740 + }, + { + "name": "CmpInnerProductMatchesInterval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1780 + }, + { + "name": "BreadthFirstAtNonFinalSlot", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1807 + }, + { + "name": "CrossLevelPathMemoizerShallowThenDeep", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1837 + }, + { + "name": "SequenceRecipeAtPrefixSlot", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1865 + }, + { + "name": "EqIfFalseAbsorbsOnEveryEvalSurface", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1904 + }, + { + "name": "EqAtIfFalseWithPackedIntervalAndXor", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 1988 + }, + { + "name": "EqIfFalseDealerMatchesDoernerShelatSurfaces", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 2045 + }, + { + "name": "PathMemoizerResumePastFullWidthCmpDepth", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 2074 + }, + { + "name": "PathMemoizerResumeCmpOnlyFullWidth", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 2113 + }, + { + "name": "EqMixedWithBlockedCmpSharesMemoizer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 2131 + }, + { + "name": "IntervalMemoizerReuseAcrossEqAndShallowAt", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/incremental_test.cpp", + "line": 2161 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_6a028eb5af.json b/test/build-asan/cmake_test_discovery_6a028eb5af.json new file mode 100644 index 0000000..86da794 --- /dev/null +++ b/test/build-asan/cmake_test_discovery_6a028eb5af.json @@ -0,0 +1,52 @@ +{ + "tests": 8, + "name": "AllTests", + "testsuites": [ + { + "name": "LaneBlast", + "tests": 8, + "testsuite": [ + { + "name": "ParseStreamsAndLimits", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/lane_blast_test.cpp", + "line": 188 + }, + { + "name": "ShareWrapsInTheLaneRing", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/lane_blast_test.cpp", + "line": 249 + }, + { + "name": "DepositDoesNotBleedIntoTheNextLane", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/lane_blast_test.cpp", + "line": 268 + }, + { + "name": "Uint8TwobitEveryInputAndEveryShape", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/lane_blast_test.cpp", + "line": 303 + }, + { + "name": "Uint8NybleAndBitSameShapes", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/lane_blast_test.cpp", + "line": 345 + }, + { + "name": "SignedInputPackedLeaf", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/lane_blast_test.cpp", + "line": 360 + }, + { + "name": "GenevalMatchesKeyOnPackedLanes", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/lane_blast_test.cpp", + "line": 381 + }, + { + "name": "GenevalNybleArithAndSigned", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/lane_blast_test.cpp", + "line": 469 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_8bc445ad94.json b/test/build-asan/cmake_test_discovery_8bc445ad94.json new file mode 100644 index 0000000..78c7603 --- /dev/null +++ b/test/build-asan/cmake_test_discovery_8bc445ad94.json @@ -0,0 +1,52 @@ +{ + "tests": 8, + "name": "AllTests", + "testsuites": [ + { + "name": "ArithPayload", + "tests": 8, + "testsuite": [ + { + "name": "DsXorIndexMatchesDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/arith_payload_test.cpp", + "line": 62 + }, + { + "name": "DsArithIndexMatchesDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/arith_payload_test.cpp", + "line": 111 + }, + { + "name": "GenevalXorSharedBeta", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/arith_payload_test.cpp", + "line": 144 + }, + { + "name": "GenevalArithSharedBeta", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/arith_payload_test.cpp", + "line": 172 + }, + { + "name": "XorWrapperSharesMatchDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/arith_payload_test.cpp", + "line": 201 + }, + { + "name": "MultiBlockUint256MatchesDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/arith_payload_test.cpp", + "line": 244 + }, + { + "name": "IncrementalMultiSlotArithBeta", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/arith_payload_test.cpp", + "line": 284 + }, + { + "name": "MixedArithBetaAndWildcard", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/arith_payload_test.cpp", + "line": 334 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_9a201f9935.json b/test/build-asan/cmake_test_discovery_9a201f9935.json new file mode 100644 index 0000000..8f86ebe --- /dev/null +++ b/test/build-asan/cmake_test_discovery_9a201f9935.json @@ -0,0 +1,635 @@ +{ + "tests": 91, + "name": "AllTests", + "testsuites": [ + { + "name": "RssSeed", + "tests": 3, + "testsuite": [ + { + "name": "RandomReplicatedSums", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 117 + }, + { + "name": "ZeroSharesSumToZero", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 126 + }, + { + "name": "MulLocalThenRefresh", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 138 + } + ] + }, + { + "name": "ScheduleSession", + "tests": 1, + "testsuite": [ + { + "name": "PipelineCreditIndependentPads", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 156 + } + ] + }, + { + "name": "Compose", + "tests": 17, + "testsuite": [ + { + "name": "BinNotLocalConvertible", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 175 + }, + { + "name": "ArithKernelsPresent", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 184 + }, + { + "name": "RssZeroFromSeeds", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 196 + }, + { + "name": "CheckOpenRejectsCorrupt", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 212 + }, + { + "name": "CheckOpenHashRing", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 591 + }, + { + "name": "TruncExactKernel", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 643 + }, + { + "name": "B2aOpenMatchesClear", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 670 + }, + { + "name": "MulTruncOpen", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 707 + }, + { + "name": "InjectAndMuxOpen", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 741 + }, + { + "name": "GmwAndOpen", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 774 + }, + { + "name": "DrivePlanOnStreamsOpen", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1414 + }, + { + "name": "DrivePlanOnStreamsTwoWaves", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1437 + }, + { + "name": "DrivePlanOnStreamsGmwAnd", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1472 + }, + { + "name": "DrivePlanOnStreamsDeepEightWaves", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1500 + }, + { + "name": "DrivePlanOnStreamsMuxTcp", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1529 + }, + { + "name": "DrivePlanOnStreamMeshRssCopy", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1593 + }, + { + "name": "NPartyComposerAllowed", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2239 + } + ] + }, + { + "name": "EdaBit", + "tests": 4, + "testsuite": [ + { + "name": "A2BThenReconstruct", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 268 + }, + { + "name": "RssArithEqualsBits", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 282 + }, + { + "name": "GmwA2bMatchesClear", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 303 + }, + { + "name": "DaBitPairConsistent", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 311 + } + ] + }, + { + "name": "BitInject", + "tests": 3, + "testsuite": [ + { + "name": "ClearMatches", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 318 + }, + { + "name": "RssAndLocal", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 324 + }, + { + "name": "RssAndRefresh", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 817 + } + ] + }, + { + "name": "Trunc", + "tests": 3, + "testsuite": [ + { + "name": "ProbErrorAtMostOne", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 340 + }, + { + "name": "ExactPartyUsesDelta", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 348 + }, + { + "name": "MulTruncClear", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 361 + } + ] + }, + { + "name": "ShareCmp", + "tests": 2, + "testsuite": [ + { + "name": "ReluMaxDivParty", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 367 + }, + { + "name": "Declassify", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 389 + } + ] + }, + { + "name": "ShareVec", + "tests": 1, + "testsuite": [ + { + "name": "MulDeclassify", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 399 + } + ] + }, + { + "name": "FixedShare", + "tests": 1, + "testsuite": [ + { + "name": "MulViaTrunc", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 410 + } + ] + }, + { + "name": "ShareExpr", + "tests": 2, + "testsuite": [ + { + "name": "MulAddDeclassify", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 425 + }, + { + "name": "BandArity", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 454 + } + ] + }, + { + "name": "Gilboa", + "tests": 6, + "testsuite": [ + { + "name": "MulFromOtMatchesClear", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 474 + }, + { + "name": "FillTapeOtRepeatedWire", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 483 + }, + { + "name": "FillTapeDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 498 + }, + { + "name": "FillTapeOtReadsStash", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 802 + }, + { + "name": "MulTapeViaStreamArrays", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1659 + }, + { + "name": "MulOnlineViaStreamArrays", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1672 + } + ] + }, + { + "name": "Matmul", + "tests": 1, + "testsuite": [ + { + "name": "EightByEight", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 513 + } + ] + }, + { + "name": "Shuffle", + "tests": 2, + "testsuite": [ + { + "name": "CliqueSendNext", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 528 + }, + { + "name": "SelectSumCountArgmax", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 853 + } + ] + }, + { + "name": "Circuit", + "tests": 4, + "testsuite": [ + { + "name": "MulOpenFromDealerFile", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 864 + }, + { + "name": "PrivateInputAndTcpPrep", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 893 + }, + { + "name": "MulOpenFromStreamArray", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1079 + }, + { + "name": "RecordsGmwAndA2bGtTruncMux", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1199 + } + ] + }, + { + "name": "Run", + "tests": 2, + "testsuite": [ + { + "name": "ThreePartyDeclassify", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 930 + }, + { + "name": "ThreePartyDeclassifyStreamClique", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1136 + } + ] + }, + { + "name": "CostPass", + "tests": 2, + "testsuite": [ + { + "name": "EmptyPlanNoSynthetic", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 945 + }, + { + "name": "RealCmpGetsChoice", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 956 + } + ] + }, + { + "name": "StreamArray", + "tests": 6, + "testsuite": [ + { + "name": "MemoryDealerRingTriple", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 968 + }, + { + "name": "FileDealerRoundTrip", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 990 + }, + { + "name": "MuxLocalhostDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1016 + }, + { + "name": "MultiRoundSinkExchange", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1107 + }, + { + "name": "DealerCursorFromStreamPrg", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1314 + }, + { + "name": "SctpStreamArrayStubThrows", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1733 + } + ] + }, + { + "name": "Factory", + "tests": 9, + "testsuite": [ + { + "name": "GmwAndRoundMemory", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1054 + }, + { + "name": "BeaverMulStreamMemory", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1171 + }, + { + "name": "MuxOnlineStreamMemory", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1217 + }, + { + "name": "A2bTapeOnline", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1248 + }, + { + "name": "TruncTapeOnline", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1268 + }, + { + "name": "GtTapeOnline", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1291 + }, + { + "name": "ScheduleOnStreams", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1346 + }, + { + "name": "RssRefreshRingStreamClique", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1691 + }, + { + "name": "AsyncByteProtocolRoundCallbacks", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1782 + } + ] + }, + { + "name": "Roles", + "tests": 1, + "testsuite": [ + { + "name": "DealerWriteFilesRoundTrip", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1399 + } + ] + }, + { + "name": "AsyncIo", + "tests": 6, + "testsuite": [ + { + "name": "MemoryOverlapTwoRounds", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1826 + }, + { + "name": "MuxLocalhostOverlap", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1865 + }, + { + "name": "ParallelSocketsTwoStreams", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1928 + }, + { + "name": "SctpLocalhostOverlap", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 1976 + }, + { + "name": "LaneReuseDeepPlan", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2100 + }, + { + "name": "OverlappedLaneModulo", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2169 + } + ] + }, + { + "name": "AppFlow", + "tests": 2, + "testsuite": [ + { + "name": "ExercisePlanUsesStreamFramework", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2069 + }, + { + "name": "ExercisePlanAsyncMemoryFramework", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2087 + } + ] + }, + { + "name": "ComposeAsync", + "tests": 1, + "testsuite": [ + { + "name": "DriveBothOnAsyncStreams", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2145 + } + ] + }, + { + "name": "TcpMesh", + "tests": 1, + "testsuite": [ + { + "name": "ThreePartyMuxExchange", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2212 + } + ] + }, + { + "name": "Session", + "tests": 3, + "testsuite": [ + { + "name": "ShipPrepAsync", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2245 + }, + { + "name": "HushmapAsyncDealerAndPeer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2268 + }, + { + "name": "PirsonaAsyncStar", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2273 + } + ] + }, + { + "name": "WireWindow", + "tests": 1, + "testsuite": [ + { + "name": "MuxTinyWindowStillCompletes", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2291 + } + ] + }, + { + "name": "IoPool", + "tests": 2, + "testsuite": [ + { + "name": "PostsComputeOnSharedWorkers", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2371 + }, + { + "name": "ComputeDoesNotUseSocketContext", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2519 + } + ] + }, + { + "name": "PartySession", + "tests": 2, + "testsuite": [ + { + "name": "JoinReconnectAndDealerOnOnePool", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2411 + }, + { + "name": "WindowAndLaneOverride", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2599 + } + ] + }, + { + "name": "SocketTune", + "tests": 1, + "testsuite": [ + { + "name": "NoDelayOnConnectedSocket", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2492 + } + ] + }, + { + "name": "DriveOptions", + "tests": 2, + "testsuite": [ + { + "name": "LaneCountAndWaitTimeout", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2536 + }, + { + "name": "KernelRunsOnComputePool", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/share_runtime_test.cpp", + "line": 2560 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_9cc54d2066.json b/test/build-asan/cmake_test_discovery_9cc54d2066.json new file mode 100644 index 0000000..b884994 --- /dev/null +++ b/test/build-asan/cmake_test_discovery_9cc54d2066.json @@ -0,0 +1,223 @@ +{ + "tests": 29, + "name": "AllTests", + "testsuites": [ + { + "name": "RunConfig", + "tests": 1, + "testsuite": [ + { + "name": "EnvAndArgsShareKeys", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 144 + } + ] + }, + { + "name": "RoundLane", + "tests": 1, + "testsuite": [ + { + "name": "FramingModesAndLimits", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 171 + } + ] + }, + { + "name": "Sink", + "tests": 4, + "testsuite": [ + { + "name": "HelloNamesTheDisagreement", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 225 + }, + { + "name": "FramedPartialPrefixReadyPerInstance", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 238 + }, + { + "name": "PeerFailureSurfacesImmediately", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 265 + }, + { + "name": "WindowGatesPipelining", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 1060 + } + ] + }, + { + "name": "Drive", + "tests": 2, + "testsuite": [ + { + "name": "HealthyPlanLongerThanWaitTimeout", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 298 + }, + { + "name": "EdgeAndRoundBudgetsNameTheWait", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 317 + } + ] + }, + { + "name": "Memory", + "tests": 1, + "testsuite": [ + { + "name": "WindowSetterAndGracefulClose", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 361 + } + ] + }, + { + "name": "Mux", + "tests": 3, + "testsuite": [ + { + "name": "StatsCountHeaders", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 421 + }, + { + "name": "SmallWriteIsNotQueuedBehindLargeWrite", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 437 + }, + { + "name": "DestroyAfterWriteStillDelivers", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 467 + } + ] + }, + { + "name": "Parallel", + "tests": 1, + "testsuite": [ + { + "name": "PerLaneWindows", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 485 + } + ] + }, + { + "name": "SyncMux", + "tests": 2, + "testsuite": [ + { + "name": "InteroperatesWithAsyncMux", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 516 + }, + { + "name": "LargeCrossFlushDoesNotDeadlock", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 546 + } + ] + }, + { + "name": "Session", + "tests": 6, + "testsuite": [ + { + "name": "ConnectHasADeadline", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 575 + }, + { + "name": "StaticTableAnyStartOrder", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 587 + }, + { + "name": "TransportMismatchIsNamed", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 612 + }, + { + "name": "ParallelAndSctpEdges", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 640 + }, + { + "name": "ReconnectResumesMidPlan", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 686 + }, + { + "name": "DealerLinkHasItsOwnEpoch", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 740 + } + ] + }, + { + "name": "Runner", + "tests": 6, + "testsuite": [ + { + "name": "TwoPartyOnEveryTransport", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 790 + }, + { + "name": "InstancesAndComputePool", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 824 + }, + { + "name": "StarOnEveryTransport", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 848 + }, + { + "name": "ShortInputIsRejectedNotZeroed", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 884 + }, + { + "name": "ThreePartyDealerRingAndPeer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 906 + }, + { + "name": "SeparateProcessesFromAStaticTable", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 956 + } + ] + }, + { + "name": "Harness", + "tests": 1, + "testsuite": [ + { + "name": "TrialsConfigAndWireRecorded", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 1005 + } + ] + }, + { + "name": "Prep", + "tests": 1, + "testsuite": [ + { + "name": "ShippedOverADealerSession", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/net_control_test.cpp", + "line": 1040 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_9e3f976d4e.json b/test/build-asan/cmake_test_discovery_9e3f976d4e.json new file mode 100644 index 0000000..d57ce58 --- /dev/null +++ b/test/build-asan/cmake_test_discovery_9e3f976d4e.json @@ -0,0 +1,174 @@ +{ + "tests": 24, + "name": "AllTests", + "testsuites": [ + { + "name": "Identity", + "tests": 2, + "testsuite": [ + { + "name": "KeyFileRoundTripAndMode", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 105 + }, + { + "name": "DevelopmentIsFixedAndMarked", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 131 + } + ] + }, + { + "name": "PeerTls", + "tests": 3, + "testsuite": [ + { + "name": "NoKeysEncryptsUnauthenticated", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 187 + }, + { + "name": "KeyAuthenticatesOneDirection", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 203 + }, + { + "name": "WrongKeyNamesBothKeys", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 219 + } + ] + }, + { + "name": "TlsBackends", + "tests": 4, + "testsuite": [ + { + "name": "PlainThroughRelay", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 551 + }, + { + "name": "TlsMuxDirect", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 557 + }, + { + "name": "MuxCiphertextOnTheWire", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 597 + }, + { + "name": "ParallelCiphertextOnTheWire", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 606 + } + ] + }, + { + "name": "ClientTls", + "tests": 4, + "testsuite": [ + { + "name": "DevelopmentCertificateIsTheDefault", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 613 + }, + { + "name": "UnknownServerKeyIsRefusedUntilPinned", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 623 + }, + { + "name": "CaChainAndHostName", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 650 + }, + { + "name": "ServerChecksPinnedClientKeys", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 670 + } + ] + }, + { + "name": "Session", + "tests": 7, + "testsuite": [ + { + "name": "EncryptedByDefaultWithoutKeys", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 751 + }, + { + "name": "KeysAuthenticatePerDirection", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 766 + }, + { + "name": "WrongKeyFailsBothEndsQuickly", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 796 + }, + { + "name": "MixedEncryptionSettingsAreNamed", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 809 + }, + { + "name": "SctpIsRefusedWhileEncrypted", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 818 + }, + { + "name": "LackOfKeysIsLogged", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 839 + }, + { + "name": "DealerKeyAuthenticatesTheDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 861 + } + ] + }, + { + "name": "ClientLink", + "tests": 2, + "testsuite": [ + { + "name": "DevelopmentDefaultWorksAndSaysSo", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 961 + }, + { + "name": "ServerIdentityNeedsAPinOrVerifyOff", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 968 + } + ] + }, + { + "name": "Config", + "tests": 1, + "testsuite": [ + { + "name": "SecurityFromAFileWithRelativePaths", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 988 + } + ] + }, + { + "name": "Deployment", + "tests": 1, + "testsuite": [ + { + "name": "TwoProcessesAuthenticateEachOther", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/security_test.cpp", + "line": 1054 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_9eaf70c959.json b/test/build-asan/cmake_test_discovery_9eaf70c959.json new file mode 100644 index 0000000..a64fd68 --- /dev/null +++ b/test/build-asan/cmake_test_discovery_9eaf70c959.json @@ -0,0 +1,417 @@ +{ + "tests": 81, + "name": "AllTests", + "testsuites": [ + { + "name": "StressScenariosTest", + "tests": 81, + "testsuite": [ + { + "name": "MlEvalFullPrefixSlot", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 274 + }, + { + "name": "MlEvalFullDeepestSlot", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 294 + }, + { + "name": "MlEvalFullOutbufMatchesReturned", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 313 + }, + { + "name": "MlEvalFullCmpSmallDomain", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 330 + }, + { + "name": "MlIntervalWithBasicIntervalMemoizer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 354 + }, + { + "name": "MlSequencePointLoopVsBreadthFirst", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 381 + }, + { + "name": "MlSequenceRecipeDepthAndBreadthFirst", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 410 + }, + { + "name": "MlMixedPointRecon", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 453 + }, + { + "name": "MlMixedIntervalRecon", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 470 + }, + { + "name": "MlMixedSequenceRecon", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 484 + }, + { + "name": "MlMixedInnerProduct", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 509 + }, + { + "name": "MlMixedCmp", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 532 + }, + { + "name": "MlWildcardEvalPointThrowsBeforeAssign", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 548 + }, + { + "name": "MlWildcardOtherSlotsStillWork", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 559 + }, + { + "name": "MlCrossLevelPathMemoizerShallowThenDeep", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 571 + }, + { + "name": "MlIndependentIntervalsTwoSlots", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 594 + }, + { + "name": "ClassicMixedByteIdenticalArgsVsConv", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 616 + }, + { + "name": "ClassicMixedDealerMatchesDoernerShelat", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 631 + }, + { + "name": "ClassicInnerProductMatchesInterval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 671 + }, + { + "name": "ClassicOutPointMatchesIndexedPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 696 + }, + { + "name": "ClassicOutIntervalMatchesIndexedInterval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 715 + }, + { + "name": "ClassicPrepareIntervalThenInnerProduct", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 729 + }, + { + "name": "ClassicPartialMisalignedInterval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 753 + }, + { + "name": "ClassicBasicVsFullTreeIntervalMemoizer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 773 + }, + { + "name": "ClassicMultiLeafFullEvalPerSlot", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 799 + }, + { + "name": "PrgAesInteriorLowmcExteriorClassicPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 818 + }, + { + "name": "PrgLowmcInteriorAesExteriorClassicPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 831 + }, + { + "name": "PrgAesLowmcMultilevelPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 844 + }, + { + "name": "PrgLowmcAesMultilevelPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 857 + }, + { + "name": "PrgDummyAesClassicPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 868 + }, + { + "name": "PrgChachaInteriorAesExteriorClassicPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 881 + }, + { + "name": "PrgAesInteriorChachaExteriorClassicPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 894 + }, + { + "name": "PrgLowmcLowmcMultilevelPacking", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 907 + }, + { + "name": "SignedInputAtAndCmp", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 927 + }, + { + "name": "ModintInputClassicPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 943 + }, + { + "name": "KeywordInputClassicPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 955 + }, + { + "name": "CmpPackedAtDeepestUnderDoernerShelat", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 967 + }, + { + "name": "Packed16xU8PartialIntervalOffAlignment", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1004 + }, + { + "name": "ClassicMultiOutputInterval012", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1039 + }, + { + "name": "MlEvalSweepAroundPointPrefixSlot", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1065 + }, + { + "name": "MlInnerProductExplicitMemoizerMatchesDefault", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1090 + }, + { + "name": "MlCmpInnerProductMatchesInterval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1110 + }, + { + "name": "ClassicOutFullMatchesIndexedFull", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1132 + }, + { + "name": "PrgAesLowmcMultilevelInterval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1144 + }, + { + "name": "ClassicRecipeMemoizerVariantsAgree", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1158 + }, + { + "name": "ClassicRecipeEntireNodeVsOutputOnly", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1194 + }, + { + "name": "ClassicBreadthFirstMatchesPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1231 + }, + { + "name": "ClassicFullInnerProductMatchesFullInterval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1259 + }, + { + "name": "MlXorSlotInnerProduct", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1286 + }, + { + "name": "MlBitstringDeepestOutput", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1313 + }, + { + "name": "MlGeqFullCmpMatchesPointSweep", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1325 + }, + { + "name": "ClassicMultiLeafPathMemoizerReuse", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1341 + }, + { + "name": "DummyInteriorLowmcExteriorMultilevel", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1362 + }, + { + "name": "ClassicMixedFullTreeFullMemoizer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1375 + }, + { + "name": "MlEqAtWithPackedNeighbors", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1407 + }, + { + "name": "ModintMultilevelGenAndPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1433 + }, + { + "name": "ModintMultilevelWithCmp", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1453 + }, + { + "name": "KeywordMultilevelGenAndPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1477 + }, + { + "name": "DsIdentityManyLevelsMixedWidthsXorAdditiveCmpLt", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1503 + }, + { + "name": "DsIdentityPacked16xU8DeepestGeq", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1546 + }, + { + "name": "DsIdentityClassicMultiLeafXorAdditiveBytes", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1583 + }, + { + "name": "DsIdentityIntermediateWildcardConcreteSiblings", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1609 + }, + { + "name": "DsIdentityFixedpointAtWithCmp", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1643 + }, + { + "name": "DsIdentityLocalCwProtocolVsDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1674 + }, + { + "name": "DsIdentityAesInteriorLowmcExteriorMultilevel", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1697 + }, + { + "name": "DsIdentityWildcardCmpThenAssign", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1724 + }, + { + "name": "DsIdentityLocalCwComplexManyLevelsCmp", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1770 + }, + { + "name": "DsIdentityModintMultilevelXorAdditiveCmp", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1800 + }, + { + "name": "DsIdentityKeywordMultilevel", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1835 + }, + { + "name": "MlEvalFullPrefixAndDeepestMultiLane", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1871 + }, + { + "name": "MlEvalFullWithPerSlotMemoizer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1906 + }, + { + "name": "ModintMlEvalFullMatchesPoint", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1944 + }, + { + "name": "MlLtFullCmpMatchesPointSweep", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1966 + }, + { + "name": "ClassicFullTreeMemoizerMultiLeafIndexed", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 1990 + }, + { + "name": "MlPackedSmallWildcardAtNonTerminalAssignAll", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 2026 + }, + { + "name": "MlPackedXorWildcardAtNonTerminalAssignAll", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 2083 + }, + { + "name": "DsIdentityPackedSmallWildcardAtNonTerminal", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 2114 + }, + { + "name": "DsIdentityPackedWildcardLowmcExteriorThenAssign", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 2200 + }, + { + "name": "PrgCounterWrapperAesClassicEvalIncrements", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 2242 + }, + { + "name": "PrgCounterWrapperLowmcMultilevelEvalIncrements", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 2260 + }, + { + "name": "PrgLowmcBothSidesPackedInterval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/stress_scenarios_test.cpp", + "line": 2285 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_d094ac409e.json b/test/build-asan/cmake_test_discovery_d094ac409e.json new file mode 100644 index 0000000..3da697b --- /dev/null +++ b/test/build-asan/cmake_test_discovery_d094ac409e.json @@ -0,0 +1,62 @@ +{ + "tests": 10, + "name": "AllTests", + "testsuites": [ + { + "name": "HalfTree", + "tests": 10, + "testsuite": [ + { + "name": "TraitsSelectedByCcrPrg", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/half_tree_test.cpp", + "line": 66 + }, + { + "name": "DealerPointAndFullDomain", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/half_tree_test.cpp", + "line": 74 + }, + { + "name": "OutputParityVsBgi", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/half_tree_test.cpp", + "line": 107 + }, + { + "name": "DoernerShelatXorMatchesDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/half_tree_test.cpp", + "line": 130 + }, + { + "name": "DoernerShelatArithMatchesDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/half_tree_test.cpp", + "line": 173 + }, + { + "name": "GenevalPointMatchesDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/half_tree_test.cpp", + "line": 204 + }, + { + "name": "GenevalArithPointMatchesDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/half_tree_test.cpp", + "line": 240 + }, + { + "name": "IncrementalCmpSmoke", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/half_tree_test.cpp", + "line": 267 + }, + { + "name": "IncrementalPlacementSmoke", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/half_tree_test.cpp", + "line": 304 + }, + { + "name": "VerifiableFullDomainDetectsSeedTamper", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/half_tree_test.cpp", + "line": 324 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_dfd1ea74e1.json b/test/build-asan/cmake_test_discovery_dfd1ea74e1.json new file mode 100644 index 0000000..99ee637 --- /dev/null +++ b/test/build-asan/cmake_test_discovery_dfd1ea74e1.json @@ -0,0 +1,82 @@ +{ + "tests": 14, + "name": "AllTests", + "testsuites": [ + { + "name": "Ic", + "tests": 14, + "testsuite": [ + { + "name": "Uint8FullDomainCorners", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 79 + }, + { + "name": "Uint8AllMasksOneInterval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 102 + }, + { + "name": "MemoizerAgrees", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 112 + }, + { + "name": "IntervalAndSequenceBuffers", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 128 + }, + { + "name": "WildcardAssign", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 159 + }, + { + "name": "DoernerShelatMatchesDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 179 + }, + { + "name": "Geneval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 213 + }, + { + "name": "RejectsWrappedBounds", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 240 + }, + { + "name": "BitPayload", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 246 + }, + { + "name": "Uint16FullDomain", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 260 + }, + { + "name": "WideMasksSampleTheWrap", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 268 + }, + { + "name": "AdditiveDoernerShelatMatchesDealer", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 287 + }, + { + "name": "AdditiveGeneval", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 314 + }, + { + "name": "IntervalRejectsDescendingEndpoints", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ic_test.cpp", + "line": 339 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_e1b8b61235.json b/test/build-asan/cmake_test_discovery_e1b8b61235.json new file mode 100644 index 0000000..ae0309b --- /dev/null +++ b/test/build-asan/cmake_test_discovery_e1b8b61235.json @@ -0,0 +1,93 @@ +{ + "tests": 15, + "name": "AllTests", + "testsuites": [ + { + "name": "Ppvc", + "tests": 11, + "testsuite": [ + { + "name": "ProgramsEveryCoordinate", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 117 + }, + { + "name": "ProgramsEverySum", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 130 + }, + { + "name": "FreshCommitOpens", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 143 + }, + { + "name": "PrescribedIndexAndWrappingShift", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 156 + }, + { + "name": "SeedExpansionIsDeterministic", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 179 + }, + { + "name": "RejectsATamperedOpening", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 207 + }, + { + "name": "RejectsAMalformedReplica", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 247 + }, + { + "name": "RejectsAnOutOfRangeProgram", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 278 + }, + { + "name": "DeeperDomain", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 290 + }, + { + "name": "FullWidthValue", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 310 + }, + { + "name": "DefaultSigmaUsesWholeBlocks", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 330 + } + ] + }, + { + "name": "KPpvc", + "tests": 4, + "testsuite": [ + { + "name": "OneCopyMatchesTheSingleScheme", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 344 + }, + { + "name": "ReprogramsOneCoordinateOfTheSum", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 357 + }, + { + "name": "SumModeAndFreshCommit", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 402 + }, + { + "name": "RejectsASharedHiddenIndex", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/ppvc_test.cpp", + "line": 423 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_eebc0ee281.json b/test/build-asan/cmake_test_discovery_eebc0ee281.json new file mode 100644 index 0000000..9042ef7 --- /dev/null +++ b/test/build-asan/cmake_test_discovery_eebc0ee281.json @@ -0,0 +1,47 @@ +{ + "tests": 7, + "name": "AllTests", + "testsuites": [ + { + "name": "SignedPrefix", + "tests": 7, + "testsuite": [ + { + "name": "MatchesComparisonEvalOnEveryUint8Point", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/signed_prefix_test.cpp", + "line": 33 + }, + { + "name": "SegmentsAreOneHot", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/signed_prefix_test.cpp", + "line": 51 + }, + { + "name": "WholeDomainIsThePublicOne", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/signed_prefix_test.cpp", + "line": 81 + }, + { + "name": "SignumLutIsSignCorrect", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/signed_prefix_test.cpp", + "line": 90 + }, + { + "name": "SharedPrefixAgreesWithAFreshWalk", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/signed_prefix_test.cpp", + "line": 121 + }, + { + "name": "RejectsAKeyWithoutAComparison", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/signed_prefix_test.cpp", + "line": 138 + }, + { + "name": "SegmentsRecoverIlogbInt8", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/signed_prefix_test.cpp", + "line": 180 + } + ] + } + ] +} diff --git a/test/build-asan/cmake_test_discovery_f56da67757.json b/test/build-asan/cmake_test_discovery_f56da67757.json new file mode 100644 index 0000000..230f742 --- /dev/null +++ b/test/build-asan/cmake_test_discovery_f56da67757.json @@ -0,0 +1,87 @@ +{ + "tests": 15, + "name": "AllTests", + "testsuites": [ + { + "name": "BlockedDcf", + "tests": 15, + "testsuite": [ + { + "name": "ExhaustiveUint8AllWidths", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 91 + }, + { + "name": "KindsIfFalseAndPayloadWidths", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 104 + }, + { + "name": "Block1MatchesFunctionNotBytes", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 115 + }, + { + "name": "DeeperOutputForcesFullTree", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 132 + }, + { + "name": "ShallowerLeafKeepsTail", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 151 + }, + { + "name": "PointIntervalFullSequenceInnerProduct", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 164 + }, + { + "name": "DealerMatchesDoernerShelat", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 232 + }, + { + "name": "WildcardAssignMatchesConcrete", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 268 + }, + { + "name": "TrivialDomainEdges", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 295 + }, + { + "name": "JsonRoundTrip", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 310 + }, + { + "name": "GenevalOpensCheckpointWords", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 337 + }, + { + "name": "UnevenScheduleMatchesDenseComparison", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 360 + }, + { + "name": "WideCheckpointFrontierMatchesDense", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 390 + }, + { + "name": "PathRecipesStayOnThePerLevelChannel", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 422 + }, + { + "name": "GrottoPrefixSegmentAndHorner", + "file": "\/home\/cryptolicious\/hushmap-specified\/libdpf\/test\/tests\/blocked_dcf_test.cpp", + "line": 439 + } + ] + } + ] +} diff --git a/test/build-asan/cohort_test[1]_include.cmake b/test/build-asan/cohort_test[1]_include.cmake new file mode 100644 index 0000000..8d19a53 --- /dev/null +++ b/test/build-asan/cohort_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/cohort_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/cohort_test[1]_tests.cmake") +else() + add_test(cohort_test_NOT_BUILT cohort_test_NOT_BUILT) +endif() diff --git a/test/build-asan/compose_test[1]_include.cmake b/test/build-asan/compose_test[1]_include.cmake new file mode 100644 index 0000000..0b050bb --- /dev/null +++ b/test/build-asan/compose_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/compose_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/compose_test[1]_tests.cmake") +else() + add_test(compose_test_NOT_BUILT compose_test_NOT_BUILT) +endif() diff --git a/test/build-asan/constant_lut_test[1]_include.cmake b/test/build-asan/constant_lut_test[1]_include.cmake new file mode 100644 index 0000000..df98ec5 --- /dev/null +++ b/test/build-asan/constant_lut_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/constant_lut_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/constant_lut_test[1]_tests.cmake") +else() + add_test(constant_lut_test_NOT_BUILT constant_lut_test_NOT_BUILT) +endif() diff --git a/test/build-asan/constrained_cmp_test[1]_include.cmake b/test/build-asan/constrained_cmp_test[1]_include.cmake new file mode 100644 index 0000000..7197964 --- /dev/null +++ b/test/build-asan/constrained_cmp_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/constrained_cmp_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/constrained_cmp_test[1]_tests.cmake") +else() + add_test(constrained_cmp_test_NOT_BUILT constrained_cmp_test_NOT_BUILT) +endif() diff --git a/test/build-asan/context_blast_test[1]_include.cmake b/test/build-asan/context_blast_test[1]_include.cmake new file mode 100644 index 0000000..dd0b55c --- /dev/null +++ b/test/build-asan/context_blast_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/context_blast_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/context_blast_test[1]_tests.cmake") +else() + add_test(context_blast_test_NOT_BUILT context_blast_test_NOT_BUILT) +endif() diff --git a/test/build-asan/corner_gaps_test[1]_include.cmake b/test/build-asan/corner_gaps_test[1]_include.cmake new file mode 100644 index 0000000..a4beff3 --- /dev/null +++ b/test/build-asan/corner_gaps_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/corner_gaps_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/corner_gaps_test[1]_tests.cmake") +else() + add_test(corner_gaps_test_NOT_BUILT corner_gaps_test_NOT_BUILT) +endif() diff --git a/test/build-asan/defer_eval_test[1]_include.cmake b/test/build-asan/defer_eval_test[1]_include.cmake new file mode 100644 index 0000000..7c48f0e --- /dev/null +++ b/test/build-asan/defer_eval_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/defer_eval_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/defer_eval_test[1]_tests.cmake") +else() + add_test(defer_eval_test_NOT_BUILT defer_eval_test_NOT_BUILT) +endif() diff --git a/test/build-asan/domain128_point_test[1]_include.cmake b/test/build-asan/domain128_point_test[1]_include.cmake new file mode 100644 index 0000000..dde7b01 --- /dev/null +++ b/test/build-asan/domain128_point_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/domain128_point_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/domain128_point_test[1]_tests.cmake") +else() + add_test(domain128_point_test_NOT_BUILT domain128_point_test_NOT_BUILT) +endif() diff --git a/test/build-asan/dpf3_test[1]_include.cmake b/test/build-asan/dpf3_test[1]_include.cmake new file mode 100644 index 0000000..e68983f --- /dev/null +++ b/test/build-asan/dpf3_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dpf3_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dpf3_test[1]_tests.cmake") +else() + add_test(dpf3_test_NOT_BUILT dpf3_test_NOT_BUILT) +endif() diff --git a/test/build-asan/dpf_key_test[1]_include.cmake b/test/build-asan/dpf_key_test[1]_include.cmake new file mode 100644 index 0000000..4ab946c --- /dev/null +++ b/test/build-asan/dpf_key_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dpf_key_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dpf_key_test[1]_tests.cmake") +else() + add_test(dpf_key_test_NOT_BUILT dpf_key_test_NOT_BUILT) +endif() diff --git a/test/build-asan/dwt_lut_test[1]_include.cmake b/test/build-asan/dwt_lut_test[1]_include.cmake new file mode 100644 index 0000000..e315d00 --- /dev/null +++ b/test/build-asan/dwt_lut_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dwt_lut_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dwt_lut_test[1]_tests.cmake") +else() + add_test(dwt_lut_test_NOT_BUILT dwt_lut_test_NOT_BUILT) +endif() diff --git a/test/build-asan/dyadic_lut_test[1]_include.cmake b/test/build-asan/dyadic_lut_test[1]_include.cmake new file mode 100644 index 0000000..d697889 --- /dev/null +++ b/test/build-asan/dyadic_lut_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dyadic_lut_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/dyadic_lut_test[1]_tests.cmake") +else() + add_test(dyadic_lut_test_NOT_BUILT dyadic_lut_test_NOT_BUILT) +endif() diff --git a/test/build-asan/easy_lut_test[1]_include.cmake b/test/build-asan/easy_lut_test[1]_include.cmake new file mode 100644 index 0000000..ca987e1 --- /dev/null +++ b/test/build-asan/easy_lut_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/easy_lut_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/easy_lut_test[1]_tests.cmake") +else() + add_test(easy_lut_test_NOT_BUILT easy_lut_test_NOT_BUILT) +endif() diff --git a/test/build-asan/eval_full_multi_test[1]_include.cmake b/test/build-asan/eval_full_multi_test[1]_include.cmake new file mode 100644 index 0000000..06cd44e --- /dev/null +++ b/test/build-asan/eval_full_multi_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_full_multi_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_full_multi_test[1]_tests.cmake") +else() + add_test(eval_full_multi_test_NOT_BUILT eval_full_multi_test_NOT_BUILT) +endif() diff --git a/test/build-asan/eval_full_test[1]_include.cmake b/test/build-asan/eval_full_test[1]_include.cmake new file mode 100644 index 0000000..838f42c --- /dev/null +++ b/test/build-asan/eval_full_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_full_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_full_test[1]_tests.cmake") +else() + add_test(eval_full_test_NOT_BUILT eval_full_test_NOT_BUILT) +endif() diff --git a/test/build-asan/eval_inner_product_test[1]_include.cmake b/test/build-asan/eval_inner_product_test[1]_include.cmake new file mode 100644 index 0000000..5a60f1a --- /dev/null +++ b/test/build-asan/eval_inner_product_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_inner_product_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_inner_product_test[1]_tests.cmake") +else() + add_test(eval_inner_product_test_NOT_BUILT eval_inner_product_test_NOT_BUILT) +endif() diff --git a/test/build-asan/eval_interval_multi_test[1]_include.cmake b/test/build-asan/eval_interval_multi_test[1]_include.cmake new file mode 100644 index 0000000..7e3d7f7 --- /dev/null +++ b/test/build-asan/eval_interval_multi_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_interval_multi_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_interval_multi_test[1]_tests.cmake") +else() + add_test(eval_interval_multi_test_NOT_BUILT eval_interval_multi_test_NOT_BUILT) +endif() diff --git a/test/build-asan/eval_interval_test[1]_include.cmake b/test/build-asan/eval_interval_test[1]_include.cmake new file mode 100644 index 0000000..6168bfd --- /dev/null +++ b/test/build-asan/eval_interval_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_interval_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_interval_test[1]_tests.cmake") +else() + add_test(eval_interval_test_NOT_BUILT eval_interval_test_NOT_BUILT) +endif() diff --git a/test/build-asan/eval_point_multi_test[1]_include.cmake b/test/build-asan/eval_point_multi_test[1]_include.cmake new file mode 100644 index 0000000..9e7cd77 --- /dev/null +++ b/test/build-asan/eval_point_multi_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_point_multi_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_point_multi_test[1]_tests.cmake") +else() + add_test(eval_point_multi_test_NOT_BUILT eval_point_multi_test_NOT_BUILT) +endif() diff --git a/test/build-asan/eval_point_test[1]_include.cmake b/test/build-asan/eval_point_test[1]_include.cmake new file mode 100644 index 0000000..fa5d5ec --- /dev/null +++ b/test/build-asan/eval_point_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_point_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_point_test[1]_tests.cmake") +else() + add_test(eval_point_test_NOT_BUILT eval_point_test_NOT_BUILT) +endif() diff --git a/test/build-asan/eval_sequence_multi_test[1]_include.cmake b/test/build-asan/eval_sequence_multi_test[1]_include.cmake new file mode 100644 index 0000000..7f89ef4 --- /dev/null +++ b/test/build-asan/eval_sequence_multi_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_sequence_multi_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_sequence_multi_test[1]_tests.cmake") +else() + add_test(eval_sequence_multi_test_NOT_BUILT eval_sequence_multi_test_NOT_BUILT) +endif() diff --git a/test/build-asan/eval_sequence_test[1]_include.cmake b/test/build-asan/eval_sequence_test[1]_include.cmake new file mode 100644 index 0000000..fb5a4df --- /dev/null +++ b/test/build-asan/eval_sequence_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_sequence_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_sequence_test[1]_tests.cmake") +else() + add_test(eval_sequence_test_NOT_BUILT eval_sequence_test_NOT_BUILT) +endif() diff --git a/test/build-asan/eval_until_test[1]_include.cmake b/test/build-asan/eval_until_test[1]_include.cmake new file mode 100644 index 0000000..a1738a1 --- /dev/null +++ b/test/build-asan/eval_until_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_until_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/eval_until_test[1]_tests.cmake") +else() + add_test(eval_until_test_NOT_BUILT eval_until_test_NOT_BUILT) +endif() diff --git a/test/build-asan/exact_steps_test[1]_include.cmake b/test/build-asan/exact_steps_test[1]_include.cmake new file mode 100644 index 0000000..35402b6 --- /dev/null +++ b/test/build-asan/exact_steps_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/exact_steps_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/exact_steps_test[1]_tests.cmake") +else() + add_test(exact_steps_test_NOT_BUILT exact_steps_test_NOT_BUILT) +endif() diff --git a/test/build-asan/experiment_test[1]_include.cmake b/test/build-asan/experiment_test[1]_include.cmake new file mode 100644 index 0000000..5ae4040 --- /dev/null +++ b/test/build-asan/experiment_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/experiment_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/experiment_test[1]_tests.cmake") +else() + add_test(experiment_test_NOT_BUILT experiment_test_NOT_BUILT) +endif() diff --git a/test/build-asan/extractable_full_test[1]_include.cmake b/test/build-asan/extractable_full_test[1]_include.cmake new file mode 100644 index 0000000..9a638e9 --- /dev/null +++ b/test/build-asan/extractable_full_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/extractable_full_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/extractable_full_test[1]_tests.cmake") +else() + add_test(extractable_full_test_NOT_BUILT extractable_full_test_NOT_BUILT) +endif() diff --git a/test/build-asan/field_output_test[1]_include.cmake b/test/build-asan/field_output_test[1]_include.cmake new file mode 100644 index 0000000..6ffbaca --- /dev/null +++ b/test/build-asan/field_output_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/field_output_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/field_output_test[1]_tests.cmake") +else() + add_test(field_output_test_NOT_BUILT field_output_test_NOT_BUILT) +endif() diff --git a/test/build-asan/fixedpoint_beaver_test[1]_include.cmake b/test/build-asan/fixedpoint_beaver_test[1]_include.cmake new file mode 100644 index 0000000..6362db1 --- /dev/null +++ b/test/build-asan/fixedpoint_beaver_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/fixedpoint_beaver_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/fixedpoint_beaver_test[1]_tests.cmake") +else() + add_test(fixedpoint_beaver_test_NOT_BUILT fixedpoint_beaver_test_NOT_BUILT) +endif() diff --git a/test/build-asan/flute_test[1]_include.cmake b/test/build-asan/flute_test[1]_include.cmake new file mode 100644 index 0000000..fc66973 --- /dev/null +++ b/test/build-asan/flute_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/flute_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/flute_test[1]_tests.cmake") +else() + add_test(flute_test_NOT_BUILT flute_test_NOT_BUILT) +endif() diff --git a/test/build-asan/fp61_test[1]_include.cmake b/test/build-asan/fp61_test[1]_include.cmake new file mode 100644 index 0000000..e6d79ce --- /dev/null +++ b/test/build-asan/fp61_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/fp61_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/fp61_test[1]_tests.cmake") +else() + add_test(fp61_test_NOT_BUILT fp61_test_NOT_BUILT) +endif() diff --git a/test/build-asan/geneval_test[1]_include.cmake b/test/build-asan/geneval_test[1]_include.cmake new file mode 100644 index 0000000..ca79f6a --- /dev/null +++ b/test/build-asan/geneval_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/geneval_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/geneval_test[1]_tests.cmake") +else() + add_test(geneval_test_NOT_BUILT geneval_test_NOT_BUILT) +endif() diff --git a/test/build-asan/geneval_test[1]_tests.cmake b/test/build-asan/geneval_test[1]_tests.cmake new file mode 100644 index 0000000..20757fd --- /dev/null +++ b/test/build-asan/geneval_test[1]_tests.cmake @@ -0,0 +1,71 @@ +add_test([=[Geneval.PointOnTargetMatchesKeyAndEval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.PointOnTargetMatchesKeyAndEval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.PointOnTargetMatchesKeyAndEval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:121 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.PointDivergesAfterSharedPrefix]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.PointDivergesAfterSharedPrefix]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.PointDivergesAfterSharedPrefix]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:151 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.SameLeafDifferentLane]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.SameLeafDifferentLane]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.SameLeafDifferentLane]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:182 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.IntervalContainsTarget]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.IntervalContainsTarget]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.IntervalContainsTarget]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:212 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.IntervalMissesAfterSharedPrefix]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.IntervalMissesAfterSharedPrefix]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.IntervalMissesAfterSharedPrefix]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:249 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.SequenceOrderAndSharedTrie]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.SequenceOrderAndSharedTrie]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.SequenceOrderAndSharedTrie]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:279 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.FullDomainUint8]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.FullDomainUint8]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.FullDomainUint8]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:322 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.EmptySequence]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.EmptySequence]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.EmptySequence]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:358 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.ArithPointMatchesDealerAtQuery]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.ArithPointMatchesDealerAtQuery]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.ArithPointMatchesDealerAtQuery]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:372 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.ArithPointOnSecretIsFullKey]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.ArithPointOnSecretIsFullKey]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.ArithPointOnSecretIsFullKey]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:401 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.ArithIntervalAndSequence]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.ArithIntervalAndSequence]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.ArithIntervalAndSequence]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:427 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.ArithFullMatchesDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.ArithFullMatchesDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.ArithFullMatchesDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:477 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.DoernerShelatKeyAgreesOnLivePrefix]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.DoernerShelatKeyAgreesOnLivePrefix]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.DoernerShelatKeyAgreesOnLivePrefix]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:507 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.EdgesZeroMaxAndSinglePointShapesAgree]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.EdgesZeroMaxAndSinglePointShapesAgree]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.EdgesZeroMaxAndSinglePointShapesAgree]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:574 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.XorSplitAndPadStreamDoNotChangeLiveWords]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.XorSplitAndPadStreamDoNotChangeLiveWords]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.XorSplitAndPadStreamDoNotChangeLiveWords]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:624 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.IntervalLiveFollowsLongestPrefixNotTheFirstPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.IntervalLiveFollowsLongestPrefixNotTheFirstPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.IntervalLiveFollowsLongestPrefixNotTheFirstPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:661 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.PartialLeafExcludesTargetButKeepsItsWord]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.PartialLeafExcludesTargetButKeepsItsWord]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.PartialLeafExcludesTargetButKeepsItsWord]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:702 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.DepthOneBitOutput]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.DepthOneBitOutput]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.DepthOneBitOutput]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:735 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.FullMatchesWholeIntervalAndRejectsHugeDomain]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.FullMatchesWholeIntervalAndRejectsHugeDomain]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.FullMatchesWholeIntervalAndRejectsHugeDomain]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:776 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.SequencePermutationKeepsWordsAndDuplicates]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.SequencePermutationKeepsWordsAndDuplicates]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.SequencePermutationKeepsWordsAndDuplicates]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:809 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.SignedPointIntervalAndCrossZero]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.SignedPointIntervalAndCrossZero]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.SignedPointIntervalAndCrossZero]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:840 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.SignedFullAndArithFull]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.SignedFullAndArithFull]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.SignedFullAndArithFull]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:907 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.ArithShareOverflowAndWrappingInterval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.ArithShareOverflowAndWrappingInterval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.ArithShareOverflowAndWrappingInterval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:953 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.XorWrapperOutput]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.XorWrapperOutput]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.XorWrapperOutput]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:1007 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.SignedRegressionsFromTheCornerPass]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.SignedRegressionsFromTheCornerPass]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.SignedRegressionsFromTheCornerPass]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:1040 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.CmpEmptyRangeOpensNothing]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.CmpEmptyRangeOpensNothing]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.CmpEmptyRangeOpensNothing]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:1094 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.CmpMatchesDoernerShelatKeyAndGtPredicate]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.CmpMatchesDoernerShelatKeyAndGtPredicate]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.CmpMatchesDoernerShelatKeyAndGtPredicate]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:1106 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.CmpSignedPayloadAndDomainMax]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.CmpSignedPayloadAndDomainMax]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.CmpSignedPayloadAndDomainMax]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:1148 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.CmpLtIsTheComplementOfTheStrictUpperSet]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.CmpLtIsTheComplementOfTheStrictUpperSet]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.CmpLtIsTheComplementOfTheStrictUpperSet]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:1179 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.DoernerShelatOnTargetSharesMatch]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.DoernerShelatOnTargetSharesMatch]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.DoernerShelatOnTargetSharesMatch]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:1196 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.WideLiveFrontierMatchesDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.WideLiveFrontierMatchesDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.WideLiveFrontierMatchesDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:1224 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.CmpLeqGeqNonzeroElseAndDomainMin]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.CmpLeqGeqNonzeroElseAndDomainMin]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.CmpLeqGeqNonzeroElseAndDomainMin]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:1258 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.ArithSignedMsbAndCarryAcrossPowerOfTwo]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.ArithSignedMsbAndCarryAcrossPowerOfTwo]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.ArithSignedMsbAndCarryAcrossPowerOfTwo]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:1321 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.ArithDoernerShelatAndCmpMatchDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.ArithDoernerShelatAndCmpMatchDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.ArithDoernerShelatAndCmpMatchDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:1373 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Geneval.ArithCarryLeavesXorShares]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/geneval_test [==[--gtest_filter=Geneval.ArithCarryLeavesXorShares]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Geneval.ArithCarryLeavesXorShares]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/geneval_test.cpp:1410 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( geneval_test_TESTS Geneval.PointOnTargetMatchesKeyAndEval Geneval.PointDivergesAfterSharedPrefix Geneval.SameLeafDifferentLane Geneval.IntervalContainsTarget Geneval.IntervalMissesAfterSharedPrefix Geneval.SequenceOrderAndSharedTrie Geneval.FullDomainUint8 Geneval.EmptySequence Geneval.ArithPointMatchesDealerAtQuery Geneval.ArithPointOnSecretIsFullKey Geneval.ArithIntervalAndSequence Geneval.ArithFullMatchesDealer Geneval.DoernerShelatKeyAgreesOnLivePrefix Geneval.EdgesZeroMaxAndSinglePointShapesAgree Geneval.XorSplitAndPadStreamDoNotChangeLiveWords Geneval.IntervalLiveFollowsLongestPrefixNotTheFirstPoint Geneval.PartialLeafExcludesTargetButKeepsItsWord Geneval.DepthOneBitOutput Geneval.FullMatchesWholeIntervalAndRejectsHugeDomain Geneval.SequencePermutationKeepsWordsAndDuplicates Geneval.SignedPointIntervalAndCrossZero Geneval.SignedFullAndArithFull Geneval.ArithShareOverflowAndWrappingInterval Geneval.XorWrapperOutput Geneval.SignedRegressionsFromTheCornerPass Geneval.CmpEmptyRangeOpensNothing Geneval.CmpMatchesDoernerShelatKeyAndGtPredicate Geneval.CmpSignedPayloadAndDomainMax Geneval.CmpLtIsTheComplementOfTheStrictUpperSet Geneval.DoernerShelatOnTargetSharesMatch Geneval.WideLiveFrontierMatchesDealer Geneval.CmpLeqGeqNonzeroElseAndDomainMin Geneval.ArithSignedMsbAndCarryAcrossPowerOfTwo Geneval.ArithDoernerShelatAndCmpMatchDealer Geneval.ArithCarryLeavesXorShares) diff --git a/test/build-asan/gf2_adversarial_test[1]_include.cmake b/test/build-asan/gf2_adversarial_test[1]_include.cmake new file mode 100644 index 0000000..f7c10ff --- /dev/null +++ b/test/build-asan/gf2_adversarial_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/gf2_adversarial_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/gf2_adversarial_test[1]_tests.cmake") +else() + add_test(gf2_adversarial_test_NOT_BUILT gf2_adversarial_test_NOT_BUILT) +endif() diff --git a/test/build-asan/gf2_test[1]_include.cmake b/test/build-asan/gf2_test[1]_include.cmake new file mode 100644 index 0000000..5356cae --- /dev/null +++ b/test/build-asan/gf2_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/gf2_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/gf2_test[1]_tests.cmake") +else() + add_test(gf2_test_NOT_BUILT gf2_test_NOT_BUILT) +endif() diff --git a/test/build-asan/googletest/CMakeFiles/CMakeDirectoryInformation.cmake b/test/build-asan/googletest/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..f27a407 --- /dev/null +++ b/test/build-asan/googletest/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,16 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Relative path conversion top directories. +set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/cryptolicious/hushmap-specified/libdpf/test") +set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan") + +# Force unix paths in dependencies. +set(CMAKE_FORCE_UNIX_PATHS 1) + + +# The C and CXX include file regular expressions for this directory. +set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/test/build-asan/googletest/CMakeFiles/progress.marks b/test/build-asan/googletest/CMakeFiles/progress.marks new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/test/build-asan/googletest/CMakeFiles/progress.marks @@ -0,0 +1 @@ +2 diff --git a/test/build-asan/googletest/CTestTestfile.cmake b/test/build-asan/googletest/CTestTestfile.cmake new file mode 100644 index 0000000..2168823 --- /dev/null +++ b/test/build-asan/googletest/CTestTestfile.cmake @@ -0,0 +1,7 @@ +# CMake generated Testfile for +# Source directory: /home/cryptolicious/hushmap-specified/libdpf/test/googletest +# Build directory: /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest +# +# This file includes the relevant testing commands required for +# testing this directory and lists subdirectories to be tested as well. +subdirs("googletest") diff --git a/test/build-asan/googletest/Makefile b/test/build-asan/googletest/Makefile new file mode 100644 index 0000000..704a548 --- /dev/null +++ b/test/build-asan/googletest/Makefile @@ -0,0 +1,151 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +# Allow only one "make -f Makefile2" at a time, but pass parallelism. +.NOTPARALLEL: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target test +test: + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running tests..." + /usr/bin/ctest $(ARGS) +.PHONY : test + +# Special rule for the target test +test/fast: test +.PHONY : test/fast + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "No interactive CMake dialog available..." + /usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available. +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# The main all target +all: cmake_check_build_system + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest//CMakeFiles/progress.marks + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 googletest/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 googletest/clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 googletest/preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 googletest/preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... rebuild_cache" + @echo "... test" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/test/build-asan/googletest/cmake_install.cmake b/test/build-asan/googletest/cmake_install.cmake new file mode 100644 index 0000000..7f48b9c --- /dev/null +++ b/test/build-asan/googletest/cmake_install.cmake @@ -0,0 +1,55 @@ +# Install script for directory: /home/cryptolicious/hushmap-specified/libdpf/test/googletest + +# Set the install prefix +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "/usr/local") +endif() +string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + if(BUILD_TYPE) + string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + else() + set(CMAKE_INSTALL_CONFIG_NAME "Debug") + endif() + message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +endif() + +# Set the component getting installed. +if(NOT CMAKE_INSTALL_COMPONENT) + if(COMPONENT) + message(STATUS "Install component: \"${COMPONENT}\"") + set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + else() + set(CMAKE_INSTALL_COMPONENT) + endif() +endif() + +# Install shared libraries without execute permission? +if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + set(CMAKE_INSTALL_SO_NO_EXE "1") +endif() + +# Is this installation the result of a crosscompile? +if(NOT DEFINED CMAKE_CROSSCOMPILING) + set(CMAKE_CROSSCOMPILING "FALSE") +endif() + +# Set path to fallback-tool for dependency-resolution. +if(NOT DEFINED CMAKE_OBJDUMP) + set(CMAKE_OBJDUMP "/usr/bin/objdump") +endif() + +if(NOT CMAKE_INSTALL_LOCAL_ONLY) + # Include the install script for the subdirectory. + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest/cmake_install.cmake") +endif() + +string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT + "${CMAKE_INSTALL_MANIFEST_FILES}") +if(CMAKE_INSTALL_LOCAL_ONLY) + file(WRITE "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/install_local_manifest.txt" + "${CMAKE_INSTALL_MANIFEST_CONTENT}") +endif() diff --git a/test/build-asan/googletest/googletest/CMakeFiles/CMakeDirectoryInformation.cmake b/test/build-asan/googletest/googletest/CMakeFiles/CMakeDirectoryInformation.cmake new file mode 100644 index 0000000..f27a407 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/CMakeDirectoryInformation.cmake @@ -0,0 +1,16 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Relative path conversion top directories. +set(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/cryptolicious/hushmap-specified/libdpf/test") +set(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan") + +# Force unix paths in dependencies. +set(CMAKE_FORCE_UNIX_PATHS 1) + + +# The C and CXX include file regular expressions for this directory. +set(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") +set(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") +set(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) +set(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/DependInfo.cmake b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/DependInfo.cmake new file mode 100644 index 0000000..b737b6f --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/DependInfo.cmake @@ -0,0 +1,23 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-all.cc" "googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o" "gcc" "googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/build.make b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/build.make new file mode 100644 index 0000000..7de2cb4 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/build.make @@ -0,0 +1,114 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include googletest/googletest/CMakeFiles/gtest.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include googletest/googletest/CMakeFiles/gtest.dir/compiler_depend.make + +# Include the progress variables for this target. +include googletest/googletest/CMakeFiles/gtest.dir/progress.make + +# Include the compile flags for this target's objects. +include googletest/googletest/CMakeFiles/gtest.dir/flags.make + +googletest/googletest/CMakeFiles/gtest.dir/codegen: +.PHONY : googletest/googletest/CMakeFiles/gtest.dir/codegen + +googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o: googletest/googletest/CMakeFiles/gtest.dir/flags.make +googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o: /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-all.cc +googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o: googletest/googletest/CMakeFiles/gtest.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o" + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o -MF CMakeFiles/gtest.dir/src/gtest-all.cc.o.d -o CMakeFiles/gtest.dir/src/gtest-all.cc.o -c /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-all.cc + +googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/gtest.dir/src/gtest-all.cc.i" + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-all.cc > CMakeFiles/gtest.dir/src/gtest-all.cc.i + +googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/gtest.dir/src/gtest-all.cc.s" + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-all.cc -o CMakeFiles/gtest.dir/src/gtest-all.cc.s + +# Object files for target gtest +gtest_OBJECTS = \ +"CMakeFiles/gtest.dir/src/gtest-all.cc.o" + +# External object files for target gtest +gtest_EXTERNAL_OBJECTS = + +lib/libgtest.a: googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o +lib/libgtest.a: googletest/googletest/CMakeFiles/gtest.dir/build.make +lib/libgtest.a: googletest/googletest/CMakeFiles/gtest.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX static library ../../lib/libgtest.a" + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest && $(CMAKE_COMMAND) -P CMakeFiles/gtest.dir/cmake_clean_target.cmake + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/gtest.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +googletest/googletest/CMakeFiles/gtest.dir/build: lib/libgtest.a +.PHONY : googletest/googletest/CMakeFiles/gtest.dir/build + +googletest/googletest/CMakeFiles/gtest.dir/clean: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest && $(CMAKE_COMMAND) -P CMakeFiles/gtest.dir/cmake_clean.cmake +.PHONY : googletest/googletest/CMakeFiles/gtest.dir/clean + +googletest/googletest/CMakeFiles/gtest.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/DependInfo.cmake "--color=$(COLOR)" gtest +.PHONY : googletest/googletest/CMakeFiles/gtest.dir/depend + diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/cmake_clean.cmake b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/cmake_clean.cmake new file mode 100644 index 0000000..13ecc9e --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/cmake_clean.cmake @@ -0,0 +1,11 @@ +file(REMOVE_RECURSE + "../../bin/libgtestpdb_debug_postfix-NOTFOUND.pdb" + "../../lib/libgtest.a" + "CMakeFiles/gtest.dir/src/gtest-all.cc.o" + "CMakeFiles/gtest.dir/src/gtest-all.cc.o.d" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/gtest.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/cmake_clean_target.cmake b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/cmake_clean_target.cmake new file mode 100644 index 0000000..4532893 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/cmake_clean_target.cmake @@ -0,0 +1,3 @@ +file(REMOVE_RECURSE + "../../lib/libgtest.a" +) diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/compiler_depend.internal b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/compiler_depend.internal new file mode 100644 index 0000000..cf2c515 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/compiler_depend.internal @@ -0,0 +1,463 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-all.cc + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-assertion-result.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-death-test.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-matchers.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-message.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-param-test.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-printers.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-spi.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-test-part.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-typed-test.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_pred_impl.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_prod.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-port.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-printers.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-filepath.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-internal.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-param-util.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port-arch.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-string.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-type-util.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-assertion-result.cc + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-death-test.cc + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-filepath.cc + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-internal-inl.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-matchers.cc + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-port.cc + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-printers.cc + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-test-part.cc + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-typed-test.cc + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest.cc + /usr/include/alloca.h + /usr/include/arpa/inet.h + /usr/include/asm-generic/bitsperlong.h + /usr/include/asm-generic/errno-base.h + /usr/include/asm-generic/errno.h + /usr/include/asm-generic/int-ll64.h + /usr/include/asm-generic/posix_types.h + /usr/include/asm-generic/socket.h + /usr/include/asm-generic/sockios.h + /usr/include/asm-generic/types.h + /usr/include/assert.h + /usr/include/c++/15/algorithm + /usr/include/c++/15/any + /usr/include/c++/15/array + /usr/include/c++/15/atomic + /usr/include/c++/15/backward/auto_ptr.h + /usr/include/c++/15/backward/binders.h + /usr/include/c++/15/bit + /usr/include/c++/15/bits/algorithmfwd.h + /usr/include/c++/15/bits/align.h + /usr/include/c++/15/bits/alloc_traits.h + /usr/include/c++/15/bits/allocated_ptr.h + /usr/include/c++/15/bits/allocator.h + /usr/include/c++/15/bits/atomic_base.h + /usr/include/c++/15/bits/atomic_lockfree_defines.h + /usr/include/c++/15/bits/basic_ios.h + /usr/include/c++/15/bits/basic_ios.tcc + /usr/include/c++/15/bits/basic_string.h + /usr/include/c++/15/bits/basic_string.tcc + /usr/include/c++/15/bits/char_traits.h + /usr/include/c++/15/bits/charconv.h + /usr/include/c++/15/bits/chrono.h + /usr/include/c++/15/bits/codecvt.h + /usr/include/c++/15/bits/concept_check.h + /usr/include/c++/15/bits/cpp_type_traits.h + /usr/include/c++/15/bits/cxxabi_forced.h + /usr/include/c++/15/bits/cxxabi_init_exception.h + /usr/include/c++/15/bits/enable_special_members.h + /usr/include/c++/15/bits/erase_if.h + /usr/include/c++/15/bits/exception.h + /usr/include/c++/15/bits/exception_defines.h + /usr/include/c++/15/bits/exception_ptr.h + /usr/include/c++/15/bits/fstream.tcc + /usr/include/c++/15/bits/functexcept.h + /usr/include/c++/15/bits/functional_hash.h + /usr/include/c++/15/bits/hash_bytes.h + /usr/include/c++/15/bits/hashtable.h + /usr/include/c++/15/bits/hashtable_policy.h + /usr/include/c++/15/bits/invoke.h + /usr/include/c++/15/bits/ios_base.h + /usr/include/c++/15/bits/istream.tcc + /usr/include/c++/15/bits/list.tcc + /usr/include/c++/15/bits/locale_classes.h + /usr/include/c++/15/bits/locale_classes.tcc + /usr/include/c++/15/bits/locale_conv.h + /usr/include/c++/15/bits/locale_facets.h + /usr/include/c++/15/bits/locale_facets.tcc + /usr/include/c++/15/bits/locale_facets_nonio.h + /usr/include/c++/15/bits/locale_facets_nonio.tcc + /usr/include/c++/15/bits/localefwd.h + /usr/include/c++/15/bits/memory_resource.h + /usr/include/c++/15/bits/memoryfwd.h + /usr/include/c++/15/bits/monostate.h + /usr/include/c++/15/bits/move.h + /usr/include/c++/15/bits/nested_exception.h + /usr/include/c++/15/bits/new_allocator.h + /usr/include/c++/15/bits/node_handle.h + /usr/include/c++/15/bits/ostream.h + /usr/include/c++/15/bits/ostream.tcc + /usr/include/c++/15/bits/ostream_insert.h + /usr/include/c++/15/bits/parse_numbers.h + /usr/include/c++/15/bits/postypes.h + /usr/include/c++/15/bits/predefined_ops.h + /usr/include/c++/15/bits/ptr_traits.h + /usr/include/c++/15/bits/quoted_string.h + /usr/include/c++/15/bits/range_access.h + /usr/include/c++/15/bits/refwrap.h + /usr/include/c++/15/bits/requires_hosted.h + /usr/include/c++/15/bits/shared_ptr.h + /usr/include/c++/15/bits/shared_ptr_atomic.h + /usr/include/c++/15/bits/shared_ptr_base.h + /usr/include/c++/15/bits/specfun.h + /usr/include/c++/15/bits/sstream.tcc + /usr/include/c++/15/bits/std_abs.h + /usr/include/c++/15/bits/std_function.h + /usr/include/c++/15/bits/std_mutex.h + /usr/include/c++/15/bits/stl_algo.h + /usr/include/c++/15/bits/stl_algobase.h + /usr/include/c++/15/bits/stl_bvector.h + /usr/include/c++/15/bits/stl_construct.h + /usr/include/c++/15/bits/stl_function.h + /usr/include/c++/15/bits/stl_heap.h + /usr/include/c++/15/bits/stl_iterator.h + /usr/include/c++/15/bits/stl_iterator_base_funcs.h + /usr/include/c++/15/bits/stl_iterator_base_types.h + /usr/include/c++/15/bits/stl_list.h + /usr/include/c++/15/bits/stl_map.h + /usr/include/c++/15/bits/stl_multimap.h + /usr/include/c++/15/bits/stl_multiset.h + /usr/include/c++/15/bits/stl_pair.h + /usr/include/c++/15/bits/stl_raw_storage_iter.h + /usr/include/c++/15/bits/stl_relops.h + /usr/include/c++/15/bits/stl_set.h + /usr/include/c++/15/bits/stl_tempbuf.h + /usr/include/c++/15/bits/stl_tree.h + /usr/include/c++/15/bits/stl_uninitialized.h + /usr/include/c++/15/bits/stl_vector.h + /usr/include/c++/15/bits/stream_iterator.h + /usr/include/c++/15/bits/streambuf.tcc + /usr/include/c++/15/bits/streambuf_iterator.h + /usr/include/c++/15/bits/string_view.tcc + /usr/include/c++/15/bits/stringfwd.h + /usr/include/c++/15/bits/uniform_int_dist.h + /usr/include/c++/15/bits/unique_lock.h + /usr/include/c++/15/bits/unique_ptr.h + /usr/include/c++/15/bits/unordered_map.h + /usr/include/c++/15/bits/unordered_set.h + /usr/include/c++/15/bits/uses_allocator.h + /usr/include/c++/15/bits/uses_allocator_args.h + /usr/include/c++/15/bits/utility.h + /usr/include/c++/15/bits/vector.tcc + /usr/include/c++/15/bits/version.h + /usr/include/c++/15/cassert + /usr/include/c++/15/cctype + /usr/include/c++/15/cerrno + /usr/include/c++/15/chrono + /usr/include/c++/15/climits + /usr/include/c++/15/clocale + /usr/include/c++/15/cmath + /usr/include/c++/15/compare + /usr/include/c++/15/concepts + /usr/include/c++/15/condition_variable + /usr/include/c++/15/csignal + /usr/include/c++/15/cstddef + /usr/include/c++/15/cstdint + /usr/include/c++/15/cstdio + /usr/include/c++/15/cstdlib + /usr/include/c++/15/cstring + /usr/include/c++/15/ctime + /usr/include/c++/15/cwchar + /usr/include/c++/15/cwctype + /usr/include/c++/15/cxxabi.h + /usr/include/c++/15/debug/assertions.h + /usr/include/c++/15/debug/debug.h + /usr/include/c++/15/exception + /usr/include/c++/15/ext/aligned_buffer.h + /usr/include/c++/15/ext/alloc_traits.h + /usr/include/c++/15/ext/atomicity.h + /usr/include/c++/15/ext/concurrence.h + /usr/include/c++/15/ext/numeric_traits.h + /usr/include/c++/15/ext/string_conversions.h + /usr/include/c++/15/ext/type_traits.h + /usr/include/c++/15/fstream + /usr/include/c++/15/functional + /usr/include/c++/15/initializer_list + /usr/include/c++/15/iomanip + /usr/include/c++/15/ios + /usr/include/c++/15/iosfwd + /usr/include/c++/15/iostream + /usr/include/c++/15/istream + /usr/include/c++/15/iterator + /usr/include/c++/15/limits + /usr/include/c++/15/list + /usr/include/c++/15/locale + /usr/include/c++/15/map + /usr/include/c++/15/memory + /usr/include/c++/15/mutex + /usr/include/c++/15/new + /usr/include/c++/15/optional + /usr/include/c++/15/ostream + /usr/include/c++/15/pstl/execution_defs.h + /usr/include/c++/15/pstl/glue_algorithm_defs.h + /usr/include/c++/15/pstl/glue_memory_defs.h + /usr/include/c++/15/pstl/pstl_config.h + /usr/include/c++/15/ratio + /usr/include/c++/15/set + /usr/include/c++/15/sstream + /usr/include/c++/15/stdexcept + /usr/include/c++/15/stdlib.h + /usr/include/c++/15/streambuf + /usr/include/c++/15/string + /usr/include/c++/15/string_view + /usr/include/c++/15/system_error + /usr/include/c++/15/tr1/bessel_function.tcc + /usr/include/c++/15/tr1/beta_function.tcc + /usr/include/c++/15/tr1/ell_integral.tcc + /usr/include/c++/15/tr1/exp_integral.tcc + /usr/include/c++/15/tr1/gamma.tcc + /usr/include/c++/15/tr1/hypergeometric.tcc + /usr/include/c++/15/tr1/legendre_function.tcc + /usr/include/c++/15/tr1/modified_bessel_func.tcc + /usr/include/c++/15/tr1/poly_hermite.tcc + /usr/include/c++/15/tr1/poly_laguerre.tcc + /usr/include/c++/15/tr1/riemann_zeta.tcc + /usr/include/c++/15/tr1/special_function_util.h + /usr/include/c++/15/tuple + /usr/include/c++/15/type_traits + /usr/include/c++/15/typeinfo + /usr/include/c++/15/unordered_map + /usr/include/c++/15/unordered_set + /usr/include/c++/15/utility + /usr/include/c++/15/variant + /usr/include/c++/15/vector + /usr/include/c++/15/version + /usr/include/ctype.h + /usr/include/endian.h + /usr/include/errno.h + /usr/include/fcntl.h + /usr/include/features-time64.h + /usr/include/features.h + /usr/include/libintl.h + /usr/include/limits.h + /usr/include/linux/close_range.h + /usr/include/linux/errno.h + /usr/include/linux/falloc.h + /usr/include/linux/limits.h + /usr/include/linux/openat2.h + /usr/include/linux/posix_types.h + /usr/include/linux/sched/types.h + /usr/include/linux/stat.h + /usr/include/linux/stddef.h + /usr/include/linux/types.h + /usr/include/locale.h + /usr/include/math.h + /usr/include/netdb.h + /usr/include/netinet/in.h + /usr/include/pthread.h + /usr/include/regex.h + /usr/include/rpc/netdb.h + /usr/include/sched.h + /usr/include/signal.h + /usr/include/stdc-predef.h + /usr/include/stdint.h + /usr/include/stdio.h + /usr/include/stdlib.h + /usr/include/string.h + /usr/include/strings.h + /usr/include/time.h + /usr/include/unistd.h + /usr/include/wchar.h + /usr/include/wctype.h + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h + /usr/include/x86_64-linux-gnu/asm/errno.h + /usr/include/x86_64-linux-gnu/asm/posix_types.h + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h + /usr/include/x86_64-linux-gnu/asm/socket.h + /usr/include/x86_64-linux-gnu/asm/sockios.h + /usr/include/x86_64-linux-gnu/asm/types.h + /usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h + /usr/include/x86_64-linux-gnu/bits/byteswap.h + /usr/include/x86_64-linux-gnu/bits/confname.h + /usr/include/x86_64-linux-gnu/bits/cpu-set.h + /usr/include/x86_64-linux-gnu/bits/endian.h + /usr/include/x86_64-linux-gnu/bits/endianness.h + /usr/include/x86_64-linux-gnu/bits/environments.h + /usr/include/x86_64-linux-gnu/bits/errno.h + /usr/include/x86_64-linux-gnu/bits/fcntl-linux-fortify.h + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h + /usr/include/x86_64-linux-gnu/bits/fcntl.h + /usr/include/x86_64-linux-gnu/bits/fcntl2.h + /usr/include/x86_64-linux-gnu/bits/floatn-common.h + /usr/include/x86_64-linux-gnu/bits/floatn.h + /usr/include/x86_64-linux-gnu/bits/flt-eval-method.h + /usr/include/x86_64-linux-gnu/bits/fp-fast.h + /usr/include/x86_64-linux-gnu/bits/fp-logb.h + /usr/include/x86_64-linux-gnu/bits/getopt_core.h + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h + /usr/include/x86_64-linux-gnu/bits/in.h + /usr/include/x86_64-linux-gnu/bits/inet-fortified-decl.h + /usr/include/x86_64-linux-gnu/bits/inet-fortified.h + /usr/include/x86_64-linux-gnu/bits/iscanonical.h + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h + /usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h + /usr/include/x86_64-linux-gnu/bits/local_lim.h + /usr/include/x86_64-linux-gnu/bits/locale.h + /usr/include/x86_64-linux-gnu/bits/long-double.h + /usr/include/x86_64-linux-gnu/bits/math-vector.h + /usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h + /usr/include/x86_64-linux-gnu/bits/mathcalls-macros.h + /usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h + /usr/include/x86_64-linux-gnu/bits/mathcalls.h + /usr/include/x86_64-linux-gnu/bits/mman-linux.h + /usr/include/x86_64-linux-gnu/bits/mman-map-flags-generic.h + /usr/include/x86_64-linux-gnu/bits/mman-shared.h + /usr/include/x86_64-linux-gnu/bits/mman.h + /usr/include/x86_64-linux-gnu/bits/mman_ext.h + /usr/include/x86_64-linux-gnu/bits/netdb.h + /usr/include/x86_64-linux-gnu/bits/openat2.h + /usr/include/x86_64-linux-gnu/bits/posix1_lim.h + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h + /usr/include/x86_64-linux-gnu/bits/posix_opt.h + /usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h + /usr/include/x86_64-linux-gnu/bits/sched.h + /usr/include/x86_64-linux-gnu/bits/select-decl.h + /usr/include/x86_64-linux-gnu/bits/select.h + /usr/include/x86_64-linux-gnu/bits/select2.h + /usr/include/x86_64-linux-gnu/bits/setjmp.h + /usr/include/x86_64-linux-gnu/bits/sigaction.h + /usr/include/x86_64-linux-gnu/bits/sigcontext.h + /usr/include/x86_64-linux-gnu/bits/sigevent-consts.h + /usr/include/x86_64-linux-gnu/bits/siginfo-arch.h + /usr/include/x86_64-linux-gnu/bits/siginfo-consts-arch.h + /usr/include/x86_64-linux-gnu/bits/siginfo-consts.h + /usr/include/x86_64-linux-gnu/bits/signal_ext.h + /usr/include/x86_64-linux-gnu/bits/signum-arch.h + /usr/include/x86_64-linux-gnu/bits/signum-generic.h + /usr/include/x86_64-linux-gnu/bits/sigstack.h + /usr/include/x86_64-linux-gnu/bits/sigstksz.h + /usr/include/x86_64-linux-gnu/bits/sigthread.h + /usr/include/x86_64-linux-gnu/bits/sockaddr.h + /usr/include/x86_64-linux-gnu/bits/socket.h + /usr/include/x86_64-linux-gnu/bits/socket2.h + /usr/include/x86_64-linux-gnu/bits/socket_type.h + /usr/include/x86_64-linux-gnu/bits/ss_flags.h + /usr/include/x86_64-linux-gnu/bits/stat.h + /usr/include/x86_64-linux-gnu/bits/statx-generic.h + /usr/include/x86_64-linux-gnu/bits/statx.h + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h + /usr/include/x86_64-linux-gnu/bits/stdint-least.h + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h + /usr/include/x86_64-linux-gnu/bits/stdio.h + /usr/include/x86_64-linux-gnu/bits/stdio2-decl.h + /usr/include/x86_64-linux-gnu/bits/stdio2.h + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h + /usr/include/x86_64-linux-gnu/bits/stdlib.h + /usr/include/x86_64-linux-gnu/bits/string_fortified.h + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h + /usr/include/x86_64-linux-gnu/bits/struct_stat.h + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h + /usr/include/x86_64-linux-gnu/bits/time.h + /usr/include/x86_64-linux-gnu/bits/time64.h + /usr/include/x86_64-linux-gnu/bits/timesize.h + /usr/include/x86_64-linux-gnu/bits/timex.h + /usr/include/x86_64-linux-gnu/bits/types.h + /usr/include/x86_64-linux-gnu/bits/types/FILE.h + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h + /usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h + /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h + /usr/include/x86_64-linux-gnu/bits/types/error_t.h + /usr/include/x86_64-linux-gnu/bits/types/idtype_t.h + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h + /usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h + /usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigval_t.h + /usr/include/x86_64-linux-gnu/bits/types/stack_t.h + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h + /usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h + /usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h + /usr/include/x86_64-linux-gnu/bits/types/struct_statx.h + /usr/include/x86_64-linux-gnu/bits/types/struct_statx_timestamp.h + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h + /usr/include/x86_64-linux-gnu/bits/types/time_t.h + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h + /usr/include/x86_64-linux-gnu/bits/types/wint_t.h + /usr/include/x86_64-linux-gnu/bits/typesizes.h + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h + /usr/include/x86_64-linux-gnu/bits/uio_lim.h + /usr/include/x86_64-linux-gnu/bits/unistd-decl.h + /usr/include/x86_64-linux-gnu/bits/unistd.h + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h + /usr/include/x86_64-linux-gnu/bits/waitflags.h + /usr/include/x86_64-linux-gnu/bits/waitstatus.h + /usr/include/x86_64-linux-gnu/bits/wchar.h + /usr/include/x86_64-linux-gnu/bits/wchar2-decl.h + /usr/include/x86_64-linux-gnu/bits/wchar2.h + /usr/include/x86_64-linux-gnu/bits/wctype-wchar.h + /usr/include/x86_64-linux-gnu/bits/wordsize.h + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h + /usr/include/x86_64-linux-gnu/c++/15/bits/atomic_word.h + /usr/include/x86_64-linux-gnu/c++/15/bits/basic_file.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++allocator.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++config.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++io.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++locale.h + /usr/include/x86_64-linux-gnu/c++/15/bits/cpu_defines.h + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_base.h + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_inline.h + /usr/include/x86_64-linux-gnu/c++/15/bits/cxxabi_tweaks.h + /usr/include/x86_64-linux-gnu/c++/15/bits/error_constants.h + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr-default.h + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr.h + /usr/include/x86_64-linux-gnu/c++/15/bits/messages_members.h + /usr/include/x86_64-linux-gnu/c++/15/bits/os_defines.h + /usr/include/x86_64-linux-gnu/c++/15/bits/time_members.h + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h + /usr/include/x86_64-linux-gnu/gnu/stubs.h + /usr/include/x86_64-linux-gnu/sys/cdefs.h + /usr/include/x86_64-linux-gnu/sys/mman.h + /usr/include/x86_64-linux-gnu/sys/select.h + /usr/include/x86_64-linux-gnu/sys/single_threaded.h + /usr/include/x86_64-linux-gnu/sys/socket.h + /usr/include/x86_64-linux-gnu/sys/stat.h + /usr/include/x86_64-linux-gnu/sys/time.h + /usr/include/x86_64-linux-gnu/sys/types.h + /usr/include/x86_64-linux-gnu/sys/ucontext.h + /usr/include/x86_64-linux-gnu/sys/wait.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/float.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/limits.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdarg.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/syslimits.h + diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/compiler_depend.make b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/compiler_depend.make new file mode 100644 index 0000000..074eca8 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/compiler_depend.make @@ -0,0 +1,1378 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o: /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-all.cc \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-assertion-result.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-death-test.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-matchers.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-message.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-param-test.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-printers.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-spi.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-test-part.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-typed-test.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_pred_impl.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_prod.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-port.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-printers.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-filepath.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-internal.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-param-util.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port-arch.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-string.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-type-util.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-assertion-result.cc \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-death-test.cc \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-filepath.cc \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-internal-inl.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-matchers.cc \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-port.cc \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-printers.cc \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-test-part.cc \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-typed-test.cc \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest.cc \ + /usr/include/alloca.h \ + /usr/include/arpa/inet.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/asm-generic/errno-base.h \ + /usr/include/asm-generic/errno.h \ + /usr/include/asm-generic/int-ll64.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/asm-generic/socket.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/asm-generic/types.h \ + /usr/include/assert.h \ + /usr/include/c++/15/algorithm \ + /usr/include/c++/15/any \ + /usr/include/c++/15/array \ + /usr/include/c++/15/atomic \ + /usr/include/c++/15/backward/auto_ptr.h \ + /usr/include/c++/15/backward/binders.h \ + /usr/include/c++/15/bit \ + /usr/include/c++/15/bits/algorithmfwd.h \ + /usr/include/c++/15/bits/align.h \ + /usr/include/c++/15/bits/alloc_traits.h \ + /usr/include/c++/15/bits/allocated_ptr.h \ + /usr/include/c++/15/bits/allocator.h \ + /usr/include/c++/15/bits/atomic_base.h \ + /usr/include/c++/15/bits/atomic_lockfree_defines.h \ + /usr/include/c++/15/bits/basic_ios.h \ + /usr/include/c++/15/bits/basic_ios.tcc \ + /usr/include/c++/15/bits/basic_string.h \ + /usr/include/c++/15/bits/basic_string.tcc \ + /usr/include/c++/15/bits/char_traits.h \ + /usr/include/c++/15/bits/charconv.h \ + /usr/include/c++/15/bits/chrono.h \ + /usr/include/c++/15/bits/codecvt.h \ + /usr/include/c++/15/bits/concept_check.h \ + /usr/include/c++/15/bits/cpp_type_traits.h \ + /usr/include/c++/15/bits/cxxabi_forced.h \ + /usr/include/c++/15/bits/cxxabi_init_exception.h \ + /usr/include/c++/15/bits/enable_special_members.h \ + /usr/include/c++/15/bits/erase_if.h \ + /usr/include/c++/15/bits/exception.h \ + /usr/include/c++/15/bits/exception_defines.h \ + /usr/include/c++/15/bits/exception_ptr.h \ + /usr/include/c++/15/bits/fstream.tcc \ + /usr/include/c++/15/bits/functexcept.h \ + /usr/include/c++/15/bits/functional_hash.h \ + /usr/include/c++/15/bits/hash_bytes.h \ + /usr/include/c++/15/bits/hashtable.h \ + /usr/include/c++/15/bits/hashtable_policy.h \ + /usr/include/c++/15/bits/invoke.h \ + /usr/include/c++/15/bits/ios_base.h \ + /usr/include/c++/15/bits/istream.tcc \ + /usr/include/c++/15/bits/list.tcc \ + /usr/include/c++/15/bits/locale_classes.h \ + /usr/include/c++/15/bits/locale_classes.tcc \ + /usr/include/c++/15/bits/locale_conv.h \ + /usr/include/c++/15/bits/locale_facets.h \ + /usr/include/c++/15/bits/locale_facets.tcc \ + /usr/include/c++/15/bits/locale_facets_nonio.h \ + /usr/include/c++/15/bits/locale_facets_nonio.tcc \ + /usr/include/c++/15/bits/localefwd.h \ + /usr/include/c++/15/bits/memory_resource.h \ + /usr/include/c++/15/bits/memoryfwd.h \ + /usr/include/c++/15/bits/monostate.h \ + /usr/include/c++/15/bits/move.h \ + /usr/include/c++/15/bits/nested_exception.h \ + /usr/include/c++/15/bits/new_allocator.h \ + /usr/include/c++/15/bits/node_handle.h \ + /usr/include/c++/15/bits/ostream.h \ + /usr/include/c++/15/bits/ostream.tcc \ + /usr/include/c++/15/bits/ostream_insert.h \ + /usr/include/c++/15/bits/parse_numbers.h \ + /usr/include/c++/15/bits/postypes.h \ + /usr/include/c++/15/bits/predefined_ops.h \ + /usr/include/c++/15/bits/ptr_traits.h \ + /usr/include/c++/15/bits/quoted_string.h \ + /usr/include/c++/15/bits/range_access.h \ + /usr/include/c++/15/bits/refwrap.h \ + /usr/include/c++/15/bits/requires_hosted.h \ + /usr/include/c++/15/bits/shared_ptr.h \ + /usr/include/c++/15/bits/shared_ptr_atomic.h \ + /usr/include/c++/15/bits/shared_ptr_base.h \ + /usr/include/c++/15/bits/specfun.h \ + /usr/include/c++/15/bits/sstream.tcc \ + /usr/include/c++/15/bits/std_abs.h \ + /usr/include/c++/15/bits/std_function.h \ + /usr/include/c++/15/bits/std_mutex.h \ + /usr/include/c++/15/bits/stl_algo.h \ + /usr/include/c++/15/bits/stl_algobase.h \ + /usr/include/c++/15/bits/stl_bvector.h \ + /usr/include/c++/15/bits/stl_construct.h \ + /usr/include/c++/15/bits/stl_function.h \ + /usr/include/c++/15/bits/stl_heap.h \ + /usr/include/c++/15/bits/stl_iterator.h \ + /usr/include/c++/15/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/15/bits/stl_iterator_base_types.h \ + /usr/include/c++/15/bits/stl_list.h \ + /usr/include/c++/15/bits/stl_map.h \ + /usr/include/c++/15/bits/stl_multimap.h \ + /usr/include/c++/15/bits/stl_multiset.h \ + /usr/include/c++/15/bits/stl_pair.h \ + /usr/include/c++/15/bits/stl_raw_storage_iter.h \ + /usr/include/c++/15/bits/stl_relops.h \ + /usr/include/c++/15/bits/stl_set.h \ + /usr/include/c++/15/bits/stl_tempbuf.h \ + /usr/include/c++/15/bits/stl_tree.h \ + /usr/include/c++/15/bits/stl_uninitialized.h \ + /usr/include/c++/15/bits/stl_vector.h \ + /usr/include/c++/15/bits/stream_iterator.h \ + /usr/include/c++/15/bits/streambuf.tcc \ + /usr/include/c++/15/bits/streambuf_iterator.h \ + /usr/include/c++/15/bits/string_view.tcc \ + /usr/include/c++/15/bits/stringfwd.h \ + /usr/include/c++/15/bits/uniform_int_dist.h \ + /usr/include/c++/15/bits/unique_lock.h \ + /usr/include/c++/15/bits/unique_ptr.h \ + /usr/include/c++/15/bits/unordered_map.h \ + /usr/include/c++/15/bits/unordered_set.h \ + /usr/include/c++/15/bits/uses_allocator.h \ + /usr/include/c++/15/bits/uses_allocator_args.h \ + /usr/include/c++/15/bits/utility.h \ + /usr/include/c++/15/bits/vector.tcc \ + /usr/include/c++/15/bits/version.h \ + /usr/include/c++/15/cassert \ + /usr/include/c++/15/cctype \ + /usr/include/c++/15/cerrno \ + /usr/include/c++/15/chrono \ + /usr/include/c++/15/climits \ + /usr/include/c++/15/clocale \ + /usr/include/c++/15/cmath \ + /usr/include/c++/15/compare \ + /usr/include/c++/15/concepts \ + /usr/include/c++/15/condition_variable \ + /usr/include/c++/15/csignal \ + /usr/include/c++/15/cstddef \ + /usr/include/c++/15/cstdint \ + /usr/include/c++/15/cstdio \ + /usr/include/c++/15/cstdlib \ + /usr/include/c++/15/cstring \ + /usr/include/c++/15/ctime \ + /usr/include/c++/15/cwchar \ + /usr/include/c++/15/cwctype \ + /usr/include/c++/15/cxxabi.h \ + /usr/include/c++/15/debug/assertions.h \ + /usr/include/c++/15/debug/debug.h \ + /usr/include/c++/15/exception \ + /usr/include/c++/15/ext/aligned_buffer.h \ + /usr/include/c++/15/ext/alloc_traits.h \ + /usr/include/c++/15/ext/atomicity.h \ + /usr/include/c++/15/ext/concurrence.h \ + /usr/include/c++/15/ext/numeric_traits.h \ + /usr/include/c++/15/ext/string_conversions.h \ + /usr/include/c++/15/ext/type_traits.h \ + /usr/include/c++/15/fstream \ + /usr/include/c++/15/functional \ + /usr/include/c++/15/initializer_list \ + /usr/include/c++/15/iomanip \ + /usr/include/c++/15/ios \ + /usr/include/c++/15/iosfwd \ + /usr/include/c++/15/iostream \ + /usr/include/c++/15/istream \ + /usr/include/c++/15/iterator \ + /usr/include/c++/15/limits \ + /usr/include/c++/15/list \ + /usr/include/c++/15/locale \ + /usr/include/c++/15/map \ + /usr/include/c++/15/memory \ + /usr/include/c++/15/mutex \ + /usr/include/c++/15/new \ + /usr/include/c++/15/optional \ + /usr/include/c++/15/ostream \ + /usr/include/c++/15/pstl/execution_defs.h \ + /usr/include/c++/15/pstl/glue_algorithm_defs.h \ + /usr/include/c++/15/pstl/glue_memory_defs.h \ + /usr/include/c++/15/pstl/pstl_config.h \ + /usr/include/c++/15/ratio \ + /usr/include/c++/15/set \ + /usr/include/c++/15/sstream \ + /usr/include/c++/15/stdexcept \ + /usr/include/c++/15/stdlib.h \ + /usr/include/c++/15/streambuf \ + /usr/include/c++/15/string \ + /usr/include/c++/15/string_view \ + /usr/include/c++/15/system_error \ + /usr/include/c++/15/tr1/bessel_function.tcc \ + /usr/include/c++/15/tr1/beta_function.tcc \ + /usr/include/c++/15/tr1/ell_integral.tcc \ + /usr/include/c++/15/tr1/exp_integral.tcc \ + /usr/include/c++/15/tr1/gamma.tcc \ + /usr/include/c++/15/tr1/hypergeometric.tcc \ + /usr/include/c++/15/tr1/legendre_function.tcc \ + /usr/include/c++/15/tr1/modified_bessel_func.tcc \ + /usr/include/c++/15/tr1/poly_hermite.tcc \ + /usr/include/c++/15/tr1/poly_laguerre.tcc \ + /usr/include/c++/15/tr1/riemann_zeta.tcc \ + /usr/include/c++/15/tr1/special_function_util.h \ + /usr/include/c++/15/tuple \ + /usr/include/c++/15/type_traits \ + /usr/include/c++/15/typeinfo \ + /usr/include/c++/15/unordered_map \ + /usr/include/c++/15/unordered_set \ + /usr/include/c++/15/utility \ + /usr/include/c++/15/variant \ + /usr/include/c++/15/vector \ + /usr/include/c++/15/version \ + /usr/include/ctype.h \ + /usr/include/endian.h \ + /usr/include/errno.h \ + /usr/include/fcntl.h \ + /usr/include/features-time64.h \ + /usr/include/features.h \ + /usr/include/libintl.h \ + /usr/include/limits.h \ + /usr/include/linux/close_range.h \ + /usr/include/linux/errno.h \ + /usr/include/linux/falloc.h \ + /usr/include/linux/limits.h \ + /usr/include/linux/openat2.h \ + /usr/include/linux/posix_types.h \ + /usr/include/linux/sched/types.h \ + /usr/include/linux/stat.h \ + /usr/include/linux/stddef.h \ + /usr/include/linux/types.h \ + /usr/include/locale.h \ + /usr/include/math.h \ + /usr/include/netdb.h \ + /usr/include/netinet/in.h \ + /usr/include/pthread.h \ + /usr/include/regex.h \ + /usr/include/rpc/netdb.h \ + /usr/include/sched.h \ + /usr/include/signal.h \ + /usr/include/stdc-predef.h \ + /usr/include/stdint.h \ + /usr/include/stdio.h \ + /usr/include/stdlib.h \ + /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/time.h \ + /usr/include/unistd.h \ + /usr/include/wchar.h \ + /usr/include/wctype.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux-fortify.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl2.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/flt-eval-method.h \ + /usr/include/x86_64-linux-gnu/bits/fp-fast.h \ + /usr/include/x86_64-linux-gnu/bits/fp-logb.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/in.h \ + /usr/include/x86_64-linux-gnu/bits/inet-fortified-decl.h \ + /usr/include/x86_64-linux-gnu/bits/inet-fortified.h \ + /usr/include/x86_64-linux-gnu/bits/iscanonical.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/bits/math-vector.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls-macros.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h \ + /usr/include/x86_64-linux-gnu/bits/mathcalls.h \ + /usr/include/x86_64-linux-gnu/bits/mman-linux.h \ + /usr/include/x86_64-linux-gnu/bits/mman-map-flags-generic.h \ + /usr/include/x86_64-linux-gnu/bits/mman-shared.h \ + /usr/include/x86_64-linux-gnu/bits/mman.h \ + /usr/include/x86_64-linux-gnu/bits/mman_ext.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/openat2.h \ + /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/select-decl.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigevent-consts.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-arch.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-consts-arch.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-consts.h \ + /usr/include/x86_64-linux-gnu/bits/signal_ext.h \ + /usr/include/x86_64-linux-gnu/bits/signum-arch.h \ + /usr/include/x86_64-linux-gnu/bits/signum-generic.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/sigstksz.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/ss_flags.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h \ + /usr/include/x86_64-linux-gnu/bits/statx-generic.h \ + /usr/include/x86_64-linux-gnu/bits/statx.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2-decl.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/struct_stat.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/error_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/idtype_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/stack_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_statx.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_statx_timestamp.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/wint_t.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/bits/uio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/unistd-decl.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2-decl.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2.h \ + /usr/include/x86_64-linux-gnu/bits/wctype-wchar.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/atomic_word.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/basic_file.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++allocator.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++config.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++io.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++locale.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/cpu_defines.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_base.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_inline.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/cxxabi_tweaks.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/error_constants.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr-default.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/messages_members.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/os_defines.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/time_members.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/sys/mman.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/sys/single_threaded.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/float.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdarg.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/syslimits.h + + +/usr/lib/gcc/x86_64-linux-gnu/15/include/syslimits.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/stdarg.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/float.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/messages_members.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/error_constants.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/cxxabi_tweaks.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/ctype_base.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++config.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++allocator.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/wctype-wchar.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/uio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/types/wint_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_statx.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/types/stack_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/basic_file.h: + +/usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/idtype_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-least.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/x86_64-linux-gnu/bits/statx-generic.h: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/x86_64-linux-gnu/bits/sigstksz.h: + +/usr/include/x86_64-linux-gnu/bits/signal_ext.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++io.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-consts.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-consts-arch.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-arch.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/mman_ext.h: + +/usr/include/x86_64-linux-gnu/bits/mman-shared.h: + +/usr/include/x86_64-linux-gnu/bits/mman-map-flags-generic.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls-macros.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/libm-simd-decl-stubs.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/x86_64-linux-gnu/bits/inet-fortified.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/wchar2.h: + +/usr/include/x86_64-linux-gnu/bits/fp-logb.h: + +/usr/include/x86_64-linux-gnu/bits/flt-eval-method.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux-fortify.h: + +/usr/include/x86_64-linux-gnu/bits/signum-arch.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/x86_64-linux-gnu/bits/statx.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/time.h: + +/usr/include/string.h: + +/usr/include/stdlib.h: + +/usr/include/stdio.h: + +/usr/include/stdc-predef.h: + +/usr/include/wctype.h: + +/usr/include/sched.h: + +/usr/include/regex.h: + +/usr/include/pthread.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/math.h: + +/usr/include/c++/15/clocale: + +/usr/include/c++/15/bits/sstream.tcc: + +/usr/include/c++/15/bits/refwrap.h: + +/usr/include/c++/15/type_traits: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/c++/15/bits/postypes.h: + +/usr/include/netdb.h: + +/usr/include/c++/15/bits/parse_numbers.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/c++/15/bits/ostream.tcc: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/limits.h: + +/usr/include/c++/15/bits/monostate.h: + +/usr/include/x86_64-linux-gnu/bits/select-decl.h: + +/usr/include/c++/15/bits/atomic_lockfree_defines.h: + +/usr/include/c++/15/bits/localefwd.h: + +/usr/include/c++/15/bits/stl_algobase.h: + +/usr/include/c++/15/bits/stl_relops.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/atomic_word.h: + +/usr/include/c++/15/bits/locale_facets_nonio.h: + +/usr/include/c++/15/bits/stl_function.h: + +/usr/include/c++/15/cwchar: + +/usr/include/c++/15/bits/locale_facets.tcc: + +/usr/include/c++/15/bits/locale_conv.h: + +/usr/include/ctype.h: + +/usr/include/c++/15/bits/locale_classes.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/os_defines.h: + +/usr/include/c++/15/bits/new_allocator.h: + +/usr/include/c++/15/bits/uses_allocator.h: + +/usr/include/c++/15/iterator: + +/usr/include/c++/15/bits/locale_facets.h: + +/usr/include/c++/15/bits/requires_hosted.h: + +/usr/include/c++/15/cstdlib: + +/usr/include/c++/15/bits/locale_facets_nonio.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-test-part.cc: + +/usr/include/c++/15/bits/invoke.h: + +/usr/include/c++/15/initializer_list: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/c++/15/concepts: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/c++/15/bits/std_function.h: + +/usr/include/c++/15/bits/codecvt.h: + +/usr/include/c++/15/bits/shared_ptr.h: + +/usr/include/x86_64-linux-gnu/sys/mman.h: + +/usr/include/c++/15/bits/chrono.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/c++/15/bits/stl_iterator_base_funcs.h: + +/usr/include/c++/15/ext/atomicity.h: + +/usr/include/limits.h: + +/usr/include/c++/15/bits/ostream.h: + +/usr/include/c++/15/bits/stringfwd.h: + +/usr/include/c++/15/bits/erase_if.h: + +/usr/include/c++/15/bits/alloc_traits.h: + +/usr/include/arpa/inet.h: + +/usr/include/c++/15/bits/cxxabi_init_exception.h: + +/usr/include/c++/15/variant: + +/usr/include/c++/15/bits/basic_string.h: + +/usr/include/c++/15/bits/cpp_type_traits.h: + +/usr/include/c++/15/streambuf: + +/usr/include/c++/15/bits/stl_iterator.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigval_t.h: + +/usr/include/c++/15/memory: + +/usr/include/c++/15/vector: + +/usr/include/c++/15/bits/basic_ios.tcc: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/c++/15/bits/basic_ios.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/mman.h: + +/usr/include/c++/15/bits/range_access.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/time_members.h: + +/usr/include/x86_64-linux-gnu/bits/math-vector.h: + +/usr/include/c++/15/bits/hash_bytes.h: + +/usr/include/c++/15/algorithm: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-assertion-result.cc: + +/usr/include/linux/sched/types.h: + +/usr/include/c++/15/bits/nested_exception.h: + +/usr/include/x86_64-linux-gnu/bits/iscanonical.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-string.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/ctype_inline.h: + +/usr/include/c++/15/bits/move.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/c++/15/tr1/poly_hermite.tcc: + +/usr/include/asm-generic/socket.h: + +/usr/include/c++/15/bits/quoted_string.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h: + +/usr/include/c++/15/ext/numeric_traits.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-death-test.cc: + +/usr/include/x86_64-linux-gnu/c++/15/bits/gthr.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-printers.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-filepath.h: + +/usr/include/c++/15/tr1/modified_bessel_func.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-typed-test.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/c++/15/bits/stl_construct.h: + +/usr/include/c++/15/bits/ptr_traits.h: + +/usr/include/c++/15/bits/ostream_insert.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-internal-inl.h: + +/usr/include/c++/15/string: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/x86_64-linux-gnu/bits/signum-generic.h: + +/usr/include/c++/15/bits/fstream.tcc: + +/usr/include/c++/15/bits/memoryfwd.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port-arch.h: + +/usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h: + +/usr/include/x86_64-linux-gnu/bits/ss_flags.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-death-test.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-assertion-result.h: + +/usr/include/c++/15/cstddef: + +/usr/include/errno.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-param-test.h: + +/usr/include/c++/15/bits/istream.tcc: + +/usr/include/c++/15/bits/allocated_ptr.h: + +/usr/include/c++/15/version: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-message.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/c++/15/bits/stream_iterator.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-test-part.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-type-util.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/c++/15/bits/algorithmfwd.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-matchers.h: + +/usr/include/c++/15/cstdint: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/c++/15/bits/char_traits.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-param-util.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_prod.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-printers.h: + +/usr/include/c++/15/bits/stl_algo.h: + +/usr/include/c++/15/bits/shared_ptr_atomic.h: + +/usr/include/c++/15/compare: + +/usr/include/c++/15/bits/cxxabi_forced.h: + +/usr/include/c++/15/map: + +/usr/include/c++/15/bits/ios_base.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-matchers.cc: + +/usr/include/c++/15/bits/functional_hash.h: + +/usr/include/c++/15/ext/type_traits.h: + +/usr/include/x86_64-linux-gnu/sys/single_threaded.h: + +/usr/include/c++/15/iomanip: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest.h: + +/usr/include/c++/15/istream: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-typed-test.cc: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/c++/15/array: + +/usr/include/c++/15/tuple: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_pred_impl.h: + +/usr/include/c++/15/bits/concept_check.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-port.h: + +/usr/include/x86_64-linux-gnu/bits/wchar2-decl.h: + +/usr/include/c++/15/bits/version.h: + +/usr/include/linux/stat.h: + +/usr/include/c++/15/bits/specfun.h: + +/usr/include/c++/15/backward/binders.h: + +/usr/include/c++/15/utility: + +/usr/include/c++/15/bits/std_mutex.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/c++/15/debug/assertions.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-port.cc: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/c++/15/bits/unordered_map.h: + +/usr/include/c++/15/bits/node_handle.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++locale.h: + +/usr/include/c++/15/pstl/glue_memory_defs.h: + +/usr/include/c++/15/bits/hashtable.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest.cc: + +/usr/include/alloca.h: + +/usr/include/c++/15/bits/std_abs.h: + +/usr/include/c++/15/typeinfo: + +/usr/include/c++/15/bits/exception_defines.h: + +/usr/include/c++/15/bits/stl_heap.h: + +/usr/include/c++/15/backward/auto_ptr.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/asm-generic/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/wchar.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-filepath.cc: + +/usr/include/c++/15/sstream: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-all.cc: + +/usr/include/c++/15/bits/align.h: + +/usr/include/c++/15/bit: + +/usr/include/c++/15/bits/allocator.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/c++/15/fstream: + +/usr/include/assert.h: + +/usr/include/c++/15/bits/stl_raw_storage_iter.h: + +/usr/include/c++/15/any: + +/usr/include/c++/15/bits/atomic_base.h: + +/usr/include/c++/15/bits/stl_iterator_base_types.h: + +/usr/include/c++/15/bits/stl_multiset.h: + +/usr/include/x86_64-linux-gnu/bits/fp-fast.h: + +/usr/include/c++/15/bits/stl_bvector.h: + +/usr/include/c++/15/bits/stl_pair.h: + +/usr/include/c++/15/cctype: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/include/c++/15/bits/stl_set.h: + +/usr/include/c++/15/bits/stl_tempbuf.h: + +/usr/include/c++/15/bits/enable_special_members.h: + +/usr/include/c++/15/bits/stl_tree.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/c++/15/cstring: + +/usr/include/c++/15/bits/shared_ptr_base.h: + +/usr/include/c++/15/bits/stl_multimap.h: + +/usr/include/c++/15/bits/stl_uninitialized.h: + +/usr/include/x86_64-linux-gnu/bits/types/error_t.h: + +/usr/include/c++/15/bits/functexcept.h: + +/usr/include/c++/15/bits/stl_vector.h: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/c++/15/cwctype: + +/usr/include/c++/15/tr1/beta_function.tcc: + +/usr/include/c++/15/unordered_set: + +/usr/include/c++/15/bits/basic_string.tcc: + +/usr/include/c++/15/bits/streambuf.tcc: + +/usr/include/c++/15/cassert: + +/usr/include/x86_64-linux-gnu/bits/struct_stat.h: + +/usr/include/c++/15/bits/streambuf_iterator.h: + +/usr/include/c++/15/tr1/exp_integral.tcc: + +/usr/include/c++/15/bits/string_view.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest-printers.cc: + +/usr/include/c++/15/bits/uniform_int_dist.h: + +/usr/include/features-time64.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/c++/15/bits/stl_list.h: + +/usr/include/c++/15/bits/unique_lock.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/c++/15/bits/unique_ptr.h: + +/usr/include/c++/15/bits/unordered_set.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/cpu_defines.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl2.h: + +/usr/include/c++/15/bits/uses_allocator_args.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/c++/15/bits/utility.h: + +/usr/include/linux/close_range.h: + +/usr/include/netinet/in.h: + +/usr/include/c++/15/cerrno: + +/usr/include/c++/15/climits: + +/usr/include/x86_64-linux-gnu/bits/types/struct_statx_timestamp.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-internal.h: + +/usr/include/c++/15/cmath: + +/usr/include/stdint.h: + +/usr/include/endian.h: + +/usr/include/c++/15/exception: + +/usr/include/c++/15/csignal: + +/usr/include/c++/15/cstdio: + +/usr/include/x86_64-linux-gnu/bits/unistd-decl.h: + +/usr/include/c++/15/stdlib.h: + +/usr/include/c++/15/ctime: + +/usr/include/c++/15/bits/list.tcc: + +/usr/include/c++/15/debug/debug.h: + +/usr/include/c++/15/ext/aligned_buffer.h: + +/usr/include/c++/15/condition_variable: + +/usr/include/c++/15/ext/alloc_traits.h: + +/usr/include/linux/types.h: + +/usr/include/c++/15/bits/exception_ptr.h: + +/usr/include/c++/15/ext/concurrence.h: + +/usr/include/c++/15/bits/hashtable_policy.h: + +/usr/include/c++/15/ext/string_conversions.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h: + +/usr/include/c++/15/functional: + +/usr/include/x86_64-linux-gnu/bits/mman-linux.h: + +/usr/include/rpc/netdb.h: + +/usr/include/c++/15/ios: + +/usr/include/x86_64-linux-gnu/bits/sigevent-consts.h: + +/usr/include/c++/15/iosfwd: + +/usr/include/x86_64-linux-gnu/c++/15/bits/gthr-default.h: + +/usr/include/c++/15/limits: + +/usr/include/c++/15/bits/vector.tcc: + +/usr/include/c++/15/iostream: + +/usr/include/c++/15/locale: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/c++/15/string_view: + +/usr/include/c++/15/bits/charconv.h: + +/usr/include/c++/15/pstl/glue_algorithm_defs.h: + +/usr/include/c++/15/tr1/poly_laguerre.tcc: + +/usr/include/linux/errno.h: + +/usr/include/c++/15/new: + +/usr/include/c++/15/bits/predefined_ops.h: + +/usr/include/c++/15/optional: + +/usr/include/strings.h: + +/usr/include/signal.h: + +/usr/include/c++/15/bits/exception.h: + +/usr/include/c++/15/ostream: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/c++/15/pstl/execution_defs.h: + +/usr/include/c++/15/pstl/pstl_config.h: + +/usr/include/c++/15/bits/memory_resource.h: + +/usr/include/c++/15/set: + +/usr/include/c++/15/atomic: + +/usr/include/c++/15/ratio: + +/usr/include/c++/15/stdexcept: + +/usr/include/c++/15/system_error: + +/usr/include/c++/15/tr1/bessel_function.tcc: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/c++/15/tr1/ell_integral.tcc: + +/usr/include/c++/15/tr1/gamma.tcc: + +/usr/include/c++/15/cxxabi.h: + +/usr/include/c++/15/tr1/hypergeometric.tcc: + +/usr/include/x86_64-linux-gnu/bits/mathcalls-helper-functions.h: + +/usr/include/x86_64-linux-gnu/bits/inet-fortified-decl.h: + +/usr/include/c++/15/tr1/legendre_function.tcc: + +/usr/include/c++/15/tr1/riemann_zeta.tcc: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/c++/15/tr1/special_function_util.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/c++/15/chrono: + +/usr/include/c++/15/unordered_map: + +/usr/include/x86_64-linux-gnu/bits/openat2.h: + +/usr/include/features.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-spi.h: + +/usr/include/libintl.h: + +/usr/include/x86_64-linux-gnu/bits/mathcalls-narrow.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/c++/15/mutex: + +/usr/include/linux/falloc.h: + +/usr/include/linux/openat2.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2-decl.h: + +/usr/include/linux/posix_types.h: + +/usr/include/c++/15/bits/locale_classes.h: + +/usr/include/c++/15/bits/stl_map.h: + +/usr/include/c++/15/list: + +/usr/include/linux/stddef.h: + +/usr/include/locale.h: diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/compiler_depend.ts b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/compiler_depend.ts new file mode 100644 index 0000000..32ab1fb --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for gtest. diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/depend.make b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/depend.make new file mode 100644 index 0000000..37ac348 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for gtest. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/flags.make b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/flags.make new file mode 100644 index 0000000..757daf9 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = + +CXX_INCLUDES = -I/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -I/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=c++17 -Wall -Wshadow -Wundef -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers + diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/link.txt b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/link.txt new file mode 100644 index 0000000..852a721 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/link.txt @@ -0,0 +1,2 @@ +/usr/bin/ar qc ../../lib/libgtest.a "CMakeFiles/gtest.dir/src/gtest-all.cc.o" +/usr/bin/ranlib ../../lib/libgtest.a diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/progress.make b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/progress.make new file mode 100644 index 0000000..1c6716b --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 42 + diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/DependInfo.cmake b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/DependInfo.cmake new file mode 100644 index 0000000..8955ec2 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/DependInfo.cmake @@ -0,0 +1,23 @@ + +# Consider dependencies only in project. +set(CMAKE_DEPENDS_IN_PROJECT_ONLY OFF) + +# The set of languages for which implicit dependencies are needed: +set(CMAKE_DEPENDS_LANGUAGES + ) + +# The set of dependency files which are needed: +set(CMAKE_DEPENDS_DEPENDENCY_FILES + "/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest_main.cc" "googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o" "gcc" "googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o.d" + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_LINKED_INFO_FILES + ) + +# Targets to which this target links which contain Fortran sources. +set(CMAKE_Fortran_TARGET_FORWARD_LINKED_INFO_FILES + ) + +# Fortran module output directory. +set(CMAKE_Fortran_TARGET_MODULE_DIR "") diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/build.make b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/build.make new file mode 100644 index 0000000..81e2318 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/build.make @@ -0,0 +1,114 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Delete rule output on recipe failure. +.DELETE_ON_ERROR: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +# Include any dependencies generated for this target. +include googletest/googletest/CMakeFiles/gtest_main.dir/depend.make +# Include any dependencies generated by the compiler for this target. +include googletest/googletest/CMakeFiles/gtest_main.dir/compiler_depend.make + +# Include the progress variables for this target. +include googletest/googletest/CMakeFiles/gtest_main.dir/progress.make + +# Include the compile flags for this target's objects. +include googletest/googletest/CMakeFiles/gtest_main.dir/flags.make + +googletest/googletest/CMakeFiles/gtest_main.dir/codegen: +.PHONY : googletest/googletest/CMakeFiles/gtest_main.dir/codegen + +googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o: googletest/googletest/CMakeFiles/gtest_main.dir/flags.make +googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o: /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest_main.cc +googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o: googletest/googletest/CMakeFiles/gtest_main.dir/compiler_depend.ts + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building CXX object googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o" + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -MD -MT googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o -MF CMakeFiles/gtest_main.dir/src/gtest_main.cc.o.d -o CMakeFiles/gtest_main.dir/src/gtest_main.cc.o -c /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest_main.cc + +googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.i: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Preprocessing CXX source to CMakeFiles/gtest_main.dir/src/gtest_main.cc.i" + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -E /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest_main.cc > CMakeFiles/gtest_main.dir/src/gtest_main.cc.i + +googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.s: cmake_force + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green "Compiling CXX source to assembly CMakeFiles/gtest_main.dir/src/gtest_main.cc.s" + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest && /usr/bin/c++ $(CXX_DEFINES) $(CXX_INCLUDES) $(CXX_FLAGS) -S /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest_main.cc -o CMakeFiles/gtest_main.dir/src/gtest_main.cc.s + +# Object files for target gtest_main +gtest_main_OBJECTS = \ +"CMakeFiles/gtest_main.dir/src/gtest_main.cc.o" + +# External object files for target gtest_main +gtest_main_EXTERNAL_OBJECTS = + +lib/libgtest_main.a: googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o +lib/libgtest_main.a: googletest/googletest/CMakeFiles/gtest_main.dir/build.make +lib/libgtest_main.a: googletest/googletest/CMakeFiles/gtest_main.dir/link.txt + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --green --bold --progress-dir=/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX static library ../../lib/libgtest_main.a" + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest && $(CMAKE_COMMAND) -P CMakeFiles/gtest_main.dir/cmake_clean_target.cmake + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/gtest_main.dir/link.txt --verbose=$(VERBOSE) + +# Rule to build all files generated by this target. +googletest/googletest/CMakeFiles/gtest_main.dir/build: lib/libgtest_main.a +.PHONY : googletest/googletest/CMakeFiles/gtest_main.dir/build + +googletest/googletest/CMakeFiles/gtest_main.dir/clean: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest && $(CMAKE_COMMAND) -P CMakeFiles/gtest_main.dir/cmake_clean.cmake +.PHONY : googletest/googletest/CMakeFiles/gtest_main.dir/clean + +googletest/googletest/CMakeFiles/gtest_main.dir/depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /home/cryptolicious/hushmap-specified/libdpf/test /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest /home/cryptolicious/hushmap-specified/libdpf/test/build-asan /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/DependInfo.cmake "--color=$(COLOR)" gtest_main +.PHONY : googletest/googletest/CMakeFiles/gtest_main.dir/depend + diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/cmake_clean.cmake b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/cmake_clean.cmake new file mode 100644 index 0000000..96ba4d1 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/cmake_clean.cmake @@ -0,0 +1,11 @@ +file(REMOVE_RECURSE + "../../bin/libgtest_mainpdb_debug_postfix-NOTFOUND.pdb" + "../../lib/libgtest_main.a" + "CMakeFiles/gtest_main.dir/src/gtest_main.cc.o" + "CMakeFiles/gtest_main.dir/src/gtest_main.cc.o.d" +) + +# Per-language clean rules from dependency scanning. +foreach(lang CXX) + include(CMakeFiles/gtest_main.dir/cmake_clean_${lang}.cmake OPTIONAL) +endforeach() diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/cmake_clean_target.cmake b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/cmake_clean_target.cmake new file mode 100644 index 0000000..9e6a636 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/cmake_clean_target.cmake @@ -0,0 +1,3 @@ +file(REMOVE_RECURSE + "../../lib/libgtest_main.a" +) diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/compiler_depend.internal b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/compiler_depend.internal new file mode 100644 index 0000000..e230bb6 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/compiler_depend.internal @@ -0,0 +1,362 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest_main.cc + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-assertion-result.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-death-test.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-matchers.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-message.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-param-test.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-printers.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-test-part.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-typed-test.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_pred_impl.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_prod.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-port.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-printers.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-filepath.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-internal.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-param-util.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port-arch.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-string.h + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-type-util.h + /usr/include/alloca.h + /usr/include/asm-generic/bitsperlong.h + /usr/include/asm-generic/errno-base.h + /usr/include/asm-generic/errno.h + /usr/include/asm-generic/int-ll64.h + /usr/include/asm-generic/posix_types.h + /usr/include/asm-generic/types.h + /usr/include/assert.h + /usr/include/c++/15/any + /usr/include/c++/15/array + /usr/include/c++/15/atomic + /usr/include/c++/15/backward/auto_ptr.h + /usr/include/c++/15/backward/binders.h + /usr/include/c++/15/bit + /usr/include/c++/15/bits/align.h + /usr/include/c++/15/bits/alloc_traits.h + /usr/include/c++/15/bits/allocated_ptr.h + /usr/include/c++/15/bits/allocator.h + /usr/include/c++/15/bits/atomic_base.h + /usr/include/c++/15/bits/atomic_lockfree_defines.h + /usr/include/c++/15/bits/basic_ios.h + /usr/include/c++/15/bits/basic_ios.tcc + /usr/include/c++/15/bits/basic_string.h + /usr/include/c++/15/bits/basic_string.tcc + /usr/include/c++/15/bits/char_traits.h + /usr/include/c++/15/bits/charconv.h + /usr/include/c++/15/bits/chrono.h + /usr/include/c++/15/bits/codecvt.h + /usr/include/c++/15/bits/concept_check.h + /usr/include/c++/15/bits/cpp_type_traits.h + /usr/include/c++/15/bits/cxxabi_forced.h + /usr/include/c++/15/bits/cxxabi_init_exception.h + /usr/include/c++/15/bits/enable_special_members.h + /usr/include/c++/15/bits/erase_if.h + /usr/include/c++/15/bits/exception.h + /usr/include/c++/15/bits/exception_defines.h + /usr/include/c++/15/bits/exception_ptr.h + /usr/include/c++/15/bits/functexcept.h + /usr/include/c++/15/bits/functional_hash.h + /usr/include/c++/15/bits/hash_bytes.h + /usr/include/c++/15/bits/hashtable.h + /usr/include/c++/15/bits/hashtable_policy.h + /usr/include/c++/15/bits/invoke.h + /usr/include/c++/15/bits/ios_base.h + /usr/include/c++/15/bits/istream.tcc + /usr/include/c++/15/bits/locale_classes.h + /usr/include/c++/15/bits/locale_classes.tcc + /usr/include/c++/15/bits/locale_conv.h + /usr/include/c++/15/bits/locale_facets.h + /usr/include/c++/15/bits/locale_facets.tcc + /usr/include/c++/15/bits/locale_facets_nonio.h + /usr/include/c++/15/bits/locale_facets_nonio.tcc + /usr/include/c++/15/bits/localefwd.h + /usr/include/c++/15/bits/memory_resource.h + /usr/include/c++/15/bits/memoryfwd.h + /usr/include/c++/15/bits/monostate.h + /usr/include/c++/15/bits/move.h + /usr/include/c++/15/bits/nested_exception.h + /usr/include/c++/15/bits/new_allocator.h + /usr/include/c++/15/bits/node_handle.h + /usr/include/c++/15/bits/ostream.h + /usr/include/c++/15/bits/ostream.tcc + /usr/include/c++/15/bits/ostream_insert.h + /usr/include/c++/15/bits/parse_numbers.h + /usr/include/c++/15/bits/postypes.h + /usr/include/c++/15/bits/predefined_ops.h + /usr/include/c++/15/bits/ptr_traits.h + /usr/include/c++/15/bits/range_access.h + /usr/include/c++/15/bits/refwrap.h + /usr/include/c++/15/bits/requires_hosted.h + /usr/include/c++/15/bits/shared_ptr.h + /usr/include/c++/15/bits/shared_ptr_atomic.h + /usr/include/c++/15/bits/shared_ptr_base.h + /usr/include/c++/15/bits/sstream.tcc + /usr/include/c++/15/bits/std_abs.h + /usr/include/c++/15/bits/std_function.h + /usr/include/c++/15/bits/std_mutex.h + /usr/include/c++/15/bits/stl_algobase.h + /usr/include/c++/15/bits/stl_bvector.h + /usr/include/c++/15/bits/stl_construct.h + /usr/include/c++/15/bits/stl_function.h + /usr/include/c++/15/bits/stl_iterator.h + /usr/include/c++/15/bits/stl_iterator_base_funcs.h + /usr/include/c++/15/bits/stl_iterator_base_types.h + /usr/include/c++/15/bits/stl_map.h + /usr/include/c++/15/bits/stl_multimap.h + /usr/include/c++/15/bits/stl_multiset.h + /usr/include/c++/15/bits/stl_pair.h + /usr/include/c++/15/bits/stl_raw_storage_iter.h + /usr/include/c++/15/bits/stl_relops.h + /usr/include/c++/15/bits/stl_set.h + /usr/include/c++/15/bits/stl_tempbuf.h + /usr/include/c++/15/bits/stl_tree.h + /usr/include/c++/15/bits/stl_uninitialized.h + /usr/include/c++/15/bits/stl_vector.h + /usr/include/c++/15/bits/stream_iterator.h + /usr/include/c++/15/bits/streambuf.tcc + /usr/include/c++/15/bits/streambuf_iterator.h + /usr/include/c++/15/bits/string_view.tcc + /usr/include/c++/15/bits/stringfwd.h + /usr/include/c++/15/bits/unique_lock.h + /usr/include/c++/15/bits/unique_ptr.h + /usr/include/c++/15/bits/unordered_map.h + /usr/include/c++/15/bits/uses_allocator.h + /usr/include/c++/15/bits/uses_allocator_args.h + /usr/include/c++/15/bits/utility.h + /usr/include/c++/15/bits/vector.tcc + /usr/include/c++/15/bits/version.h + /usr/include/c++/15/cassert + /usr/include/c++/15/cctype + /usr/include/c++/15/cerrno + /usr/include/c++/15/clocale + /usr/include/c++/15/compare + /usr/include/c++/15/concepts + /usr/include/c++/15/condition_variable + /usr/include/c++/15/cstddef + /usr/include/c++/15/cstdint + /usr/include/c++/15/cstdio + /usr/include/c++/15/cstdlib + /usr/include/c++/15/ctime + /usr/include/c++/15/cwchar + /usr/include/c++/15/cwctype + /usr/include/c++/15/cxxabi.h + /usr/include/c++/15/debug/assertions.h + /usr/include/c++/15/debug/debug.h + /usr/include/c++/15/exception + /usr/include/c++/15/ext/aligned_buffer.h + /usr/include/c++/15/ext/alloc_traits.h + /usr/include/c++/15/ext/atomicity.h + /usr/include/c++/15/ext/concurrence.h + /usr/include/c++/15/ext/numeric_traits.h + /usr/include/c++/15/ext/string_conversions.h + /usr/include/c++/15/ext/type_traits.h + /usr/include/c++/15/functional + /usr/include/c++/15/initializer_list + /usr/include/c++/15/ios + /usr/include/c++/15/iosfwd + /usr/include/c++/15/iostream + /usr/include/c++/15/istream + /usr/include/c++/15/iterator + /usr/include/c++/15/limits + /usr/include/c++/15/locale + /usr/include/c++/15/map + /usr/include/c++/15/memory + /usr/include/c++/15/mutex + /usr/include/c++/15/new + /usr/include/c++/15/optional + /usr/include/c++/15/ostream + /usr/include/c++/15/pstl/execution_defs.h + /usr/include/c++/15/pstl/glue_memory_defs.h + /usr/include/c++/15/pstl/pstl_config.h + /usr/include/c++/15/ratio + /usr/include/c++/15/set + /usr/include/c++/15/sstream + /usr/include/c++/15/stdexcept + /usr/include/c++/15/stdlib.h + /usr/include/c++/15/streambuf + /usr/include/c++/15/string + /usr/include/c++/15/string_view + /usr/include/c++/15/system_error + /usr/include/c++/15/tuple + /usr/include/c++/15/type_traits + /usr/include/c++/15/typeinfo + /usr/include/c++/15/unordered_map + /usr/include/c++/15/utility + /usr/include/c++/15/variant + /usr/include/c++/15/vector + /usr/include/c++/15/version + /usr/include/ctype.h + /usr/include/endian.h + /usr/include/errno.h + /usr/include/features-time64.h + /usr/include/features.h + /usr/include/libintl.h + /usr/include/linux/close_range.h + /usr/include/linux/errno.h + /usr/include/linux/posix_types.h + /usr/include/linux/sched/types.h + /usr/include/linux/stat.h + /usr/include/linux/stddef.h + /usr/include/linux/types.h + /usr/include/locale.h + /usr/include/pthread.h + /usr/include/regex.h + /usr/include/sched.h + /usr/include/signal.h + /usr/include/stdc-predef.h + /usr/include/stdint.h + /usr/include/stdio.h + /usr/include/stdlib.h + /usr/include/string.h + /usr/include/strings.h + /usr/include/time.h + /usr/include/unistd.h + /usr/include/wchar.h + /usr/include/wctype.h + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h + /usr/include/x86_64-linux-gnu/asm/errno.h + /usr/include/x86_64-linux-gnu/asm/posix_types.h + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h + /usr/include/x86_64-linux-gnu/asm/types.h + /usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h + /usr/include/x86_64-linux-gnu/bits/byteswap.h + /usr/include/x86_64-linux-gnu/bits/confname.h + /usr/include/x86_64-linux-gnu/bits/cpu-set.h + /usr/include/x86_64-linux-gnu/bits/endian.h + /usr/include/x86_64-linux-gnu/bits/endianness.h + /usr/include/x86_64-linux-gnu/bits/environments.h + /usr/include/x86_64-linux-gnu/bits/errno.h + /usr/include/x86_64-linux-gnu/bits/floatn-common.h + /usr/include/x86_64-linux-gnu/bits/floatn.h + /usr/include/x86_64-linux-gnu/bits/getopt_core.h + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h + /usr/include/x86_64-linux-gnu/bits/locale.h + /usr/include/x86_64-linux-gnu/bits/long-double.h + /usr/include/x86_64-linux-gnu/bits/posix_opt.h + /usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h + /usr/include/x86_64-linux-gnu/bits/sched.h + /usr/include/x86_64-linux-gnu/bits/select-decl.h + /usr/include/x86_64-linux-gnu/bits/select.h + /usr/include/x86_64-linux-gnu/bits/select2.h + /usr/include/x86_64-linux-gnu/bits/setjmp.h + /usr/include/x86_64-linux-gnu/bits/sigaction.h + /usr/include/x86_64-linux-gnu/bits/sigcontext.h + /usr/include/x86_64-linux-gnu/bits/sigevent-consts.h + /usr/include/x86_64-linux-gnu/bits/siginfo-arch.h + /usr/include/x86_64-linux-gnu/bits/siginfo-consts-arch.h + /usr/include/x86_64-linux-gnu/bits/siginfo-consts.h + /usr/include/x86_64-linux-gnu/bits/signal_ext.h + /usr/include/x86_64-linux-gnu/bits/signum-arch.h + /usr/include/x86_64-linux-gnu/bits/signum-generic.h + /usr/include/x86_64-linux-gnu/bits/sigstack.h + /usr/include/x86_64-linux-gnu/bits/sigstksz.h + /usr/include/x86_64-linux-gnu/bits/sigthread.h + /usr/include/x86_64-linux-gnu/bits/ss_flags.h + /usr/include/x86_64-linux-gnu/bits/stat.h + /usr/include/x86_64-linux-gnu/bits/statx-generic.h + /usr/include/x86_64-linux-gnu/bits/statx.h + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h + /usr/include/x86_64-linux-gnu/bits/stdint-least.h + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h + /usr/include/x86_64-linux-gnu/bits/stdio.h + /usr/include/x86_64-linux-gnu/bits/stdio2-decl.h + /usr/include/x86_64-linux-gnu/bits/stdio2.h + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h + /usr/include/x86_64-linux-gnu/bits/stdlib.h + /usr/include/x86_64-linux-gnu/bits/string_fortified.h + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h + /usr/include/x86_64-linux-gnu/bits/struct_stat.h + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h + /usr/include/x86_64-linux-gnu/bits/time.h + /usr/include/x86_64-linux-gnu/bits/time64.h + /usr/include/x86_64-linux-gnu/bits/timesize.h + /usr/include/x86_64-linux-gnu/bits/timex.h + /usr/include/x86_64-linux-gnu/bits/types.h + /usr/include/x86_64-linux-gnu/bits/types/FILE.h + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h + /usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h + /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h + /usr/include/x86_64-linux-gnu/bits/types/error_t.h + /usr/include/x86_64-linux-gnu/bits/types/idtype_t.h + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h + /usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h + /usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h + /usr/include/x86_64-linux-gnu/bits/types/sigval_t.h + /usr/include/x86_64-linux-gnu/bits/types/stack_t.h + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h + /usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h + /usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h + /usr/include/x86_64-linux-gnu/bits/types/struct_statx.h + /usr/include/x86_64-linux-gnu/bits/types/struct_statx_timestamp.h + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h + /usr/include/x86_64-linux-gnu/bits/types/time_t.h + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h + /usr/include/x86_64-linux-gnu/bits/types/wint_t.h + /usr/include/x86_64-linux-gnu/bits/typesizes.h + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h + /usr/include/x86_64-linux-gnu/bits/unistd-decl.h + /usr/include/x86_64-linux-gnu/bits/unistd.h + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h + /usr/include/x86_64-linux-gnu/bits/waitflags.h + /usr/include/x86_64-linux-gnu/bits/waitstatus.h + /usr/include/x86_64-linux-gnu/bits/wchar.h + /usr/include/x86_64-linux-gnu/bits/wchar2-decl.h + /usr/include/x86_64-linux-gnu/bits/wchar2.h + /usr/include/x86_64-linux-gnu/bits/wctype-wchar.h + /usr/include/x86_64-linux-gnu/bits/wordsize.h + /usr/include/x86_64-linux-gnu/c++/15/bits/atomic_word.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++allocator.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++config.h + /usr/include/x86_64-linux-gnu/c++/15/bits/c++locale.h + /usr/include/x86_64-linux-gnu/c++/15/bits/cpu_defines.h + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_base.h + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_inline.h + /usr/include/x86_64-linux-gnu/c++/15/bits/cxxabi_tweaks.h + /usr/include/x86_64-linux-gnu/c++/15/bits/error_constants.h + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr-default.h + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr.h + /usr/include/x86_64-linux-gnu/c++/15/bits/messages_members.h + /usr/include/x86_64-linux-gnu/c++/15/bits/os_defines.h + /usr/include/x86_64-linux-gnu/c++/15/bits/time_members.h + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h + /usr/include/x86_64-linux-gnu/gnu/stubs.h + /usr/include/x86_64-linux-gnu/sys/cdefs.h + /usr/include/x86_64-linux-gnu/sys/select.h + /usr/include/x86_64-linux-gnu/sys/single_threaded.h + /usr/include/x86_64-linux-gnu/sys/stat.h + /usr/include/x86_64-linux-gnu/sys/types.h + /usr/include/x86_64-linux-gnu/sys/ucontext.h + /usr/include/x86_64-linux-gnu/sys/wait.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/float.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdarg.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h + diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/compiler_depend.make b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/compiler_depend.make new file mode 100644 index 0000000..0f47505 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/compiler_depend.make @@ -0,0 +1,1075 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o: /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest_main.cc \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-assertion-result.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-death-test.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-matchers.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-message.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-param-test.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-printers.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-test-part.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-typed-test.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_pred_impl.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_prod.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-port.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-printers.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-filepath.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-internal.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-param-util.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port-arch.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-string.h \ + /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-type-util.h \ + /usr/include/alloca.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/asm-generic/errno-base.h \ + /usr/include/asm-generic/errno.h \ + /usr/include/asm-generic/int-ll64.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/asm-generic/types.h \ + /usr/include/assert.h \ + /usr/include/c++/15/any \ + /usr/include/c++/15/array \ + /usr/include/c++/15/atomic \ + /usr/include/c++/15/backward/auto_ptr.h \ + /usr/include/c++/15/backward/binders.h \ + /usr/include/c++/15/bit \ + /usr/include/c++/15/bits/align.h \ + /usr/include/c++/15/bits/alloc_traits.h \ + /usr/include/c++/15/bits/allocated_ptr.h \ + /usr/include/c++/15/bits/allocator.h \ + /usr/include/c++/15/bits/atomic_base.h \ + /usr/include/c++/15/bits/atomic_lockfree_defines.h \ + /usr/include/c++/15/bits/basic_ios.h \ + /usr/include/c++/15/bits/basic_ios.tcc \ + /usr/include/c++/15/bits/basic_string.h \ + /usr/include/c++/15/bits/basic_string.tcc \ + /usr/include/c++/15/bits/char_traits.h \ + /usr/include/c++/15/bits/charconv.h \ + /usr/include/c++/15/bits/chrono.h \ + /usr/include/c++/15/bits/codecvt.h \ + /usr/include/c++/15/bits/concept_check.h \ + /usr/include/c++/15/bits/cpp_type_traits.h \ + /usr/include/c++/15/bits/cxxabi_forced.h \ + /usr/include/c++/15/bits/cxxabi_init_exception.h \ + /usr/include/c++/15/bits/enable_special_members.h \ + /usr/include/c++/15/bits/erase_if.h \ + /usr/include/c++/15/bits/exception.h \ + /usr/include/c++/15/bits/exception_defines.h \ + /usr/include/c++/15/bits/exception_ptr.h \ + /usr/include/c++/15/bits/functexcept.h \ + /usr/include/c++/15/bits/functional_hash.h \ + /usr/include/c++/15/bits/hash_bytes.h \ + /usr/include/c++/15/bits/hashtable.h \ + /usr/include/c++/15/bits/hashtable_policy.h \ + /usr/include/c++/15/bits/invoke.h \ + /usr/include/c++/15/bits/ios_base.h \ + /usr/include/c++/15/bits/istream.tcc \ + /usr/include/c++/15/bits/locale_classes.h \ + /usr/include/c++/15/bits/locale_classes.tcc \ + /usr/include/c++/15/bits/locale_conv.h \ + /usr/include/c++/15/bits/locale_facets.h \ + /usr/include/c++/15/bits/locale_facets.tcc \ + /usr/include/c++/15/bits/locale_facets_nonio.h \ + /usr/include/c++/15/bits/locale_facets_nonio.tcc \ + /usr/include/c++/15/bits/localefwd.h \ + /usr/include/c++/15/bits/memory_resource.h \ + /usr/include/c++/15/bits/memoryfwd.h \ + /usr/include/c++/15/bits/monostate.h \ + /usr/include/c++/15/bits/move.h \ + /usr/include/c++/15/bits/nested_exception.h \ + /usr/include/c++/15/bits/new_allocator.h \ + /usr/include/c++/15/bits/node_handle.h \ + /usr/include/c++/15/bits/ostream.h \ + /usr/include/c++/15/bits/ostream.tcc \ + /usr/include/c++/15/bits/ostream_insert.h \ + /usr/include/c++/15/bits/parse_numbers.h \ + /usr/include/c++/15/bits/postypes.h \ + /usr/include/c++/15/bits/predefined_ops.h \ + /usr/include/c++/15/bits/ptr_traits.h \ + /usr/include/c++/15/bits/range_access.h \ + /usr/include/c++/15/bits/refwrap.h \ + /usr/include/c++/15/bits/requires_hosted.h \ + /usr/include/c++/15/bits/shared_ptr.h \ + /usr/include/c++/15/bits/shared_ptr_atomic.h \ + /usr/include/c++/15/bits/shared_ptr_base.h \ + /usr/include/c++/15/bits/sstream.tcc \ + /usr/include/c++/15/bits/std_abs.h \ + /usr/include/c++/15/bits/std_function.h \ + /usr/include/c++/15/bits/std_mutex.h \ + /usr/include/c++/15/bits/stl_algobase.h \ + /usr/include/c++/15/bits/stl_bvector.h \ + /usr/include/c++/15/bits/stl_construct.h \ + /usr/include/c++/15/bits/stl_function.h \ + /usr/include/c++/15/bits/stl_iterator.h \ + /usr/include/c++/15/bits/stl_iterator_base_funcs.h \ + /usr/include/c++/15/bits/stl_iterator_base_types.h \ + /usr/include/c++/15/bits/stl_map.h \ + /usr/include/c++/15/bits/stl_multimap.h \ + /usr/include/c++/15/bits/stl_multiset.h \ + /usr/include/c++/15/bits/stl_pair.h \ + /usr/include/c++/15/bits/stl_raw_storage_iter.h \ + /usr/include/c++/15/bits/stl_relops.h \ + /usr/include/c++/15/bits/stl_set.h \ + /usr/include/c++/15/bits/stl_tempbuf.h \ + /usr/include/c++/15/bits/stl_tree.h \ + /usr/include/c++/15/bits/stl_uninitialized.h \ + /usr/include/c++/15/bits/stl_vector.h \ + /usr/include/c++/15/bits/stream_iterator.h \ + /usr/include/c++/15/bits/streambuf.tcc \ + /usr/include/c++/15/bits/streambuf_iterator.h \ + /usr/include/c++/15/bits/string_view.tcc \ + /usr/include/c++/15/bits/stringfwd.h \ + /usr/include/c++/15/bits/unique_lock.h \ + /usr/include/c++/15/bits/unique_ptr.h \ + /usr/include/c++/15/bits/unordered_map.h \ + /usr/include/c++/15/bits/uses_allocator.h \ + /usr/include/c++/15/bits/uses_allocator_args.h \ + /usr/include/c++/15/bits/utility.h \ + /usr/include/c++/15/bits/vector.tcc \ + /usr/include/c++/15/bits/version.h \ + /usr/include/c++/15/cassert \ + /usr/include/c++/15/cctype \ + /usr/include/c++/15/cerrno \ + /usr/include/c++/15/clocale \ + /usr/include/c++/15/compare \ + /usr/include/c++/15/concepts \ + /usr/include/c++/15/condition_variable \ + /usr/include/c++/15/cstddef \ + /usr/include/c++/15/cstdint \ + /usr/include/c++/15/cstdio \ + /usr/include/c++/15/cstdlib \ + /usr/include/c++/15/ctime \ + /usr/include/c++/15/cwchar \ + /usr/include/c++/15/cwctype \ + /usr/include/c++/15/cxxabi.h \ + /usr/include/c++/15/debug/assertions.h \ + /usr/include/c++/15/debug/debug.h \ + /usr/include/c++/15/exception \ + /usr/include/c++/15/ext/aligned_buffer.h \ + /usr/include/c++/15/ext/alloc_traits.h \ + /usr/include/c++/15/ext/atomicity.h \ + /usr/include/c++/15/ext/concurrence.h \ + /usr/include/c++/15/ext/numeric_traits.h \ + /usr/include/c++/15/ext/string_conversions.h \ + /usr/include/c++/15/ext/type_traits.h \ + /usr/include/c++/15/functional \ + /usr/include/c++/15/initializer_list \ + /usr/include/c++/15/ios \ + /usr/include/c++/15/iosfwd \ + /usr/include/c++/15/iostream \ + /usr/include/c++/15/istream \ + /usr/include/c++/15/iterator \ + /usr/include/c++/15/limits \ + /usr/include/c++/15/locale \ + /usr/include/c++/15/map \ + /usr/include/c++/15/memory \ + /usr/include/c++/15/mutex \ + /usr/include/c++/15/new \ + /usr/include/c++/15/optional \ + /usr/include/c++/15/ostream \ + /usr/include/c++/15/pstl/execution_defs.h \ + /usr/include/c++/15/pstl/glue_memory_defs.h \ + /usr/include/c++/15/pstl/pstl_config.h \ + /usr/include/c++/15/ratio \ + /usr/include/c++/15/set \ + /usr/include/c++/15/sstream \ + /usr/include/c++/15/stdexcept \ + /usr/include/c++/15/stdlib.h \ + /usr/include/c++/15/streambuf \ + /usr/include/c++/15/string \ + /usr/include/c++/15/string_view \ + /usr/include/c++/15/system_error \ + /usr/include/c++/15/tuple \ + /usr/include/c++/15/type_traits \ + /usr/include/c++/15/typeinfo \ + /usr/include/c++/15/unordered_map \ + /usr/include/c++/15/utility \ + /usr/include/c++/15/variant \ + /usr/include/c++/15/vector \ + /usr/include/c++/15/version \ + /usr/include/ctype.h \ + /usr/include/endian.h \ + /usr/include/errno.h \ + /usr/include/features-time64.h \ + /usr/include/features.h \ + /usr/include/libintl.h \ + /usr/include/linux/close_range.h \ + /usr/include/linux/errno.h \ + /usr/include/linux/posix_types.h \ + /usr/include/linux/sched/types.h \ + /usr/include/linux/stat.h \ + /usr/include/linux/stddef.h \ + /usr/include/linux/types.h \ + /usr/include/locale.h \ + /usr/include/pthread.h \ + /usr/include/regex.h \ + /usr/include/sched.h \ + /usr/include/signal.h \ + /usr/include/stdc-predef.h \ + /usr/include/stdint.h \ + /usr/include/stdio.h \ + /usr/include/stdlib.h \ + /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/time.h \ + /usr/include/unistd.h \ + /usr/include/wchar.h \ + /usr/include/wctype.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/x86_64-linux-gnu/asm/types.h \ + /usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/select-decl.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigevent-consts.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-arch.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-consts-arch.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-consts.h \ + /usr/include/x86_64-linux-gnu/bits/signal_ext.h \ + /usr/include/x86_64-linux-gnu/bits/signum-arch.h \ + /usr/include/x86_64-linux-gnu/bits/signum-generic.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/sigstksz.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h \ + /usr/include/x86_64-linux-gnu/bits/ss_flags.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h \ + /usr/include/x86_64-linux-gnu/bits/statx-generic.h \ + /usr/include/x86_64-linux-gnu/bits/statx.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-least.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2-decl.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/struct_stat.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/timex.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/error_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/idtype_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/stack_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_statx.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_statx_timestamp.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/wint_t.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/bits/unistd-decl.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2-decl.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2.h \ + /usr/include/x86_64-linux-gnu/bits/wctype-wchar.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/atomic_word.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++allocator.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++config.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/c++locale.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/cpu_defines.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_base.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/ctype_inline.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/cxxabi_tweaks.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/error_constants.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr-default.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/gthr.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/messages_members.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/os_defines.h \ + /usr/include/x86_64-linux-gnu/c++/15/bits/time_members.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/sys/single_threaded.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/sys/wait.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/float.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdarg.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h + + +/usr/lib/gcc/x86_64-linux-gnu/15/include/stdint.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/stdarg.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/float.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/sys/single_threaded.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/messages_members.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/error_constants.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/cxxabi_tweaks.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/ctype_base.h: + +/usr/lib/gcc/x86_64-linux-gnu/15/include/stddef.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++config.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++allocator.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/wctype-wchar.h: + +/usr/include/x86_64-linux-gnu/bits/wchar2.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/types/wint_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_statx.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/stack_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/idtype_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct___jmp_buf_tag.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/timex.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-least.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/x86_64-linux-gnu/bits/statx-generic.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/x86_64-linux-gnu/bits/sigstksz.h: + +/usr/include/c++/15/bits/unique_ptr.h: + +/usr/include/c++/15/bits/string_view.tcc: + +/usr/include/c++/15/cassert: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/c++/15/bits/stl_set.h: + +/usr/include/c++/15/bits/stl_raw_storage_iter.h: + +/usr/include/assert.h: + +/usr/include/c++/15/cctype: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/c++/15/bits/stl_iterator_base_funcs.h: + +/usr/include/c++/15/ext/atomicity.h: + +/usr/include/c++/15/clocale: + +/usr/include/c++/15/bits/sstream.tcc: + +/usr/include/c++/15/bits/stl_uninitialized.h: + +/usr/include/c++/15/bits/stl_multimap.h: + +/usr/include/c++/15/bits/shared_ptr_base.h: + +/usr/include/regex.h: + +/usr/include/c++/15/bits/refwrap.h: + +/usr/include/c++/15/type_traits: + +/usr/include/c++/15/bits/stl_multiset.h: + +/usr/include/c++/15/bits/range_access.h: + +/usr/include/c++/15/bits/stl_construct.h: + +/usr/include/c++/15/bits/ptr_traits.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/c++/15/bits/postypes.h: + +/usr/include/c++/15/bits/parse_numbers.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/os_defines.h: + +/usr/include/c++/15/bits/new_allocator.h: + +/usr/include/c++/15/bits/uses_allocator.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/ctype_inline.h: + +/usr/include/c++/15/bits/move.h: + +/usr/include/c++/15/bits/monostate.h: + +/usr/include/c++/15/bits/localefwd.h: + +/usr/include/c++/15/bits/stl_algobase.h: + +/usr/include/c++/15/bits/stl_relops.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/c++/15/bits/stream_iterator.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-message.h: + +/usr/include/c++/15/bits/ostream_insert.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/atomic_word.h: + +/usr/include/c++/15/bits/locale_facets_nonio.h: + +/usr/include/c++/15/exception: + +/usr/include/c++/15/bits/stl_function.h: + +/usr/include/c++/15/cwchar: + +/usr/include/string.h: + +/usr/include/c++/15/bits/locale_facets.tcc: + +/usr/include/c++/15/bits/locale_conv.h: + +/usr/include/ctype.h: + +/usr/include/c++/15/bits/locale_classes.tcc: + +/usr/include/x86_64-linux-gnu/c++/15/bits/time_members.h: + +/usr/include/c++/15/bits/hash_bytes.h: + +/usr/include/c++/15/bits/locale_facets_nonio.tcc: + +/usr/include/c++/15/bits/invoke.h: + +/usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h: + +/usr/include/c++/15/bits/hashtable.h: + +/usr/include/c++/15/iterator: + +/usr/include/c++/15/bits/locale_facets.h: + +/usr/include/c++/15/bits/requires_hosted.h: + +/usr/include/c++/15/cstdlib: + +/usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h: + +/usr/include/x86_64-linux-gnu/bits/types/error_t.h: + +/usr/include/c++/15/bits/stl_vector.h: + +/usr/include/c++/15/bits/functexcept.h: + +/usr/include/c++/15/bits/charconv.h: + +/usr/include/asm-generic/int-ll64.h: + +/usr/include/x86_64-linux-gnu/bits/signum-generic.h: + +/usr/include/c++/15/bits/memoryfwd.h: + +/usr/include/x86_64-linux-gnu/sys/wait.h: + +/usr/include/asm-generic/errno-base.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-string.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/x86_64-linux-gnu/bits/signum-arch.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port.h: + +/usr/include/x86_64-linux-gnu/bits/struct_stat.h: + +/usr/include/c++/15/bits/streambuf_iterator.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_statx_timestamp.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-internal.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-death-test-internal.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-type-util.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-test-part.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/gthr.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-printers.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-filepath.h: + +/usr/include/c++/15/bits/unique_lock.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-typed-test.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-port-arch.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/asm-generic/types.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h: + +/usr/include/x86_64-linux-gnu/bits/ss_flags.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-death-test.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-assertion-result.h: + +/usr/include/c++/15/cstddef: + +/usr/include/errno.h: + +/usr/include/c++/15/bits/ios_base.h: + +/usr/include/c++/15/bits/alloc_traits.h: + +/usr/include/c++/15/bits/istream.tcc: + +/usr/include/c++/15/bits/allocated_ptr.h: + +/usr/include/c++/15/version: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/asm-generic/errno.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-matchers.h: + +/usr/include/c++/15/cstdint: + +/usr/include/c++/15/bits/std_abs.h: + +/usr/include/c++/15/typeinfo: + +/usr/include/c++/15/bits/exception_defines.h: + +/usr/include/c++/15/backward/auto_ptr.h: + +/usr/include/c++/15/bits/stl_iterator.h: + +/usr/include/c++/15/bits/stl_pair.h: + +/usr/include/c++/15/bits/stl_bvector.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigval_t.h: + +/usr/include/c++/15/memory: + +/usr/include/c++/15/vector: + +/usr/include/alloca.h: + +/usr/include/c++/15/bits/ostream.h: + +/usr/include/c++/15/bits/streambuf.tcc: + +/usr/include/c++/15/bits/basic_string.tcc: + +/usr/include/c++/15/bits/std_mutex.h: + +/usr/include/c++/15/bits/node_handle.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/c++locale.h: + +/usr/include/c++/15/pstl/glue_memory_defs.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/custom/gtest-port.h: + +/usr/include/c++/15/bits/concept_check.h: + +/usr/include/x86_64-linux-gnu/bits/wchar2-decl.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/src/gtest_main.cc: + +/usr/include/c++/15/bits/version.h: + +/usr/include/linux/stat.h: + +/usr/include/c++/15/bits/functional_hash.h: + +/usr/include/c++/15/ext/type_traits.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest.h: + +/usr/include/c++/15/istream: + +/usr/include/c++/15/tuple: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-param-test.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_pred_impl.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/c++/15/bits/stl_tempbuf.h: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest-printers.h: + +/usr/include/c++/15/bits/shared_ptr_atomic.h: + +/usr/include/c++/15/map: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/gtest_prod.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/c++/15/concepts: + +/usr/include/c++/15/bits/std_function.h: + +/usr/include/c++/15/bits/codecvt.h: + +/usr/include/c++/15/bits/erase_if.h: + +/usr/include/c++/15/bits/stringfwd.h: + +/usr/include/c++/15/bits/shared_ptr.h: + +/usr/include/c++/15/any: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-arch.h: + +/usr/include/c++/15/bits/align.h: + +/usr/include/c++/15/bits/stl_iterator_base_types.h: + +/usr/include/stdc-predef.h: + +/usr/include/c++/15/bits/atomic_base.h: + +/usr/include/c++/15/bits/chrono.h: + +/usr/include/c++/15/bits/nested_exception.h: + +/usr/include/linux/sched/types.h: + +/usr/include/c++/15/bits/basic_ios.tcc: + +/home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include/gtest/internal/gtest-param-util.h: + +/usr/include/c++/15/bits/char_traits.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/cpu_defines.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/c++/15/bits/uses_allocator_args.h: + +/usr/include/c++/15/bits/cpp_type_traits.h: + +/usr/include/c++/15/bits/basic_string.h: + +/usr/include/c++/15/streambuf: + +/usr/include/c++/15/backward/binders.h: + +/usr/include/c++/15/utility: + +/usr/include/c++/15/bits/enable_special_members.h: + +/usr/include/c++/15/bits/stl_tree.h: + +/usr/include/c++/15/bits/cxxabi_init_exception.h: + +/usr/include/c++/15/variant: + +/usr/include/c++/15/initializer_list: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/c++/15/bits/allocator.h: + +/usr/include/c++/15/bit: + +/usr/include/pthread.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/c++/15/bits/utility.h: + +/usr/include/linux/close_range.h: + +/usr/include/c++/15/cerrno: + +/usr/include/c++/15/bits/cxxabi_forced.h: + +/usr/include/c++/15/compare: + +/usr/include/c++/15/cstdio: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/bits/unistd-decl.h: + +/usr/include/c++/15/stdlib.h: + +/usr/include/c++/15/ctime: + +/usr/include/c++/15/cxxabi.h: + +/usr/include/features-time64.h: + +/usr/include/c++/15/debug/debug.h: + +/usr/include/c++/15/ext/aligned_buffer.h: + +/usr/include/c++/15/cwctype: + +/usr/include/x86_64-linux-gnu/asm/types.h: + +/usr/include/c++/15/condition_variable: + +/usr/include/c++/15/ext/alloc_traits.h: + +/usr/include/linux/types.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/c++/15/bits/exception_ptr.h: + +/usr/include/c++/15/ext/concurrence.h: + +/usr/include/c++/15/ext/numeric_traits.h: + +/usr/include/c++/15/bits/hashtable_policy.h: + +/usr/include/c++/15/ext/string_conversions.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h: + +/usr/include/c++/15/functional: + +/usr/include/c++/15/ios: + +/usr/include/c++/15/bits/ostream.tcc: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/c++/15/bits/gthr-default.h: + +/usr/include/c++/15/limits: + +/usr/include/c++/15/bits/vector.tcc: + +/usr/include/c++/15/iostream: + +/usr/include/c++/15/locale: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/c++/15/string_view: + +/usr/include/c++/15/mutex: + +/usr/include/linux/errno.h: + +/usr/include/c++/15/new: + +/usr/include/x86_64-linux-gnu/bits/siginfo-consts.h: + +/usr/include/c++/15/bits/predefined_ops.h: + +/usr/include/c++/15/optional: + +/usr/include/signal.h: + +/usr/include/strings.h: + +/usr/include/c++/15/bits/exception.h: + +/usr/include/c++/15/ostream: + +/usr/include/c++/15/pstl/execution_defs.h: + +/usr/include/c++/15/pstl/pstl_config.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/c++/15/bits/memory_resource.h: + +/usr/include/c++/15/set: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/wchar.h: + +/usr/include/c++/15/sstream: + +/usr/include/c++/15/atomic: + +/usr/include/c++/15/ratio: + +/usr/include/c++/15/stdexcept: + +/usr/include/c++/15/string: + +/usr/include/c++/15/system_error: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/c++/15/unordered_map: + +/usr/include/stdint.h: + +/usr/include/endian.h: + +/usr/include/features.h: + +/usr/include/libintl.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2-decl.h: + +/usr/include/linux/posix_types.h: + +/usr/include/c++/15/bits/stl_map.h: + +/usr/include/c++/15/bits/locale_classes.h: + +/usr/include/linux/stddef.h: + +/usr/include/locale.h: + +/usr/include/c++/15/debug/assertions.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/wctype.h: + +/usr/include/sched.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/statx.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-consts-arch.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/c++/15/bits/unordered_map.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/c++/15/bits/basic_ios.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/c++/15/bits/atomic_lockfree_defines.h: + +/usr/include/x86_64-linux-gnu/bits/select-decl.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/c++/15/array: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/c++/15/iosfwd: + +/usr/include/x86_64-linux-gnu/bits/sigevent-consts.h: + +/usr/include/x86_64-linux-gnu/bits/signal_ext.h: diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/compiler_depend.ts b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/compiler_depend.ts new file mode 100644 index 0000000..033891a --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/compiler_depend.ts @@ -0,0 +1,2 @@ +# CMAKE generated file: DO NOT EDIT! +# Timestamp file for compiler generated dependencies management for gtest_main. diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/depend.make b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/depend.make new file mode 100644 index 0000000..1d67c1a --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/depend.make @@ -0,0 +1,2 @@ +# Empty dependencies file for gtest_main. +# This may be replaced when dependencies are built. diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/flags.make b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/flags.make new file mode 100644 index 0000000..9bf6ed6 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/flags.make @@ -0,0 +1,10 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# compile CXX with /usr/bin/c++ +CXX_DEFINES = + +CXX_INCLUDES = -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest/include -isystem /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +CXX_FLAGS = -fsanitize=address,undefined -fno-omit-frame-pointer -g -O1 -g -std=c++17 -Wall -Wshadow -Wundef -Wno-error=dangling-else -DGTEST_HAS_PTHREAD=1 -fexceptions -Wextra -Wno-unused-parameter -Wno-missing-field-initializers + diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/link.txt b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/link.txt new file mode 100644 index 0000000..e03e009 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/link.txt @@ -0,0 +1,2 @@ +/usr/bin/ar qc ../../lib/libgtest_main.a CMakeFiles/gtest_main.dir/src/gtest_main.cc.o +/usr/bin/ranlib ../../lib/libgtest_main.a diff --git a/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/progress.make b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/progress.make new file mode 100644 index 0000000..a0338d9 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/gtest_main.dir/progress.make @@ -0,0 +1,3 @@ +CMAKE_PROGRESS_1 = +CMAKE_PROGRESS_2 = 43 + diff --git a/test/build-asan/googletest/googletest/CMakeFiles/progress.marks b/test/build-asan/googletest/googletest/CMakeFiles/progress.marks new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/test/build-asan/googletest/googletest/CMakeFiles/progress.marks @@ -0,0 +1 @@ +2 diff --git a/test/build-asan/googletest/googletest/CTestTestfile.cmake b/test/build-asan/googletest/googletest/CTestTestfile.cmake new file mode 100644 index 0000000..34f09a8 --- /dev/null +++ b/test/build-asan/googletest/googletest/CTestTestfile.cmake @@ -0,0 +1,6 @@ +# CMake generated Testfile for +# Source directory: /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest +# Build directory: /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest +# +# This file includes the relevant testing commands required for +# testing this directory and lists subdirectories to be tested as well. diff --git a/test/build-asan/googletest/googletest/Makefile b/test/build-asan/googletest/googletest/Makefile new file mode 100644 index 0000000..e55f3d7 --- /dev/null +++ b/test/build-asan/googletest/googletest/Makefile @@ -0,0 +1,235 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 4.2 + +# Default target executed when no arguments are given to make. +default_target: all +.PHONY : default_target + +# Allow only one "make -f Makefile2" at a time, but pass parallelism. +.NOTPARALLEL: + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + +# Disable VCS-based implicit rules. +% : %,v + +# Disable VCS-based implicit rules. +% : RCS/% + +# Disable VCS-based implicit rules. +% : RCS/%,v + +# Disable VCS-based implicit rules. +% : SCCS/s.% + +# Disable VCS-based implicit rules. +% : s.% + +.SUFFIXES: .hpux_make_needs_suffix_list + +# Command-line flag to silence nested $(MAKE). +$(VERBOSE)MAKESILENT = -s + +#Suppress display of executed commands. +$(VERBOSE).SILENT: + +# A target that is always out of date. +cmake_force: +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E rm -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /home/cryptolicious/hushmap-specified/libdpf/test + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /home/cryptolicious/hushmap-specified/libdpf/test/build-asan + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target test +test: + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running tests..." + /usr/bin/ctest $(ARGS) +.PHONY : test + +# Special rule for the target test +test/fast: test +.PHONY : test/fast + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "No interactive CMake dialog available..." + /usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available. +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache +.PHONY : edit_cache/fast + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color "--switch=$(COLOR)" --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache +.PHONY : rebuild_cache/fast + +# The main all target +all: cmake_check_build_system + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest//CMakeFiles/progress.marks + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 googletest/googletest/all + $(CMAKE_COMMAND) -E cmake_progress_start /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 googletest/googletest/clean +.PHONY : clean + +# The main clean target +clean/fast: clean +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 googletest/googletest/preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 googletest/googletest/preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +# Convenience name for target. +googletest/googletest/CMakeFiles/gtest.dir/rule: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 googletest/googletest/CMakeFiles/gtest.dir/rule +.PHONY : googletest/googletest/CMakeFiles/gtest.dir/rule + +# Convenience name for target. +gtest: googletest/googletest/CMakeFiles/gtest.dir/rule +.PHONY : gtest + +# fast build rule for target. +gtest/fast: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest.dir/build.make googletest/googletest/CMakeFiles/gtest.dir/build +.PHONY : gtest/fast + +# Convenience name for target. +googletest/googletest/CMakeFiles/gtest_main.dir/rule: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 googletest/googletest/CMakeFiles/gtest_main.dir/rule +.PHONY : googletest/googletest/CMakeFiles/gtest_main.dir/rule + +# Convenience name for target. +gtest_main: googletest/googletest/CMakeFiles/gtest_main.dir/rule +.PHONY : gtest_main + +# fast build rule for target. +gtest_main/fast: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest_main.dir/build.make googletest/googletest/CMakeFiles/gtest_main.dir/build +.PHONY : gtest_main/fast + +src/gtest-all.o: src/gtest-all.cc.o +.PHONY : src/gtest-all.o + +# target to build an object file +src/gtest-all.cc.o: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest.dir/build.make googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o +.PHONY : src/gtest-all.cc.o + +src/gtest-all.i: src/gtest-all.cc.i +.PHONY : src/gtest-all.i + +# target to preprocess a source file +src/gtest-all.cc.i: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest.dir/build.make googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.i +.PHONY : src/gtest-all.cc.i + +src/gtest-all.s: src/gtest-all.cc.s +.PHONY : src/gtest-all.s + +# target to generate assembly for a file +src/gtest-all.cc.s: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest.dir/build.make googletest/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.s +.PHONY : src/gtest-all.cc.s + +src/gtest_main.o: src/gtest_main.cc.o +.PHONY : src/gtest_main.o + +# target to build an object file +src/gtest_main.cc.o: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest_main.dir/build.make googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o +.PHONY : src/gtest_main.cc.o + +src/gtest_main.i: src/gtest_main.cc.i +.PHONY : src/gtest_main.i + +# target to preprocess a source file +src/gtest_main.cc.i: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest_main.dir/build.make googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.i +.PHONY : src/gtest_main.cc.i + +src/gtest_main.s: src/gtest_main.cc.s +.PHONY : src/gtest_main.s + +# target to generate assembly for a file +src/gtest_main.cc.s: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(MAKE) $(MAKESILENT) -f googletest/googletest/CMakeFiles/gtest_main.dir/build.make googletest/googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.s +.PHONY : src/gtest_main.cc.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... edit_cache" + @echo "... rebuild_cache" + @echo "... test" + @echo "... gtest" + @echo "... gtest_main" + @echo "... src/gtest-all.o" + @echo "... src/gtest-all.i" + @echo "... src/gtest-all.s" + @echo "... src/gtest_main.o" + @echo "... src/gtest_main.i" + @echo "... src/gtest_main.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + cd /home/cryptolicious/hushmap-specified/libdpf/test/build-asan && $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/test/build-asan/googletest/googletest/cmake_install.cmake b/test/build-asan/googletest/googletest/cmake_install.cmake new file mode 100644 index 0000000..d74e10a --- /dev/null +++ b/test/build-asan/googletest/googletest/cmake_install.cmake @@ -0,0 +1,50 @@ +# Install script for directory: /home/cryptolicious/hushmap-specified/libdpf/test/googletest/googletest + +# Set the install prefix +if(NOT DEFINED CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "/usr/local") +endif() +string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") + +# Set the install configuration name. +if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME) + if(BUILD_TYPE) + string(REGEX REPLACE "^[^A-Za-z0-9_]+" "" + CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}") + else() + set(CMAKE_INSTALL_CONFIG_NAME "Debug") + endif() + message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"") +endif() + +# Set the component getting installed. +if(NOT CMAKE_INSTALL_COMPONENT) + if(COMPONENT) + message(STATUS "Install component: \"${COMPONENT}\"") + set(CMAKE_INSTALL_COMPONENT "${COMPONENT}") + else() + set(CMAKE_INSTALL_COMPONENT) + endif() +endif() + +# Install shared libraries without execute permission? +if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE) + set(CMAKE_INSTALL_SO_NO_EXE "1") +endif() + +# Is this installation the result of a crosscompile? +if(NOT DEFINED CMAKE_CROSSCOMPILING) + set(CMAKE_CROSSCOMPILING "FALSE") +endif() + +# Set path to fallback-tool for dependency-resolution. +if(NOT DEFINED CMAKE_OBJDUMP) + set(CMAKE_OBJDUMP "/usr/bin/objdump") +endif() + +string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT + "${CMAKE_INSTALL_MANIFEST_FILES}") +if(CMAKE_INSTALL_LOCAL_ONLY) + file(WRITE "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/googletest/googletest/install_local_manifest.txt" + "${CMAKE_INSTALL_MANIFEST_CONTENT}") +endif() diff --git a/test/build-asan/growing_idpf_test[1]_include.cmake b/test/build-asan/growing_idpf_test[1]_include.cmake new file mode 100644 index 0000000..f212d4d --- /dev/null +++ b/test/build-asan/growing_idpf_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/growing_idpf_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/growing_idpf_test[1]_tests.cmake") +else() + add_test(growing_idpf_test_NOT_BUILT growing_idpf_test_NOT_BUILT) +endif() diff --git a/test/build-asan/growing_idpf_test[1]_tests.cmake b/test/build-asan/growing_idpf_test[1]_tests.cmake new file mode 100644 index 0000000..fac0546 --- /dev/null +++ b/test/build-asan/growing_idpf_test[1]_tests.cmake @@ -0,0 +1,37 @@ +add_test([=[GrowingIdpf.PrefixesOpenToOwnPayload]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.PrefixesOpenToOwnPayload]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.PrefixesOpenToOwnPayload]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:63 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpf.ExtendMatchesFullySpecified]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.ExtendMatchesFullySpecified]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.ExtendMatchesFullySpecified]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:94 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpf.AddOutputWildcardOnExistingLevel]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.AddOutputWildcardOnExistingLevel]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.AddOutputWildcardOnExistingLevel]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:140 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpf.DeepestPrefixMatchesClassicDpf]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.DeepestPrefixMatchesClassicDpf]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.DeepestPrefixMatchesClassicDpf]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:162 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpf.ChaChaPrgOpensThePrefix]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.ChaChaPrgOpensThePrefix]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.ChaChaPrgOpensThePrefix]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:189 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpf.MemoizerExtendMatchesRewalk]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.MemoizerExtendMatchesRewalk]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.MemoizerExtendMatchesRewalk]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:224 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpf.ExtendDsMatchesDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.ExtendDsMatchesDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.ExtendDsMatchesDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:255 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpf.AddOutputDsWildcard]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.AddOutputDsWildcard]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.AddOutputDsWildcard]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:284 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpf.ShallowMemoizerThrows]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.ShallowMemoizerThrows]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.ShallowMemoizerThrows]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:307 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpf.ExtendSaturatesEightBitDomain]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.ExtendSaturatesEightBitDomain]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.ExtendSaturatesEightBitDomain]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:356 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpf.ExhaustiveDomainAfterMemoGrow]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.ExhaustiveDomainAfterMemoGrow]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.ExhaustiveDomainAfterMemoGrow]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:421 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpf.DsAndDealerAgreeFullDomain]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.DsAndDealerAgreeFullDomain]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.DsAndDealerAgreeFullDomain]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:450 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpf.EmptyAddOutputThrows]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpf.EmptyAddOutputThrows]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpf.EmptyAddOutputThrows]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:482 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpfDeath.MismatchedKeyPairThrows]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpfDeath.MismatchedKeyPairThrows]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpfDeath.MismatchedKeyPairThrows]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:323 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpfDeath.WrongPathBitThrows]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpfDeath.WrongPathBitThrows]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpfDeath.WrongPathBitThrows]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:334 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpfDeath.SpecNotOnNewDepthThrows]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpfDeath.SpecNotOnNewDepthThrows]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpfDeath.SpecNotOnNewDepthThrows]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:345 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpfDeath.MemoizerOnSiblingCorruptsNewSlot]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpfDeath.MemoizerOnSiblingCorruptsNewSlot]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpfDeath.MemoizerOnSiblingCorruptsNewSlot]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:371 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[GrowingIdpfDeath.DsWrongSharesDisagreeWithDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/growing_idpf_test [==[--gtest_filter=GrowingIdpfDeath.DsWrongSharesDisagreeWithDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[GrowingIdpfDeath.DsWrongSharesDisagreeWithDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/growing_idpf_test.cpp:396 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( growing_idpf_test_TESTS GrowingIdpf.PrefixesOpenToOwnPayload GrowingIdpf.ExtendMatchesFullySpecified GrowingIdpf.AddOutputWildcardOnExistingLevel GrowingIdpf.DeepestPrefixMatchesClassicDpf GrowingIdpf.ChaChaPrgOpensThePrefix GrowingIdpf.MemoizerExtendMatchesRewalk GrowingIdpf.ExtendDsMatchesDealer GrowingIdpf.AddOutputDsWildcard GrowingIdpf.ShallowMemoizerThrows GrowingIdpf.ExtendSaturatesEightBitDomain GrowingIdpf.ExhaustiveDomainAfterMemoGrow GrowingIdpf.DsAndDealerAgreeFullDomain GrowingIdpf.EmptyAddOutputThrows GrowingIdpfDeath.MismatchedKeyPairThrows GrowingIdpfDeath.WrongPathBitThrows GrowingIdpfDeath.SpecNotOnNewDepthThrows GrowingIdpfDeath.MemoizerOnSiblingCorruptsNewSlot GrowingIdpfDeath.DsWrongSharesDisagreeWithDealer) diff --git a/test/build-asan/half_tree_test[1]_include.cmake b/test/build-asan/half_tree_test[1]_include.cmake new file mode 100644 index 0000000..2bf306b --- /dev/null +++ b/test/build-asan/half_tree_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/half_tree_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/half_tree_test[1]_tests.cmake") +else() + add_test(half_tree_test_NOT_BUILT half_tree_test_NOT_BUILT) +endif() diff --git a/test/build-asan/half_tree_test[1]_tests.cmake b/test/build-asan/half_tree_test[1]_tests.cmake new file mode 100644 index 0000000..bce63ed --- /dev/null +++ b/test/build-asan/half_tree_test[1]_tests.cmake @@ -0,0 +1,21 @@ +add_test([=[HalfTree.TraitsSelectedByCcrPrg]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/half_tree_test [==[--gtest_filter=HalfTree.TraitsSelectedByCcrPrg]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[HalfTree.TraitsSelectedByCcrPrg]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp:66 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[HalfTree.DealerPointAndFullDomain]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/half_tree_test [==[--gtest_filter=HalfTree.DealerPointAndFullDomain]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[HalfTree.DealerPointAndFullDomain]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp:74 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[HalfTree.OutputParityVsBgi]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/half_tree_test [==[--gtest_filter=HalfTree.OutputParityVsBgi]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[HalfTree.OutputParityVsBgi]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp:107 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[HalfTree.DoernerShelatXorMatchesDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/half_tree_test [==[--gtest_filter=HalfTree.DoernerShelatXorMatchesDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[HalfTree.DoernerShelatXorMatchesDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp:130 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[HalfTree.DoernerShelatArithMatchesDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/half_tree_test [==[--gtest_filter=HalfTree.DoernerShelatArithMatchesDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[HalfTree.DoernerShelatArithMatchesDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp:173 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[HalfTree.GenevalPointMatchesDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/half_tree_test [==[--gtest_filter=HalfTree.GenevalPointMatchesDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[HalfTree.GenevalPointMatchesDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp:204 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[HalfTree.GenevalArithPointMatchesDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/half_tree_test [==[--gtest_filter=HalfTree.GenevalArithPointMatchesDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[HalfTree.GenevalArithPointMatchesDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp:240 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[HalfTree.IncrementalCmpSmoke]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/half_tree_test [==[--gtest_filter=HalfTree.IncrementalCmpSmoke]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[HalfTree.IncrementalCmpSmoke]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp:267 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[HalfTree.IncrementalPlacementSmoke]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/half_tree_test [==[--gtest_filter=HalfTree.IncrementalPlacementSmoke]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[HalfTree.IncrementalPlacementSmoke]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp:304 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[HalfTree.VerifiableFullDomainDetectsSeedTamper]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/half_tree_test [==[--gtest_filter=HalfTree.VerifiableFullDomainDetectsSeedTamper]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[HalfTree.VerifiableFullDomainDetectsSeedTamper]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/half_tree_test.cpp:324 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( half_tree_test_TESTS HalfTree.TraitsSelectedByCcrPrg HalfTree.DealerPointAndFullDomain HalfTree.OutputParityVsBgi HalfTree.DoernerShelatXorMatchesDealer HalfTree.DoernerShelatArithMatchesDealer HalfTree.GenevalPointMatchesDealer HalfTree.GenevalArithPointMatchesDealer HalfTree.IncrementalCmpSmoke HalfTree.IncrementalPlacementSmoke HalfTree.VerifiableFullDomainDetectsSeedTamper) diff --git a/test/build-asan/ic_test[1]_include.cmake b/test/build-asan/ic_test[1]_include.cmake new file mode 100644 index 0000000..da00a97 --- /dev/null +++ b/test/build-asan/ic_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/ic_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/ic_test[1]_tests.cmake") +else() + add_test(ic_test_NOT_BUILT ic_test_NOT_BUILT) +endif() diff --git a/test/build-asan/ic_test[1]_tests.cmake b/test/build-asan/ic_test[1]_tests.cmake new file mode 100644 index 0000000..5b2e7e4 --- /dev/null +++ b/test/build-asan/ic_test[1]_tests.cmake @@ -0,0 +1,29 @@ +add_test([=[Ic.Uint8FullDomainCorners]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.Uint8FullDomainCorners]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.Uint8FullDomainCorners]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:79 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.Uint8AllMasksOneInterval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.Uint8AllMasksOneInterval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.Uint8AllMasksOneInterval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:102 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.MemoizerAgrees]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.MemoizerAgrees]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.MemoizerAgrees]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:112 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.IntervalAndSequenceBuffers]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.IntervalAndSequenceBuffers]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.IntervalAndSequenceBuffers]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:128 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.WildcardAssign]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.WildcardAssign]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.WildcardAssign]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:159 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.DoernerShelatMatchesDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.DoernerShelatMatchesDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.DoernerShelatMatchesDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:179 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.Geneval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.Geneval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.Geneval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:213 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.RejectsWrappedBounds]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.RejectsWrappedBounds]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.RejectsWrappedBounds]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:240 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.BitPayload]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.BitPayload]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.BitPayload]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:246 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.Uint16FullDomain]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.Uint16FullDomain]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.Uint16FullDomain]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:260 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.WideMasksSampleTheWrap]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.WideMasksSampleTheWrap]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.WideMasksSampleTheWrap]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:268 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.AdditiveDoernerShelatMatchesDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.AdditiveDoernerShelatMatchesDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.AdditiveDoernerShelatMatchesDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:287 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.AdditiveGeneval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.AdditiveGeneval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.AdditiveGeneval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:314 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ic.IntervalRejectsDescendingEndpoints]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ic_test [==[--gtest_filter=Ic.IntervalRejectsDescendingEndpoints]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ic.IntervalRejectsDescendingEndpoints]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ic_test.cpp:339 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( ic_test_TESTS Ic.Uint8FullDomainCorners Ic.Uint8AllMasksOneInterval Ic.MemoizerAgrees Ic.IntervalAndSequenceBuffers Ic.WildcardAssign Ic.DoernerShelatMatchesDealer Ic.Geneval Ic.RejectsWrappedBounds Ic.BitPayload Ic.Uint16FullDomain Ic.WideMasksSampleTheWrap Ic.AdditiveDoernerShelatMatchesDealer Ic.AdditiveGeneval Ic.IntervalRejectsDescendingEndpoints) diff --git a/test/build-asan/idpf_agg_test[1]_include.cmake b/test/build-asan/idpf_agg_test[1]_include.cmake new file mode 100644 index 0000000..d795cc0 --- /dev/null +++ b/test/build-asan/idpf_agg_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/idpf_agg_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/idpf_agg_test[1]_tests.cmake") +else() + add_test(idpf_agg_test_NOT_BUILT idpf_agg_test_NOT_BUILT) +endif() diff --git a/test/build-asan/iknp_party_test[1]_include.cmake b/test/build-asan/iknp_party_test[1]_include.cmake new file mode 100644 index 0000000..a17f177 --- /dev/null +++ b/test/build-asan/iknp_party_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/iknp_party_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/iknp_party_test[1]_tests.cmake") +else() + add_test(iknp_party_test_NOT_BUILT iknp_party_test_NOT_BUILT) +endif() diff --git a/test/build-asan/incremental_json_test[1]_include.cmake b/test/build-asan/incremental_json_test[1]_include.cmake new file mode 100644 index 0000000..dd4339d --- /dev/null +++ b/test/build-asan/incremental_json_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/incremental_json_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/incremental_json_test[1]_tests.cmake") +else() + add_test(incremental_json_test_NOT_BUILT incremental_json_test_NOT_BUILT) +endif() diff --git a/test/build-asan/incremental_test[1]_include.cmake b/test/build-asan/incremental_test[1]_include.cmake new file mode 100644 index 0000000..147b5d4 --- /dev/null +++ b/test/build-asan/incremental_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/incremental_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/incremental_test[1]_tests.cmake") +else() + add_test(incremental_test_NOT_BUILT incremental_test_NOT_BUILT) +endif() diff --git a/test/build-asan/incremental_test[1]_tests.cmake b/test/build-asan/incremental_test[1]_tests.cmake new file mode 100644 index 0000000..35fdece --- /dev/null +++ b/test/build-asan/incremental_test[1]_tests.cmake @@ -0,0 +1,117 @@ +add_test([=[IncrementalDpfTest.ClassicPathByteIdentical]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.ClassicPathByteIdentical]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.ClassicPathByteIdentical]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:196 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.At10BitDepthAndLanes]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.At10BitDepthAndLanes]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.At10BitDepthAndLanes]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:216 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.SameWidthPackedInOneGroup]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.SameWidthPackedInOneGroup]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.SameWidthPackedInOneGroup]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:236 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.MixedWidthsSamePrefixSeparateGroups]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.MixedWidthsSamePrefixSeparateGroups]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.MixedWidthsSamePrefixSeparateGroups]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:263 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.ManyLevelsManyTypes]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.ManyLevelsManyTypes]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.ManyLevelsManyTypes]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:286 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.ManySameLevelGroupsHighPosBase]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.ManySameLevelGroupsHighPosBase]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.ManySameLevelGroupsHighPosBase]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:346 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.NinePlusGroupsScales]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.NinePlusGroupsScales]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.NinePlusGroupsScales]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:405 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.DealerMatchesDoernerShelat]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.DealerMatchesDoernerShelat]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.DealerMatchesDoernerShelat]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:435 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.IntermediateWildcardSameKey]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.IntermediateWildcardSameKey]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.IntermediateWildcardSameKey]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:477 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.EvalSweepAroundPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.EvalSweepAroundPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.EvalSweepAroundPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:511 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.SignedInput]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.SignedInput]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.SignedInput]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:546 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.FullDomainAtEqualsBare]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.FullDomainAtEqualsBare]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.FullDomainAtEqualsBare]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:560 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.DepthZeroLeaf]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.DepthZeroLeaf]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.DepthZeroLeaf]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:578 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.MemoizedPathEval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.MemoizedPathEval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.MemoizedPathEval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:592 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.DsEvalAgreesWithDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.DsEvalAgreesWithDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.DsEvalAgreesWithDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:615 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.SixteenUint8PackedOneLevel]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.SixteenUint8PackedOneLevel]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.SixteenUint8PackedOneLevel]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:646 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.EightUint16AndFourUint32Packed]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.EightUint16AndFourUint32Packed]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.EightUint16AndFourUint32Packed]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:682 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.ManyBitsOnePrefix]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.ManyBitsOnePrefix]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.ManyBitsOnePrefix]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:710 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.FixedpointIntermediateAndFullDomain]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.FixedpointIntermediateAndFullDomain]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.FixedpointIntermediateAndFullDomain]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:733 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.FixedpointMixedWithIntegralAndBit]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.FixedpointMixedWithIntegralAndBit]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.FixedpointMixedWithIntegralAndBit]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:768 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.FixedpointDealerMatchesDoernerShelat]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.FixedpointDealerMatchesDoernerShelat]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.FixedpointDealerMatchesDoernerShelat]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:792 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.DenseSameLevelManyGroups]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.DenseSameLevelManyGroups]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.DenseSameLevelManyGroups]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:832 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.TwelveBitPrefixesPlusFullDomain]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.TwelveBitPrefixesPlusFullDomain]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.TwelveBitPrefixesPlusFullDomain]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:886 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.TwoFullPackedNodesSameLevel]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.TwoFullPackedNodesSameLevel]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.TwoFullPackedNodesSameLevel]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:920 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.IntervalAtMatchesPointEval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.IntervalAtMatchesPointEval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.IntervalAtMatchesPointEval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:955 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.FullAtDeepestAndSequenceAt]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.FullAtDeepestAndSequenceAt]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.FullAtDeepestAndSequenceAt]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:992 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.LocalCwProtocolMatchesDsRandomness]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.LocalCwProtocolMatchesDsRandomness]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.LocalCwProtocolMatchesDsRandomness]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1021 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.DpfAndCmpSameKey]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.DpfAndCmpSameKey]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.DpfAndCmpSameKey]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1050 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpPairAndRelations]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpPairAndRelations]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpPairAndRelations]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1081 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.EqSynonymAndEqAt]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.EqSynonymAndEqAt]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.EqSynonymAndEqAt]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1114 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpWithDoernerShelat]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpWithDoernerShelat]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpWithDoernerShelat]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1148 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpDealerMatchesDoernerShelat]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpDealerMatchesDoernerShelat]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpDealerMatchesDoernerShelat]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1164 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpIntervalAndSequenceBuffers]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpIntervalAndSequenceBuffers]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpIntervalAndSequenceBuffers]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1211 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpSharesPathMemoizerWithEvalAt]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpSharesPathMemoizerWithEvalAt]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpSharesPathMemoizerWithEvalAt]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1253 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpOnlyZeroOutputs]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpOnlyZeroOutputs]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpOnlyZeroOutputs]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1277 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpDomainEdgeTrivial]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpDomainEdgeTrivial]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpDomainEdgeTrivial]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1291 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpValueCwGroupWidth]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpValueCwGroupWidth]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpValueCwGroupWidth]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1312 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpValueCwGroupWidthDsParity]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpValueCwGroupWidthDsParity]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpValueCwGroupWidthDsParity]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1346 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpPayloadHiddenOnKeys]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpPayloadHiddenOnKeys]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpPayloadHiddenOnKeys]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1382 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.UnifiedEvalTargetSurface]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.UnifiedEvalTargetSurface]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.UnifiedEvalTargetSurface]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1410 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.ClassicKeyHasSlotMetaAndOutEval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.ClassicKeyHasSlotMetaAndOutEval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.ClassicKeyHasSlotMetaAndOutEval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1472 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpWildcardAssignMatchesConcrete]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpWildcardAssignMatchesConcrete]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpWildcardAssignMatchesConcrete]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1522 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpWildcardPairAndGeqAndInterval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpWildcardPairAndGeqAndInterval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpWildcardPairAndGeqAndInterval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1571 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpWildcardNarrowPayloadAndAt]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpWildcardNarrowPayloadAndAt]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpWildcardNarrowPayloadAndAt]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1611 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.DsWildcardCmpMatchesDealerThenAssign]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.DsWildcardCmpMatchesDealerThenAssign]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.DsWildcardCmpMatchesDealerThenAssign]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1638 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.DsWildcardCmpWithAtAndNarrowPayload]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.DsWildcardCmpWithAtAndNarrowPayload]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.DsWildcardCmpWithAtAndNarrowPayload]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1704 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.MultilevelInnerProductMatchesInterval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.MultilevelInnerProductMatchesInterval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.MultilevelInnerProductMatchesInterval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1740 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CmpInnerProductMatchesInterval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CmpInnerProductMatchesInterval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CmpInnerProductMatchesInterval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1780 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.BreadthFirstAtNonFinalSlot]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.BreadthFirstAtNonFinalSlot]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.BreadthFirstAtNonFinalSlot]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1807 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.CrossLevelPathMemoizerShallowThenDeep]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.CrossLevelPathMemoizerShallowThenDeep]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.CrossLevelPathMemoizerShallowThenDeep]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1837 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.SequenceRecipeAtPrefixSlot]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.SequenceRecipeAtPrefixSlot]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.SequenceRecipeAtPrefixSlot]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1865 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.EqIfFalseAbsorbsOnEveryEvalSurface]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.EqIfFalseAbsorbsOnEveryEvalSurface]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.EqIfFalseAbsorbsOnEveryEvalSurface]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1904 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.EqAtIfFalseWithPackedIntervalAndXor]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.EqAtIfFalseWithPackedIntervalAndXor]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.EqAtIfFalseWithPackedIntervalAndXor]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:1988 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.EqIfFalseDealerMatchesDoernerShelatSurfaces]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.EqIfFalseDealerMatchesDoernerShelatSurfaces]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.EqIfFalseDealerMatchesDoernerShelatSurfaces]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:2045 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.PathMemoizerResumePastFullWidthCmpDepth]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.PathMemoizerResumePastFullWidthCmpDepth]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.PathMemoizerResumePastFullWidthCmpDepth]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:2074 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.PathMemoizerResumeCmpOnlyFullWidth]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.PathMemoizerResumeCmpOnlyFullWidth]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.PathMemoizerResumeCmpOnlyFullWidth]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:2113 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.EqMixedWithBlockedCmpSharesMemoizer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.EqMixedWithBlockedCmpSharesMemoizer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.EqMixedWithBlockedCmpSharesMemoizer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:2131 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IncrementalDpfTest.IntervalMemoizerReuseAcrossEqAndShallowAt]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/incremental_test [==[--gtest_filter=IncrementalDpfTest.IntervalMemoizerReuseAcrossEqAndShallowAt]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IncrementalDpfTest.IntervalMemoizerReuseAcrossEqAndShallowAt]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/incremental_test.cpp:2161 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( incremental_test_TESTS IncrementalDpfTest.ClassicPathByteIdentical IncrementalDpfTest.At10BitDepthAndLanes IncrementalDpfTest.SameWidthPackedInOneGroup IncrementalDpfTest.MixedWidthsSamePrefixSeparateGroups IncrementalDpfTest.ManyLevelsManyTypes IncrementalDpfTest.ManySameLevelGroupsHighPosBase IncrementalDpfTest.NinePlusGroupsScales IncrementalDpfTest.DealerMatchesDoernerShelat IncrementalDpfTest.IntermediateWildcardSameKey IncrementalDpfTest.EvalSweepAroundPoint IncrementalDpfTest.SignedInput IncrementalDpfTest.FullDomainAtEqualsBare IncrementalDpfTest.DepthZeroLeaf IncrementalDpfTest.MemoizedPathEval IncrementalDpfTest.DsEvalAgreesWithDealer IncrementalDpfTest.SixteenUint8PackedOneLevel IncrementalDpfTest.EightUint16AndFourUint32Packed IncrementalDpfTest.ManyBitsOnePrefix IncrementalDpfTest.FixedpointIntermediateAndFullDomain IncrementalDpfTest.FixedpointMixedWithIntegralAndBit IncrementalDpfTest.FixedpointDealerMatchesDoernerShelat IncrementalDpfTest.DenseSameLevelManyGroups IncrementalDpfTest.TwelveBitPrefixesPlusFullDomain IncrementalDpfTest.TwoFullPackedNodesSameLevel IncrementalDpfTest.IntervalAtMatchesPointEval IncrementalDpfTest.FullAtDeepestAndSequenceAt IncrementalDpfTest.LocalCwProtocolMatchesDsRandomness IncrementalDpfTest.DpfAndCmpSameKey IncrementalDpfTest.CmpPairAndRelations IncrementalDpfTest.EqSynonymAndEqAt IncrementalDpfTest.CmpWithDoernerShelat IncrementalDpfTest.CmpDealerMatchesDoernerShelat IncrementalDpfTest.CmpIntervalAndSequenceBuffers IncrementalDpfTest.CmpSharesPathMemoizerWithEvalAt IncrementalDpfTest.CmpOnlyZeroOutputs IncrementalDpfTest.CmpDomainEdgeTrivial IncrementalDpfTest.CmpValueCwGroupWidth IncrementalDpfTest.CmpValueCwGroupWidthDsParity IncrementalDpfTest.CmpPayloadHiddenOnKeys IncrementalDpfTest.UnifiedEvalTargetSurface IncrementalDpfTest.ClassicKeyHasSlotMetaAndOutEval IncrementalDpfTest.CmpWildcardAssignMatchesConcrete IncrementalDpfTest.CmpWildcardPairAndGeqAndInterval IncrementalDpfTest.CmpWildcardNarrowPayloadAndAt IncrementalDpfTest.DsWildcardCmpMatchesDealerThenAssign IncrementalDpfTest.DsWildcardCmpWithAtAndNarrowPayload IncrementalDpfTest.MultilevelInnerProductMatchesInterval IncrementalDpfTest.CmpInnerProductMatchesInterval IncrementalDpfTest.BreadthFirstAtNonFinalSlot IncrementalDpfTest.CrossLevelPathMemoizerShallowThenDeep IncrementalDpfTest.SequenceRecipeAtPrefixSlot IncrementalDpfTest.EqIfFalseAbsorbsOnEveryEvalSurface IncrementalDpfTest.EqAtIfFalseWithPackedIntervalAndXor IncrementalDpfTest.EqIfFalseDealerMatchesDoernerShelatSurfaces IncrementalDpfTest.PathMemoizerResumePastFullWidthCmpDepth IncrementalDpfTest.PathMemoizerResumeCmpOnlyFullWidth IncrementalDpfTest.EqMixedWithBlockedCmpSharesMemoizer IncrementalDpfTest.IntervalMemoizerReuseAcrossEqAndShallowAt) diff --git a/test/build-asan/interleave_leaves_test[1]_include.cmake b/test/build-asan/interleave_leaves_test[1]_include.cmake new file mode 100644 index 0000000..d95b829 --- /dev/null +++ b/test/build-asan/interleave_leaves_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/interleave_leaves_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/interleave_leaves_test[1]_tests.cmake") +else() + add_test(interleave_leaves_test_NOT_BUILT interleave_leaves_test_NOT_BUILT) +endif() diff --git a/test/build-asan/it_dpf3_test[1]_include.cmake b/test/build-asan/it_dpf3_test[1]_include.cmake new file mode 100644 index 0000000..028f68a --- /dev/null +++ b/test/build-asan/it_dpf3_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/it_dpf3_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/it_dpf3_test[1]_tests.cmake") +else() + add_test(it_dpf3_test_NOT_BUILT it_dpf3_test_NOT_BUILT) +endif() diff --git a/test/build-asan/keyword2_test[1]_include.cmake b/test/build-asan/keyword2_test[1]_include.cmake new file mode 100644 index 0000000..5136c60 --- /dev/null +++ b/test/build-asan/keyword2_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/keyword2_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/keyword2_test[1]_tests.cmake") +else() + add_test(keyword2_test_NOT_BUILT keyword2_test_NOT_BUILT) +endif() diff --git a/test/build-asan/lane_blast_test[1]_include.cmake b/test/build-asan/lane_blast_test[1]_include.cmake new file mode 100644 index 0000000..94c82f8 --- /dev/null +++ b/test/build-asan/lane_blast_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/lane_blast_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/lane_blast_test[1]_tests.cmake") +else() + add_test(lane_blast_test_NOT_BUILT lane_blast_test_NOT_BUILT) +endif() diff --git a/test/build-asan/lane_blast_test[1]_tests.cmake b/test/build-asan/lane_blast_test[1]_tests.cmake new file mode 100644 index 0000000..f1995ec --- /dev/null +++ b/test/build-asan/lane_blast_test[1]_tests.cmake @@ -0,0 +1,17 @@ +add_test([=[LaneBlast.ParseStreamsAndLimits]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/lane_blast_test [==[--gtest_filter=LaneBlast.ParseStreamsAndLimits]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[LaneBlast.ParseStreamsAndLimits]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp:188 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[LaneBlast.ShareWrapsInTheLaneRing]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/lane_blast_test [==[--gtest_filter=LaneBlast.ShareWrapsInTheLaneRing]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[LaneBlast.ShareWrapsInTheLaneRing]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp:249 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[LaneBlast.DepositDoesNotBleedIntoTheNextLane]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/lane_blast_test [==[--gtest_filter=LaneBlast.DepositDoesNotBleedIntoTheNextLane]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[LaneBlast.DepositDoesNotBleedIntoTheNextLane]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp:268 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[LaneBlast.Uint8TwobitEveryInputAndEveryShape]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/lane_blast_test [==[--gtest_filter=LaneBlast.Uint8TwobitEveryInputAndEveryShape]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[LaneBlast.Uint8TwobitEveryInputAndEveryShape]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp:303 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[LaneBlast.Uint8NybleAndBitSameShapes]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/lane_blast_test [==[--gtest_filter=LaneBlast.Uint8NybleAndBitSameShapes]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[LaneBlast.Uint8NybleAndBitSameShapes]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp:345 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[LaneBlast.SignedInputPackedLeaf]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/lane_blast_test [==[--gtest_filter=LaneBlast.SignedInputPackedLeaf]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[LaneBlast.SignedInputPackedLeaf]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp:360 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[LaneBlast.GenevalMatchesKeyOnPackedLanes]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/lane_blast_test [==[--gtest_filter=LaneBlast.GenevalMatchesKeyOnPackedLanes]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[LaneBlast.GenevalMatchesKeyOnPackedLanes]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp:381 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[LaneBlast.GenevalNybleArithAndSigned]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/lane_blast_test [==[--gtest_filter=LaneBlast.GenevalNybleArithAndSigned]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[LaneBlast.GenevalNybleArithAndSigned]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/lane_blast_test.cpp:469 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( lane_blast_test_TESTS LaneBlast.ParseStreamsAndLimits LaneBlast.ShareWrapsInTheLaneRing LaneBlast.DepositDoesNotBleedIntoTheNextLane LaneBlast.Uint8TwobitEveryInputAndEveryShape LaneBlast.Uint8NybleAndBitSameShapes LaneBlast.SignedInputPackedLeaf LaneBlast.GenevalMatchesKeyOnPackedLanes LaneBlast.GenevalNybleArithAndSigned) diff --git a/test/build-asan/leaf_later_test[1]_include.cmake b/test/build-asan/leaf_later_test[1]_include.cmake new file mode 100644 index 0000000..8b68e64 --- /dev/null +++ b/test/build-asan/leaf_later_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/leaf_later_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/leaf_later_test[1]_tests.cmake") +else() + add_test(leaf_later_test_NOT_BUILT leaf_later_test_NOT_BUILT) +endif() diff --git a/test/build-asan/log_test[1]_include.cmake b/test/build-asan/log_test[1]_include.cmake new file mode 100644 index 0000000..ad00d18 --- /dev/null +++ b/test/build-asan/log_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/log_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/log_test[1]_tests.cmake") +else() + add_test(log_test_NOT_BUILT log_test_NOT_BUILT) +endif() diff --git a/test/build-asan/lut_union_test[1]_include.cmake b/test/build-asan/lut_union_test[1]_include.cmake new file mode 100644 index 0000000..d2a47da --- /dev/null +++ b/test/build-asan/lut_union_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/lut_union_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/lut_union_test[1]_tests.cmake") +else() + add_test(lut_union_test_NOT_BUILT lut_union_test_NOT_BUILT) +endif() diff --git a/test/build-asan/multipoint_test[1]_include.cmake b/test/build-asan/multipoint_test[1]_include.cmake new file mode 100644 index 0000000..6d1790a --- /dev/null +++ b/test/build-asan/multipoint_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/multipoint_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/multipoint_test[1]_tests.cmake") +else() + add_test(multipoint_test_NOT_BUILT multipoint_test_NOT_BUILT) +endif() diff --git a/test/build-asan/net_control_test[1]_include.cmake b/test/build-asan/net_control_test[1]_include.cmake new file mode 100644 index 0000000..815550a --- /dev/null +++ b/test/build-asan/net_control_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/net_control_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/net_control_test[1]_tests.cmake") +else() + add_test(net_control_test_NOT_BUILT net_control_test_NOT_BUILT) +endif() diff --git a/test/build-asan/net_control_test[1]_tests.cmake b/test/build-asan/net_control_test[1]_tests.cmake new file mode 100644 index 0000000..e9c1ea7 --- /dev/null +++ b/test/build-asan/net_control_test[1]_tests.cmake @@ -0,0 +1,59 @@ +add_test([=[RunConfig.EnvAndArgsShareKeys]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=RunConfig.EnvAndArgsShareKeys]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[RunConfig.EnvAndArgsShareKeys]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:144 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[RoundLane.FramingModesAndLimits]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=RoundLane.FramingModesAndLimits]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[RoundLane.FramingModesAndLimits]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:171 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Sink.HelloNamesTheDisagreement]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Sink.HelloNamesTheDisagreement]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Sink.HelloNamesTheDisagreement]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:225 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Sink.FramedPartialPrefixReadyPerInstance]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Sink.FramedPartialPrefixReadyPerInstance]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Sink.FramedPartialPrefixReadyPerInstance]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:238 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Sink.PeerFailureSurfacesImmediately]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Sink.PeerFailureSurfacesImmediately]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Sink.PeerFailureSurfacesImmediately]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:265 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Sink.WindowGatesPipelining]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Sink.WindowGatesPipelining]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Sink.WindowGatesPipelining]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:1060 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Drive.HealthyPlanLongerThanWaitTimeout]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Drive.HealthyPlanLongerThanWaitTimeout]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Drive.HealthyPlanLongerThanWaitTimeout]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:298 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Drive.EdgeAndRoundBudgetsNameTheWait]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Drive.EdgeAndRoundBudgetsNameTheWait]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Drive.EdgeAndRoundBudgetsNameTheWait]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:317 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Memory.WindowSetterAndGracefulClose]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Memory.WindowSetterAndGracefulClose]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Memory.WindowSetterAndGracefulClose]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:361 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Mux.StatsCountHeaders]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Mux.StatsCountHeaders]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Mux.StatsCountHeaders]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:421 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Mux.SmallWriteIsNotQueuedBehindLargeWrite]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Mux.SmallWriteIsNotQueuedBehindLargeWrite]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Mux.SmallWriteIsNotQueuedBehindLargeWrite]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:437 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Mux.DestroyAfterWriteStillDelivers]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Mux.DestroyAfterWriteStillDelivers]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Mux.DestroyAfterWriteStillDelivers]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:467 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Parallel.PerLaneWindows]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Parallel.PerLaneWindows]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Parallel.PerLaneWindows]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:485 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[SyncMux.InteroperatesWithAsyncMux]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=SyncMux.InteroperatesWithAsyncMux]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[SyncMux.InteroperatesWithAsyncMux]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:516 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[SyncMux.LargeCrossFlushDoesNotDeadlock]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=SyncMux.LargeCrossFlushDoesNotDeadlock]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[SyncMux.LargeCrossFlushDoesNotDeadlock]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:546 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.ConnectHasADeadline]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Session.ConnectHasADeadline]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.ConnectHasADeadline]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:575 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.StaticTableAnyStartOrder]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Session.StaticTableAnyStartOrder]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.StaticTableAnyStartOrder]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:587 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.TransportMismatchIsNamed]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Session.TransportMismatchIsNamed]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.TransportMismatchIsNamed]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:612 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.ParallelAndSctpEdges]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Session.ParallelAndSctpEdges]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.ParallelAndSctpEdges]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:640 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.ReconnectResumesMidPlan]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Session.ReconnectResumesMidPlan]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.ReconnectResumesMidPlan]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:686 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.DealerLinkHasItsOwnEpoch]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Session.DealerLinkHasItsOwnEpoch]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.DealerLinkHasItsOwnEpoch]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:740 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Runner.TwoPartyOnEveryTransport]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Runner.TwoPartyOnEveryTransport]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Runner.TwoPartyOnEveryTransport]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:790 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Runner.InstancesAndComputePool]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Runner.InstancesAndComputePool]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Runner.InstancesAndComputePool]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:824 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Runner.StarOnEveryTransport]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Runner.StarOnEveryTransport]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Runner.StarOnEveryTransport]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:848 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Runner.ShortInputIsRejectedNotZeroed]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Runner.ShortInputIsRejectedNotZeroed]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Runner.ShortInputIsRejectedNotZeroed]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:884 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Runner.ThreePartyDealerRingAndPeer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Runner.ThreePartyDealerRingAndPeer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Runner.ThreePartyDealerRingAndPeer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:906 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Runner.SeparateProcessesFromAStaticTable]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Runner.SeparateProcessesFromAStaticTable]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Runner.SeparateProcessesFromAStaticTable]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:956 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Harness.TrialsConfigAndWireRecorded]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Harness.TrialsConfigAndWireRecorded]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Harness.TrialsConfigAndWireRecorded]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:1005 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Prep.ShippedOverADealerSession]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/net_control_test [==[--gtest_filter=Prep.ShippedOverADealerSession]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Prep.ShippedOverADealerSession]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/net_control_test.cpp:1040 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( net_control_test_TESTS RunConfig.EnvAndArgsShareKeys RoundLane.FramingModesAndLimits Sink.HelloNamesTheDisagreement Sink.FramedPartialPrefixReadyPerInstance Sink.PeerFailureSurfacesImmediately Sink.WindowGatesPipelining Drive.HealthyPlanLongerThanWaitTimeout Drive.EdgeAndRoundBudgetsNameTheWait Memory.WindowSetterAndGracefulClose Mux.StatsCountHeaders Mux.SmallWriteIsNotQueuedBehindLargeWrite Mux.DestroyAfterWriteStillDelivers Parallel.PerLaneWindows SyncMux.InteroperatesWithAsyncMux SyncMux.LargeCrossFlushDoesNotDeadlock Session.ConnectHasADeadline Session.StaticTableAnyStartOrder Session.TransportMismatchIsNamed Session.ParallelAndSctpEdges Session.ReconnectResumesMidPlan Session.DealerLinkHasItsOwnEpoch Runner.TwoPartyOnEveryTransport Runner.InstancesAndComputePool Runner.StarOnEveryTransport Runner.ShortInputIsRejectedNotZeroed Runner.ThreePartyDealerRingAndPeer Runner.SeparateProcessesFromAStaticTable Harness.TrialsConfigAndWireRecorded Prep.ShippedOverADealerSession) diff --git a/test/build-asan/nmod_test[1]_include.cmake b/test/build-asan/nmod_test[1]_include.cmake new file mode 100644 index 0000000..67a92d6 --- /dev/null +++ b/test/build-asan/nmod_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/nmod_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/nmod_test[1]_tests.cmake") +else() + add_test(nmod_test_NOT_BUILT nmod_test_NOT_BUILT) +endif() diff --git a/test/build-asan/offset_horner_test[1]_include.cmake b/test/build-asan/offset_horner_test[1]_include.cmake new file mode 100644 index 0000000..56e8b09 --- /dev/null +++ b/test/build-asan/offset_horner_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_horner_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_horner_test[1]_tests.cmake") +else() + add_test(offset_horner_test_NOT_BUILT offset_horner_test_NOT_BUILT) +endif() diff --git a/test/build-asan/offset_horner_test[1]_tests.cmake b/test/build-asan/offset_horner_test[1]_tests.cmake new file mode 100644 index 0000000..0b449a4 --- /dev/null +++ b/test/build-asan/offset_horner_test[1]_tests.cmake @@ -0,0 +1,73 @@ +add_test([=[OffsetHorner.BinomialAgreesWithPowerSum]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.BinomialAgreesWithPowerSum]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.BinomialAgreesWithPowerSum]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:176 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.HandCubicAtCenterPlusEta]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.HandCubicAtCenterPlusEta]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.HandCubicAtCenterPlusEta]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:195 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.MultiPieceSelectsWrappedInput]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.MultiPieceSelectsWrappedInput]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.MultiPieceSelectsWrappedInput]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:219 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.CarrySplitEvaluatesTheWrappedRepresentative]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.CarrySplitEvaluatesTheWrappedRepresentative]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.CarrySplitEvaluatesTheWrappedRepresentative]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:236 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.XPlusRWiring]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.XPlusRWiring]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.XPlusRWiring]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:271 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.DegreesZeroOneAndTwo]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.DegreesZeroOneAndTwo]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.DegreesZeroOneAndTwo]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:289 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.WholeDomainAndWrapPiece]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.WholeDomainAndWrapPiece]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.WholeDomainAndWrapPiece]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:324 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.CenterOrEtaZero]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.CenterOrEtaZero]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.CenterOrEtaZero]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:346 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.NegativeCoefficientsAndSignedDomain]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.NegativeCoefficientsAndSignedDomain]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.NegativeCoefficientsAndSignedDomain]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:363 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.ShiftedKnotsThatAreNotSortedStillSelect]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.ShiftedKnotsThatAreNotSortedStillSelect]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.ShiftedKnotsThatAreNotSortedStillSelect]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:393 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.RingOverflowDiffersFromWideInteger]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.RingOverflowDiffersFromWideInteger]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.RingOverflowDiffersFromWideInteger]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:415 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.WrapSharesHideThePayload]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.WrapSharesHideThePayload]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.WrapSharesHideThePayload]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:433 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.PowerKeysAreIndependentComparisons]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.PowerKeysAreIndependentComparisons]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.PowerKeysAreIndependentComparisons]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:448 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.DegreeZeroMatchesSignRespectingDot]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.DegreeZeroMatchesSignRespectingDot]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.DegreeZeroMatchesSignRespectingDot]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:467 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.AdviceBitSignIsNotACoefficientShare]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.AdviceBitSignIsNotACoefficientShare]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.AdviceBitSignIsNotACoefficientShare]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:500 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.SignRespectingOneHotIsNotTheShiftedCubic]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.SignRespectingOneHotIsNotTheShiftedCubic]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.SignRespectingOneHotIsNotTheShiftedCubic]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:551 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.PrefixIntoMatchesFixedArray]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.PrefixIntoMatchesFixedArray]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.PrefixIntoMatchesFixedArray]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:578 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.RejectsBadKnots]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.RejectsBadKnots]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.RejectsBadKnots]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:598 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.ManyPiecesAndRandomUint16]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.ManyPiecesAndRandomUint16]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.ManyPiecesAndRandomUint16]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:609 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.ExhaustiveUint8AgreesWithGoldAndCountsWraps]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.ExhaustiveUint8AgreesWithGoldAndCountsWraps]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.ExhaustiveUint8AgreesWithGoldAndCountsWraps]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:636 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.ExhaustiveInt8AgreesWithGoldAndCountsOverflows]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.ExhaustiveInt8AgreesWithGoldAndCountsOverflows]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.ExhaustiveInt8AgreesWithGoldAndCountsOverflows]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:685 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.GenevalXorSharesMatchTheDealerPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.GenevalXorSharesMatchTheDealerPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.GenevalXorSharesMatchTheDealerPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:730 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.GenevalFromAdditiveSharesOfXAndR]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.GenevalFromAdditiveSharesOfXAndR]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.GenevalFromAdditiveSharesOfXAndR]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:753 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.GenevalSignedSharesUseGenevalConvention]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.GenevalSignedSharesUseGenevalConvention]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.GenevalSignedSharesUseGenevalConvention]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:782 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.HornerOfOpenedCoefficientsMatchesValue]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.HornerOfOpenedCoefficientsMatchesValue]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.HornerOfOpenedCoefficientsMatchesValue]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:818 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.OpenedSharesAreNotHornerInputs]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.OpenedSharesAreNotHornerInputs]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.OpenedSharesAreNotHornerInputs]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:838 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.KnotsThatOmitZeroStillSplitTheCarry]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.KnotsThatOmitZeroStillSplitTheCarry]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.KnotsThatOmitZeroStillSplitTheCarry]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:902 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.SignedKnotsThatOmitTheMinimum]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.SignedKnotsThatOmitTheMinimum]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.SignedKnotsThatOmitTheMinimum]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:929 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.CarryThresholdLandsOnEveryKnotAndOnTheDomainEnds]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.CarryThresholdLandsOnEveryKnotAndOnTheDomainEnds]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.CarryThresholdLandsOnEveryKnotAndOnTheDomainEnds]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:955 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.DegreeZeroIsThePieceConstantOnBothSidesOfTheCarry]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.DegreeZeroIsThePieceConstantOnBothSidesOfTheCarry]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.DegreeZeroIsThePieceConstantOnBothSidesOfTheCarry]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:996 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.CubicAcrossUnsignedAndSignedCarryHasANegativeKappa]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.CubicAcrossUnsignedAndSignedCarryHasANegativeKappa]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.CubicAcrossUnsignedAndSignedCarryHasANegativeKappa]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:1023 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.ZeroPolynomialAndProperShares]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.ZeroPolynomialAndProperShares]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.ZeroPolynomialAndProperShares]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:1066 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.XPlusRMatchesTheWrappedSumOnAStride]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.XPlusRMatchesTheWrappedSumOnAStride]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.XPlusRMatchesTheWrappedSumOnAStride]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:1092 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.GenevalAgreesWithDealerAcrossCarryAndEdges]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.GenevalAgreesWithDealerAcrossCarryAndEdges]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.GenevalAgreesWithDealerAcrossCarryAndEdges]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:1126 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.WiderRandomDomainsMatchWrappedGold]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.WiderRandomDomainsMatchWrappedGold]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.WiderRandomDomainsMatchWrappedGold]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:1188 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[OffsetHorner.BiggerDomainsExerciseCarrySplitAndGeneval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/offset_horner_test [==[--gtest_filter=OffsetHorner.BiggerDomainsExerciseCarrySplitAndGeneval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[OffsetHorner.BiggerDomainsExerciseCarrySplitAndGeneval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/offset_horner_test.cpp:1411 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( offset_horner_test_TESTS OffsetHorner.BinomialAgreesWithPowerSum OffsetHorner.HandCubicAtCenterPlusEta OffsetHorner.MultiPieceSelectsWrappedInput OffsetHorner.CarrySplitEvaluatesTheWrappedRepresentative OffsetHorner.XPlusRWiring OffsetHorner.DegreesZeroOneAndTwo OffsetHorner.WholeDomainAndWrapPiece OffsetHorner.CenterOrEtaZero OffsetHorner.NegativeCoefficientsAndSignedDomain OffsetHorner.ShiftedKnotsThatAreNotSortedStillSelect OffsetHorner.RingOverflowDiffersFromWideInteger OffsetHorner.WrapSharesHideThePayload OffsetHorner.PowerKeysAreIndependentComparisons OffsetHorner.DegreeZeroMatchesSignRespectingDot OffsetHorner.AdviceBitSignIsNotACoefficientShare OffsetHorner.SignRespectingOneHotIsNotTheShiftedCubic OffsetHorner.PrefixIntoMatchesFixedArray OffsetHorner.RejectsBadKnots OffsetHorner.ManyPiecesAndRandomUint16 OffsetHorner.ExhaustiveUint8AgreesWithGoldAndCountsWraps OffsetHorner.ExhaustiveInt8AgreesWithGoldAndCountsOverflows OffsetHorner.GenevalXorSharesMatchTheDealerPoint OffsetHorner.GenevalFromAdditiveSharesOfXAndR OffsetHorner.GenevalSignedSharesUseGenevalConvention OffsetHorner.HornerOfOpenedCoefficientsMatchesValue OffsetHorner.OpenedSharesAreNotHornerInputs OffsetHorner.KnotsThatOmitZeroStillSplitTheCarry OffsetHorner.SignedKnotsThatOmitTheMinimum OffsetHorner.CarryThresholdLandsOnEveryKnotAndOnTheDomainEnds OffsetHorner.DegreeZeroIsThePieceConstantOnBothSidesOfTheCarry OffsetHorner.CubicAcrossUnsignedAndSignedCarryHasANegativeKappa OffsetHorner.ZeroPolynomialAndProperShares OffsetHorner.XPlusRMatchesTheWrappedSumOnAStride OffsetHorner.GenevalAgreesWithDealerAcrossCarryAndEdges OffsetHorner.WiderRandomDomainsMatchWrappedGold OffsetHorner.BiggerDomainsExerciseCarrySplitAndGeneval) diff --git a/test/build-asan/offset_jet_test[1]_include.cmake b/test/build-asan/offset_jet_test[1]_include.cmake new file mode 100644 index 0000000..573b337 --- /dev/null +++ b/test/build-asan/offset_jet_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_jet_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_jet_test[1]_tests.cmake") +else() + add_test(offset_jet_test_NOT_BUILT offset_jet_test_NOT_BUILT) +endif() diff --git a/test/build-asan/offset_poly_test[1]_include.cmake b/test/build-asan/offset_poly_test[1]_include.cmake new file mode 100644 index 0000000..d3aa039 --- /dev/null +++ b/test/build-asan/offset_poly_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_poly_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_poly_test[1]_tests.cmake") +else() + add_test(offset_poly_test_NOT_BUILT offset_poly_test_NOT_BUILT) +endif() diff --git a/test/build-asan/offset_repr_test[1]_include.cmake b/test/build-asan/offset_repr_test[1]_include.cmake new file mode 100644 index 0000000..033492d --- /dev/null +++ b/test/build-asan/offset_repr_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_repr_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_repr_test[1]_tests.cmake") +else() + add_test(offset_repr_test_NOT_BUILT offset_repr_test_NOT_BUILT) +endif() diff --git a/test/build-asan/offset_twist_test[1]_include.cmake b/test/build-asan/offset_twist_test[1]_include.cmake new file mode 100644 index 0000000..f58de3a --- /dev/null +++ b/test/build-asan/offset_twist_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_twist_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/offset_twist_test[1]_tests.cmake") +else() + add_test(offset_twist_test_NOT_BUILT offset_twist_test_NOT_BUILT) +endif() diff --git a/test/build-asan/opt_in_malicious_test[1]_include.cmake b/test/build-asan/opt_in_malicious_test[1]_include.cmake new file mode 100644 index 0000000..08891e2 --- /dev/null +++ b/test/build-asan/opt_in_malicious_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/opt_in_malicious_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/opt_in_malicious_test[1]_tests.cmake") +else() + add_test(opt_in_malicious_test_NOT_BUILT opt_in_malicious_test_NOT_BUILT) +endif() diff --git a/test/build-asan/packed_lane_test[1]_include.cmake b/test/build-asan/packed_lane_test[1]_include.cmake new file mode 100644 index 0000000..886465d --- /dev/null +++ b/test/build-asan/packed_lane_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/packed_lane_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/packed_lane_test[1]_tests.cmake") +else() + add_test(packed_lane_test_NOT_BUILT packed_lane_test_NOT_BUILT) +endif() diff --git a/test/build-asan/parallel_bit_iterable_test[1]_include.cmake b/test/build-asan/parallel_bit_iterable_test[1]_include.cmake new file mode 100644 index 0000000..2ad4c81 --- /dev/null +++ b/test/build-asan/parallel_bit_iterable_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/parallel_bit_iterable_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/parallel_bit_iterable_test[1]_tests.cmake") +else() + add_test(parallel_bit_iterable_test_NOT_BUILT parallel_bit_iterable_test_NOT_BUILT) +endif() diff --git a/test/build-asan/path_recipe_test[1]_include.cmake b/test/build-asan/path_recipe_test[1]_include.cmake new file mode 100644 index 0000000..3a6699b --- /dev/null +++ b/test/build-asan/path_recipe_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/path_recipe_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/path_recipe_test[1]_tests.cmake") +else() + add_test(path_recipe_test_NOT_BUILT path_recipe_test_NOT_BUILT) +endif() diff --git a/test/build-asan/path_sketch_test[1]_include.cmake b/test/build-asan/path_sketch_test[1]_include.cmake new file mode 100644 index 0000000..22dc0a4 --- /dev/null +++ b/test/build-asan/path_sketch_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/path_sketch_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/path_sketch_test[1]_tests.cmake") +else() + add_test(path_sketch_test_NOT_BUILT path_sketch_test_NOT_BUILT) +endif() diff --git a/test/build-asan/pprf_test[1]_include.cmake b/test/build-asan/pprf_test[1]_include.cmake new file mode 100644 index 0000000..e5c9b7f --- /dev/null +++ b/test/build-asan/pprf_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/pprf_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/pprf_test[1]_tests.cmake") +else() + add_test(pprf_test_NOT_BUILT pprf_test_NOT_BUILT) +endif() diff --git a/test/build-asan/ppvc_test[1]_include.cmake b/test/build-asan/ppvc_test[1]_include.cmake new file mode 100644 index 0000000..9d4a7c1 --- /dev/null +++ b/test/build-asan/ppvc_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/ppvc_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/ppvc_test[1]_tests.cmake") +else() + add_test(ppvc_test_NOT_BUILT ppvc_test_NOT_BUILT) +endif() diff --git a/test/build-asan/ppvc_test[1]_tests.cmake b/test/build-asan/ppvc_test[1]_tests.cmake new file mode 100644 index 0000000..aa134e3 --- /dev/null +++ b/test/build-asan/ppvc_test[1]_tests.cmake @@ -0,0 +1,31 @@ +add_test([=[Ppvc.ProgramsEveryCoordinate]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=Ppvc.ProgramsEveryCoordinate]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ppvc.ProgramsEveryCoordinate]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:117 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ppvc.ProgramsEverySum]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=Ppvc.ProgramsEverySum]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ppvc.ProgramsEverySum]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:130 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ppvc.FreshCommitOpens]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=Ppvc.FreshCommitOpens]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ppvc.FreshCommitOpens]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:143 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ppvc.PrescribedIndexAndWrappingShift]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=Ppvc.PrescribedIndexAndWrappingShift]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ppvc.PrescribedIndexAndWrappingShift]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:156 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ppvc.SeedExpansionIsDeterministic]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=Ppvc.SeedExpansionIsDeterministic]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ppvc.SeedExpansionIsDeterministic]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:179 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ppvc.RejectsATamperedOpening]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=Ppvc.RejectsATamperedOpening]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ppvc.RejectsATamperedOpening]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:207 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ppvc.RejectsAMalformedReplica]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=Ppvc.RejectsAMalformedReplica]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ppvc.RejectsAMalformedReplica]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:247 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ppvc.RejectsAnOutOfRangeProgram]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=Ppvc.RejectsAnOutOfRangeProgram]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ppvc.RejectsAnOutOfRangeProgram]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:278 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ppvc.DeeperDomain]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=Ppvc.DeeperDomain]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ppvc.DeeperDomain]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:290 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ppvc.FullWidthValue]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=Ppvc.FullWidthValue]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ppvc.FullWidthValue]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:310 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Ppvc.DefaultSigmaUsesWholeBlocks]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=Ppvc.DefaultSigmaUsesWholeBlocks]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Ppvc.DefaultSigmaUsesWholeBlocks]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:330 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[KPpvc.OneCopyMatchesTheSingleScheme]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=KPpvc.OneCopyMatchesTheSingleScheme]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[KPpvc.OneCopyMatchesTheSingleScheme]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:344 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[KPpvc.ReprogramsOneCoordinateOfTheSum]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=KPpvc.ReprogramsOneCoordinateOfTheSum]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[KPpvc.ReprogramsOneCoordinateOfTheSum]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:357 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[KPpvc.SumModeAndFreshCommit]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=KPpvc.SumModeAndFreshCommit]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[KPpvc.SumModeAndFreshCommit]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:402 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[KPpvc.RejectsASharedHiddenIndex]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/ppvc_test [==[--gtest_filter=KPpvc.RejectsASharedHiddenIndex]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[KPpvc.RejectsASharedHiddenIndex]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/ppvc_test.cpp:423 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( ppvc_test_TESTS Ppvc.ProgramsEveryCoordinate Ppvc.ProgramsEverySum Ppvc.FreshCommitOpens Ppvc.PrescribedIndexAndWrappingShift Ppvc.SeedExpansionIsDeterministic Ppvc.RejectsATamperedOpening Ppvc.RejectsAMalformedReplica Ppvc.RejectsAnOutOfRangeProgram Ppvc.DeeperDomain Ppvc.FullWidthValue Ppvc.DefaultSigmaUsesWholeBlocks KPpvc.OneCopyMatchesTheSingleScheme KPpvc.ReprogramsOneCoordinateOfTheSum KPpvc.SumModeAndFreshCommit KPpvc.RejectsASharedHiddenIndex) diff --git a/test/build-asan/prg_aes_ccr_test[1]_include.cmake b/test/build-asan/prg_aes_ccr_test[1]_include.cmake new file mode 100644 index 0000000..c1702d0 --- /dev/null +++ b/test/build-asan/prg_aes_ccr_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/prg_aes_ccr_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/prg_aes_ccr_test[1]_tests.cmake") +else() + add_test(prg_aes_ccr_test_NOT_BUILT prg_aes_ccr_test_NOT_BUILT) +endif() diff --git a/test/build-asan/prg_chacha_test[1]_include.cmake b/test/build-asan/prg_chacha_test[1]_include.cmake new file mode 100644 index 0000000..b0420f1 --- /dev/null +++ b/test/build-asan/prg_chacha_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/prg_chacha_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/prg_chacha_test[1]_tests.cmake") +else() + add_test(prg_chacha_test_NOT_BUILT prg_chacha_test_NOT_BUILT) +endif() diff --git a/test/build-asan/prg_lowmc_test[1]_include.cmake b/test/build-asan/prg_lowmc_test[1]_include.cmake new file mode 100644 index 0000000..11bd57e --- /dev/null +++ b/test/build-asan/prg_lowmc_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/prg_lowmc_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/prg_lowmc_test[1]_tests.cmake") +else() + add_test(prg_lowmc_test_NOT_BUILT prg_lowmc_test_NOT_BUILT) +endif() diff --git a/test/build-asan/principal_lut_test[1]_include.cmake b/test/build-asan/principal_lut_test[1]_include.cmake new file mode 100644 index 0000000..80b197a --- /dev/null +++ b/test/build-asan/principal_lut_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/principal_lut_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/principal_lut_test[1]_tests.cmake") +else() + add_test(principal_lut_test_NOT_BUILT principal_lut_test_NOT_BUILT) +endif() diff --git a/test/build-asan/protocol_batch_test[1]_include.cmake b/test/build-asan/protocol_batch_test[1]_include.cmake new file mode 100644 index 0000000..06231eb --- /dev/null +++ b/test/build-asan/protocol_batch_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/protocol_batch_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/protocol_batch_test[1]_tests.cmake") +else() + add_test(protocol_batch_test_NOT_BUILT protocol_batch_test_NOT_BUILT) +endif() diff --git a/test/build-asan/random_test[1]_include.cmake b/test/build-asan/random_test[1]_include.cmake new file mode 100644 index 0000000..6aab7b7 --- /dev/null +++ b/test/build-asan/random_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/random_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/random_test[1]_tests.cmake") +else() + add_test(random_test_NOT_BUILT random_test_NOT_BUILT) +endif() diff --git a/test/build-asan/range_lut_test[1]_include.cmake b/test/build-asan/range_lut_test[1]_include.cmake new file mode 100644 index 0000000..77b6a53 --- /dev/null +++ b/test/build-asan/range_lut_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/range_lut_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/range_lut_test[1]_tests.cmake") +else() + add_test(range_lut_test_NOT_BUILT range_lut_test_NOT_BUILT) +endif() diff --git a/test/build-asan/ring_switch_test[1]_include.cmake b/test/build-asan/ring_switch_test[1]_include.cmake new file mode 100644 index 0000000..9fbf128 --- /dev/null +++ b/test/build-asan/ring_switch_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/ring_switch_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/ring_switch_test[1]_tests.cmake") +else() + add_test(ring_switch_test_NOT_BUILT ring_switch_test_NOT_BUILT) +endif() diff --git a/test/build-asan/secret_share_test[1]_include.cmake b/test/build-asan/secret_share_test[1]_include.cmake new file mode 100644 index 0000000..d5cbf72 --- /dev/null +++ b/test/build-asan/secret_share_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/secret_share_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/secret_share_test[1]_tests.cmake") +else() + add_test(secret_share_test_NOT_BUILT secret_share_test_NOT_BUILT) +endif() diff --git a/test/build-asan/security_test[1]_include.cmake b/test/build-asan/security_test[1]_include.cmake new file mode 100644 index 0000000..b694b44 --- /dev/null +++ b/test/build-asan/security_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/security_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/security_test[1]_tests.cmake") +else() + add_test(security_test_NOT_BUILT security_test_NOT_BUILT) +endif() diff --git a/test/build-asan/security_test[1]_tests.cmake b/test/build-asan/security_test[1]_tests.cmake new file mode 100644 index 0000000..8568807 --- /dev/null +++ b/test/build-asan/security_test[1]_tests.cmake @@ -0,0 +1,49 @@ +add_test([=[Identity.KeyFileRoundTripAndMode]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=Identity.KeyFileRoundTripAndMode]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Identity.KeyFileRoundTripAndMode]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:105 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Identity.DevelopmentIsFixedAndMarked]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=Identity.DevelopmentIsFixedAndMarked]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Identity.DevelopmentIsFixedAndMarked]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:131 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[PeerTls.NoKeysEncryptsUnauthenticated]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=PeerTls.NoKeysEncryptsUnauthenticated]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[PeerTls.NoKeysEncryptsUnauthenticated]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:187 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[PeerTls.KeyAuthenticatesOneDirection]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=PeerTls.KeyAuthenticatesOneDirection]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[PeerTls.KeyAuthenticatesOneDirection]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:203 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[PeerTls.WrongKeyNamesBothKeys]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=PeerTls.WrongKeyNamesBothKeys]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[PeerTls.WrongKeyNamesBothKeys]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:219 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[TlsBackends.PlainThroughRelay]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=TlsBackends.PlainThroughRelay]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[TlsBackends.PlainThroughRelay]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:551 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[TlsBackends.TlsMuxDirect]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=TlsBackends.TlsMuxDirect]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[TlsBackends.TlsMuxDirect]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:557 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[TlsBackends.MuxCiphertextOnTheWire]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=TlsBackends.MuxCiphertextOnTheWire]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[TlsBackends.MuxCiphertextOnTheWire]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:597 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[TlsBackends.ParallelCiphertextOnTheWire]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=TlsBackends.ParallelCiphertextOnTheWire]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[TlsBackends.ParallelCiphertextOnTheWire]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:606 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ClientTls.DevelopmentCertificateIsTheDefault]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=ClientTls.DevelopmentCertificateIsTheDefault]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ClientTls.DevelopmentCertificateIsTheDefault]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:613 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ClientTls.UnknownServerKeyIsRefusedUntilPinned]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=ClientTls.UnknownServerKeyIsRefusedUntilPinned]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ClientTls.UnknownServerKeyIsRefusedUntilPinned]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:623 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ClientTls.CaChainAndHostName]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=ClientTls.CaChainAndHostName]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ClientTls.CaChainAndHostName]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:650 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ClientTls.ServerChecksPinnedClientKeys]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=ClientTls.ServerChecksPinnedClientKeys]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ClientTls.ServerChecksPinnedClientKeys]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:670 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.EncryptedByDefaultWithoutKeys]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=Session.EncryptedByDefaultWithoutKeys]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.EncryptedByDefaultWithoutKeys]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:751 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.KeysAuthenticatePerDirection]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=Session.KeysAuthenticatePerDirection]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.KeysAuthenticatePerDirection]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:766 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.WrongKeyFailsBothEndsQuickly]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=Session.WrongKeyFailsBothEndsQuickly]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.WrongKeyFailsBothEndsQuickly]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:796 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.MixedEncryptionSettingsAreNamed]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=Session.MixedEncryptionSettingsAreNamed]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.MixedEncryptionSettingsAreNamed]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:809 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.SctpIsRefusedWhileEncrypted]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=Session.SctpIsRefusedWhileEncrypted]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.SctpIsRefusedWhileEncrypted]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:818 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.LackOfKeysIsLogged]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=Session.LackOfKeysIsLogged]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.LackOfKeysIsLogged]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:839 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.DealerKeyAuthenticatesTheDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=Session.DealerKeyAuthenticatesTheDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.DealerKeyAuthenticatesTheDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:861 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ClientLink.DevelopmentDefaultWorksAndSaysSo]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=ClientLink.DevelopmentDefaultWorksAndSaysSo]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ClientLink.DevelopmentDefaultWorksAndSaysSo]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:961 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ClientLink.ServerIdentityNeedsAPinOrVerifyOff]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=ClientLink.ServerIdentityNeedsAPinOrVerifyOff]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ClientLink.ServerIdentityNeedsAPinOrVerifyOff]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:968 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Config.SecurityFromAFileWithRelativePaths]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=Config.SecurityFromAFileWithRelativePaths]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Config.SecurityFromAFileWithRelativePaths]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:988 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Deployment.TwoProcessesAuthenticateEachOther]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/security_test [==[--gtest_filter=Deployment.TwoProcessesAuthenticateEachOther]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Deployment.TwoProcessesAuthenticateEachOther]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/security_test.cpp:1054 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( security_test_TESTS Identity.KeyFileRoundTripAndMode Identity.DevelopmentIsFixedAndMarked PeerTls.NoKeysEncryptsUnauthenticated PeerTls.KeyAuthenticatesOneDirection PeerTls.WrongKeyNamesBothKeys TlsBackends.PlainThroughRelay TlsBackends.TlsMuxDirect TlsBackends.MuxCiphertextOnTheWire TlsBackends.ParallelCiphertextOnTheWire ClientTls.DevelopmentCertificateIsTheDefault ClientTls.UnknownServerKeyIsRefusedUntilPinned ClientTls.CaChainAndHostName ClientTls.ServerChecksPinnedClientKeys Session.EncryptedByDefaultWithoutKeys Session.KeysAuthenticatePerDirection Session.WrongKeyFailsBothEndsQuickly Session.MixedEncryptionSettingsAreNamed Session.SctpIsRefusedWhileEncrypted Session.LackOfKeysIsLogged Session.DealerKeyAuthenticatesTheDealer ClientLink.DevelopmentDefaultWorksAndSaysSo ClientLink.ServerIdentityNeedsAPinOrVerifyOff Config.SecurityFromAFileWithRelativePaths Deployment.TwoProcessesAuthenticateEachOther) diff --git a/test/build-asan/setbit_index_iterable_test[1]_include.cmake b/test/build-asan/setbit_index_iterable_test[1]_include.cmake new file mode 100644 index 0000000..c1def4f --- /dev/null +++ b/test/build-asan/setbit_index_iterable_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/setbit_index_iterable_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/setbit_index_iterable_test[1]_tests.cmake") +else() + add_test(setbit_index_iterable_test_NOT_BUILT setbit_index_iterable_test_NOT_BUILT) +endif() diff --git a/test/build-asan/sfss_test[1]_include.cmake b/test/build-asan/sfss_test[1]_include.cmake new file mode 100644 index 0000000..935aac3 --- /dev/null +++ b/test/build-asan/sfss_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/sfss_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/sfss_test[1]_tests.cmake") +else() + add_test(sfss_test_NOT_BUILT sfss_test_NOT_BUILT) +endif() diff --git a/test/build-asan/shamir_adversarial_test[1]_include.cmake b/test/build-asan/shamir_adversarial_test[1]_include.cmake new file mode 100644 index 0000000..77d1730 --- /dev/null +++ b/test/build-asan/shamir_adversarial_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/shamir_adversarial_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/shamir_adversarial_test[1]_tests.cmake") +else() + add_test(shamir_adversarial_test_NOT_BUILT shamir_adversarial_test_NOT_BUILT) +endif() diff --git a/test/build-asan/share_runtime_test[1]_include.cmake b/test/build-asan/share_runtime_test[1]_include.cmake new file mode 100644 index 0000000..cd15229 --- /dev/null +++ b/test/build-asan/share_runtime_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/share_runtime_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/share_runtime_test[1]_tests.cmake") +else() + add_test(share_runtime_test_NOT_BUILT share_runtime_test_NOT_BUILT) +endif() diff --git a/test/build-asan/share_runtime_test[1]_tests.cmake b/test/build-asan/share_runtime_test[1]_tests.cmake new file mode 100644 index 0000000..53f7fdc --- /dev/null +++ b/test/build-asan/share_runtime_test[1]_tests.cmake @@ -0,0 +1,183 @@ +add_test([=[RssSeed.RandomReplicatedSums]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=RssSeed.RandomReplicatedSums]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[RssSeed.RandomReplicatedSums]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:117 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[RssSeed.ZeroSharesSumToZero]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=RssSeed.ZeroSharesSumToZero]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[RssSeed.ZeroSharesSumToZero]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:126 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[RssSeed.MulLocalThenRefresh]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=RssSeed.MulLocalThenRefresh]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[RssSeed.MulLocalThenRefresh]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:138 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ScheduleSession.PipelineCreditIndependentPads]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=ScheduleSession.PipelineCreditIndependentPads]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ScheduleSession.PipelineCreditIndependentPads]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:156 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.BinNotLocalConvertible]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.BinNotLocalConvertible]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.BinNotLocalConvertible]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:175 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.ArithKernelsPresent]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.ArithKernelsPresent]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.ArithKernelsPresent]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:184 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.RssZeroFromSeeds]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.RssZeroFromSeeds]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.RssZeroFromSeeds]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:196 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.CheckOpenRejectsCorrupt]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.CheckOpenRejectsCorrupt]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.CheckOpenRejectsCorrupt]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:212 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.CheckOpenHashRing]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.CheckOpenHashRing]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.CheckOpenHashRing]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:591 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.TruncExactKernel]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.TruncExactKernel]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.TruncExactKernel]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:643 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.B2aOpenMatchesClear]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.B2aOpenMatchesClear]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.B2aOpenMatchesClear]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:670 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.MulTruncOpen]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.MulTruncOpen]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.MulTruncOpen]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:707 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.InjectAndMuxOpen]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.InjectAndMuxOpen]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.InjectAndMuxOpen]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:741 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.GmwAndOpen]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.GmwAndOpen]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.GmwAndOpen]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:774 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.DrivePlanOnStreamsOpen]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.DrivePlanOnStreamsOpen]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.DrivePlanOnStreamsOpen]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1414 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.DrivePlanOnStreamsTwoWaves]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.DrivePlanOnStreamsTwoWaves]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.DrivePlanOnStreamsTwoWaves]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1437 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.DrivePlanOnStreamsGmwAnd]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.DrivePlanOnStreamsGmwAnd]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.DrivePlanOnStreamsGmwAnd]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1472 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.DrivePlanOnStreamsDeepEightWaves]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.DrivePlanOnStreamsDeepEightWaves]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.DrivePlanOnStreamsDeepEightWaves]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1500 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.DrivePlanOnStreamsMuxTcp]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.DrivePlanOnStreamsMuxTcp]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.DrivePlanOnStreamsMuxTcp]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1529 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.DrivePlanOnStreamMeshRssCopy]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.DrivePlanOnStreamMeshRssCopy]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.DrivePlanOnStreamMeshRssCopy]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1593 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Compose.NPartyComposerAllowed]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Compose.NPartyComposerAllowed]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Compose.NPartyComposerAllowed]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2239 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[EdaBit.A2BThenReconstruct]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=EdaBit.A2BThenReconstruct]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[EdaBit.A2BThenReconstruct]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:268 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[EdaBit.RssArithEqualsBits]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=EdaBit.RssArithEqualsBits]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[EdaBit.RssArithEqualsBits]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:282 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[EdaBit.GmwA2bMatchesClear]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=EdaBit.GmwA2bMatchesClear]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[EdaBit.GmwA2bMatchesClear]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:303 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[EdaBit.DaBitPairConsistent]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=EdaBit.DaBitPairConsistent]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[EdaBit.DaBitPairConsistent]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:311 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BitInject.ClearMatches]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=BitInject.ClearMatches]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BitInject.ClearMatches]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:318 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BitInject.RssAndLocal]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=BitInject.RssAndLocal]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BitInject.RssAndLocal]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:324 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[BitInject.RssAndRefresh]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=BitInject.RssAndRefresh]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[BitInject.RssAndRefresh]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:817 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Trunc.ProbErrorAtMostOne]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Trunc.ProbErrorAtMostOne]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Trunc.ProbErrorAtMostOne]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:340 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Trunc.ExactPartyUsesDelta]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Trunc.ExactPartyUsesDelta]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Trunc.ExactPartyUsesDelta]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:348 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Trunc.MulTruncClear]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Trunc.MulTruncClear]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Trunc.MulTruncClear]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:361 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ShareCmp.ReluMaxDivParty]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=ShareCmp.ReluMaxDivParty]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ShareCmp.ReluMaxDivParty]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:367 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ShareCmp.Declassify]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=ShareCmp.Declassify]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ShareCmp.Declassify]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:389 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ShareVec.MulDeclassify]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=ShareVec.MulDeclassify]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ShareVec.MulDeclassify]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:399 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[FixedShare.MulViaTrunc]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=FixedShare.MulViaTrunc]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[FixedShare.MulViaTrunc]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:410 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ShareExpr.MulAddDeclassify]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=ShareExpr.MulAddDeclassify]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ShareExpr.MulAddDeclassify]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:425 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ShareExpr.BandArity]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=ShareExpr.BandArity]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ShareExpr.BandArity]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:454 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Gilboa.MulFromOtMatchesClear]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Gilboa.MulFromOtMatchesClear]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Gilboa.MulFromOtMatchesClear]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:474 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Gilboa.FillTapeOtRepeatedWire]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Gilboa.FillTapeOtRepeatedWire]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Gilboa.FillTapeOtRepeatedWire]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:483 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Gilboa.FillTapeDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Gilboa.FillTapeDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Gilboa.FillTapeDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:498 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Gilboa.FillTapeOtReadsStash]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Gilboa.FillTapeOtReadsStash]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Gilboa.FillTapeOtReadsStash]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:802 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Gilboa.MulTapeViaStreamArrays]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Gilboa.MulTapeViaStreamArrays]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Gilboa.MulTapeViaStreamArrays]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1659 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Gilboa.MulOnlineViaStreamArrays]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Gilboa.MulOnlineViaStreamArrays]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Gilboa.MulOnlineViaStreamArrays]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1672 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Matmul.EightByEight]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Matmul.EightByEight]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Matmul.EightByEight]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:513 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Shuffle.CliqueSendNext]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Shuffle.CliqueSendNext]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Shuffle.CliqueSendNext]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:528 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Shuffle.SelectSumCountArgmax]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Shuffle.SelectSumCountArgmax]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Shuffle.SelectSumCountArgmax]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:853 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Circuit.MulOpenFromDealerFile]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Circuit.MulOpenFromDealerFile]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Circuit.MulOpenFromDealerFile]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:864 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Circuit.PrivateInputAndTcpPrep]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Circuit.PrivateInputAndTcpPrep]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Circuit.PrivateInputAndTcpPrep]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:893 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Circuit.MulOpenFromStreamArray]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Circuit.MulOpenFromStreamArray]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Circuit.MulOpenFromStreamArray]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1079 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Circuit.RecordsGmwAndA2bGtTruncMux]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Circuit.RecordsGmwAndA2bGtTruncMux]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Circuit.RecordsGmwAndA2bGtTruncMux]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1199 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Run.ThreePartyDeclassify]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Run.ThreePartyDeclassify]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Run.ThreePartyDeclassify]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:930 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Run.ThreePartyDeclassifyStreamClique]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Run.ThreePartyDeclassifyStreamClique]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Run.ThreePartyDeclassifyStreamClique]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1136 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[CostPass.EmptyPlanNoSynthetic]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=CostPass.EmptyPlanNoSynthetic]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[CostPass.EmptyPlanNoSynthetic]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:945 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[CostPass.RealCmpGetsChoice]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=CostPass.RealCmpGetsChoice]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[CostPass.RealCmpGetsChoice]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:956 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StreamArray.MemoryDealerRingTriple]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=StreamArray.MemoryDealerRingTriple]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StreamArray.MemoryDealerRingTriple]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:968 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StreamArray.FileDealerRoundTrip]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=StreamArray.FileDealerRoundTrip]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StreamArray.FileDealerRoundTrip]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:990 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StreamArray.MuxLocalhostDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=StreamArray.MuxLocalhostDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StreamArray.MuxLocalhostDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1016 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StreamArray.MultiRoundSinkExchange]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=StreamArray.MultiRoundSinkExchange]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StreamArray.MultiRoundSinkExchange]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1107 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StreamArray.DealerCursorFromStreamPrg]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=StreamArray.DealerCursorFromStreamPrg]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StreamArray.DealerCursorFromStreamPrg]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1314 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StreamArray.SctpStreamArrayStubThrows]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=StreamArray.SctpStreamArrayStubThrows]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StreamArray.SctpStreamArrayStubThrows]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1733 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Factory.GmwAndRoundMemory]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Factory.GmwAndRoundMemory]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Factory.GmwAndRoundMemory]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1054 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Factory.BeaverMulStreamMemory]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Factory.BeaverMulStreamMemory]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Factory.BeaverMulStreamMemory]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1171 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Factory.MuxOnlineStreamMemory]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Factory.MuxOnlineStreamMemory]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Factory.MuxOnlineStreamMemory]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1217 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Factory.A2bTapeOnline]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Factory.A2bTapeOnline]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Factory.A2bTapeOnline]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1248 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Factory.TruncTapeOnline]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Factory.TruncTapeOnline]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Factory.TruncTapeOnline]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1268 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Factory.GtTapeOnline]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Factory.GtTapeOnline]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Factory.GtTapeOnline]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1291 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Factory.ScheduleOnStreams]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Factory.ScheduleOnStreams]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Factory.ScheduleOnStreams]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1346 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Factory.RssRefreshRingStreamClique]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Factory.RssRefreshRingStreamClique]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Factory.RssRefreshRingStreamClique]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1691 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Factory.AsyncByteProtocolRoundCallbacks]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Factory.AsyncByteProtocolRoundCallbacks]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Factory.AsyncByteProtocolRoundCallbacks]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1782 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Roles.DealerWriteFilesRoundTrip]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Roles.DealerWriteFilesRoundTrip]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Roles.DealerWriteFilesRoundTrip]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1399 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[AsyncIo.MemoryOverlapTwoRounds]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=AsyncIo.MemoryOverlapTwoRounds]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[AsyncIo.MemoryOverlapTwoRounds]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1826 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[AsyncIo.MuxLocalhostOverlap]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=AsyncIo.MuxLocalhostOverlap]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[AsyncIo.MuxLocalhostOverlap]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1865 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[AsyncIo.ParallelSocketsTwoStreams]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=AsyncIo.ParallelSocketsTwoStreams]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[AsyncIo.ParallelSocketsTwoStreams]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1928 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[AsyncIo.SctpLocalhostOverlap]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=AsyncIo.SctpLocalhostOverlap]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[AsyncIo.SctpLocalhostOverlap]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:1976 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[AsyncIo.LaneReuseDeepPlan]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=AsyncIo.LaneReuseDeepPlan]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[AsyncIo.LaneReuseDeepPlan]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2100 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[AsyncIo.OverlappedLaneModulo]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=AsyncIo.OverlappedLaneModulo]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[AsyncIo.OverlappedLaneModulo]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2169 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[AppFlow.ExercisePlanUsesStreamFramework]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=AppFlow.ExercisePlanUsesStreamFramework]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[AppFlow.ExercisePlanUsesStreamFramework]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2069 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[AppFlow.ExercisePlanAsyncMemoryFramework]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=AppFlow.ExercisePlanAsyncMemoryFramework]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[AppFlow.ExercisePlanAsyncMemoryFramework]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2087 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[ComposeAsync.DriveBothOnAsyncStreams]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=ComposeAsync.DriveBothOnAsyncStreams]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[ComposeAsync.DriveBothOnAsyncStreams]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2145 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[TcpMesh.ThreePartyMuxExchange]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=TcpMesh.ThreePartyMuxExchange]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[TcpMesh.ThreePartyMuxExchange]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2212 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.ShipPrepAsync]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Session.ShipPrepAsync]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.ShipPrepAsync]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2245 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.HushmapAsyncDealerAndPeer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Session.HushmapAsyncDealerAndPeer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.HushmapAsyncDealerAndPeer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2268 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[Session.PirsonaAsyncStar]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=Session.PirsonaAsyncStar]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[Session.PirsonaAsyncStar]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2273 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[WireWindow.MuxTinyWindowStillCompletes]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=WireWindow.MuxTinyWindowStillCompletes]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[WireWindow.MuxTinyWindowStillCompletes]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2291 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IoPool.PostsComputeOnSharedWorkers]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=IoPool.PostsComputeOnSharedWorkers]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IoPool.PostsComputeOnSharedWorkers]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2371 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[IoPool.ComputeDoesNotUseSocketContext]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=IoPool.ComputeDoesNotUseSocketContext]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[IoPool.ComputeDoesNotUseSocketContext]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2519 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[PartySession.JoinReconnectAndDealerOnOnePool]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=PartySession.JoinReconnectAndDealerOnOnePool]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[PartySession.JoinReconnectAndDealerOnOnePool]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2411 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[PartySession.WindowAndLaneOverride]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=PartySession.WindowAndLaneOverride]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[PartySession.WindowAndLaneOverride]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2599 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[SocketTune.NoDelayOnConnectedSocket]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=SocketTune.NoDelayOnConnectedSocket]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[SocketTune.NoDelayOnConnectedSocket]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2492 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[DriveOptions.LaneCountAndWaitTimeout]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=DriveOptions.LaneCountAndWaitTimeout]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[DriveOptions.LaneCountAndWaitTimeout]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2536 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[DriveOptions.KernelRunsOnComputePool]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/share_runtime_test [==[--gtest_filter=DriveOptions.KernelRunsOnComputePool]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[DriveOptions.KernelRunsOnComputePool]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/share_runtime_test.cpp:2560 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( share_runtime_test_TESTS RssSeed.RandomReplicatedSums RssSeed.ZeroSharesSumToZero RssSeed.MulLocalThenRefresh ScheduleSession.PipelineCreditIndependentPads Compose.BinNotLocalConvertible Compose.ArithKernelsPresent Compose.RssZeroFromSeeds Compose.CheckOpenRejectsCorrupt Compose.CheckOpenHashRing Compose.TruncExactKernel Compose.B2aOpenMatchesClear Compose.MulTruncOpen Compose.InjectAndMuxOpen Compose.GmwAndOpen Compose.DrivePlanOnStreamsOpen Compose.DrivePlanOnStreamsTwoWaves Compose.DrivePlanOnStreamsGmwAnd Compose.DrivePlanOnStreamsDeepEightWaves Compose.DrivePlanOnStreamsMuxTcp Compose.DrivePlanOnStreamMeshRssCopy Compose.NPartyComposerAllowed EdaBit.A2BThenReconstruct EdaBit.RssArithEqualsBits EdaBit.GmwA2bMatchesClear EdaBit.DaBitPairConsistent BitInject.ClearMatches BitInject.RssAndLocal BitInject.RssAndRefresh Trunc.ProbErrorAtMostOne Trunc.ExactPartyUsesDelta Trunc.MulTruncClear ShareCmp.ReluMaxDivParty ShareCmp.Declassify ShareVec.MulDeclassify FixedShare.MulViaTrunc ShareExpr.MulAddDeclassify ShareExpr.BandArity Gilboa.MulFromOtMatchesClear Gilboa.FillTapeOtRepeatedWire Gilboa.FillTapeDealer Gilboa.FillTapeOtReadsStash Gilboa.MulTapeViaStreamArrays Gilboa.MulOnlineViaStreamArrays Matmul.EightByEight Shuffle.CliqueSendNext Shuffle.SelectSumCountArgmax Circuit.MulOpenFromDealerFile Circuit.PrivateInputAndTcpPrep Circuit.MulOpenFromStreamArray Circuit.RecordsGmwAndA2bGtTruncMux Run.ThreePartyDeclassify Run.ThreePartyDeclassifyStreamClique CostPass.EmptyPlanNoSynthetic CostPass.RealCmpGetsChoice StreamArray.MemoryDealerRingTriple StreamArray.FileDealerRoundTrip StreamArray.MuxLocalhostDealer StreamArray.MultiRoundSinkExchange StreamArray.DealerCursorFromStreamPrg StreamArray.SctpStreamArrayStubThrows Factory.GmwAndRoundMemory Factory.BeaverMulStreamMemory Factory.MuxOnlineStreamMemory Factory.A2bTapeOnline Factory.TruncTapeOnline Factory.GtTapeOnline Factory.ScheduleOnStreams Factory.RssRefreshRingStreamClique Factory.AsyncByteProtocolRoundCallbacks Roles.DealerWriteFilesRoundTrip AsyncIo.MemoryOverlapTwoRounds AsyncIo.MuxLocalhostOverlap AsyncIo.ParallelSocketsTwoStreams AsyncIo.SctpLocalhostOverlap AsyncIo.LaneReuseDeepPlan AsyncIo.OverlappedLaneModulo AppFlow.ExercisePlanUsesStreamFramework AppFlow.ExercisePlanAsyncMemoryFramework ComposeAsync.DriveBothOnAsyncStreams TcpMesh.ThreePartyMuxExchange Session.ShipPrepAsync Session.HushmapAsyncDealerAndPeer Session.PirsonaAsyncStar WireWindow.MuxTinyWindowStillCompletes IoPool.PostsComputeOnSharedWorkers IoPool.ComputeDoesNotUseSocketContext PartySession.JoinReconnectAndDealerOnOnePool PartySession.WindowAndLaneOverride SocketTune.NoDelayOnConnectedSocket DriveOptions.LaneCountAndWaitTimeout DriveOptions.KernelRunsOnComputePool) diff --git a/test/build-asan/shared_and_test[1]_include.cmake b/test/build-asan/shared_and_test[1]_include.cmake new file mode 100644 index 0000000..2a2f077 --- /dev/null +++ b/test/build-asan/shared_and_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/shared_and_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/shared_and_test[1]_tests.cmake") +else() + add_test(shared_and_test_NOT_BUILT shared_and_test_NOT_BUILT) +endif() diff --git a/test/build-asan/shuffle_hidden_test[1]_include.cmake b/test/build-asan/shuffle_hidden_test[1]_include.cmake new file mode 100644 index 0000000..82b9979 --- /dev/null +++ b/test/build-asan/shuffle_hidden_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/shuffle_hidden_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/shuffle_hidden_test[1]_tests.cmake") +else() + add_test(shuffle_hidden_test_NOT_BUILT shuffle_hidden_test_NOT_BUILT) +endif() diff --git a/test/build-asan/signed_prefix_test[1]_include.cmake b/test/build-asan/signed_prefix_test[1]_include.cmake new file mode 100644 index 0000000..a342265 --- /dev/null +++ b/test/build-asan/signed_prefix_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/signed_prefix_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/signed_prefix_test[1]_tests.cmake") +else() + add_test(signed_prefix_test_NOT_BUILT signed_prefix_test_NOT_BUILT) +endif() diff --git a/test/build-asan/signed_prefix_test[1]_tests.cmake b/test/build-asan/signed_prefix_test[1]_tests.cmake new file mode 100644 index 0000000..62c9262 --- /dev/null +++ b/test/build-asan/signed_prefix_test[1]_tests.cmake @@ -0,0 +1,15 @@ +add_test([=[SignedPrefix.MatchesComparisonEvalOnEveryUint8Point]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/signed_prefix_test [==[--gtest_filter=SignedPrefix.MatchesComparisonEvalOnEveryUint8Point]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[SignedPrefix.MatchesComparisonEvalOnEveryUint8Point]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/signed_prefix_test.cpp:33 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[SignedPrefix.SegmentsAreOneHot]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/signed_prefix_test [==[--gtest_filter=SignedPrefix.SegmentsAreOneHot]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[SignedPrefix.SegmentsAreOneHot]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/signed_prefix_test.cpp:51 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[SignedPrefix.WholeDomainIsThePublicOne]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/signed_prefix_test [==[--gtest_filter=SignedPrefix.WholeDomainIsThePublicOne]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[SignedPrefix.WholeDomainIsThePublicOne]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/signed_prefix_test.cpp:81 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[SignedPrefix.SignumLutIsSignCorrect]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/signed_prefix_test [==[--gtest_filter=SignedPrefix.SignumLutIsSignCorrect]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[SignedPrefix.SignumLutIsSignCorrect]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/signed_prefix_test.cpp:90 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[SignedPrefix.SharedPrefixAgreesWithAFreshWalk]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/signed_prefix_test [==[--gtest_filter=SignedPrefix.SharedPrefixAgreesWithAFreshWalk]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[SignedPrefix.SharedPrefixAgreesWithAFreshWalk]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/signed_prefix_test.cpp:121 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[SignedPrefix.RejectsAKeyWithoutAComparison]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/signed_prefix_test [==[--gtest_filter=SignedPrefix.RejectsAKeyWithoutAComparison]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[SignedPrefix.RejectsAKeyWithoutAComparison]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/signed_prefix_test.cpp:138 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[SignedPrefix.SegmentsRecoverIlogbInt8]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/signed_prefix_test [==[--gtest_filter=SignedPrefix.SegmentsRecoverIlogbInt8]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[SignedPrefix.SegmentsRecoverIlogbInt8]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/signed_prefix_test.cpp:180 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( signed_prefix_test_TESTS SignedPrefix.MatchesComparisonEvalOnEveryUint8Point SignedPrefix.SegmentsAreOneHot SignedPrefix.WholeDomainIsThePublicOne SignedPrefix.SignumLutIsSignCorrect SignedPrefix.SharedPrefixAgreesWithAFreshWalk SignedPrefix.RejectsAKeyWithoutAComparison SignedPrefix.SegmentsRecoverIlogbInt8) diff --git a/test/build-asan/stress_scenarios_test[1]_include.cmake b/test/build-asan/stress_scenarios_test[1]_include.cmake new file mode 100644 index 0000000..1b5c8aa --- /dev/null +++ b/test/build-asan/stress_scenarios_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/stress_scenarios_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/stress_scenarios_test[1]_tests.cmake") +else() + add_test(stress_scenarios_test_NOT_BUILT stress_scenarios_test_NOT_BUILT) +endif() diff --git a/test/build-asan/stress_scenarios_test[1]_tests.cmake b/test/build-asan/stress_scenarios_test[1]_tests.cmake new file mode 100644 index 0000000..5bff37e --- /dev/null +++ b/test/build-asan/stress_scenarios_test[1]_tests.cmake @@ -0,0 +1,163 @@ +add_test([=[StressScenariosTest.MlEvalFullPrefixSlot]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlEvalFullPrefixSlot]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlEvalFullPrefixSlot]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:274 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlEvalFullDeepestSlot]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlEvalFullDeepestSlot]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlEvalFullDeepestSlot]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:294 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlEvalFullOutbufMatchesReturned]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlEvalFullOutbufMatchesReturned]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlEvalFullOutbufMatchesReturned]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:313 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlEvalFullCmpSmallDomain]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlEvalFullCmpSmallDomain]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlEvalFullCmpSmallDomain]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:330 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlIntervalWithBasicIntervalMemoizer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlIntervalWithBasicIntervalMemoizer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlIntervalWithBasicIntervalMemoizer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:354 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlSequencePointLoopVsBreadthFirst]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlSequencePointLoopVsBreadthFirst]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlSequencePointLoopVsBreadthFirst]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:381 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlSequenceRecipeDepthAndBreadthFirst]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlSequenceRecipeDepthAndBreadthFirst]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlSequenceRecipeDepthAndBreadthFirst]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:410 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlMixedPointRecon]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlMixedPointRecon]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlMixedPointRecon]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:453 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlMixedIntervalRecon]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlMixedIntervalRecon]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlMixedIntervalRecon]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:470 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlMixedSequenceRecon]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlMixedSequenceRecon]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlMixedSequenceRecon]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:484 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlMixedInnerProduct]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlMixedInnerProduct]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlMixedInnerProduct]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:509 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlMixedCmp]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlMixedCmp]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlMixedCmp]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:532 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlWildcardEvalPointThrowsBeforeAssign]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlWildcardEvalPointThrowsBeforeAssign]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlWildcardEvalPointThrowsBeforeAssign]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:548 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlWildcardOtherSlotsStillWork]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlWildcardOtherSlotsStillWork]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlWildcardOtherSlotsStillWork]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:559 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlCrossLevelPathMemoizerShallowThenDeep]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlCrossLevelPathMemoizerShallowThenDeep]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlCrossLevelPathMemoizerShallowThenDeep]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:571 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlIndependentIntervalsTwoSlots]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlIndependentIntervalsTwoSlots]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlIndependentIntervalsTwoSlots]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:594 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicMixedByteIdenticalArgsVsConv]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicMixedByteIdenticalArgsVsConv]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicMixedByteIdenticalArgsVsConv]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:616 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicMixedDealerMatchesDoernerShelat]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicMixedDealerMatchesDoernerShelat]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicMixedDealerMatchesDoernerShelat]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:631 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicInnerProductMatchesInterval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicInnerProductMatchesInterval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicInnerProductMatchesInterval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:671 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicOutPointMatchesIndexedPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicOutPointMatchesIndexedPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicOutPointMatchesIndexedPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:696 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicOutIntervalMatchesIndexedInterval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicOutIntervalMatchesIndexedInterval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicOutIntervalMatchesIndexedInterval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:715 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicPrepareIntervalThenInnerProduct]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicPrepareIntervalThenInnerProduct]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicPrepareIntervalThenInnerProduct]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:729 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicPartialMisalignedInterval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicPartialMisalignedInterval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicPartialMisalignedInterval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:753 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicBasicVsFullTreeIntervalMemoizer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicBasicVsFullTreeIntervalMemoizer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicBasicVsFullTreeIntervalMemoizer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:773 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicMultiLeafFullEvalPerSlot]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicMultiLeafFullEvalPerSlot]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicMultiLeafFullEvalPerSlot]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:799 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.PrgAesInteriorLowmcExteriorClassicPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.PrgAesInteriorLowmcExteriorClassicPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.PrgAesInteriorLowmcExteriorClassicPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:818 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.PrgLowmcInteriorAesExteriorClassicPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.PrgLowmcInteriorAesExteriorClassicPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.PrgLowmcInteriorAesExteriorClassicPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:831 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.PrgAesLowmcMultilevelPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.PrgAesLowmcMultilevelPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.PrgAesLowmcMultilevelPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:844 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.PrgLowmcAesMultilevelPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.PrgLowmcAesMultilevelPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.PrgLowmcAesMultilevelPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:857 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.PrgDummyAesClassicPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.PrgDummyAesClassicPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.PrgDummyAesClassicPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:868 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.PrgChachaInteriorAesExteriorClassicPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.PrgChachaInteriorAesExteriorClassicPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.PrgChachaInteriorAesExteriorClassicPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:881 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.PrgAesInteriorChachaExteriorClassicPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.PrgAesInteriorChachaExteriorClassicPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.PrgAesInteriorChachaExteriorClassicPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:894 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.PrgLowmcLowmcMultilevelPacking]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.PrgLowmcLowmcMultilevelPacking]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.PrgLowmcLowmcMultilevelPacking]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:907 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.SignedInputAtAndCmp]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.SignedInputAtAndCmp]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.SignedInputAtAndCmp]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:927 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ModintInputClassicPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ModintInputClassicPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ModintInputClassicPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:943 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.KeywordInputClassicPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.KeywordInputClassicPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.KeywordInputClassicPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:955 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.CmpPackedAtDeepestUnderDoernerShelat]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.CmpPackedAtDeepestUnderDoernerShelat]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.CmpPackedAtDeepestUnderDoernerShelat]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:967 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.Packed16xU8PartialIntervalOffAlignment]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.Packed16xU8PartialIntervalOffAlignment]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.Packed16xU8PartialIntervalOffAlignment]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1004 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicMultiOutputInterval012]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicMultiOutputInterval012]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicMultiOutputInterval012]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1039 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlEvalSweepAroundPointPrefixSlot]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlEvalSweepAroundPointPrefixSlot]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlEvalSweepAroundPointPrefixSlot]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1065 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlInnerProductExplicitMemoizerMatchesDefault]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlInnerProductExplicitMemoizerMatchesDefault]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlInnerProductExplicitMemoizerMatchesDefault]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1090 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlCmpInnerProductMatchesInterval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlCmpInnerProductMatchesInterval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlCmpInnerProductMatchesInterval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1110 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicOutFullMatchesIndexedFull]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicOutFullMatchesIndexedFull]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicOutFullMatchesIndexedFull]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1132 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.PrgAesLowmcMultilevelInterval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.PrgAesLowmcMultilevelInterval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.PrgAesLowmcMultilevelInterval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1144 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicRecipeMemoizerVariantsAgree]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicRecipeMemoizerVariantsAgree]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicRecipeMemoizerVariantsAgree]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1158 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicRecipeEntireNodeVsOutputOnly]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicRecipeEntireNodeVsOutputOnly]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicRecipeEntireNodeVsOutputOnly]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1194 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicBreadthFirstMatchesPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicBreadthFirstMatchesPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicBreadthFirstMatchesPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1231 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicFullInnerProductMatchesFullInterval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicFullInnerProductMatchesFullInterval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicFullInnerProductMatchesFullInterval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1259 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlXorSlotInnerProduct]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlXorSlotInnerProduct]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlXorSlotInnerProduct]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1286 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlBitstringDeepestOutput]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlBitstringDeepestOutput]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlBitstringDeepestOutput]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1313 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlGeqFullCmpMatchesPointSweep]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlGeqFullCmpMatchesPointSweep]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlGeqFullCmpMatchesPointSweep]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1325 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicMultiLeafPathMemoizerReuse]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicMultiLeafPathMemoizerReuse]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicMultiLeafPathMemoizerReuse]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1341 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DummyInteriorLowmcExteriorMultilevel]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DummyInteriorLowmcExteriorMultilevel]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DummyInteriorLowmcExteriorMultilevel]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1362 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicMixedFullTreeFullMemoizer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicMixedFullTreeFullMemoizer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicMixedFullTreeFullMemoizer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1375 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlEqAtWithPackedNeighbors]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlEqAtWithPackedNeighbors]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlEqAtWithPackedNeighbors]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1407 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ModintMultilevelGenAndPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ModintMultilevelGenAndPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ModintMultilevelGenAndPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1433 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ModintMultilevelWithCmp]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ModintMultilevelWithCmp]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ModintMultilevelWithCmp]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1453 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.KeywordMultilevelGenAndPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.KeywordMultilevelGenAndPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.KeywordMultilevelGenAndPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1477 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityManyLevelsMixedWidthsXorAdditiveCmpLt]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityManyLevelsMixedWidthsXorAdditiveCmpLt]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityManyLevelsMixedWidthsXorAdditiveCmpLt]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1503 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityPacked16xU8DeepestGeq]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityPacked16xU8DeepestGeq]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityPacked16xU8DeepestGeq]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1546 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityClassicMultiLeafXorAdditiveBytes]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityClassicMultiLeafXorAdditiveBytes]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityClassicMultiLeafXorAdditiveBytes]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1583 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityIntermediateWildcardConcreteSiblings]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityIntermediateWildcardConcreteSiblings]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityIntermediateWildcardConcreteSiblings]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1609 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityFixedpointAtWithCmp]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityFixedpointAtWithCmp]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityFixedpointAtWithCmp]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1643 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityLocalCwProtocolVsDealer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityLocalCwProtocolVsDealer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityLocalCwProtocolVsDealer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1674 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityAesInteriorLowmcExteriorMultilevel]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityAesInteriorLowmcExteriorMultilevel]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityAesInteriorLowmcExteriorMultilevel]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1697 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityWildcardCmpThenAssign]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityWildcardCmpThenAssign]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityWildcardCmpThenAssign]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1724 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityLocalCwComplexManyLevelsCmp]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityLocalCwComplexManyLevelsCmp]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityLocalCwComplexManyLevelsCmp]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1770 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityModintMultilevelXorAdditiveCmp]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityModintMultilevelXorAdditiveCmp]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityModintMultilevelXorAdditiveCmp]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1800 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityKeywordMultilevel]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityKeywordMultilevel]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityKeywordMultilevel]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1835 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlEvalFullPrefixAndDeepestMultiLane]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlEvalFullPrefixAndDeepestMultiLane]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlEvalFullPrefixAndDeepestMultiLane]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1871 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlEvalFullWithPerSlotMemoizer]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlEvalFullWithPerSlotMemoizer]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlEvalFullWithPerSlotMemoizer]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1906 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ModintMlEvalFullMatchesPoint]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ModintMlEvalFullMatchesPoint]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ModintMlEvalFullMatchesPoint]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1944 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlLtFullCmpMatchesPointSweep]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlLtFullCmpMatchesPointSweep]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlLtFullCmpMatchesPointSweep]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1966 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.ClassicFullTreeMemoizerMultiLeafIndexed]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.ClassicFullTreeMemoizerMultiLeafIndexed]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.ClassicFullTreeMemoizerMultiLeafIndexed]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:1990 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlPackedSmallWildcardAtNonTerminalAssignAll]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlPackedSmallWildcardAtNonTerminalAssignAll]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlPackedSmallWildcardAtNonTerminalAssignAll]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:2026 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.MlPackedXorWildcardAtNonTerminalAssignAll]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.MlPackedXorWildcardAtNonTerminalAssignAll]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.MlPackedXorWildcardAtNonTerminalAssignAll]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:2083 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityPackedSmallWildcardAtNonTerminal]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityPackedSmallWildcardAtNonTerminal]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityPackedSmallWildcardAtNonTerminal]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:2114 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.DsIdentityPackedWildcardLowmcExteriorThenAssign]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.DsIdentityPackedWildcardLowmcExteriorThenAssign]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.DsIdentityPackedWildcardLowmcExteriorThenAssign]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:2200 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.PrgCounterWrapperAesClassicEvalIncrements]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.PrgCounterWrapperAesClassicEvalIncrements]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.PrgCounterWrapperAesClassicEvalIncrements]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:2242 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.PrgCounterWrapperLowmcMultilevelEvalIncrements]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.PrgCounterWrapperLowmcMultilevelEvalIncrements]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.PrgCounterWrapperLowmcMultilevelEvalIncrements]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:2260 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +add_test([=[StressScenariosTest.PrgLowmcBothSidesPackedInterval]=] /home/cryptolicious/hushmap-specified/libdpf/test/build-asan/bin/stress_scenarios_test [==[--gtest_filter=StressScenariosTest.PrgLowmcBothSidesPackedInterval]==] --gtest_also_run_disabled_tests) +set_tests_properties([=[StressScenariosTest.PrgLowmcBothSidesPackedInterval]=] PROPERTIES DEF_SOURCE_LINE /home/cryptolicious/hushmap-specified/libdpf/test/tests/stress_scenarios_test.cpp:2285 WORKING_DIRECTORY /home/cryptolicious/hushmap-specified/libdpf/test/build-asan SKIP_REGULAR_EXPRESSION [==[\[ SKIPPED \]]==]) +set( stress_scenarios_test_TESTS StressScenariosTest.MlEvalFullPrefixSlot StressScenariosTest.MlEvalFullDeepestSlot StressScenariosTest.MlEvalFullOutbufMatchesReturned StressScenariosTest.MlEvalFullCmpSmallDomain StressScenariosTest.MlIntervalWithBasicIntervalMemoizer StressScenariosTest.MlSequencePointLoopVsBreadthFirst StressScenariosTest.MlSequenceRecipeDepthAndBreadthFirst StressScenariosTest.MlMixedPointRecon StressScenariosTest.MlMixedIntervalRecon StressScenariosTest.MlMixedSequenceRecon StressScenariosTest.MlMixedInnerProduct StressScenariosTest.MlMixedCmp StressScenariosTest.MlWildcardEvalPointThrowsBeforeAssign StressScenariosTest.MlWildcardOtherSlotsStillWork StressScenariosTest.MlCrossLevelPathMemoizerShallowThenDeep StressScenariosTest.MlIndependentIntervalsTwoSlots StressScenariosTest.ClassicMixedByteIdenticalArgsVsConv StressScenariosTest.ClassicMixedDealerMatchesDoernerShelat StressScenariosTest.ClassicInnerProductMatchesInterval StressScenariosTest.ClassicOutPointMatchesIndexedPoint StressScenariosTest.ClassicOutIntervalMatchesIndexedInterval StressScenariosTest.ClassicPrepareIntervalThenInnerProduct StressScenariosTest.ClassicPartialMisalignedInterval StressScenariosTest.ClassicBasicVsFullTreeIntervalMemoizer StressScenariosTest.ClassicMultiLeafFullEvalPerSlot StressScenariosTest.PrgAesInteriorLowmcExteriorClassicPoint StressScenariosTest.PrgLowmcInteriorAesExteriorClassicPoint StressScenariosTest.PrgAesLowmcMultilevelPoint StressScenariosTest.PrgLowmcAesMultilevelPoint StressScenariosTest.PrgDummyAesClassicPoint StressScenariosTest.PrgChachaInteriorAesExteriorClassicPoint StressScenariosTest.PrgAesInteriorChachaExteriorClassicPoint StressScenariosTest.PrgLowmcLowmcMultilevelPacking StressScenariosTest.SignedInputAtAndCmp StressScenariosTest.ModintInputClassicPoint StressScenariosTest.KeywordInputClassicPoint StressScenariosTest.CmpPackedAtDeepestUnderDoernerShelat StressScenariosTest.Packed16xU8PartialIntervalOffAlignment StressScenariosTest.ClassicMultiOutputInterval012 StressScenariosTest.MlEvalSweepAroundPointPrefixSlot StressScenariosTest.MlInnerProductExplicitMemoizerMatchesDefault StressScenariosTest.MlCmpInnerProductMatchesInterval StressScenariosTest.ClassicOutFullMatchesIndexedFull StressScenariosTest.PrgAesLowmcMultilevelInterval StressScenariosTest.ClassicRecipeMemoizerVariantsAgree StressScenariosTest.ClassicRecipeEntireNodeVsOutputOnly StressScenariosTest.ClassicBreadthFirstMatchesPoint StressScenariosTest.ClassicFullInnerProductMatchesFullInterval StressScenariosTest.MlXorSlotInnerProduct StressScenariosTest.MlBitstringDeepestOutput StressScenariosTest.MlGeqFullCmpMatchesPointSweep StressScenariosTest.ClassicMultiLeafPathMemoizerReuse StressScenariosTest.DummyInteriorLowmcExteriorMultilevel StressScenariosTest.ClassicMixedFullTreeFullMemoizer StressScenariosTest.MlEqAtWithPackedNeighbors StressScenariosTest.ModintMultilevelGenAndPoint StressScenariosTest.ModintMultilevelWithCmp StressScenariosTest.KeywordMultilevelGenAndPoint StressScenariosTest.DsIdentityManyLevelsMixedWidthsXorAdditiveCmpLt StressScenariosTest.DsIdentityPacked16xU8DeepestGeq StressScenariosTest.DsIdentityClassicMultiLeafXorAdditiveBytes StressScenariosTest.DsIdentityIntermediateWildcardConcreteSiblings StressScenariosTest.DsIdentityFixedpointAtWithCmp StressScenariosTest.DsIdentityLocalCwProtocolVsDealer StressScenariosTest.DsIdentityAesInteriorLowmcExteriorMultilevel StressScenariosTest.DsIdentityWildcardCmpThenAssign StressScenariosTest.DsIdentityLocalCwComplexManyLevelsCmp StressScenariosTest.DsIdentityModintMultilevelXorAdditiveCmp StressScenariosTest.DsIdentityKeywordMultilevel StressScenariosTest.MlEvalFullPrefixAndDeepestMultiLane StressScenariosTest.MlEvalFullWithPerSlotMemoizer StressScenariosTest.ModintMlEvalFullMatchesPoint StressScenariosTest.MlLtFullCmpMatchesPointSweep StressScenariosTest.ClassicFullTreeMemoizerMultiLeafIndexed StressScenariosTest.MlPackedSmallWildcardAtNonTerminalAssignAll StressScenariosTest.MlPackedXorWildcardAtNonTerminalAssignAll StressScenariosTest.DsIdentityPackedSmallWildcardAtNonTerminal StressScenariosTest.DsIdentityPackedWildcardLowmcExteriorThenAssign StressScenariosTest.PrgCounterWrapperAesClassicEvalIncrements StressScenariosTest.PrgCounterWrapperLowmcMultilevelEvalIncrements StressScenariosTest.PrgLowmcBothSidesPackedInterval) diff --git a/test/build-asan/types_test[1]_include.cmake b/test/build-asan/types_test[1]_include.cmake new file mode 100644 index 0000000..fb9b538 --- /dev/null +++ b/test/build-asan/types_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/types_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/types_test[1]_tests.cmake") +else() + add_test(types_test_NOT_BUILT types_test_NOT_BUILT) +endif() diff --git a/test/build-asan/vdpf_adversarial_test[1]_include.cmake b/test/build-asan/vdpf_adversarial_test[1]_include.cmake new file mode 100644 index 0000000..ea77387 --- /dev/null +++ b/test/build-asan/vdpf_adversarial_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/vdpf_adversarial_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/vdpf_adversarial_test[1]_tests.cmake") +else() + add_test(vdpf_adversarial_test_NOT_BUILT vdpf_adversarial_test_NOT_BUILT) +endif() diff --git a/test/build-asan/vdpf_regression_test[1]_include.cmake b/test/build-asan/vdpf_regression_test[1]_include.cmake new file mode 100644 index 0000000..5bc3b0d --- /dev/null +++ b/test/build-asan/vdpf_regression_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/vdpf_regression_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/vdpf_regression_test[1]_tests.cmake") +else() + add_test(vdpf_regression_test_NOT_BUILT vdpf_regression_test_NOT_BUILT) +endif() diff --git a/test/build-asan/verifiable_test[1]_include.cmake b/test/build-asan/verifiable_test[1]_include.cmake new file mode 100644 index 0000000..b537c67 --- /dev/null +++ b/test/build-asan/verifiable_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/verifiable_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/verifiable_test[1]_tests.cmake") +else() + add_test(verifiable_test_NOT_BUILT verifiable_test_NOT_BUILT) +endif() diff --git a/test/build-asan/walk_helpers_test[1]_include.cmake b/test/build-asan/walk_helpers_test[1]_include.cmake new file mode 100644 index 0000000..6f59c4f --- /dev/null +++ b/test/build-asan/walk_helpers_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/walk_helpers_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/walk_helpers_test[1]_tests.cmake") +else() + add_test(walk_helpers_test_NOT_BUILT walk_helpers_test_NOT_BUILT) +endif() diff --git a/test/build-asan/wide_payload_test[1]_include.cmake b/test/build-asan/wide_payload_test[1]_include.cmake new file mode 100644 index 0000000..3673ca2 --- /dev/null +++ b/test/build-asan/wide_payload_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/wide_payload_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/wide_payload_test[1]_tests.cmake") +else() + add_test(wide_payload_test_NOT_BUILT wide_payload_test_NOT_BUILT) +endif() diff --git a/test/build-asan/wildcard_test[1]_include.cmake b/test/build-asan/wildcard_test[1]_include.cmake new file mode 100644 index 0000000..f43fd0f --- /dev/null +++ b/test/build-asan/wildcard_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/wildcard_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/wildcard_test[1]_tests.cmake") +else() + add_test(wildcard_test_NOT_BUILT wildcard_test_NOT_BUILT) +endif() diff --git a/test/build-asan/window_lut_test[1]_include.cmake b/test/build-asan/window_lut_test[1]_include.cmake new file mode 100644 index 0000000..198b207 --- /dev/null +++ b/test/build-asan/window_lut_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/window_lut_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/window_lut_test[1]_tests.cmake") +else() + add_test(window_lut_test_NOT_BUILT window_lut_test_NOT_BUILT) +endif() diff --git a/test/build-asan/wrap_and_rotate_test[1]_include.cmake b/test/build-asan/wrap_and_rotate_test[1]_include.cmake new file mode 100644 index 0000000..e51af5c --- /dev/null +++ b/test/build-asan/wrap_and_rotate_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/wrap_and_rotate_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/wrap_and_rotate_test[1]_tests.cmake") +else() + add_test(wrap_and_rotate_test_NOT_BUILT wrap_and_rotate_test_NOT_BUILT) +endif() diff --git a/test/build-asan/yao_share_test[1]_include.cmake b/test/build-asan/yao_share_test[1]_include.cmake new file mode 100644 index 0000000..0670c84 --- /dev/null +++ b/test/build-asan/yao_share_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/yao_share_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/yao_share_test[1]_tests.cmake") +else() + add_test(yao_share_test_NOT_BUILT yao_share_test_NOT_BUILT) +endif() diff --git a/test/build-asan/yao_stack_test[1]_include.cmake b/test/build-asan/yao_stack_test[1]_include.cmake new file mode 100644 index 0000000..e608851 --- /dev/null +++ b/test/build-asan/yao_stack_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/yao_stack_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/yao_stack_test[1]_tests.cmake") +else() + add_test(yao_stack_test_NOT_BUILT yao_stack_test_NOT_BUILT) +endif() diff --git a/test/build-asan/yao_test[1]_include.cmake b/test/build-asan/yao_test[1]_include.cmake new file mode 100644 index 0000000..bdcaedc --- /dev/null +++ b/test/build-asan/yao_test[1]_include.cmake @@ -0,0 +1,5 @@ +if(EXISTS "/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/yao_test[1]_tests.cmake") + include("/home/cryptolicious/hushmap-specified/libdpf/test/build-asan/yao_test[1]_tests.cmake") +else() + add_test(yao_test_NOT_BUILT yao_test_NOT_BUILT) +endif() diff --git a/test/profile/__pycache__/cost_matrix.cpython-314.pyc b/test/profile/__pycache__/cost_matrix.cpython-314.pyc new file mode 100644 index 0000000..9b15431 Binary files /dev/null and b/test/profile/__pycache__/cost_matrix.cpython-314.pyc differ diff --git a/test/profile/cost_matrix.py b/test/profile/cost_matrix.py new file mode 100755 index 0000000..ea3f357 --- /dev/null +++ b/test/profile/cost_matrix.py @@ -0,0 +1,505 @@ +#!/usr/bin/env python3 +"""Cost matrix for libdpf profile harnesses. + +Each cell is one named case. Cells are grouped into slices so an optimization +pass can rerun only the code it touched. A label is a directory of results. +Rerunning a slice under the same label replaces those rows and leaves the rest. + +Examples: + test/profile/cost_matrix.py --list + test/profile/cost_matrix.py --label baseline + test/profile/cost_matrix.py --label baseline --slice interval + test/profile/cost_matrix.py --label baseline --slice memoizer --slice bits + test/profile/cost_matrix.py --label baseline --family grotto --slice horner + test/profile/cost_matrix.py --label baseline --case interval_u32_L4096 + test/profile/cost_matrix.py --label after-horner --slice horner + test/profile/cost_matrix.py --compare baseline after-horner + +Tiers: + std default. Benchable party flows, plus every in-process cell. + heavy wildcard_single_leaf, long beaver streams, full-domain DCFs, + and party flows whose names end in _domain. + all std and heavy. + smoke party flows that are negative tests, not cost points. + +Default repeats are per slice (party 3, tables 20, walks 12). --repeat +overrides every selected cell. + +Columns (blank when not instrumented): + prg_evals, bytes_sent, bytes_recv_from_p2, bytes_recv_from_peer, + rounds (channel exchange barriers; not frames), preprocess_bytes, + alloc_bytes, logical_bytes, layout_waste (alloc-logical), + payload_sent/recv, wire_overhead (framed bytes minus payload). + For p2, bytes_*_from_peer / bytes_*_to_peer sum the p0 and p1 links. +""" + +from __future__ import annotations + +import argparse +import csv +import os +import subprocess +import sys +from collections import defaultdict +from pathlib import Path + +LONG_FIELDS = [ + "family", + "slice", + "tier", + "case", + "role", + "items", + "repeat", + "warmup", + "avg_ns", + "min_ns", + "max_ns", + "avg_cycles", + "per_item_ns", + "out_bytes", + "prg_evals", + "preprocess_bytes", + "alloc_bytes", + "logical_bytes", + "layout_waste", + "bytes_sent", + "bytes_recv", + "bytes_recv_from_p2", + "bytes_recv_from_peer", + "bytes_sent_to_p2", + "bytes_sent_to_peer", + "payload_sent", + "payload_recv", + "wire_overhead", + "rounds", + "frames_sent", + "frames_recv", + "avg_bytes_sent", + "avg_frames_sent", + "wall_ms", + "rc", + "sink", +] + +MATRIX_FIELDS = [ + "family", + "slice", + "tier", + "case", + "role", + "avg_ns", + "per_item_ns", + "avg_cycles", + "out_bytes", + "prg_evals", + "preprocess_bytes", + "alloc_bytes", + "logical_bytes", + "layout_waste", + "bytes_sent", + "bytes_recv", + "bytes_recv_from_p2", + "bytes_recv_from_peer", + "rounds", + "wire_overhead", + "frames_sent", + "frames_recv", + "wall_ms", + "repeat", +] + +COMPARE_NUM = [ + "avg_ns", + "prg_evals", + "bytes_sent", + "bytes_recv_from_p2", + "bytes_recv_from_peer", + "rounds", + "preprocess_bytes", + "alloc_bytes", + "wire_overhead", +] + + +def default_bin_dir() -> Path: + here = Path(__file__).resolve().parent + candidate = here.parents[1] / "build" / "test" / "bin" + return candidate + + +def timing_for(family: str, slice_name: str, tier: str) -> tuple[int, int]: + if tier == "heavy": + return 1, 0 + if family == "party": + return 3, 1 + if slice_name in {"window", "principal", "closed", "reduced", "exact"}: + return 20, 2 + if slice_name == "keygen": + return 8, 1 + if slice_name in {"memoizer", "bits", "inner-product", "helpers"}: + return 12, 2 + return 12, 2 + + +def run_capture(cmd: list[str]) -> tuple[int, str, str]: + proc = subprocess.run(cmd, text=True, capture_output=True) + return proc.returncode, proc.stdout, proc.stderr + + +def parse_list(text: str) -> list[dict[str, str]]: + rows = [] + reader = csv.DictReader(text.splitlines(), delimiter="\t") + for row in reader: + if not row.get("case"): + continue + rows.append(row) + return rows + + +def discover(bin_dir: Path) -> list[dict[str, str]]: + cells: list[dict[str, str]] = [] + for binary in ("profile_eval", "profile_grotto", "profile_party"): + path = bin_dir / binary + if not path.is_file(): + raise SystemExit(f"missing {path}; build the profile targets first") + cmd = [str(path), "--list"] + if binary == "profile_party": + cmd.extend(["--tier", "all"]) + rc, out, err = run_capture(cmd) + if rc != 0: + raise SystemExit(err or out or f"{binary} --list failed") + if err.strip(): + print(err, file=sys.stderr, end="" if err.endswith("\n") else "\n") + for row in parse_list(out): + row["driver"] = binary + row.setdefault("tier", "std") + cells.append(row) + heavy_party = [ + "wildcard_single_leaf", + "beaver_stream_n512", + "beaver_stream_n2048", + ] + for row in cells: + if row["family"] == "party" and ( + row["case"] in heavy_party or row["case"].startswith("dcf_full_") + ): + row["tier"] = "heavy" + return cells + + +def select_cells(cells, args) -> list[dict[str, str]]: + chosen = [] + for row in cells: + if args.family and row["family"] not in args.family: + continue + if args.slice and row["slice"] not in args.slice: + continue + if args.case and row["case"] not in args.case: + continue + tier = row.get("tier") or "std" + if args.tier == "std" and tier != "std": + continue + if args.tier == "heavy" and tier != "heavy": + continue + if args.tier == "smoke" and tier != "smoke": + continue + if args.tier == "all" and tier == "smoke": + continue + chosen.append(row) + return chosen + + +def blank_cost_fields() -> dict[str, str]: + return { + "prg_evals": "", + "preprocess_bytes": "", + "alloc_bytes": "", + "logical_bytes": "", + "layout_waste": "", + "bytes_sent": "", + "bytes_recv": "", + "bytes_recv_from_p2": "", + "bytes_recv_from_peer": "", + "bytes_sent_to_p2": "", + "bytes_sent_to_peer": "", + "payload_sent": "", + "payload_recv": "", + "wire_overhead": "", + "rounds": "", + "frames_sent": "", + "frames_recv": "", + "avg_bytes_sent": "", + "avg_frames_sent": "", + "wall_ms": "", + } + + +def parse_inprocess(text: str, tier_of: dict[tuple[str, str], str]) -> list[dict[str, str]]: + rows = [] + reader = csv.DictReader(text.splitlines(), delimiter="\t") + for row in reader: + if not row or row.get("family") == "sink" or not row.get("case"): + continue + # Skip the trailing sink summary line if DictReader mis-parses it. + if row.get("family") == "sink": + continue + out = blank_cost_fields() + out.update({ + "family": row.get("family") or "", + "slice": row.get("slice") or "", + "tier": tier_of.get((row.get("family") or "", row.get("case") or ""), "std"), + "case": row.get("case") or "", + "role": "-", + "items": row.get("items") or "", + "repeat": row.get("repeat") or "", + "warmup": row.get("warmup") or "", + "avg_ns": row.get("avg_ns") or "", + "min_ns": row.get("min_ns") or "", + "max_ns": row.get("max_ns") or "", + "avg_cycles": row.get("avg_cycles") or "", + "per_item_ns": row.get("per_item_ns") or "", + "out_bytes": row.get("out_bytes") or "", + "prg_evals": row.get("prg_evals") or "", + "preprocess_bytes": row.get("preprocess_bytes") or "", + "alloc_bytes": row.get("alloc_bytes") or "", + "logical_bytes": row.get("logical_bytes") or "", + "layout_waste": row.get("layout_waste") or "", + "rc": "0", + "sink": row.get("sink") or "", + }) + rows.append(out) + return rows + + +def parse_party(text: str) -> list[dict[str, str]]: + rows = [] + reader = csv.DictReader(text.splitlines(), delimiter="\t") + for row in reader: + if not row.get("flow"): + continue + out = blank_cost_fields() + out.update({ + "family": row.get("family") or "party", + "slice": row.get("slice") or "", + "tier": row.get("tier") or "std", + "case": row["flow"], + "role": row.get("role") or "-", + "items": "1", + "repeat": "", + "warmup": "", + "avg_ns": row.get("avg_ns") or "", + "min_ns": row.get("min_ns") or "", + "max_ns": row.get("max_ns") or "", + "avg_cycles": "", + "per_item_ns": row.get("avg_ns") or "", + "out_bytes": "", + "prg_evals": row.get("prg_evals") or "", + "bytes_sent": row.get("bytes_sent") or "", + "bytes_recv": row.get("bytes_recv") or "", + "bytes_recv_from_p2": row.get("bytes_recv_from_p2") or "", + "bytes_recv_from_peer": row.get("bytes_recv_from_peer") or "", + "bytes_sent_to_p2": row.get("bytes_sent_to_p2") or "", + "bytes_sent_to_peer": row.get("bytes_sent_to_peer") or "", + "payload_sent": row.get("payload_sent") or "", + "payload_recv": row.get("payload_recv") or "", + "wire_overhead": row.get("wire_overhead") or "", + "rounds": row.get("rounds") or "", + "frames_sent": row.get("frames_sent") or "", + "frames_recv": row.get("frames_recv") or "", + "avg_bytes_sent": row.get("avg_bytes_sent") or "", + "avg_frames_sent": row.get("avg_frames_sent") or "", + "wall_ms": row.get("wall_ms") or "", + "rc": row.get("rc") or "", + "sink": "", + }) + rows.append(out) + return rows + + +def fill_timing(rows: list[dict[str, str]], repeat: int, warmup: int) -> None: + for row in rows: + if not row["repeat"]: + row["repeat"] = str(repeat) + if not row["warmup"]: + row["warmup"] = str(warmup) + + +def invoke_group(bin_dir: Path, driver: str, cases: list[dict[str, str]], + repeat: int, warmup: int) -> tuple[int, list[dict[str, str]], str]: + cmd = [str(bin_dir / driver), "--repeat", str(repeat), "--warmup", str(warmup)] + for case in cases: + cmd.extend(["--case", case["case"]]) + rc, out, err = run_capture(cmd) + tier_of = {(c["family"], c["case"]): c.get("tier") or "std" for c in cases} + if driver == "profile_party": + parsed = parse_party(out) + else: + parsed = parse_inprocess(out, tier_of) + fill_timing(parsed, repeat, warmup) + return rc, parsed, err + + +def write_tsv(path: Path, fields: list[str], rows: list[dict[str, str]]) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + with path.open("w", newline="") as fh: + writer = csv.DictWriter(fh, fieldnames=fields, delimiter="\t", extrasaction="ignore") + writer.writeheader() + for row in rows: + writer.writerow(row) + + +def read_tsv(path: Path) -> list[dict[str, str]]: + if not path.is_file(): + return [] + with path.open(newline="") as fh: + return list(csv.DictReader(fh, delimiter="\t")) + + +def merge_rows(old: list[dict[str, str]], new: list[dict[str, str]]) -> list[dict[str, str]]: + replaced = {(row["family"], row["slice"], row["case"], row["role"]) for row in new} + kept = [ + row for row in old + if (row.get("family"), row.get("slice"), row.get("case"), row.get("role")) not in replaced + ] + # Older long.tsv rows may lack new columns; normalize on merge. + merged = [] + for row in kept + new: + full = blank_cost_fields() + full.update({k: "" for k in LONG_FIELDS}) + full.update({k: v for k, v in row.items() if v is not None}) + merged.append(full) + return merged + + +def matrix_view(rows: list[dict[str, str]]) -> list[dict[str, str]]: + view = [] + for row in rows: + view.append({key: row.get(key, "") for key in MATRIX_FIELDS}) + view.sort(key=lambda r: (r["family"], r["slice"], r["case"], r["role"])) + return view + + +def print_catalog(cells: list[dict[str, str]]) -> None: + groups: dict[tuple[str, str, str], int] = defaultdict(int) + for row in cells: + groups[(row["family"], row["slice"], row.get("tier") or "std")] += 1 + print("family\tslice\ttier\tcases") + for (family, slice_name, tier), count in sorted(groups.items()): + print(f"{family}\t{slice_name}\t{tier}\t{count}") + print(f"# {len(cells)} cases in {len(groups)} slices") + + +def compare_labels(out_root: Path, left: str, right: str) -> int: + a_rows = read_tsv(out_root / left / "matrix.tsv") + b_rows = read_tsv(out_root / right / "matrix.tsv") + if not a_rows or not b_rows: + raise SystemExit(f"need matrix.tsv in both {left} and {right}") + b_index = { + (row["family"], row["slice"], row["case"], row["role"]): row + for row in b_rows + } + header = ["family", "slice", "case", "role"] + for col in COMPARE_NUM: + header.extend([f"{col}_a", f"{col}_b", f"delta_{col}"]) + print("\t".join(header)) + missing = 0 + for row in a_rows: + key = (row["family"], row["slice"], row["case"], row["role"]) + other = b_index.get(key) + if other is None: + missing += 1 + continue + parts = [row["family"], row["slice"], row["case"], row["role"]] + for col in COMPARE_NUM: + av_s = row.get(col, "") or "" + bv_s = other.get(col, "") or "" + try: + av = float(av_s) + bv = float(bv_s) + delta = f"{bv - av:.0f}" + except ValueError: + delta = "" + parts.extend([av_s, bv_s, delta]) + print("\t".join(parts)) + if missing: + print(f"# {missing} rows in {left} have no match in {right}", file=sys.stderr) + return 0 + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("--bin-dir", type=Path, default=default_bin_dir()) + parser.add_argument("--out", type=Path, default=None, + help="directory that holds one subdirectory per label") + parser.add_argument("--label", default="baseline") + parser.add_argument("--family", action="append", default=[]) + parser.add_argument("--slice", action="append", default=[]) + parser.add_argument("--case", action="append", default=[]) + parser.add_argument("--tier", choices=("std", "heavy", "all", "smoke"), default="std") + parser.add_argument("--repeat", type=int, default=None) + parser.add_argument("--warmup", type=int, default=None) + parser.add_argument("--list", action="store_true") + parser.add_argument("--compare", nargs=2, metavar=("LABEL_A", "LABEL_B")) + args = parser.parse_args() + + out_root = args.out + if out_root is None: + out_root = args.bin_dir.parent / "cost-matrix" + + if args.compare: + return compare_labels(out_root, args.compare[0], args.compare[1]) + + cells = discover(args.bin_dir) + chosen = select_cells(cells, args) + if args.list: + print_catalog(chosen) + return 0 + if not chosen: + print("no cells match", file=sys.stderr) + return 2 + + by_driver: dict[str, list[dict[str, str]]] = defaultdict(list) + for row in chosen: + by_driver[row["driver"]].append(row) + + fresh: list[dict[str, str]] = [] + failures = 0 + for driver, rows in by_driver.items(): + buckets: dict[tuple[str, str, str], list[dict[str, str]]] = defaultdict(list) + for row in rows: + buckets[(row["family"], row["slice"], row.get("tier") or "std")].append(row) + for (family, slice_name, tier), group in buckets.items(): + repeat, warmup = timing_for(family, slice_name, tier) + if args.repeat is not None: + repeat = args.repeat + if args.warmup is not None: + warmup = args.warmup + print(f"# {driver} {family}/{slice_name} tier={tier} " + f"cases={len(group)} repeat={repeat} warmup={warmup}", + file=sys.stderr) + rc, parsed, err = invoke_group(args.bin_dir, driver, group, repeat, warmup) + if err.strip(): + print(err, file=sys.stderr, end="" if err.endswith("\n") else "\n") + got = {(row["case"], row["role"]) for row in parsed} + expected = {row["case"] for row in group} + have_cases = {case for case, _role in got} + missing = sorted(expected - have_cases) + if missing: + print(f"# missing results: {', '.join(missing)}", file=sys.stderr) + failures += len(missing) + if rc != 0: + failures += 1 + fresh.extend(parsed) + + label_dir = out_root / args.label + merged = merge_rows(read_tsv(label_dir / "long.tsv"), fresh) + write_tsv(label_dir / "long.tsv", LONG_FIELDS, merged) + write_tsv(label_dir / "matrix.tsv", MATRIX_FIELDS, matrix_view(merged)) + print(f"# wrote {label_dir / 'matrix.tsv'} ({len(merged)} rows)", file=sys.stderr) + return 1 if failures else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/test/profile/eval_profile.cpp b/test/profile/eval_profile.cpp new file mode 100644 index 0000000..c9c3cef --- /dev/null +++ b/test/profile/eval_profile.cpp @@ -0,0 +1,907 @@ +/// @file test/profile/eval_profile.cpp +/// @brief Workload for sequence and interval evaluation. +/// +/// Both party keys are evaluated inside each sample. Key generation is its +/// own case, not part of the eval samples. `out_bytes` is the output buffer +/// volume of one sample (both parties). `per_item_ns` divides by the point +/// count, not by the number of parties. +/// +/// profile_eval --list +/// profile_eval --case interval_u32_L4096 --repeat 50 --warmup 3 +/// +/// Profile-guided build, separate from COVERAGE: +/// cmake -S test -B build-pgo -DLIBDPF_PGO=generate -DCMAKE_BUILD_TYPE=Release +/// cmake --build build-pgo --target profile_eval +/// build-pgo/bin/profile_eval --repeat 40 --warmup 2 +/// cmake -S test -B build-pgo -DLIBDPF_PGO=use -DCMAKE_BUILD_TYPE=Release +/// cmake --build build-pgo --target profile_eval + +#include "harness.hpp" + +#include "dpf.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + +using profile::sample; +using profile::touch_buf; +using profile::touch_word; +using profile::work; + +template +std::shared_ptr> clustered(Input start, std::size_t n) +{ + auto pts = std::make_shared>(n); + for (std::size_t i = 0; i < n; ++i) + (*pts)[i] = static_cast(start + static_cast(i)); + return pts; +} + +template +std::shared_ptr> strided(Input start, Input step, std::size_t n) +{ + auto pts = std::make_shared>(n); + for (std::size_t i = 0; i < n; ++i) + (*pts)[i] = static_cast(start + step * static_cast(i)); + return pts; +} + +template +sample hash_roots(const Keys & keys) +{ + std::uint64_t w0 = 0; + std::uint64_t w1 = 0; + const auto r0 = std::get<0>(keys).root(); + const auto r1 = std::get<1>(keys).root(); + const std::size_t n0 = sizeof(r0) < sizeof(w0) ? sizeof(r0) : sizeof(w0); + const std::size_t n1 = sizeof(r1) < sizeof(w1) ? sizeof(r1) : sizeof(w1); + std::memcpy(&w0, &r0, n0); + std::memcpy(&w1, &r1, n1); + return touch_word(w0 ^ w1, sizeof(r0) + sizeof(r1)); +} + +template +sample interval_packed(const Keys & keys, Input from, Input to, unsigned lane_bits) +{ + return profile::with_prg([&] { + auto a = dpf::eval_interval(std::get<0>(keys), from, to); + auto b = dpf::eval_interval(std::get<1>(keys), from, to); + auto fold = [lane_bits](const auto & buf) { + std::uint64_t w = 0; + const std::size_t bytes = (buf.size() * lane_bits + 7u) / 8u; + if (bytes != 0 && buf.data() != nullptr) + { + const std::size_t n = bytes < sizeof(w) ? bytes : sizeof(w); + std::memcpy(&w, buf.data(), n); + } + return touch_word(w, bytes); + }; + return fold(a.first) + fold(b.first); + }); +} + +template +sample interval_both(const Keys & keys, Input from, Input to) +{ + return profile::with_prg([&] { + auto a = dpf::eval_interval(std::get<0>(keys), from, to); + auto b = dpf::eval_interval(std::get<1>(keys), from, to); + return touch_buf(a.first) + touch_buf(b.first); + }); +} + +template +sample interval_reuse(const Keys & keys, Input from, Input to, + decltype(dpf::make_output_buffer_for_interval(std::get<0>(keys), from, to)) & buf0, + decltype(dpf::make_output_buffer_for_interval(std::get<1>(keys), from, to)) & buf1) +{ + return profile::with_prg([&] { + auto i0 = dpf::eval_interval(std::get<0>(keys), from, to, buf0); + auto i1 = dpf::eval_interval(std::get<1>(keys), from, to, buf1); + (void)i0; + (void)i1; + return touch_buf(buf0) + touch_buf(buf1); + }); +} + +template +sample interval_prove(const Keys & keys, Input from, Input to) +{ + auto buf0 = dpf::make_output_buffer_for_interval(std::get<0>(keys), from, to); + auto buf1 = dpf::make_output_buffer_for_interval(std::get<1>(keys), from, to); + dpf::proof_token p0{}; + dpf::proof_token p1{}; + auto i0 = dpf::eval_interval(std::get<0>(keys), from, to, buf0, dpf::prove(p0)); + auto i1 = dpf::eval_interval(std::get<1>(keys), from, to, buf1, dpf::prove(p1)); + (void)i0; + (void)i1; + std::uint64_t extra = 0; + std::memcpy(&extra, &p0, sizeof(extra) < sizeof(p0) ? sizeof(extra) : sizeof(p0)); + return touch_buf(buf0) + touch_buf(buf1) + touch_word(extra, 0); +} + +template +sample sequence_both(const Keys & keys, const Pts & pts, bool output_only) +{ + return profile::with_prg([&] { + sample s; + if (output_only) + { + auto a = dpf::eval_sequence(std::get<0>(keys), pts.begin(), pts.end(), + dpf::return_output_only_tag_{}); + auto b = dpf::eval_sequence(std::get<1>(keys), pts.begin(), pts.end(), + dpf::return_output_only_tag_{}); + s = touch_buf(a.first) + touch_buf(b.first); + } + else + { + auto a = dpf::eval_sequence(std::get<0>(keys), pts.begin(), pts.end()); + auto b = dpf::eval_sequence(std::get<1>(keys), pts.begin(), pts.end()); + s = touch_buf(a.first) + touch_buf(b.first); + } + return s; + }); +} + +template +sample sequence_breadth(const Keys & keys, const Pts & pts) +{ + return profile::with_prg([&] { + auto a = dpf::eval_sequence_breadth_first(std::get<0>(keys), pts.begin(), pts.end()); + auto b = dpf::eval_sequence_breadth_first(std::get<1>(keys), pts.begin(), pts.end()); + return touch_buf(a.first) + touch_buf(b.first); + }); +} + +template +sample sequence_recipe(const Keys & keys, const Recipe0 & r0, const Recipe1 & r1) +{ + return profile::with_prg([&] { + auto a = dpf::eval_sequence(std::get<0>(keys), r0); + auto b = dpf::eval_sequence(std::get<1>(keys), r1); + return touch_buf(a.first) + touch_buf(b.first); + }); +} + +template +sample sequence_prove(const Keys & keys, const Pts & pts) +{ + auto buf0 = dpf::make_output_buffer_for_subsequence(std::get<0>(keys), + pts.begin(), pts.end(), dpf::return_output_only_tag_{}); + auto buf1 = dpf::make_output_buffer_for_subsequence(std::get<1>(keys), + pts.begin(), pts.end(), dpf::return_output_only_tag_{}); + dpf::proof_token p0{}; + dpf::proof_token p1{}; + auto i0 = dpf::eval_sequence(std::get<0>(keys), pts.begin(), pts.end(), buf0, + dpf::prove(p0), dpf::return_output_only_tag_{}); + auto i1 = dpf::eval_sequence(std::get<1>(keys), pts.begin(), pts.end(), buf1, + dpf::prove(p1), dpf::return_output_only_tag_{}); + (void)i0; + (void)i1; + std::uint64_t extra = 0; + std::memcpy(&extra, &p0, sizeof(extra) < sizeof(p0) ? sizeof(extra) : sizeof(p0)); + return touch_buf(buf0) + touch_buf(buf1) + touch_word(extra, 0); +} + +template +auto make_keys(Input alpha, Extra && ...extra) +{ + auto keys = dpf::make_dpf(alpha, std::uint64_t{0x9e3779b97f4a7c15ull}, + std::forward(extra)...); + using keys_t = std::decay_t; + return std::make_shared(std::move(keys)); +} + +template +auto make_out_keys(Input alpha, Output beta, Extra && ...extra) +{ + auto keys = dpf::make_dpf(alpha, beta, std::forward(extra)...); + using keys_t = std::decay_t; + return std::make_shared(std::move(keys)); +} + +const char kUsage[] = + "profile_eval [--list] [--family F] [--slice S] [--case NAME] [--tier std]\n" + " [--repeat N=20] [--warmup W=2]\n" + "Slices: keygen, interval, interval-shape, sequence, sequence-algo,\n" + " memoizer, bits, gf, inner-product, helpers, defer.\n" + "Times sequence and interval evaluation on both party keys.\n"; + +template +void add_interval_at(std::vector & works, const char * slice, + const std::string & name, Input from, Input to, const KeysPtr & keys) +{ + const auto items = static_cast(to) - static_cast(from) + 1; + works.push_back(profile::make_work("eval", slice, name, items, [keys, from, to] { + return interval_both(*keys, from, to); + })); +} + +} // namespace + +int main(int argc, char ** argv) +{ + const auto opt = profile::parse_args(argc, argv, 20, 2, kUsage); + + using u8 = std::uint8_t; + using u16 = std::uint16_t; + using u32 = std::uint32_t; + + const auto k8 = make_keys(u8{40}); + const auto k16 = make_keys(u16{1512}); + const auto k16v = make_keys(u16{1512}, dpf::verifiable{}); + const auto k32 = make_keys(u32{1002048u}); + const auto k32v = make_keys(u32{1002048u}, dpf::verifiable{}); + + std::vector works; + + works.push_back(profile::make_work("eval", "keygen", "keygen_u8", 1, [] { + return hash_roots(*make_keys(u8{40})); + })); + works.push_back(profile::make_work("eval", "keygen", "keygen_u16", 1, [] { + return hash_roots(*make_keys(u16{1512})); + })); + works.push_back(profile::make_work("eval", "keygen", "keygen_u32", 1, [] { + return hash_roots(*make_keys(u32{0x01000000u})); + })); + works.push_back(profile::make_work("eval", "keygen", "keygen_u32_verifiable", 1, [] { + return hash_roots(*make_keys(u32{0x01000000u}, dpf::verifiable{})); + })); + + const auto add_gf = [&](const char * name, auto beta) { + using out = std::decay_t; + works.push_back(profile::make_work("eval", "gf", + std::string("keygen_") + name, 1, [beta] { + return hash_roots(*make_out_keys(u8{40}, beta)); + })); + works.push_back(profile::make_work("eval", "gf", + std::string("keygen_") + name + "_verifiable", 1, [beta] { + return hash_roots(*make_out_keys(u8{40}, beta, dpf::verifiable{})); + })); + const auto keys = make_out_keys(u8{40}, beta); + if constexpr (dpf::utils::is_packed_subbyte_v) + { + constexpr unsigned bits = dpf::utils::packed_lane_bits_v; + works.push_back(profile::make_work("eval", "gf", + std::string("interval_") + name + "_u8_L256", 256, + [keys, bits] { + return interval_packed(*keys, u8{0}, u8{255}, bits); + })); + } + else + { + add_interval_at(works, "gf", std::string("interval_") + name + "_u8_L256", + u8{0}, u8{255}, keys); + } + }; + add_gf("gf2", dpf::gf2{1}); + add_gf("gf22", dpf::gf22{3}); + add_gf("gf24", dpf::gf24{0xa}); + add_gf("gf28", dpf::gf28{0x1b}); + add_gf("gf216", dpf::gf216{0x2d}); + add_gf("gf232", dpf::gf232{0x90200001u}); + add_gf("gf264", dpf::gf264{0x11}); + + const auto add_lengths = [&](auto from0, auto keys, const char * width, + std::initializer_list lengths) { + using input = decltype(from0); + for (const std::uint64_t n : lengths) + { + const input from = from0; + const input to = static_cast(from + static_cast(n - 1)); + add_interval_at(works, "interval", + std::string("interval_") + width + "_L" + std::to_string(n), + from, to, keys); + } + }; + add_lengths(u8{0}, k8, "u8", {1, 16, 64, 256}); + add_lengths(u16{1000}, k16, "u16", {1, 16, 256, 1024, 4096}); + add_lengths(u32{1000000}, k32, "u32", {1, 16, 64, 256, 1024, 4096, 16384}); + + add_interval_at(works, "interval-shape", "interval_u32_L256_unaligned", + u32{1000003}, u32{1000258}, k32); + add_interval_at(works, "interval-shape", "interval_u32_L4096_unaligned", + u32{1000003}, u32{1004098}, k32); + + const auto add_reuse = [&](u32 from, u32 to, const char * name) { + using buf0_t = std::decay_t(*k32), from, to))>; + using buf1_t = std::decay_t(*k32), from, to))>; + auto buf0 = std::make_shared( + dpf::make_output_buffer_for_interval(std::get<0>(*k32), from, to)); + auto buf1 = std::make_shared( + dpf::make_output_buffer_for_interval(std::get<1>(*k32), from, to)); + const auto items = static_cast(to - from + 1); + works.push_back(profile::make_work("eval", "interval-shape", name, items, + [k32, buf0, buf1, from, to] { + return interval_reuse(*k32, from, to, *buf0, *buf1); + })); + }; + add_reuse(1000000, 1000255, "interval_u32_L256_reuse"); + add_reuse(1000000, 1004095, "interval_u32_L4096_reuse"); + + works.push_back(profile::make_work("eval", "interval-shape", + "interval_u16_L1024_verifiable", 1024, [k16v] { + return interval_prove(*k16v, u16{1000}, u16{2023}); + })); + works.push_back(profile::make_work("eval", "interval-shape", + "interval_u32_L256_verifiable", 256, [k32v] { + return interval_prove(*k32v, u32{1000000}, u32{1000255}); + })); + + const auto add_seq = [&](auto keys, const char * width, const char * shape, + auto pts) { + const auto n = static_cast(pts->size()); + const std::string name = std::string("sequence_") + width + "_" + shape + + "_" + std::to_string(n); + works.push_back(profile::make_work("eval", "sequence", name, n, + [keys, pts] { + return sequence_both(*keys, *pts, false); + })); + }; + const std::size_t seq32[] = {8, 32, 64, 128, 256, 512, 1024, 2048}; + for (const std::size_t n : seq32) + { + add_seq(k32, "u32", "cluster", clustered(1u << 20, n)); + const u32 step = n <= 64 ? u32{1u << 20} : u32{1u << 12}; + add_seq(k32, "u32", "stride", strided(16u, step, n)); + } + const std::size_t seq16[] = {8, 64, 256, 1024}; + for (const std::size_t n : seq16) + add_seq(k16, "u16", "cluster", clustered(1000, n)); + const std::size_t seq8[] = {8, 32, 64}; + for (const std::size_t n : seq8) + { + add_seq(k8, "u8", "cluster", clustered(0, n)); + add_seq(k8, "u8", "stride", strided(0, 3, n)); + } + + const auto c256 = clustered(1u << 20, 256); + const auto s64 = strided(16u, 1u << 20, 64); + const auto c16s = clustered(1000, 64); + const auto c32s = clustered(1u << 20, 64); + + works.push_back(profile::make_work("eval", "sequence-algo", + "sequence_u32_cluster_256_output_only", 256, [k32, c256] { + return sequence_both(*k32, *c256, true); + })); + works.push_back(profile::make_work("eval", "sequence-algo", + "sequence_u32_cluster_256_breadth", 256, [k32, c256] { + return sequence_breadth(*k32, *c256); + })); + works.push_back(profile::make_work("eval", "sequence-algo", + "sequence_u32_stride_64_breadth", 64, [k32, s64] { + return sequence_breadth(*k32, *s64); + })); + + using recipe0_t = std::decay_t(*k32), c256->begin(), c256->end()))>; + using recipe1_t = std::decay_t(*k32), c256->begin(), c256->end()))>; + auto recipe0 = std::make_shared(dpf::make_sequence_recipe( + std::get<0>(*k32), c256->begin(), c256->end())); + auto recipe1 = std::make_shared(dpf::make_sequence_recipe( + std::get<1>(*k32), c256->begin(), c256->end())); + works.push_back(profile::make_work("eval", "sequence-algo", + "sequence_u32_cluster_256_recipe", 256, [k32, recipe0, recipe1] { + return sequence_recipe(*k32, *recipe0, *recipe1); + })); + works.push_back(profile::make_work("eval", "sequence-algo", + "sequence_u16_cluster_64_verifiable", 64, [k16v, c16s] { + return sequence_prove(*k16v, *c16s); + })); + works.push_back(profile::make_work("eval", "sequence-algo", + "sequence_u32_cluster_64_verifiable", 64, [k32v, c32s] { + return sequence_prove(*k32v, *c32s); + })); + + // --- memoizer: built-in reuse vs hand-rolled pointwise / fresh memo --- + { + using u32 = std::uint32_t; + const u32 from = 1000000u; + const u32 to = 1000255u; // L256 + const auto items = static_cast(to - from + 1); + const auto prep = sizeof(std::get<0>(*k32)) + sizeof(std::get<1>(*k32)); + using dpf_t = std::decay_t(*k32))>; + using node_t = typename dpf_t::interior_node; + const auto out_elem = sizeof(std::uint64_t); + const auto logical = items * out_elem * 2; + // Match `basic_interval_memoizer` capacity (leaf nodes, not output slots). + const auto leaf_nodes = + dpf::utils::get_leafnodes_in_output_interval(from, to); + const auto slots = leaf_nodes == 0 ? std::size_t{1} : leaf_nodes; + const auto pivot = std::max((slots >> 1) + (slots & 1) - 1, + (slots + 6) >> 2); + const auto memo_nodes = pivot + ((slots + 2) >> 1); + const auto memo_bytes = 2ull * memo_nodes * sizeof(node_t); + + auto memo0 = std::make_shared(*k32), from, to))>>( + dpf::make_basic_interval_memoizer(std::get<0>(*k32), from, to)); + auto memo1 = std::make_shared(*k32), from, to))>>( + dpf::make_basic_interval_memoizer(std::get<1>(*k32), from, to)); + + works.push_back(profile::make_work("eval", "memoizer", + "memo_interval_reuse", items, [k32, memo0, memo1, from, to, prep, memo_bytes, logical] { + return profile::with_prg([&] { + auto a = dpf::eval_interval(std::get<0>(*k32), from, to, *memo0); + auto b = dpf::eval_interval(std::get<1>(*k32), from, to, *memo1); + auto s = touch_buf(a.first) + touch_buf(b.first); + // Warm reuse: second pass on the same memoizers. + auto a2 = dpf::eval_interval(std::get<0>(*k32), from, to, *memo0); + auto b2 = dpf::eval_interval(std::get<1>(*k32), from, to, *memo1); + s = s + touch_buf(a2.first) + touch_buf(b2.first); + return profile::with_costs(s, prep, memo_bytes + s.out_bytes, logical * 2); + }); + })); + works.push_back(profile::make_work("eval", "memoizer", + "memo_interval_fresh", items, [k32, from, to, prep, logical, memo_bytes] { + return profile::with_prg([&] { + auto m0 = dpf::make_basic_interval_memoizer(std::get<0>(*k32), from, to); + auto m1 = dpf::make_basic_interval_memoizer(std::get<1>(*k32), from, to); + auto a = dpf::eval_interval(std::get<0>(*k32), from, to, m0); + auto b = dpf::eval_interval(std::get<1>(*k32), from, to, m1); + auto s = touch_buf(a.first) + touch_buf(b.first); + auto m0b = dpf::make_basic_interval_memoizer(std::get<0>(*k32), from, to); + auto m1b = dpf::make_basic_interval_memoizer(std::get<1>(*k32), from, to); + auto a2 = dpf::eval_interval(std::get<0>(*k32), from, to, m0b); + auto b2 = dpf::eval_interval(std::get<1>(*k32), from, to, m1b); + s = s + touch_buf(a2.first) + touch_buf(b2.first); + return profile::with_costs(s, prep, memo_bytes + s.out_bytes, logical * 2); + }); + })); + + const auto pts = clustered(1u << 20, 64); + auto path0 = std::make_shared(*k32)))>>( + dpf::make_basic_path_memoizer(std::get<0>(*k32))); + auto path1 = std::make_shared(*k32)))>>( + dpf::make_basic_path_memoizer(std::get<1>(*k32))); + works.push_back(profile::make_work("eval", "memoizer", + "memo_path_reuse", 64, [k32, pts, path0, path1, prep] { + return profile::with_prg([&] { + std::uint64_t h = 0; + for (auto x : *pts) + { + h ^= static_cast( + (*dpf::eval_point(std::get<0>(*k32), x, *path0)).raw()); + h ^= static_cast( + (*dpf::eval_point(std::get<1>(*k32), x, *path1)).raw()); + } + auto s = touch_word(h, 64 * sizeof(std::uint64_t) * 2); + return profile::with_costs(s, prep, + 2 * sizeof(node_t) * 32, 64 * sizeof(std::uint64_t) * 2); + }); + })); + works.push_back(profile::make_work("eval", "memoizer", + "memo_path_pointwise", 64, [k32, pts, prep] { + return profile::with_prg([&] { + std::uint64_t h = 0; + for (auto x : *pts) + { + h ^= static_cast( + (*dpf::eval_point(std::get<0>(*k32), x)).raw()); + h ^= static_cast( + (*dpf::eval_point(std::get<1>(*k32), x)).raw()); + } + auto s = touch_word(h, 64 * sizeof(std::uint64_t) * 2); + return profile::with_costs(s, prep, 0, + 64 * sizeof(std::uint64_t) * 2); + }); + })); + + using recipe0_t = std::decay_t(*k32), pts->begin(), pts->end()))>; + using recipe1_t = std::decay_t(*k32), pts->begin(), pts->end()))>; + auto rec0 = std::make_shared(dpf::make_sequence_recipe( + std::get<0>(*k32), pts->begin(), pts->end())); + auto rec1 = std::make_shared(dpf::make_sequence_recipe( + std::get<1>(*k32), pts->begin(), pts->end())); + auto smemo0 = std::make_shared(*k32), *rec0))>>( + dpf::make_inplace_reversing_sequence_memoizer(std::get<0>(*k32), *rec0)); + auto smemo1 = std::make_shared(*k32), *rec1))>>( + dpf::make_inplace_reversing_sequence_memoizer(std::get<1>(*k32), *rec1)); + works.push_back(profile::make_work("eval", "memoizer", + "memo_recipe_reuse", 64, [k32, rec0, rec1, smemo0, smemo1, prep] { + return profile::with_prg([&] { + auto a = dpf::eval_sequence(std::get<0>(*k32), *rec0, *smemo0); + auto b = dpf::eval_sequence(std::get<1>(*k32), *rec1, *smemo1); + auto s = touch_buf(a.first) + touch_buf(b.first); + auto a2 = dpf::eval_sequence(std::get<0>(*k32), *rec0, *smemo0); + auto b2 = dpf::eval_sequence(std::get<1>(*k32), *rec1, *smemo1); + s = s + touch_buf(a2.first) + touch_buf(b2.first); + return profile::with_costs(s, prep, s.out_bytes, + 64 * sizeof(std::uint64_t) * 4); + }); + })); + works.push_back(profile::make_work("eval", "memoizer", + "memo_recipe_fresh", 64, [k32, rec0, rec1, prep] { + return profile::with_prg([&] { + auto m0 = dpf::make_inplace_reversing_sequence_memoizer( + std::get<0>(*k32), *rec0); + auto m1 = dpf::make_inplace_reversing_sequence_memoizer( + std::get<1>(*k32), *rec1); + auto a = dpf::eval_sequence(std::get<0>(*k32), *rec0, m0); + auto b = dpf::eval_sequence(std::get<1>(*k32), *rec1, m1); + auto s = touch_buf(a.first) + touch_buf(b.first); + auto m0b = dpf::make_inplace_reversing_sequence_memoizer( + std::get<0>(*k32), *rec0); + auto m1b = dpf::make_inplace_reversing_sequence_memoizer( + std::get<1>(*k32), *rec1); + auto a2 = dpf::eval_sequence(std::get<0>(*k32), *rec0, m0b); + auto b2 = dpf::eval_sequence(std::get<1>(*k32), *rec1, m1b); + s = s + touch_buf(a2.first) + touch_buf(b2.first); + return profile::with_costs(s, prep, s.out_bytes, + 64 * sizeof(std::uint64_t) * 4); + }); + })); + } + + // --- bits: built-in iterators vs hand-rolled scans (u8 domain) --- + { + using input_type = std::uint8_t; + using output_type = dpf::bit; + const input_type alpha = 40; + auto bit_keys = std::make_shared>( + dpf::make_dpf(alpha, output_type::one)); + using dpf_type = std::decay_t(*bit_keys))>; + auto memo0 = std::make_shared())>>( + dpf::make_basic_full_memoizer()); + auto memo1 = std::make_shared())>>( + dpf::make_basic_full_memoizer()); + auto full0 = dpf::eval_full(std::get<0>(*bit_keys), *memo0); + auto full1 = dpf::eval_full(std::get<1>(*bit_keys), *memo1); + auto buf0 = std::make_shared>(std::move(full0.first)); + auto buf1 = std::make_shared>(std::move(full1.first)); + auto iter0 = std::make_shared>(std::move(full0.second)); + auto iter1 = std::make_shared>(std::move(full1.second)); + const auto leaf_nodes = static_cast(1) << dpf_type::depth; + const auto bit_items = static_cast(buf0->size()); + const auto prep = sizeof(std::get<0>(*bit_keys)) + sizeof(std::get<1>(*bit_keys)); + + works.push_back(profile::make_work("eval", "bits", + "bits_advice_builtin", leaf_nodes, [memo0, memo1, prep, leaf_nodes] { + std::uint64_t h = 0; + std::uint64_t n = 0; + for (auto b : dpf::advice_bits_of(*memo0)) + { + h = (h << 1) ^ (b ? 1u : 0u); + ++n; + } + for (auto b : dpf::advice_bits_of(*memo1)) + h ^= (b ? 1u : 0u); + auto s = touch_word(h ^ n, n); + return profile::with_costs(s, prep, 0, leaf_nodes); + })); + works.push_back(profile::make_work("eval", "bits", + "bits_advice_handroll", leaf_nodes, [memo0, memo1, prep, leaf_nodes] { + std::uint64_t h = 0; + std::uint64_t n = 0; + const auto * p0 = memo0->begin(); + const auto * e0 = memo0->end(); + for (; p0 != e0; ++p0) + { + const auto * bytes = reinterpret_cast(p0); + h = (h << 1) ^ (bytes[0] & 1u); + ++n; + } + const auto * p1 = memo1->begin(); + const auto * e1 = memo1->end(); + for (; p1 != e1; ++p1) + { + const auto * bytes = reinterpret_cast(p1); + h ^= (bytes[0] & 1u); + } + auto s = touch_word(h ^ n, n); + return profile::with_costs(s, prep, 0, leaf_nodes); + })); + + works.push_back(profile::make_work("eval", "bits", + "bits_setbit_builtin", bit_items, [iter0, iter1, prep] { + std::uint64_t h = 0; + std::uint64_t n = 0; + for (auto i : dpf::indices_set_in(*iter0)) + { + h ^= static_cast(i) + 0x9e3779b97f4a7c15ull; + ++n; + } + for (auto i : dpf::indices_set_in(*iter1)) + h ^= static_cast(i); + auto s = touch_word(h ^ n, n * sizeof(std::size_t)); + return profile::with_costs(s, prep, 0, n * sizeof(std::size_t)); + })); + works.push_back(profile::make_work("eval", "bits", + "bits_setbit_handroll", bit_items, [buf0, buf1, prep] { + std::uint64_t h = 0; + std::uint64_t n = 0; + const auto scan = [&](const auto & buf) { + for (std::size_t i = 0; i < buf.size(); ++i) + { + if (static_cast(buf[i])) + { + h ^= i + 0x9e3779b97f4a7c15ull; + ++n; + } + } + }; + scan(*buf0); + scan(*buf1); + auto s = touch_word(h ^ n, n * sizeof(std::size_t)); + return profile::with_costs(s, prep, 0, n * sizeof(std::size_t)); + })); + + works.push_back(profile::make_work("eval", "bits", + "bits_parallel_builtin", bit_items, [buf0, buf1, prep, bit_items] { + std::uint64_t h = 0; + std::uint64_t n = 0; + for (auto word : dpf::batch_of(*buf0, *buf1)) + { + h ^= static_cast(word[0]) + ^ static_cast(word[1]); + ++n; + } + auto s = touch_word(h ^ n, n * sizeof(std::uint64_t)); + return profile::with_costs(s, prep, 0, bit_items); + })); + works.push_back(profile::make_work("eval", "bits", + "bits_parallel_handroll", bit_items, [buf0, buf1, prep, bit_items] { + std::uint64_t h = 0; + const std::size_t n = std::min(buf0->size(), buf1->size()); + for (std::size_t i = 0; i < n; ++i) + h ^= (static_cast((*buf0)[i]) ? 1ull : 0ull) + ^ (static_cast((*buf1)[i]) ? 2ull : 0ull); + auto s = touch_word(h ^ n, n); + return profile::with_costs(s, prep, 0, bit_items); + })); + } + + // --- inner-product: built-in vs hand-rolled interval + dot --- + { + using u32 = std::uint32_t; + const u32 from = 1000000u; + const u32 to = 1000255u; + const auto items = static_cast(to - from + 1); + auto weights = std::make_shared>(items); + for (std::size_t i = 0; i < items; ++i) + (*weights)[i] = 0x9e3779b97f4a7c15ull * (i + 1); + const auto prep = sizeof(std::get<0>(*k32)) + sizeof(std::get<1>(*k32)); + auto ip_memo0 = std::make_shared(*k32), from, to))>>( + dpf::make_basic_interval_memoizer(std::get<0>(*k32), from, to)); + auto ip_memo1 = std::make_shared(*k32), from, to))>>( + dpf::make_basic_interval_memoizer(std::get<1>(*k32), from, to)); + + works.push_back(profile::make_work("eval", "inner-product", + "ip_interval_builtin", items, + [k32, weights, from, to, prep, items, ip_memo0, ip_memo1] { + return profile::with_prg([&] { + auto a = dpf::eval_inner_product(std::get<0>(*k32), from, to, + *weights, *ip_memo0); + auto b = dpf::eval_inner_product(std::get<1>(*k32), from, to, + *weights, *ip_memo1); + std::uint64_t ha = 0; + std::uint64_t hb = 0; + std::memcpy(&ha, &a, sizeof(ha) < sizeof(a) ? sizeof(ha) : sizeof(a)); + std::memcpy(&hb, &b, sizeof(hb) < sizeof(b) ? sizeof(hb) : sizeof(b)); + auto s = touch_word(ha ^ hb, sizeof(a) + sizeof(b)); + return profile::with_costs(s, prep, 0, items * sizeof(std::uint64_t)); + }); + })); + works.push_back(profile::make_work("eval", "inner-product", + "ip_interval_handroll", items, [k32, weights, from, to, prep, items] { + return profile::with_prg([&] { + auto a = dpf::eval_interval(std::get<0>(*k32), from, to); + auto b = dpf::eval_interval(std::get<1>(*k32), from, to); + std::uint64_t dot0 = 0; + std::uint64_t dot1 = 0; + const std::size_t n = std::min(items, a.first.size()); + for (std::size_t i = 0; i < n; ++i) + { + dot0 += static_cast(a.first[i].raw()) * (*weights)[i]; + dot1 += static_cast(b.first[i].raw()) * (*weights)[i]; + } + auto s = touch_word(dot0 ^ dot1, a.first.size() * sizeof(a.first[0]) + + b.first.size() * sizeof(b.first[0])); + return profile::with_costs(s, prep, s.out_bytes, + items * sizeof(std::uint64_t) * 2); + }); + })); + works.push_back(profile::make_work("eval", "inner-product", + "ip_interval_paired", items, + [k32, weights, from, to, prep, items] { + return profile::with_prg([&] { + auto a = dpf::eval_inner_product(dpf::paired, + std::get<0>(*k32), from, to, *weights); + auto b = dpf::eval_inner_product(dpf::paired, + std::get<1>(*k32), from, to, *weights); + std::uint64_t ha = 0; + std::uint64_t hb = 0; + std::memcpy(&ha, &a, sizeof(ha) < sizeof(a) ? sizeof(ha) : sizeof(a)); + std::memcpy(&hb, &b, sizeof(hb) < sizeof(b) ? sizeof(hb) : sizeof(b)); + auto s = touch_word(ha ^ hb, sizeof(a) + sizeof(b)); + return profile::with_costs(s, prep, 0, items * sizeof(std::uint64_t)); + }); + })); + works.push_back(profile::make_work("eval", "inner-product", + "ip_interval_columns", items, + [k32, weights, from, to, prep, items] { + return profile::with_prg([&] { + auto a = dpf::eval_inner_product(dpf::columns, + std::get<0>(*k32), from, to, std::tie(*weights)); + auto b = dpf::eval_inner_product(dpf::columns, + std::get<1>(*k32), from, to, std::tie(*weights)); + std::uint64_t ha = 0; + std::uint64_t hb = 0; + const auto & a0 = std::get<0>(a); + const auto & b0 = std::get<0>(b); + std::memcpy(&ha, &a0, + sizeof(ha) < sizeof(a0) ? sizeof(ha) : sizeof(a0)); + std::memcpy(&hb, &b0, + sizeof(hb) < sizeof(b0) ? sizeof(hb) : sizeof(b0)); + auto s = touch_word(ha ^ hb, sizeof(a0) + sizeof(b0)); + return profile::with_costs(s, prep, 0, items * sizeof(std::uint64_t)); + }); + })); + } + + // --- helpers: point vs interval vs full (representative widths) --- + { + using u16 = std::uint16_t; + const auto prep16 = sizeof(std::get<0>(*k16)) + sizeof(std::get<1>(*k16)); + works.push_back(profile::make_work("eval", "helpers", + "helper_point_u16", 1, [k16, prep16] { + return profile::with_prg([&] { + auto a = *dpf::eval_point(std::get<0>(*k16), u16{1512}); + auto b = *dpf::eval_point(std::get<1>(*k16), u16{1512}); + auto s = touch_word( + static_cast(a.raw()) ^ static_cast(b.raw()), + sizeof(a) + sizeof(b)); + return profile::with_costs(s, prep16, 0, sizeof(a) + sizeof(b)); + }); + })); + works.push_back(profile::make_work("eval", "helpers", + "helper_interval_u16_L256", 256, [k16, prep16] { + return profile::with_prg([&] { + auto a = dpf::eval_interval(std::get<0>(*k16), u16{1000}, u16{1255}); + auto b = dpf::eval_interval(std::get<1>(*k16), u16{1000}, u16{1255}); + auto s = touch_buf(a.first) + touch_buf(b.first); + return profile::with_costs(s, prep16, s.out_bytes, + 256 * sizeof(std::uint64_t) * 2); + }); + })); + works.push_back(profile::make_work("eval", "helpers", + "helper_full_u8", 256, [k8] { + const auto prep = sizeof(std::get<0>(*k8)) + sizeof(std::get<1>(*k8)); + return profile::with_prg([&] { + auto a = dpf::eval_full(std::get<0>(*k8)); + auto b = dpf::eval_full(std::get<1>(*k8)); + auto s = touch_buf(a.first) + touch_buf(b.first); + return profile::with_costs(s, prep, s.out_bytes, s.out_bytes); + }); + })); + } + + // --- defer: pre-assign full-domain expand vs rotate-after-assign --- + { + using u8 = std::uint8_t; + using out_t = std::uint64_t; + const u8 alpha = 40; + const out_t beta = 0x9e3779b97f4a7c15ull; + + works.push_back(profile::make_work("eval", "defer", + "defer_full_u8_expand", 256, [beta] { + return profile::with_prg([&] { + auto keys = dpf::make_dpf(dpf::wildcard_value{}, beta); + auto b0 = dpf::make_output_buffer_for_full(std::get<0>(keys)); + auto b1 = dpf::make_output_buffer_for_full(std::get<1>(keys)); + auto d0 = dpf::defer_eval_full(std::get<0>(keys), b0); + auto d1 = dpf::defer_eval_full(std::get<1>(keys), b1); + (void)d0; + (void)d1; + return touch_buf(b0) + touch_buf(b1); + }); + })); + + works.push_back(profile::make_work("eval", "defer", + "defer_interval_u8_L64_expand", 64, [beta] { + return profile::with_prg([&] { + auto keys = dpf::make_dpf(dpf::wildcard_value{}, beta); + auto b0 = dpf::make_output_buffer_for_full(std::get<0>(keys)); + auto b1 = dpf::make_output_buffer_for_full(std::get<1>(keys)); + auto d0 = dpf::defer_eval_interval(std::get<0>(keys), + u8{16}, u8{79}, b0); + auto d1 = dpf::defer_eval_interval(std::get<1>(keys), + u8{16}, u8{79}, b1); + (void)d0; + (void)d1; + return touch_buf(b0) + touch_buf(b1); + }); + })); + + // Expand once against stable key storage, assign, then time .get(). + { + using keys_t = std::decay_t{}, beta))>; + auto keys = std::make_shared( + dpf::make_dpf(dpf::wildcard_value{}, beta)); + using buf0_t = std::decay_t(*keys)))>; + using buf1_t = std::decay_t(*keys)))>; + auto b0 = std::make_shared( + dpf::make_output_buffer_for_full(std::get<0>(*keys))); + auto b1 = std::make_shared( + dpf::make_output_buffer_for_full(std::get<1>(*keys))); + using def0_t = std::decay_t(*keys), *b0))>; + using def1_t = std::decay_t(*keys), *b1))>; + auto def0 = std::make_shared( + dpf::defer_eval_full(std::get<0>(*keys), *b0)); + auto def1 = std::make_shared( + dpf::defer_eval_full(std::get<1>(*keys), *b1)); + { + auto & k0 = std::get<0>(*keys); + auto & k1 = std::get<1>(*keys); + const u8 a0 = 0x12; + const u8 a1 = static_cast(alpha - a0); + const auto sh0 = k0.offset_x.compute_and_get_share(a0); + const auto sh1 = k1.offset_x.compute_and_get_share(a1); + k0.offset_x.reconstruct(sh1); + k1.offset_x.reconstruct(sh0); + } + works.push_back(profile::make_work("eval", "defer", + "defer_full_u8_get", 256, [keys, def0, def1, b0, b1] { + (void)keys; + auto v0 = def0->get(); + auto v1 = def1->get(); + std::uint64_t sink = 0; + for (auto it = std::begin(v0); it != std::end(v0); ++it) + sink ^= static_cast((*it).raw()); + for (auto it = std::begin(v1); it != std::end(v1); ++it) + sink ^= static_cast((*it).raw()); + return touch_word(sink, b0->size() * sizeof((*b0)[0]) + + b1->size() * sizeof((*b1)[0])); + })); + } + + works.push_back(profile::make_work("eval", "defer", + "eager_full_u8_after_assign", 256, [beta, alpha] { + return profile::with_prg([&] { + auto keys = dpf::make_dpf(dpf::wildcard_value{}, beta); + auto & k0 = std::get<0>(keys); + auto & k1 = std::get<1>(keys); + const u8 a0 = 0x12; + const u8 a1 = static_cast(alpha - a0); + const auto sh0 = k0.offset_x.compute_and_get_share(a0); + const auto sh1 = k1.offset_x.compute_and_get_share(a1); + k0.offset_x.reconstruct(sh1); + k1.offset_x.reconstruct(sh0); + auto a = dpf::eval_full(k0); + auto b = dpf::eval_full(k1); + return touch_buf(a.first) + touch_buf(b.first); + }); + })); + } + + return profile::run_works(opt, works); +} diff --git a/test/profile/grotto_profile.cpp b/test/profile/grotto_profile.cpp new file mode 100644 index 0000000..d1c3250 --- /dev/null +++ b/test/profile/grotto_profile.cpp @@ -0,0 +1,509 @@ +/// @file test/profile/grotto_profile.cpp +/// @brief Workload for grotto evaluation: tables, offset walks, prefix parity. +/// +/// Key generation is a separate case from the eval that consumes those keys. +/// Table cases probe the domain once, then time only inputs that evaluate. +/// `items` is the number of table evaluations inside one sample, or 1 for a +/// single offset / prefix walk (both parties). +/// +/// profile_grotto --list +/// profile_grotto --case window_gelu_p16 --repeat 100 +/// +/// Profile-guided build, separate from COVERAGE: +/// cmake -S test -B build-pgo -DLIBDPF_PGO=generate -DCMAKE_BUILD_TYPE=Release +/// cmake --build build-pgo --target profile_grotto +/// build-pgo/bin/profile_grotto --repeat 40 --warmup 2 +/// cmake -S test -B build-pgo -DLIBDPF_PGO=use -DCMAKE_BUILD_TYPE=Release +/// cmake --build build-pgo --target profile_grotto + +#include "harness.hpp" + +#include "dpf.hpp" +#include "grotto/closed_form.hpp" +#include "grotto/exact_steps.hpp" +#include "grotto/offset_horner.hpp" +#include "grotto/offset_jet.hpp" +#include "grotto/offset_poly.hpp" +#include "grotto/offset_repr.hpp" +#include "grotto/offset_twist.hpp" +#include "grotto/prefix_parity.hpp" +#include "grotto/range_lut.hpp" +#include "grotto/window_lut.hpp" + +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + +using profile::sample; +using profile::touch_arr; +using profile::touch_vec; +using profile::touch_word; +using profile::work; + +const char kUsage[] = + "profile_grotto [--list] [--family grotto] [--slice S] [--case NAME]\n" + " [--repeat N=30] [--warmup W=2]\n" + "Slices: window, principal, closed, reduced, exact, horner, poly, jet,\n" + " twist, repr, prefix, keygen.\n" + "Times grotto table evals and offset / prefix walks.\n"; + +inline work cell(const char * slice, std::string name, std::uint64_t items, + std::function fn) +{ + return profile::make_work("grotto", slice, std::move(name), items, std::move(fn)); +} + +template +std::vector probe(Enum which, unsigned bits, Fn fn, + const std::vector & cand) +{ + std::vector ok; + ok.reserve(cand.size()); + for (const std::int64_t raw : cand) + { + try + { + (void)fn(which, bits, raw); + ok.push_back(raw); + } + catch (const std::exception &) + { + } + } + return ok; +} + +std::vector around_one(unsigned bits) +{ + const std::int64_t one = std::int64_t{1} << bits; + return { + -4 * one, -2 * one, -one, -one / 2, -1, 0, 1, + one / 20, one / 5, one / 3, one / 2, one, (3 * one) / 2, 2 * one, 4 * one + }; +} + +template +void add_table(std::vector & works, const char * slice, std::string name, Fn fn, + std::vector samples) +{ + if (samples.empty()) + { + std::cerr << name << " skipped: no in-domain sample\n"; + return; + } + auto held = std::make_shared>(std::move(samples)); + const std::uint64_t items = static_cast(held->size()) * 32u; + std::function body = [held, fn]() -> sample { + std::uint64_t h = 0x84222325cbf29ce4ull; + for (int rep = 0; rep < 32; ++rep) + { + for (const std::int64_t raw : *held) + { + // Multiply-add, not a plain xor: an even number of identical + // xors cancels, and the compiler will delete the evals. + h = (h * 0x100000001b3ull) ^ static_cast(fn(raw)) + ^ static_cast(rep); + } + } + return touch_word(h, held->size() * sizeof(std::int64_t)); + }; + works.push_back(cell(slice, std::move(name), items, std::move(body))); +} + +template +std::vector knots_of(std::size_t n, T gap) +{ + std::vector knots(n); + for (std::size_t i = 0; i < n; ++i) + knots[i] = static_cast(1 + gap * static_cast(i)); + return knots; +} + +template +std::vector> horner_rows(std::size_t n) +{ + std::vector> rows(n); + for (std::size_t i = 0; i < n; ++i) + for (std::size_t m = 0; m <= Degree; ++m) + rows[i][m] = (i + 1) * (m + 3); + return rows; +} + +std::vector> poly_rows(std::size_t n, std::size_t degree) +{ + std::vector> rows(n, std::vector(degree + 1)); + for (std::size_t i = 0; i < n; ++i) + for (std::size_t m = 0; m <= degree; ++m) + rows[i][m] = (i + 1) * (m + 3); + return rows; +} + +std::vector coeff_col(std::size_t degree) +{ + std::vector c(degree + 1); + for (std::size_t m = 0; m <= degree; ++m) + c[m] = m + 5; + return c; +} + +template +std::array ends_of(T start, T step) +{ + std::array ends{}; + for (std::size_t i = 0; i < N; ++i) + ends[i] = static_cast(start + step * static_cast(i)); + return ends; +} + +} // namespace + +template +void add_horner_degree(std::vector & works) +{ + using in_t = std::uint32_t; + const in_t center = 50; + const in_t eta = 7; + works.push_back(cell("keygen", "horner_keygen_d" + std::to_string(Degree), 1, [] { + auto built = grotto::make_offset_horner_keys(in_t{50}); + return touch_word(built.wrap_share[0][0] ^ built.wrap_share[Degree][1], + sizeof(built.wrap_share)); + })); + using mat_t = decltype(grotto::make_offset_horner_keys(center)); + auto mat = std::make_shared(grotto::make_offset_horner_keys(center)); + for (const std::size_t pieces : std::initializer_list{1, 4, 16, 64}) + { + auto knots = std::make_shared>(knots_of(pieces, 1000)); + auto rows = std::make_shared>>( + horner_rows(pieces)); + const auto name = "horner_eval_d" + std::to_string(Degree) + + "_p" + std::to_string(pieces); + works.push_back(cell("horner", name, 1, [mat, knots, rows, eta] { + const auto a = grotto::offset_horner_eval<0, Degree>(*mat, *knots, *rows, eta); + const auto b = grotto::offset_horner_eval<1, Degree>(*mat, *knots, *rows, eta); + return touch_word(a ^ b, 16); + })); + } +} + +template +void add_prefix_n(std::vector & works, const char * width, Input step, + const BitPtr & bits, const GtPtr & gts) +{ + const auto ends = ends_of(Input{1}, step); + const auto ntag = std::to_string(N); + works.push_back(cell("prefix", std::string("prefix_") + width + "_e" + ntag, N, + [bits, ends] { + const auto a = grotto::prefix_parities(std::get<0>(*bits), ends); + const auto b = grotto::prefix_parities(std::get<1>(*bits), ends); + return touch_arr(std::get<0>(a)) + touch_arr(std::get<0>(b)); + })); + works.push_back(cell("prefix", std::string("signed_prefix_") + width + "_e" + ntag, N, + [gts, ends] { + const auto a = grotto::signed_prefix_parities(std::get<0>(*gts), ends); + const auto b = grotto::signed_prefix_parities(std::get<1>(*gts), ends); + return touch_arr(a) + touch_arr(b); + })); +} + +template +void add_prefix_width(std::vector & works, const char * width, Input step) +{ + const auto bit_keys = dpf::make_dpf(Input{1000}, dpf::bit{1}); + const auto gt_keys = dpf::make_dpf(Input{1000}, dpf::gt(std::uint64_t{1})); + using bit_ptr = std::shared_ptr>; + using gt_ptr = std::shared_ptr>; + auto bits = std::make_shared>(bit_keys); + auto gts = std::make_shared>(gt_keys); + add_prefix_n(works, width, step, bits, gts); + add_prefix_n(works, width, step, bits, gts); + add_prefix_n(works, width, step, bits, gts); + add_prefix_n(works, width, step, bits, gts); +} + +int main(int argc, char ** argv) +{ + const auto opt = profile::parse_args(argc, argv, 30, 2, kUsage); + std::vector works; + + const unsigned precisions[] = {8u, 16u, 24u, 32u}; + const auto add_window = [&](const char * stem, grotto::window which, unsigned bits) { + auto samples = probe(which, bits, + [](grotto::window w, unsigned b, std::int64_t raw) { + return grotto::eval_window(w, b, raw); + }, around_one(bits)); + add_table(works, "window", + std::string("window_") + stem + "_p" + std::to_string(bits), + [which, bits](std::int64_t raw) { + return grotto::eval_window(which, bits, raw); + }, std::move(samples)); + }; + const auto add_principal = [&](const char * stem, grotto::principal which, unsigned bits) { + auto samples = probe(which, bits, + [](grotto::principal w, unsigned b, std::int64_t raw) { + return grotto::eval_principal(w, b, raw); + }, around_one(bits)); + add_table(works, "principal", + std::string("principal_") + stem + "_p" + std::to_string(bits), + [which, bits](std::int64_t raw) { + return grotto::eval_principal(which, bits, raw); + }, std::move(samples)); + }; + const auto add_closed = [&](const char * stem, grotto::closed which, unsigned bits) { + auto samples = probe(which, bits, + [](grotto::closed w, unsigned b, std::int64_t raw) { + return grotto::eval_closed(w, b, raw); + }, around_one(bits)); + add_table(works, "closed", + std::string("closed_") + stem + "_p" + std::to_string(bits), + [which, bits](std::int64_t raw) { + return grotto::eval_closed(which, bits, raw); + }, std::move(samples)); + }; + const auto add_reduced = [&](const char * stem, grotto::reduced which, unsigned bits) { + auto samples = probe(which, bits, + [](grotto::reduced w, unsigned b, std::int64_t raw) { + return grotto::eval_reduced(w, b, raw); + }, around_one(bits)); + add_table(works, "reduced", + std::string("reduced_") + stem + "_p" + std::to_string(bits), + [which, bits](std::int64_t raw) { + return grotto::eval_reduced(which, bits, raw); + }, std::move(samples)); + }; + + const struct { const char * stem; grotto::window which; } windows[] = { + {"gelu", grotto::window::gelu}, + {"sigmoid", grotto::window::sigmoid}, + {"tanh", grotto::window::tanh}, + {"erf", grotto::window::erf}, + {"erfc", grotto::window::erfc}, + {"silu", grotto::window::silu}, + {"mish", grotto::window::mish}, + {"softplus", grotto::window::softplus}, + {"probit", grotto::window::probit}, + {"smoothstep", grotto::window::smoothstep}, + {"asin", grotto::window::asin}, + {"acos", grotto::window::acos}, + {"hardelish", grotto::window::hardelish}, + {"lecun_tanh", grotto::window::lecun_tanh}, + }; + for (const auto & spec : windows) + for (const unsigned bits : precisions) + add_window(spec.stem, spec.which, bits); + + const struct { const char * stem; grotto::principal which; } principals[] = { + {"ln", grotto::principal::ln}, + {"exp", grotto::principal::exp}, + {"sin", grotto::principal::sin}, + {"sqrt", grotto::principal::sqrt}, + {"sinh", grotto::principal::sinh}, + {"inv", grotto::principal::inv}, + }; + for (const auto & spec : principals) + for (const unsigned bits : precisions) + add_principal(spec.stem, spec.which, bits); + + const struct { const char * stem; grotto::closed which; } closeds[] = { + {"atan", grotto::closed::atan}, + {"cbrt", grotto::closed::cbrt}, + {"sinc", grotto::closed::sinc}, + {"softsign", grotto::closed::softsign}, + {"logistic", grotto::closed::logistic}, + }; + for (const auto & spec : closeds) + for (const unsigned bits : precisions) + add_closed(spec.stem, spec.which, bits); + + const struct { const char * stem; grotto::reduced which; } reduceds[] = { + {"ln", grotto::reduced::ln}, + {"exp", grotto::reduced::exp}, + {"sin", grotto::reduced::sin}, + {"expm1", grotto::reduced::expm1}, + {"log1p", grotto::reduced::log1p}, + {"sqrt", grotto::reduced::sqrt}, + }; + for (const auto & spec : reduceds) + for (const unsigned bits : precisions) + add_reduced(spec.stem, spec.which, bits); + + const auto add_exact = [&](const std::string & name, unsigned bits, auto fn) { + std::vector samples; + for (const std::int64_t raw : around_one(bits)) + { + try + { + (void)fn(raw); + samples.push_back(raw); + } + catch (const std::exception &) + { + } + } + add_table(works, "exact", name, fn, std::move(samples)); + }; + for (const unsigned bits : {8u, 16u, 32u}) + { + const auto tag = "_p" + std::to_string(bits); + add_exact("exact_dec_floor" + tag, bits, [bits](std::int64_t raw) { + return grotto::eval_dec_floor(raw, bits); + }); + add_exact("exact_bit_width" + tag, bits, [bits](std::int64_t raw) { + return grotto::eval_bit_width(raw, bits); + }); + add_exact("exact_dec_width" + tag, bits, [bits](std::int64_t raw) { + return grotto::eval_dec_width(raw, bits); + }); + add_exact("exact_ilog256" + tag, bits, [bits](std::int64_t raw) { + return grotto::eval_ilog256(raw, bits); + }); + } + + add_horner_degree<1>(works); + add_horner_degree<3>(works); + + using in_t = std::uint32_t; + const in_t center = 50; + const in_t eta = 7; + for (const std::size_t degree : std::initializer_list{1, 4, 8, 16}) + { + works.push_back(cell("keygen", "poly_keygen_d" + std::to_string(degree), 1, + [degree] { + auto built = grotto::make_offset_poly_keys(in_t{50}, degree); + return touch_word(built.wrap_share[0][0], + built.wrap_share.size() * sizeof(built.wrap_share[0])); + })); + using mat_t = decltype(grotto::make_offset_poly_keys(center, degree)); + auto mat = std::make_shared(grotto::make_offset_poly_keys(center, degree)); + for (const std::size_t pieces : std::initializer_list{4, 8, 16}) + { + if (degree == 16 && pieces == 16) + continue; + auto knots = std::make_shared>(knots_of(pieces, 800)); + auto rows = std::make_shared>>( + poly_rows(pieces, degree)); + const auto name = "poly_eval_d" + std::to_string(degree) + + "_p" + std::to_string(pieces); + works.push_back(cell("poly", name, 1, [mat, knots, rows] { + const auto a = grotto::offset_poly_eval<0>(*mat, *knots, *rows, eta, nullptr); + const auto b = grotto::offset_poly_eval<1>(*mat, *knots, *rows, eta, nullptr); + return touch_word(a ^ b, 16); + })); + } + } + + for (const std::size_t degree : std::initializer_list{1, 4, 8, 16}) + { + works.push_back(cell("keygen", "jet_keygen_d" + std::to_string(degree), 1, + [degree] { + auto built = grotto::make_offset_jet_keys(in_t{50}, degree); + return touch_word(built.wrap_share[0][0], + built.wrap_share.size() * sizeof(built.wrap_share[0])); + })); + using mat_t = decltype(grotto::make_offset_jet_keys(center, degree)); + auto mat = std::make_shared(grotto::make_offset_jet_keys(center, degree)); + for (const std::size_t pieces : std::initializer_list{4, 16}) + { + auto knots = std::make_shared>(knots_of(pieces, 800)); + auto col = std::make_shared>(coeff_col(degree)); + const auto name = "jet_eval_d" + std::to_string(degree) + + "_p" + std::to_string(pieces); + works.push_back(cell("jet", name, 1, [mat, knots, col] { + const auto a = grotto::offset_jet_eval<0>(*mat, *knots, *col, eta); + const auto b = grotto::offset_jet_eval<1>(*mat, *knots, *col, eta); + return touch_word(a ^ b, 16); + })); + } + } + + for (const std::size_t degree : std::initializer_list{1, 4, 8}) + { + auto knots = std::make_shared>(knots_of(8, 900)); + auto col = std::make_shared>(coeff_col(degree)); + using odd_t = decltype(grotto::make_offset_twist_keys(center, degree, std::uint64_t{3})); + using half_t = decltype(grotto::make_offset_twist_keys(center, degree, grotto::twist_half)); + auto odd = std::make_shared( + grotto::make_offset_twist_keys(center, degree, std::uint64_t{3})); + auto half = std::make_shared( + grotto::make_offset_twist_keys(center, degree, grotto::twist_half)); + const auto dtag = std::to_string(degree); + works.push_back(cell("keygen", "twist_keygen_odd_d" + dtag, 1, [degree] { + auto built = grotto::make_offset_twist_keys(in_t{50}, degree, std::uint64_t{3}); + return touch_word(built.wrap_share[0][0], + built.wrap_share.size() * sizeof(built.wrap_share[0])); + })); + works.push_back(cell("twist", "twist_eval_odd_d" + dtag + "_p8", 1, + [odd, knots, col] { + const auto a = grotto::offset_twist_eval<0>(*odd, *knots, *col, eta); + const auto b = grotto::offset_twist_eval<1>(*odd, *knots, *col, eta); + return touch_word(a ^ b, 16); + })); + works.push_back(cell("twist", "twist_eval_half_d" + dtag + "_p8", 1, + [half, knots, col] { + const auto a = grotto::offset_twist_eval<0>(*half, *knots, *col, eta); + const auto b = grotto::offset_twist_eval<1>(*half, *knots, *col, eta); + return touch_word(a ^ b, 16); + })); + } + + { + const std::vector fib_state{1, 0}; + const std::vector wide_state{1, 2, 3, 4}; + using fib_t = decltype(grotto::make_offset_repr_keys(center, fib_state)); + using wide_t = decltype(grotto::make_offset_repr_keys(center, wide_state)); + auto fib = std::make_shared(grotto::make_offset_repr_keys(center, fib_state)); + auto wide = std::make_shared(grotto::make_offset_repr_keys(center, wide_state)); + auto fib_m = std::make_shared>>( + grotto::offset_repr_fibonacci_matrix()); + auto tri_m = std::make_shared>>( + std::vector>{ + {1, 1, 0, 0}, + {0, 1, 1, 0}, + {0, 0, 1, 1}, + {0, 0, 0, 1}, + }); + works.push_back(cell("keygen", "repr_keygen_dim2", 1, [] { + auto built = grotto::make_offset_repr_keys(in_t{50}, std::vector{1, 0}); + return touch_word(built.wrap_share[0][0], + built.wrap_share.size() * sizeof(built.wrap_share[0])); + })); + works.push_back(cell("keygen", "repr_keygen_dim4", 1, [] { + auto built = grotto::make_offset_repr_keys(in_t{50}, + std::vector{1, 2, 3, 4}); + return touch_word(built.wrap_share[0][0], + built.wrap_share.size() * sizeof(built.wrap_share[0])); + })); + for (const std::size_t pieces : std::initializer_list{4, 8, 16}) + { + auto knots = std::make_shared>(knots_of(pieces, 700)); + const auto tag = "_p" + std::to_string(pieces); + works.push_back(cell("repr", "repr_eval_fib" + tag, 1, [fib, fib_m, knots] { + const auto a = grotto::offset_repr_eval<0>(*fib, *fib_m, *knots, eta); + const auto b = grotto::offset_repr_eval<1>(*fib, *fib_m, *knots, eta); + return touch_vec(a) + touch_vec(b); + })); + works.push_back(cell("repr", "repr_eval_dim4" + tag, 1, [wide, tri_m, knots] { + const auto a = grotto::offset_repr_eval<0>(*wide, *tri_m, *knots, eta); + const auto b = grotto::offset_repr_eval<1>(*wide, *tri_m, *knots, eta); + return touch_vec(a) + touch_vec(b); + })); + } + works.push_back(cell("repr", "repr_crc32_jump", 64, [] { + std::uint32_t state = 0x12345678u; + for (unsigned i = 0; i < 64; ++i) + state = grotto::offset_repr_crc32_jump(state, 1ull << (i % 17)); + return touch_word(state, 64u * 32u * sizeof(std::uint32_t)); + })); + } + + add_prefix_width(works, "u16", 400); + add_prefix_width(works, "u32", 100000); + + return profile::run_works(opt, works); +} diff --git a/test/profile/harness.hpp b/test/profile/harness.hpp new file mode 100644 index 0000000..4a0b1ab --- /dev/null +++ b/test/profile/harness.hpp @@ -0,0 +1,365 @@ +/// @file test/profile/harness.hpp +/// @brief Timing loop shared by the in-process profile drivers. +#ifndef LIBDPF_TEST_PROFILE_HARNESS_HPP__ +#define LIBDPF_TEST_PROFILE_HARNESS_HPP__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dpf/prg_count.hpp" + +namespace profile +{ + +struct sample +{ + std::uint64_t sink = 0; + std::uint64_t out_bytes = 0; + /// @brief Set when the case instruments the named cost; blank in TSV otherwise. + std::optional prg_evals; + std::optional preprocess_bytes; + std::optional alloc_bytes; + std::optional logical_bytes; +}; + +inline sample operator+(sample a, sample b) +{ + a.sink ^= b.sink + 0x9e3779b97f4a7c15ull; + a.out_bytes += b.out_bytes; + if (a.prg_evals || b.prg_evals) + a.prg_evals = a.prg_evals.value_or(0) + b.prg_evals.value_or(0); + if (a.preprocess_bytes || b.preprocess_bytes) + a.preprocess_bytes = a.preprocess_bytes.value_or(0) + + b.preprocess_bytes.value_or(0); + if (a.alloc_bytes || b.alloc_bytes) + a.alloc_bytes = a.alloc_bytes.value_or(0) + b.alloc_bytes.value_or(0); + if (a.logical_bytes || b.logical_bytes) + a.logical_bytes = a.logical_bytes.value_or(0) + + b.logical_bytes.value_or(0); + return a; +} + +/// @brief Keep `word` live. `out_bytes` is reported, not timed on its own. +inline sample touch_word(std::uint64_t word, std::uint64_t out_bytes = 0) +{ + sample s; + s.sink = word; + s.out_bytes = out_bytes; + asm volatile("" : "+r"(s.sink)::"memory"); + return s; +} + +/// @brief Fold the ends of a buffer and publish a compiler barrier over it. +template +sample touch_buf(const Buf & buf) +{ + sample s; + using value_type = typename Buf::value_type; + s.out_bytes = buf.size() * sizeof(value_type); + s.sink = buf.size(); + if (buf.size() != 0) + { + std::uint64_t a = 0; + std::uint64_t b = 0; + const std::size_t n = sizeof(value_type) < sizeof(a) ? sizeof(value_type) : sizeof(a); + std::memcpy(&a, &buf[0], n); + std::memcpy(&b, &buf[buf.size() - 1], n); + s.sink ^= a ^ (b + buf.size()); + } + if (buf.size() != 0) + asm volatile("" : "+r"(s.sink) : "r"(buf.data()) : "memory"); + else + asm volatile("" : "+r"(s.sink)::"memory"); + return s; +} + +template +sample touch_vec(const std::vector & v) +{ + std::uint64_t h = v.size(); + for (const T & x : v) + { + std::uint64_t w = 0; + if constexpr (std::is_integral_v) + w = static_cast(x); + else + { + const std::size_t n = sizeof(T) < sizeof(w) ? sizeof(T) : sizeof(w); + std::memcpy(&w, &x, n); + } + h ^= w + 0x9e3779b97f4a7c15ull; + h *= 0x100000001b3ull; + } + return touch_word(h, v.size() * sizeof(T)); +} + +template +sample touch_arr(const std::array & a) +{ + std::uint64_t h = N; + for (const T & x : a) + { + std::uint64_t w = 0; + if constexpr (std::is_integral_v) + w = static_cast(x); + else + w = x ? 1u : 0u; + h = (h << 1) ^ w; + } + return touch_word(h, N * sizeof(T)); +} + +/// @brief Reset the PRG counter, run `fn`, and attach the delta to the sample. +template +sample with_prg(Fn && fn) +{ + dpf::prg::reset_eval_count(); + sample s = std::forward(fn)(); + s.prg_evals = dpf::prg::eval_count(); + return s; +} + +inline sample with_costs(sample s, std::uint64_t preprocess, std::uint64_t alloc, + std::uint64_t logical) +{ + s.preprocess_bytes = preprocess; + s.alloc_bytes = alloc; + s.logical_bytes = logical; + return s; +} + +inline std::string opt_field(const std::optional & v) +{ + return v ? std::to_string(*v) : std::string{}; +} + +inline std::uint64_t ticks() +{ +#if defined(__x86_64__) || defined(__i386__) + unsigned lo = 0; + unsigned hi = 0; + asm volatile("rdtscp" : "=a"(lo), "=d"(hi)::"rcx"); + return (static_cast(hi) << 32) | lo; +#else + return 0; +#endif +} + +struct work +{ + std::string name; + std::uint64_t items = 1; + std::function fn; + /// @brief Top-level group: `eval` or `grotto`. + std::string family; + /// @brief Piecewise rerun unit, such as `interval` or `horner`. + std::string slice; + /// @brief `std` is the default matrix. `heavy` is opt-in. + std::string tier = "std"; +}; + +inline work make_work(std::string family, std::string slice, std::string name, + std::uint64_t items, std::function fn, std::string tier = "std") +{ + work w; + w.family = std::move(family); + w.slice = std::move(slice); + w.name = std::move(name); + w.items = items; + w.fn = std::move(fn); + w.tier = std::move(tier); + return w; +} + +struct parsed +{ + std::uint64_t repeat = 1; + std::uint64_t warmup = 0; + bool list = false; + std::vector only; + std::vector families; + std::vector slices; + std::string tier; +}; + +inline parsed parse_args(int argc, char ** argv, std::uint64_t repeat, + std::uint64_t warmup, const char * usage) +{ + parsed o; + o.repeat = repeat; + o.warmup = warmup; + for (int i = 1; i < argc; ++i) + { + const std::string a = argv[i]; + auto need = [&](const char * flag) { + if (i + 1 >= argc) + { + std::cerr << "missing value for " << flag << "\n"; + std::exit(2); + } + return std::string(argv[++i]); + }; + if (a == "--list") + o.list = true; + else if (a == "--repeat") + o.repeat = std::stoull(need("--repeat")); + else if (a == "--warmup") + o.warmup = std::stoull(need("--warmup")); + else if (a == "--case") + o.only.push_back(need("--case")); + else if (a == "--family") + o.families.push_back(need("--family")); + else if (a == "--slice") + o.slices.push_back(need("--slice")); + else if (a == "--tier") + o.tier = need("--tier"); + else if (a == "--help" || a == "-h") + { + std::cout << usage; + std::exit(0); + } + else + { + std::cerr << "unknown argument: " << a << "\n" << usage; + std::exit(2); + } + } + if (o.repeat == 0) + o.repeat = 1; + return o; +} + +inline bool contains(const std::vector & hay, const std::string & needle) +{ + return std::find(hay.begin(), hay.end(), needle) != hay.end(); +} + +inline bool matches(const parsed & opt, const work & w) +{ + if (!opt.tier.empty() && opt.tier != "all" && w.tier != opt.tier) + return false; + if (!opt.families.empty() && !contains(opt.families, w.family)) + return false; + if (!opt.slices.empty() && !contains(opt.slices, w.slice)) + return false; + if (!opt.only.empty() && !contains(opt.only, w.name)) + return false; + return true; +} + +inline int run_works(const parsed & opt, const std::vector & all) +{ + for (const auto & name : opt.only) + { + bool found = false; + for (const auto & w : all) + found = found || w.name == name; + if (!found) + { + std::cerr << "unknown case: " << name << "\n"; + return 2; + } + } + + std::vector chosen; + for (const auto & w : all) + { + if (matches(opt, w)) + chosen.push_back(&w); + } + if (chosen.empty()) + { + std::cerr << "no cases match the requested family/slice/tier/case\n"; + return 2; + } + + if (opt.list) + { + std::cout << "family\tslice\tcase\titems\ttier\n"; + for (const work * w : chosen) + std::cout << w->family << '\t' << w->slice << '\t' << w->name + << '\t' << w->items << '\t' << w->tier << '\n'; + return 0; + } + + std::cout + << "family\tslice\tcase\titems\trepeat\twarmup\tavg_ns\tmin_ns\tmax_ns\t" + << "avg_cycles\tper_item_ns\tout_bytes\tsink\t" + << "prg_evals\tpreprocess_bytes\talloc_bytes\tlogical_bytes\tlayout_waste\n"; + int fails = 0; + std::uint64_t all_sink = 0; + for (const work * w : chosen) + { + try + { + for (std::uint64_t i = 0; i < opt.warmup; ++i) + all_sink ^= w->fn().sink; + + std::uint64_t total_ns = 0; + std::uint64_t min_ns = ~std::uint64_t{0}; + std::uint64_t max_ns = 0; + std::uint64_t total_cycles = 0; + sample last{}; + for (std::uint64_t i = 0; i < opt.repeat; ++i) + { + const auto c0 = ticks(); + const auto t0 = std::chrono::steady_clock::now(); + const sample s = w->fn(); + const auto t1 = std::chrono::steady_clock::now(); + const auto c1 = ticks(); + const auto ns = static_cast( + std::chrono::duration_cast(t1 - t0).count()); + total_ns += ns; + min_ns = std::min(min_ns, ns); + max_ns = std::max(max_ns, ns); + total_cycles += c1 - c0; + // Last sample, not an xor across repeats: identical samples + // would cancel and the column would read as zero. + last = s; + all_sink ^= s.sink + i; + } + const std::uint64_t avg_ns = total_ns / opt.repeat; + const std::uint64_t avg_cycles = total_cycles / opt.repeat; + const std::uint64_t per_item = w->items == 0 ? avg_ns : avg_ns / w->items; + std::string layout_waste; + if (last.alloc_bytes && last.logical_bytes + && *last.alloc_bytes >= *last.logical_bytes) + { + layout_waste = std::to_string(*last.alloc_bytes - *last.logical_bytes); + } + std::cout << w->family << '\t' << w->slice << '\t' << w->name << '\t' + << w->items << '\t' << opt.repeat << '\t' + << opt.warmup << '\t' << avg_ns << '\t' << min_ns << '\t' << max_ns + << '\t' << avg_cycles << '\t' << per_item << '\t' << last.out_bytes + << '\t' << last.sink << '\t' + << opt_field(last.prg_evals) << '\t' + << opt_field(last.preprocess_bytes) << '\t' + << opt_field(last.alloc_bytes) << '\t' + << opt_field(last.logical_bytes) << '\t' + << layout_waste << '\n'; + } + catch (const std::exception & ex) + { + std::cerr << w->name << " failed: " << ex.what() << "\n"; + ++fails; + } + } + std::cout << "sink\t" << all_sink << "\n"; + return fails == 0 ? 0 : 1; +} + +} // namespace profile + +#endif // LIBDPF_TEST_PROFILE_HARNESS_HPP__ diff --git a/test/profile/party_profile.cpp b/test/profile/party_profile.cpp new file mode 100644 index 0000000..775955c --- /dev/null +++ b/test/profile/party_profile.cpp @@ -0,0 +1,478 @@ +/// @file test/profile/party_profile.cpp +/// @brief Workload for the (2+1) party protocols. +/// +/// Spawns p0/p1/p2 the same way party_bench does. Each role reports CPU time +/// and the bytes and frames of the flow itself. The repeat barrier is not +/// included in those counters. `wall_ms` includes process startup. +/// +/// profile_party --list +/// profile_party --suite core --repeat 5 --warmup 1 +/// profile_party --suite extreme +/// profile_party --suite gadget --repeat 3 --warmup 1 +/// profile_party --tag "beaver,bench" --repeat 3 +/// profile_party --case beaver_dot_n32 +/// +/// Profile-guided build. The party binaries must be rebuilt with the same +/// mode, because the protocol code lives in those processes: +/// cmake -S test -B build-pgo -DLIBDPF_PGO=generate -DCMAKE_BUILD_TYPE=Release +/// cmake --build build-pgo --target profile_party p0 p1 p2 +/// build-pgo/bin/profile_party --suite all --repeat 4 --warmup 1 +/// cmake -S test -B build-pgo -DLIBDPF_PGO=use -DCMAKE_BUILD_TYPE=Release +/// cmake --build build-pgo --target profile_party p0 p1 p2 + +#include "cases.hpp" +#include "registry.hpp" +#include "spawn.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + +const char * const kCore[] = { + "beaver_dot_n32", + "beaver_product_100_200", + "beaver_stream_n128", + "beaver_horner_d4", + "beaver_batch_one_round", + "beaver_xor_mux", + "dcf_gt", + "dpf_point_2a_7", + "geneval_point", + "geneval_arith_point", + "blocked_dcf_point", + "ds_key_agrees", + "grotto_prefix_horner", + "verifiable_honest_point", +}; + +const char * const kExtreme[] = { + "beaver_dot_n128", + "beaver_stream_n2048", + "dcf_dense_gt", + "dcf_blocked_interval_ip", + "grotto_signed_prefix_dense", + "grotto_offset_horner_d3", + "grotto_offset_horner_multipiece", + "grotto_geneval_offset_horner", + "geneval_interval_dense", + "geneval_cmp_dense_gt", + "ds_cmp_many_points", + "recent_offset_poly", + "recent_offset_jet", + "recent_offset_twist", + "recent_offset_repr", + "recent_dist_dpf3_point", + "wildcard_single_leaf", +}; + +const char * const kGadget[] = { + "arith_proj_m5", + "arith_proj_m17", + "arith_proj_m64", + "arith_mul_p5", + "arith_mul_p7", + "arith_mul_p11", + "arith_thresh_b8", + "arith_thresh_b16", + "arith_chain_mul4", + "yao_if_4_2", + "yao_if_16_8", + "yao_onehot_k4", + "yao_onehot_k8", + "flute_d2", + "flute_d4", + "flute_d8", + "flute_d4_o8", + "shuffle_n16", + "shuffle_n64", + "shuffle_n256", +}; + +const char kUsage[] = + "profile_party [--list] [--slice S ...] [--tier std|heavy|all|smoke]\n" + " [--suite core|extreme|gadget|all] [--tag TAGS] [--case NAME ...]\n" + " [--repeat N=3] [--warmup W=1]\n" + "Default run is the core suite. --suite gadget is the word-garbling,\n" + "stacked-Yao, FLUTE, and hidden-shuffle battery on the party mesh.\n" + "--slice/--tier select the cost-matrix catalog instead.\n" + "--list with no filter prints every bench flow.\n" + "heavy: wildcard_single_leaf, beaver_stream_n512/n2048, dcf_full_*, *_domain.\n" + "smoke: flows that are not benchable (rejects and negative tests).\n"; + +bool starts_with(const std::string & s, const char * prefix) +{ + const auto n = std::char_traits::length(prefix); + return s.size() >= n && s.compare(0, n, prefix) == 0; +} + +std::string slice_of(const std::string & name) +{ + if (starts_with(name, "arith_")) + return "arith-garble"; + if (starts_with(name, "yao_")) + return "yao-stack"; + if (starts_with(name, "flute_")) + return "flute"; + if (starts_with(name, "shuffle_")) + return "shuffle"; + if (starts_with(name, "beaver_dot")) + return "beaver-dot"; + if (starts_with(name, "beaver_stream")) + return "beaver-stream"; + if (starts_with(name, "beaver_scale")) + return "beaver-scale"; + if (starts_with(name, "beaver_horner") || name == "beaver_sign_horner") + return "beaver-horner"; + if (starts_with(name, "beaver_product") || starts_with(name, "beaver_mul") + || starts_with(name, "beaver_chained")) + return "beaver-product"; + if (starts_with(name, "beaver_poly") || name == "beaver_like_terms" + || starts_with(name, "beaver_nested") || starts_with(name, "beaver_tuple") + || starts_with(name, "beaver_mixed") || starts_with(name, "beaver_factored")) + return "beaver-poly"; + if (starts_with(name, "beaver_")) + return "beaver-misc"; + if (starts_with(name, "dcf_full")) + return "dcf-full"; + if (starts_with(name, "dcf_dense")) + return "dcf-dense"; + if (starts_with(name, "dcf_blocked") || starts_with(name, "blocked_")) + return "blocked"; + if (starts_with(name, "dcf_")) + return "dcf"; + if (starts_with(name, "geneval_cmp")) + return "geneval-cmp"; + if (starts_with(name, "geneval_")) + return "geneval"; + if (starts_with(name, "grotto_")) + return "grotto-net"; + if (starts_with(name, "ds_")) + return "ds"; + if (starts_with(name, "recent_offset") || starts_with(name, "recent_ring") + || starts_with(name, "recent_closed") || starts_with(name, "recent_exact")) + return "recent-grotto"; + if (starts_with(name, "recent_dpf3") || starts_with(name, "recent_dist_dpf3")) + return "dpf3"; + if (starts_with(name, "recent_")) + return "recent"; + if (starts_with(name, "wildcard_")) + return "wildcard"; + if (starts_with(name, "verifiable_")) + return "verifiable"; + if (starts_with(name, "dpf_")) + return "dpf-point"; + if (starts_with(name, "carry_") || starts_with(name, "extractable_")) + return "auth"; + if (starts_with(name, "cov_paint") || starts_with(name, "cov_idcf") + || name == "cov_eq_at" || name == "cov_ccmp") + return "coverage-cmp"; + if (starts_with(name, "cov_geneval") || name == "cov_idpf_at" + || name == "cov_eval_inner_product") + return "coverage-eval"; + if (starts_with(name, "cov_")) + return "coverage"; + return "other"; +} + +std::string tier_of(const std::string & name, bool) +{ + const bool domain = name.size() >= 7 + && name.compare(name.size() - 7, 7, "_domain") == 0; + const bool dpf3_walk = name.find("dpf3") != std::string::npos + && (name.find("update") != std::string::npos + || name.find("proof") != std::string::npos + || name.find("blocked") != std::string::npos); + if (name == "wildcard_single_leaf" + || name == "beaver_stream_n512" + || name == "beaver_stream_n2048" + || starts_with(name, "dcf_full_") + || domain + || dpf3_walk + || starts_with(name, "recent_dist_dpf3")) + return "heavy"; + const bool negative = name.find("fail") != std::string::npos + || name.find("tamper") != std::string::npos + || name.find("reject") != std::string::npos + || name.find("wrong") != std::string::npos + || name.find("bad_use") != std::string::npos; + if (negative) + return "smoke"; + return "std"; +} + +std::map fields_of(const std::string & line) +{ + std::map out; + std::istringstream in(line); + std::string tok; + while (in >> tok) + { + const auto eq = tok.find('='); + if (eq == std::string::npos) + continue; + out.emplace(tok.substr(0, eq), tok.substr(eq + 1)); + } + return out; +} + +std::string field(const std::map & m, const char * key) +{ + const auto it = m.find(key); + return it == m.end() ? "0" : it->second; +} + +} // namespace + +int main(int argc, char ** argv) +{ + dpf::party::register_all_flows(); + + std::string suite = "core"; + std::string tag; + std::string tier; + std::vector slices; + std::vector case_names; + std::uint64_t repeat = 3; + std::uint64_t warmup = 1; + bool list_only = false; + bool suite_set = false; + bool tier_set = false; + + for (int i = 1; i < argc; ++i) + { + const std::string a = argv[i]; + auto need = [&](const char * flag) { + if (i + 1 >= argc) + { + std::cerr << "missing value for " << flag << "\n"; + std::exit(2); + } + return std::string(argv[++i]); + }; + if (a == "--list") + list_only = true; + else if (a == "--suite") + { + suite = need("--suite"); + suite_set = true; + } + else if (a == "--tag") + tag = need("--tag"); + else if (a == "--case") + case_names.push_back(need("--case")); + else if (a == "--slice") + slices.push_back(need("--slice")); + else if (a == "--tier") + { + tier = need("--tier"); + tier_set = true; + } + else if (a == "--repeat") + repeat = std::stoull(need("--repeat")); + else if (a == "--warmup") + warmup = std::stoull(need("--warmup")); + else if (a == "--help" || a == "-h") + { + std::cout << kUsage; + return 0; + } + else + { + std::cerr << "unknown argument: " << a << "\n" << kUsage; + return 2; + } + } + if (repeat == 0) + repeat = 1; + + const bool catalog_mode = tier_set || !slices.empty() + || (list_only && !suite_set && tag.empty() && case_names.empty()); + + struct picked + { + std::string name; + std::string slice; + std::string tier; + }; + std::vector picked_flows; + + auto take_catalog = [&](const std::string & want_tier) { + for (const auto * f : dpf::party::select_flows("")) + { + const std::string slice = slice_of(f->name); + const std::string flow_tier = tier_of(f->name, f->bench); + if (want_tier == "std" && flow_tier != "std") + continue; + if (want_tier == "heavy" && flow_tier != "heavy") + continue; + if (want_tier == "smoke" && flow_tier != "smoke") + continue; + if (want_tier == "all" && flow_tier == "smoke") + continue; + if (!slices.empty() + && std::find(slices.begin(), slices.end(), slice) == slices.end()) + continue; + if (!case_names.empty() + && std::find(case_names.begin(), case_names.end(), f->name) == case_names.end()) + continue; + picked_flows.push_back(picked{f->name, slice, flow_tier}); + } + }; + + if (catalog_mode) + { + const std::string want = tier_set ? tier : (list_only ? "all" : "std"); + if (want != "std" && want != "heavy" && want != "all" && want != "smoke") + { + std::cerr << "unknown tier: " << want << "\n" << kUsage; + return 2; + } + take_catalog(want); + for (const auto & name : case_names) + { + bool found = false; + for (const auto & row : picked_flows) + found = found || row.name == name; + if (!found) + { + std::cerr << "unknown flow: " << name << "\n"; + return 2; + } + } + if (picked_flows.empty()) + { + std::cerr << "no flows match the requested slice/tier/case\n"; + return 2; + } + } + else + { + std::vector names; + if (!case_names.empty()) + names = std::move(case_names); + else if (!tag.empty()) + { + for (const auto * f : dpf::party::select_flows(tag)) + names.emplace_back(f->name); + if (names.empty()) + { + std::cerr << "no flows match tag: " << tag << "\n"; + return 2; + } + } + else if (suite == "core" || suite == "all") + { + for (const char * n : kCore) + names.emplace_back(n); + if (suite == "all") + { + for (const char * n : kExtreme) + names.emplace_back(n); + for (const char * n : kGadget) + names.emplace_back(n); + } + } + else if (suite == "extreme") + { + for (const char * n : kExtreme) + names.emplace_back(n); + } + else if (suite == "gadget") + { + for (const char * n : kGadget) + names.emplace_back(n); + } + else + { + std::cerr << "unknown suite: " << suite << "\n" << kUsage; + return 2; + } + + for (const auto & name : names) + { + const auto * f = dpf::party::find_flow(name); + if (!f) + { + std::cerr << "unknown flow: " << name << "\n"; + return 2; + } + picked_flows.push_back(picked{name, slice_of(name), tier_of(name, f->bench)}); + } + } + + if (list_only) + { + std::cout << "family\tslice\tcase\titems\ttier\n"; + for (const auto & row : picked_flows) + std::cout << "party\t" << row.slice << '\t' << row.name + << "\t1\t" << row.tier << '\n'; + return 0; + } + + dpf::party::spawn_opts opts; + opts.repeat = repeat; + opts.warmup = warmup; + opts.metrics = true; + + std::cout + << "family\tslice\ttier\tflow\trole\twall_ms\tavg_ns\tmin_ns\tmax_ns\t" + << "bytes_sent\tbytes_recv\tframes_sent\tframes_recv\t" + << "bytes_recv_from_p2\tbytes_recv_from_peer\t" + << "bytes_sent_to_p2\tbytes_sent_to_peer\t" + << "payload_sent\tpayload_recv\twire_overhead\trounds\tprg_evals\t" + << "avg_bytes_sent\tavg_frames_sent\trc\n"; + + int fails = 0; + for (const auto & row : picked_flows) + { + const auto result = dpf::party::spawn_trio_flow(row.name, opts); + if (result.metrics_lines.empty()) + { + std::cout << "party\t" << row.slice << '\t' << row.tier << '\t' + << row.name << "\t-\t" << result.wall_ms + << "\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t" + << result.rc[0] << "," << result.rc[1] << "," << result.rc[2] + << "\n"; + } + for (const auto & line : result.metrics_lines) + { + const auto f = fields_of(line); + const auto role = field(f, "role"); + const int rc = role == "p0" ? result.rc[0] + : role == "p1" ? result.rc[1] + : role == "p2" ? result.rc[2] : 0; + std::cout << "party\t" << row.slice << '\t' << row.tier << '\t' + << row.name << '\t' << role << '\t' << result.wall_ms << '\t' + << field(f, "avg_ns") << '\t' + << field(f, "min_ns") << '\t' + << field(f, "max_ns") << '\t' + << field(f, "bytes_sent") << '\t' + << field(f, "bytes_recv") << '\t' + << field(f, "frames_sent") << '\t' + << field(f, "frames_recv") << '\t' + << field(f, "bytes_recv_from_p2") << '\t' + << field(f, "bytes_recv_from_peer") << '\t' + << field(f, "bytes_sent_to_p2") << '\t' + << field(f, "bytes_sent_to_peer") << '\t' + << field(f, "payload_sent") << '\t' + << field(f, "payload_recv") << '\t' + << field(f, "wire_overhead") << '\t' + << field(f, "rounds") << '\t' + << field(f, "prg_evals") << '\t' + << field(f, "avg_bytes_sent") << '\t' + << field(f, "avg_frames_sent") << '\t' + << rc << '\n'; + } + if (result.rc[0] || result.rc[1] || result.rc[2]) + ++fails; + } + return fails ? 1 : 0; +} diff --git a/test/tests/all_test.cpp b/test/tests/all_test.cpp index 0564dbb..13dc3cd 100644 --- a/test/tests/all_test.cpp +++ b/test/tests/all_test.cpp @@ -2,23 +2,23 @@ int main() { - system("./bin/dpf_key_test"); - system("./bin/wildcard_test"); + (void)std::system("./bin/dpf_key_test"); + (void)std::system("./bin/wildcard_test"); - system("./bin/eval_point_test"); - system("./bin/eval_interval_test"); - system("./bin/eval_full_test"); - system("./bin/eval_sequence_test"); + (void)std::system("./bin/eval_point_test"); + (void)std::system("./bin/eval_interval_test"); + (void)std::system("./bin/eval_full_test"); + (void)std::system("./bin/eval_sequence_test"); - system("./bin/eval_point_multi_test"); - system("./bin/eval_interval_multi_test"); - system("./bin/eval_full_multi_test"); - system("./bin/eval_sequence_multi_test"); + (void)std::system("./bin/eval_point_multi_test"); + (void)std::system("./bin/eval_interval_multi_test"); + (void)std::system("./bin/eval_full_multi_test"); + (void)std::system("./bin/eval_sequence_multi_test"); - system("./bin/advice_bit_iterable_test"); - system("./bin/parallel_bit_iterable_test"); - system("./bin/setbit_index_iterable_test"); - system("./bin/keyword2_test"); + (void)std::system("./bin/advice_bit_iterable_test"); + (void)std::system("./bin/parallel_bit_iterable_test"); + (void)std::system("./bin/setbit_index_iterable_test"); + (void)std::system("./bin/keyword2_test"); return 0; } diff --git a/test/tests/arith_garble_test.cpp b/test/tests/arith_garble_test.cpp new file mode 100644 index 0000000..af253c7 --- /dev/null +++ b/test/tests/arith_garble_test.cpp @@ -0,0 +1,241 @@ +#include + +#include +#include + +#include "dpf/arith_garble.hpp" + +namespace +{ + +using dpf::arith_garble::circuit; +using dpf::arith_garble::wire; + +std::vector plain_outs(const circuit & c, + const std::uint16_t * in) +{ + auto all = dpf::arith_garble::eval_plain(c, in); + std::vector out; + for (auto id : c.outputs()) + out.push_back(all[id]); + return out; +} + +void expect_match(const circuit & c, const std::vector & in) +{ + auto got = dpf::arith_garble::eval_pair(c, in.data()); + auto want = plain_outs(c, in.data()); + ASSERT_EQ(got.opened, want); + ASSERT_EQ(got.mask.size(), want.size()); + for (std::size_t i = 0; i < want.size(); ++i) + { + EXPECT_EQ(got.opened[i], + dpf::arith_garble::open_shares(got.modulus[i], got.mask[i], got.color[i])); + } +} + +} // namespace + +TEST(ArithGarble, ProjectionRowsAreModulusMinusOne) +{ + circuit c; + auto x = c.input(5); + std::vector sq{0, 1, 4, 4, 1}; + c.out(c.project(x, 5, sq)); + auto got = dpf::arith_garble::eval_pair(c, std::vector{3}.data()); + EXPECT_EQ(got.ciphertext_rows, 4u); + EXPECT_EQ(got.opened[0], 4u); +} + +TEST(ArithGarble, AddScaleAndPublicShift) +{ + circuit c; + auto x = c.input(7); + auto y = c.input(7); + auto s = c.add(x, y); + auto t = c.scale(s, 3); + c.out(c.add_const(t, 4)); + for (std::uint16_t a = 0; a < 7; ++a) + for (std::uint16_t b = 0; b < 7; ++b) + expect_match(c, {a, b}); +} + +TEST(ArithGarble, ThresholdCostsFanInRows) +{ + circuit c; + std::vector bits; + for (int i = 0; i < 3; ++i) + bits.push_back(c.input(4)); + c.out(c.threshold(bits, 3)); + auto got = dpf::arith_garble::eval_pair( + c, std::vector{1, 1, 1}.data()); + EXPECT_EQ(got.ciphertext_rows, 3u); + EXPECT_EQ(got.opened[0], 1u); + expect_match(c, {1, 1, 0}); + expect_match(c, {0, 0, 0}); +} + +TEST(ArithGarble, FanInAndOfBits) +{ + circuit c; + std::vector bits; + for (int i = 0; i < 4; ++i) + bits.push_back(c.input(2)); + c.out(c.fanin_and(bits)); + expect_match(c, {1, 1, 1, 1}); + expect_match(c, {1, 1, 0, 1}); + expect_match(c, {0, 0, 0, 0}); +} + +TEST(ArithGarble, PrimeProduct) +{ + for (std::uint16_t p : {2, 3, 5, 7}) + { + circuit c; + auto x = c.input(p); + auto y = c.input(p); + c.out(c.mul(x, y)); + for (std::uint16_t a = 0; a < p; ++a) + for (std::uint16_t b = 0; b < p; ++b) + expect_match(c, {a, b}); + } +} + +TEST(ArithGarble, ChainedProduct) +{ + circuit c; + auto x = c.input(5); + auto y = c.input(5); + auto z = c.input(5); + c.out(c.mul(c.add(x, y), z)); + expect_match(c, {2, 4, 3}); + expect_match(c, {0, 1, 4}); + expect_match(c, {4, 4, 0}); +} + +TEST(ArithGarble, EveryResidueOfAProjectionAndAScale) +{ + circuit c; + auto x = c.input(11); + std::vector cube(11); + for (std::uint16_t i = 0; i < 11; ++i) + cube[i] = static_cast((i * i * i) % 11); + auto y = c.project(x, 11, cube); + c.out(y); + c.out(c.scale(y, 10)); + c.out(c.add_const(x, 18)); + for (std::uint16_t a = 0; a < 11; ++a) + { + expect_match(c, {a}); + auto got = dpf::arith_garble::eval_pair(c, &a); + EXPECT_EQ(got.ciphertext_rows, 10u); + } +} + +TEST(ArithGarble, FreeGatesSendNoRows) +{ + circuit c; + auto x = c.input(9); + auto y = c.input(9); + c.out(c.add_const(c.scale(c.add(x, y), 5), 4)); + auto got = dpf::arith_garble::eval_pair(c, std::vector{8, 8}.data()); + EXPECT_EQ(got.ciphertext_rows, 0u); + EXPECT_EQ(got.opened[0], static_cast((5 * (8 + 8) + 4) % 9)); +} + +TEST(ArithGarble, ThresholdEveryWeight) +{ + circuit c; + std::vector bits; + for (int i = 0; i < 5; ++i) + bits.push_back(c.input(6)); + for (std::uint16_t t = 0; t <= 5; ++t) + c.out(c.threshold(bits, t)); + auto one = dpf::arith_garble::eval_pair( + c, std::vector{1, 1, 1, 1, 1}.data()); + EXPECT_EQ(one.ciphertext_rows, 5u * 6u); + for (unsigned mask = 0; mask < 32; ++mask) + { + std::vector in(5); + for (int i = 0; i < 5; ++i) + in[i] = static_cast((mask >> i) & 1u); + expect_match(c, in); + } +} + +TEST(ArithGarble, FanInAndEveryPattern) +{ + circuit c; + std::vector bits; + for (int i = 0; i < 4; ++i) + bits.push_back(c.input(2)); + c.out(c.fanin_and(bits)); + auto rows = dpf::arith_garble::eval_pair( + c, std::vector{1, 1, 1, 1}.data()); + EXPECT_EQ(rows.ciphertext_rows, 8u); + for (unsigned mask = 0; mask < 16; ++mask) + { + std::vector in(4); + for (int i = 0; i < 4; ++i) + in[i] = static_cast((mask >> i) & 1u); + expect_match(c, in); + } +} + +TEST(ArithGarble, PrimeElevenAndBitScale) +{ + circuit mul; + auto x = mul.input(11); + auto y = mul.input(11); + mul.out(mul.mul(x, y)); + for (std::uint16_t a = 0; a < 11; ++a) + for (std::uint16_t b = 0; b < 11; ++b) + expect_match(mul, {a, b}); + + circuit pass; + auto word = pass.input(5); + auto bit = pass.input(2); + pass.out(pass.bit_scale(word, bit)); + for (std::uint16_t w = 0; w < 5; ++w) + for (std::uint16_t b = 0; b < 2; ++b) + expect_match(pass, {w, b}); +} + +TEST(ArithGarble, TwoEvalutionsOpenTheSameValue) +{ + circuit c; + auto x = c.input(5); + auto y = c.input(5); + c.out(c.mul(x, y)); + const std::uint16_t in[2] = {3, 4}; + auto a = dpf::arith_garble::eval_pair(c, in); + auto b = dpf::arith_garble::eval_pair(c, in); + EXPECT_EQ(a.opened, b.opened); + EXPECT_EQ(a.opened[0], static_cast((3 * 4) % 5)); +} + +TEST(ArithGarble, RejectsBadModuliTablesAndInputs) +{ + circuit c; + EXPECT_THROW(c.input(1), std::invalid_argument); + EXPECT_THROW(c.input(129), std::invalid_argument); + auto x = c.input(8); + auto y = c.input(7); + EXPECT_THROW(c.add(x, y), std::invalid_argument); + EXPECT_THROW(c.scale(x, 2), std::invalid_argument); + EXPECT_THROW(c.scale(x, 0), std::invalid_argument); + EXPECT_THROW(c.project(x, 3, {0, 1}), std::invalid_argument); + EXPECT_THROW(c.project(x, 3, std::vector(8, 3)), std::invalid_argument); + auto bit = c.input(2); + EXPECT_THROW(c.bit_scale(x, x), std::invalid_argument); + EXPECT_THROW(c.fanin_and({x}), std::invalid_argument); + EXPECT_THROW(c.threshold({}, 0), std::invalid_argument); + circuit bare; + bare.input(3); + EXPECT_THROW(dpf::arith_garble::eval_pair(bare, std::vector{0}.data()), + std::invalid_argument); + circuit one; + one.out(one.input(4)); + EXPECT_THROW(expect_match(one, {4}), std::invalid_argument); + (void)bit; +} diff --git a/test/tests/beaver_party_test.cpp b/test/tests/beaver_party_test.cpp new file mode 100644 index 0000000..a6932d9 --- /dev/null +++ b/test/tests/beaver_party_test.cpp @@ -0,0 +1,87 @@ +#include + +#include +#include +#include + +#include "cases.hpp" +#include "registry.hpp" +#include "spawn.hpp" + +namespace +{ + +class PartyFlowTest : public ::testing::TestWithParam +{ +}; + +TEST_P(PartyFlowTest, Trio) +{ + dpf::party::register_all_flows(); + const auto & name = GetParam(); + const auto * f = dpf::party::find_flow(name); + ASSERT_NE(f, nullptr) << name; + // IKNP replaces the dealer. Spawning p2 makes that role call a keygen + // that refuses `role::p2` (`iknp point/comparison keygen has no dealer`). + const bool pair = dpf::party::flow_is_pair(*f); + auto r = pair ? dpf::party::spawn_pair_flow(name) + : dpf::party::spawn_trio_flow(name); + EXPECT_EQ(r.rc[0], 0) << "p0 failed for " << name; + EXPECT_EQ(r.rc[1], 0) << "p1 failed for " << name; + if (!pair) + EXPECT_EQ(r.rc[2], 0) << "p2 failed for " << name; + else + EXPECT_EQ(r.rc[2], 0) << "pair spawn must not report a dealer"; +} + +std::vector all_flow_names() +{ + dpf::party::register_all_flows(); + std::vector names; + for (const auto * f : dpf::party::select_flows({})) + names.emplace_back(f->name); + return names; +} + +TEST(PartyFlow, PairFlowsAreTheIknpOnes) +{ + dpf::party::register_all_flows(); + int pairs = 0; + int trios = 0; + for (const auto * f : dpf::party::select_flows({})) + { + ASSERT_NE(f, nullptr); + ASSERT_NE(f->name, nullptr); + const std::string name = f->name; + const bool iknp = name.rfind("iknp_", 0) == 0 + || dpf::party::flow_has_tag(*f, "iknp"); + EXPECT_EQ(dpf::party::flow_is_pair(*f), iknp) << name; + if (iknp) + { + ++pairs; + EXPECT_EQ(name.rfind("iknp_", 0), 0u) << name; + } + else + { + ++trios; + } + } + EXPECT_GE(pairs, 5); + EXPECT_GT(trios, pairs); +} + +INSTANTIATE_TEST_SUITE_P( + AllFlows, + PartyFlowTest, + ::testing::ValuesIn(all_flow_names()), + [](const auto & info) { + std::string n = info.param; + for (char & c : n) + { + if (!(std::isalnum(static_cast(c)) || c == '_')) + c = '_'; + } + return n; + }); + +} // namespace diff --git a/test/tests/beaver_test.cpp b/test/tests/beaver_test.cpp index f63c2ed..51f125a 100644 --- a/test/tests/beaver_test.cpp +++ b/test/tests/beaver_test.cpp @@ -5,8 +5,11 @@ #include #include +#include + #include "dpf/beaver.hpp" #include "dpf/buffered_prg.hpp" +#include "dpf/doerner_shelat.hpp" #include "dpf/modint.hpp" namespace @@ -303,6 +306,37 @@ TEST(Beaver, InnerProductMatchesTheSumAndIsOneCross) EXPECT_EQ(fused.open(again), expect); } +TEST(Beaver, ScheduleObjectiveRoundsKeepsOneRound) +{ + session64 latency; + latency.set_schedule_objective(dpf::beavers::schedule_objective::rounds); + auto sgn = latency.input(); + auto x = latency.input(); + auto a0 = latency.input(); + auto a1 = latency.input(); + auto lin = latency(sgn * (a1 * x + a0)); + EXPECT_EQ(latency.round_of(lin), 1); + + session64 prep; + prep.set_schedule_objective(dpf::beavers::schedule_objective::prep); + auto ps = prep.input(); + auto px = prep.input(); + auto pa0 = prep.input(); + auto pa1 = prep.input(); + auto plin = prep(ps * (pa1 * px + pa0)); + EXPECT_EQ(prep.round_of(plin), 2); + EXPECT_LT(prep.preprocessing_count(), latency.preprocessing_count()); + + Counter rng; + latency.sample(rng); + latency.bind(sgn, u64{3}, rng); + latency.bind(x, u64{2}, rng); + latency.bind(a0, u64{4}, rng); + latency.bind(a1, u64{5}, rng); + latency.evaluate(); + EXPECT_EQ(latency.open(lin), 3u * (5u * 2u + 4u)); +} + TEST(Beaver, InnerProductPeelsASharedFactor) { session64 s; @@ -632,16 +666,16 @@ TEST(Beaver, InnerProductRejectsABadShape) auto x = s.input(); auto y = s.input(); auto z = s.input(); - EXPECT_THROW((void)[&] { + EXPECT_THROW([&] { return s.dot(std::initializer_list{}, std::initializer_list{}); }(), std::invalid_argument); - EXPECT_THROW((void)[&] { return s.dot({x}, {y, z}); }(), std::invalid_argument); + EXPECT_THROW([&] { return s.dot({x}, {y, z}); }(), std::invalid_argument); session64 other; auto w = other.input(); - EXPECT_THROW((void)[&] { return s.dot({x}, {w}); }(), std::invalid_argument); + EXPECT_THROW([&] { return s.dot({x}, {w}); }(), std::invalid_argument); auto dotted = s.dot({x}, {y}); - EXPECT_THROW((void)[&] { return s.dot_cross(dotted); }(), std::logic_error); - EXPECT_THROW((void)[&] { return s.dot_cross(x); }(), std::invalid_argument); + EXPECT_THROW([&] { return s.dot_cross(dotted); }(), std::logic_error); + EXPECT_THROW([&] { return s.dot_cross(x); }(), std::invalid_argument); } TEST(Beaver, ScaleSharesScalarBlind) @@ -1531,7 +1565,7 @@ TEST(Beaver, FactoredProductIsVisibleAndTheSexticTermIsNot) EXPECT_EQ(s.preprocessing_count(), prep); EXPECT_EQ(s.monomial({{x, 1u}, {z, 1u}}).open(), s.lambda(x).open() * s.lambda(z).open()); - EXPECT_THROW((void)[&] { return s.monomial({{x, 2u}, {z, 2u}}); }(), + EXPECT_THROW([&] { return s.monomial({{x, 2u}, {z, 2u}}); }(), std::logic_error); s.bind(x, u64{6}, rng); s.bind(z, u64{7}, rng); @@ -1909,8 +1943,8 @@ TEST(Beaver, HighPowersAndTheExpansionLimit) session64 s; auto x = s.input(); - EXPECT_THROW((void)[&] { return pow(x, 17u); }(), std::invalid_argument); - EXPECT_THROW((void)[&] { return pow(x, 10) * pow(x, 7); }(), std::invalid_argument); + EXPECT_THROW([&] { return pow(x, 17u); }(), std::invalid_argument); + EXPECT_THROW([&] { return pow(x, 10) * pow(x, 7); }(), std::invalid_argument); std::vector wide; wide.reserve(12); @@ -1929,7 +1963,7 @@ TEST(Beaver, HighPowersAndTheExpansionLimit) EXPECT_EQ(s.open(all), 1u); auto thirteenth = s.input(); - EXPECT_THROW((void)[&] { return s(expr12 * thirteenth); }(), std::invalid_argument); + EXPECT_THROW([&] { return s(expr12 * thirteenth); }(), std::invalid_argument); } TEST(Beaver, ScheduledPolynomialRejectsEarlyUse) @@ -1938,8 +1972,8 @@ TEST(Beaver, ScheduledPolynomialRejectsEarlyUse) session64 b; auto x = a.input(); auto y = b.input(); - EXPECT_THROW((void)[&] { return x + y; }(), std::invalid_argument); - EXPECT_THROW((void)[&] { return x * y; }(), std::invalid_argument); + EXPECT_THROW([&] { return x + y; }(), std::invalid_argument); + EXPECT_THROW([&] { return x * y; }(), std::invalid_argument); auto z = a(x + pow(x, 2)); EXPECT_THROW(a.open(z), std::logic_error); EXPECT_THROW(a.evaluate(), std::logic_error); @@ -1959,15 +1993,15 @@ TEST(Beaver, RejectsBadUse) dpf::beavers::session b; auto x = a.input(); auto y = b.input(); - EXPECT_THROW((void)[&] { return a.product(x, y); }(), std::invalid_argument); - EXPECT_THROW((void)[&] { return x * y; }(), std::invalid_argument); + EXPECT_THROW([&] { return a.product(x, y); }(), std::invalid_argument); + EXPECT_THROW([&] { return x * y; }(), std::invalid_argument); auto bit = a.bit(); EXPECT_THROW(a.bind(bit, u64{2}), std::invalid_argument); auto z = a.product(x, x); EXPECT_THROW(a.evaluate(), std::logic_error); a.sample(); EXPECT_THROW(a.evaluate(), std::logic_error); - EXPECT_THROW((void)[&] { return a.bit_mul(x, x); }(), std::invalid_argument); + EXPECT_THROW([&] { return a.bit_mul(x, x); }(), std::invalid_argument); (void)z; } @@ -1993,3 +2027,178 @@ TEST(Beaver, ProductExtremes) EXPECT_EQ(s.open(z), want) << a << " * " << b; } } + +TEST(BeaverAuth, AuthBeaver2HonestAndTamper) +{ + auto key = dpf::sample_mac_key(); + auto t = dpf::beavers::sample_auth_beaver2(key); + EXPECT_TRUE(t.verify(key)); + EXPECT_EQ(t.ab.open(), t.a.open() * t.b.open()); + + auto bad = t; + bad.ab.tag.p0 ^= 1ull; + EXPECT_FALSE(bad.verify(key)); +} + +TEST(BeaverAuth, AuthBeaverMulMatchesProduct) +{ + auto key = dpf::sample_mac_key(); + auto bev = dpf::beavers::sample_auth_beaver2(key); + const u64 x = 7, y = 11; + auto xs = dpf::beavers::auth_share(x, key); + auto ys = dpf::beavers::auth_share(y, key); + auto [z0, z1] = dpf::beavers::auth_beaver_mul( + xs.party(0), xs.party(1), ys.party(0), ys.party(1), bev, key); + EXPECT_EQ(z0.value + z1.value, x * y); + EXPECT_TRUE(dpf::mac_verify(z0, z1, key)); + + z0.tag ^= 1ull; + EXPECT_FALSE(dpf::mac_verify(z0, z1, key)); +} + +TEST(BeaverAuth, SessionAby2ValuesVerify) +{ + auto key = dpf::sample_mac_key(); + session64 s; + s.set_mac_key(key); + auto x = s.input(); + auto y = s.input(); + auto z = s(x * y); + Counter rng; + s.sample(rng); + s.bind(x, u64{6}, rng); + s.bind(y, u64{7}, rng); + s.evaluate(); + EXPECT_EQ(s.open(z), 42u); + EXPECT_TRUE(s.lambda_auth(x).verify(key)); + EXPECT_TRUE(s.value_auth(x).verify(key)); + EXPECT_TRUE(s.value_auth(z).verify(key)); + EXPECT_TRUE(s.verify_delta(x)); + EXPECT_TRUE(s.verify_delta(y)); + EXPECT_TRUE(s.verify_all()); + + auto tampered = s.value_auth(z); + tampered.tag.p0 ^= 1ull; + EXPECT_FALSE(tampered.verify(key)); +} + +TEST(BeaverAuth, PartyTapeCarriesTagsAndOpeningsCheck) +{ + auto key = dpf::sample_mac_key(); + session64 dealer; + dealer.set_mac_key(key); + auto x = dealer.input(); + auto y = dealer.input(); + auto z = dealer(x * y); + Counter rng; + dealer.sample(rng); + auto tape0 = dealer.export_party(0); + auto tape1 = dealer.export_party(1); + EXPECT_TRUE(tape0.has_mac); + EXPECT_TRUE(tape1.has_mac); + EXPECT_EQ(tape0.lambda_tag.size(), tape0.lambda.size()); + EXPECT_EQ(tape0.lambda[0] + tape1.lambda[0], dealer.lambda(x).open()); + EXPECT_EQ(tape0.lambda_tag[0] + tape1.lambda_tag[0], + dealer.lambda_auth(x).tag.open()); + + dealer.bind(x, u64{3}, rng); + dealer.bind(y, u64{5}, rng); + dealer.evaluate(); + EXPECT_EQ(dealer.open(z), 15u); + EXPECT_TRUE(dealer.verify_all()); + + auto honest = dealer.delta_auth(x); + dpf::beavers::auth_opening a{honest.value.p0, honest.tag.p0}; + dpf::beavers::auth_opening b{honest.value.p1, honest.tag.p1}; + EXPECT_TRUE(dpf::beavers::verify_auth_opening(a, b, key)); + b.value ^= 1ull; + EXPECT_FALSE(dpf::beavers::verify_auth_opening(a, b, key)); + + // Party views: authenticated input shares + λ tags reconstruct δ. + auto xv = dealer.value_auth(x); + dpf::beavers::auth_opening ox0{ + xv.party(0).value + tape0.lambda[0], + xv.party(0).tag + tape0.lambda_tag[0]}; + dpf::beavers::auth_opening ox1{ + xv.party(1).value + tape1.lambda[0], + xv.party(1).tag + tape1.lambda_tag[0]}; + EXPECT_TRUE(dpf::beavers::verify_auth_opening(ox0, ox1, key)); + EXPECT_EQ(ox0.value + ox1.value, dealer.delta(x)); +} + +TEST(Beaver, OracleAuthTagsReplayFromTheSeed) +{ + using block = dpf::prg::aes128::block_type; + const block seed = simde_mm_set_epi64x(0x51, 0x52); + auto key = dpf::sample_mac_key(); + dpf::beavers::oracle left(seed, 4); + dpf::beavers::oracle right(seed, 4); + auto a = dpf::beavers::sample_auth_beaver2(key, left, 3); + auto b = dpf::beavers::sample_auth_beaver2(key, right, 3); + EXPECT_EQ(a.a, b.a); + EXPECT_EQ(a.b, b.b); + EXPECT_EQ(a.ab, b.ab); + EXPECT_EQ(a.out, b.out); + EXPECT_TRUE(a.verify(key)); + EXPECT_EQ(a.ab.open(), a.a.open() * a.b.open()); + + dpf::beavers::session session; + session.set_mac_key(key); + auto x = session.input(); + auto y = session.input(); + auto z = session(x * y); + session.pin(z); + session.sample_from(left, 3); + EXPECT_TRUE(session.lambda_auth(x).verify(key)); + EXPECT_TRUE(session.monomial_auth({{x, 1u}, {y, 1u}}).verify(key)); + EXPECT_EQ(session.lambda(x), a.a.value); +} + +TEST(Beaver, OracleShapesOpen) +{ + using block = dpf::prg::aes128::block_type; + const block seed = simde_mm_set_epi64x(0x71, 0x72); + dpf::beavers::oracle src(seed, 8); + auto p3 = dpf::beavers::sample_beaver3(src, 1); + EXPECT_EQ(p3.abc.open(), p3.a.open() * p3.b.open() * p3.c.open()); + auto sq = dpf::beavers::sample_square(src, 2); + EXPECT_EQ(sq.x2.open(), sq.x.open() * sq.x.open()); + auto sc = dpf::beavers::sample_scale(2, src, 4); + EXPECT_EQ(sc.cross[1].open(), sc.scalar.open() * sc.lanes[1].open()); + auto fresh = dpf::beavers::sample_fresh<3, u64>(src, 5); + EXPECT_EQ(fresh.subset[(1u << 3) - 2].open(), + fresh.in[0].open() * fresh.in[1].open() * fresh.in[2].open()); +} + +TEST(Beaver, PrgPadReplaysDsGadgets) +{ + using block = dpf::prg::aes128::block_type; + const block seed = simde_mm_set_epi64x(0x81, 0x82); + dpf::prg_pad_rng<> left(seed); + dpf::prg_pad_rng<> right(seed); + const auto a = dpf::detail::ds_sample_bit_and(left); + const auto b = dpf::detail::ds_sample_bit_and(right); + EXPECT_EQ(a.a0, b.a0); + EXPECT_EQ(a.c1, b.c1); + const auto abit = static_cast(a.a0 ^ a.a1); + const auto bbit = static_cast(a.b0 ^ a.b1); + const auto cbit = static_cast(a.c0 ^ a.c1); + EXPECT_EQ(cbit, static_cast(abit & bbit)); + + dpf::prg_pad_rng<> cleft(seed); + dpf::prg_pad_rng<> cright(seed); + const auto cw0 = dpf::detail::ds_sample_cw(cleft); + const auto cw1 = dpf::detail::ds_sample_cw(cright); + EXPECT_EQ(std::memcmp(&cw0.p0.rand, &cw1.p0.rand, sizeof(cw0.p0.rand)), 0); + EXPECT_EQ(std::memcmp(&cw0.p1.gamma, &cw1.p1.gamma, sizeof(cw0.p1.gamma)), 0); + const auto prod = dpf::detail::ds_xor( + (cw0.p1.bit & 1u) ? cw0.p0.rand : simde_mm_setzero_si128(), + (cw0.p0.bit & 1u) ? cw0.p1.rand : simde_mm_setzero_si128()); + const auto got = dpf::detail::ds_xor(cw0.p0.gamma, cw0.p1.gamma); + EXPECT_EQ(std::memcmp(&got, &prod, sizeof(got)), 0); + + dpf::detail::urandom_pad_rng pad; + const auto shares = dpf::beavers::sample_bit_arith(pad); + EXPECT_EQ(shares.add0 + shares.add1, + static_cast(shares.xor0 ^ shares.xor1)); +} diff --git a/test/tests/bench_cell_test.cpp b/test/tests/bench_cell_test.cpp new file mode 100644 index 0000000..b2637cf --- /dev/null +++ b/test/tests/bench_cell_test.cpp @@ -0,0 +1,45 @@ +#include + +#include + +#include "dpf/bench_cells.hpp" +#include "dpf/party_runner.hpp" + +namespace +{ + +void drive(const char * name, dpf::bench::kind id, int parties) +{ + dpf::app::run_config cfg; + cfg.kind = dpf::net::transport::async_memory; + cfg.n_lanes = 1; + std::vector plans; + for (int p = 0; p < parties; ++p) + plans.push_back(dpf::bench::plan_for(static_cast(p), id)); + ASSERT_GT(plans[0].rounds(), 0u); + std::vector values(plans.size()); + auto result = dpf::app::run_parties(plans, values, {}, cfg, nullptr, + &dpf::bench::run_cell); + EXPECT_GT(result.party0_wall_ns, 0u); + ASSERT_FALSE(result.wire.empty()); + EXPECT_GT(result.wire[0].payload_out, 0u); + (void)name; +} + +} // namespace + +TEST(BenchCells, ProjectionCrossesTheMesh) +{ + drive("arith_proj_m5", dpf::bench::kind::proj5, 2); +} + +TEST(BenchCells, ShuffleCrossesTheRing) +{ + drive("shuffle_n16", dpf::bench::kind::shuf16, 3); +} + +TEST(BenchCells, FluteAndStackCrossTheMesh) +{ + drive("flute_d2", dpf::bench::kind::flute2, 2); + drive("yao_if_4_2", dpf::bench::kind::yao_if4, 2); +} diff --git a/test/tests/bitmore_mod_test.cpp b/test/tests/bitmore_mod_test.cpp new file mode 100644 index 0000000..8697137 --- /dev/null +++ b/test/tests/bitmore_mod_test.cpp @@ -0,0 +1,393 @@ +#include + +#include +#include + +#include "dpf.hpp" +#include "simde/simde/x86/avx2.h" + +namespace +{ + +template +struct scalar_acc +{ + using mod = dpf::bitmore_mod; + unsigned acc = 0; + unsigned bound = 0; + + void add(unsigned x, unsigned addend_max) + { + x &= mod::slot_max; + if (addend_max > mod::slot_max) + addend_max = mod::slot_max; + for (;;) + { + if (bound + addend_max <= mod::slot_max) + break; + if (bound > mod::partial_bound) + { + acc = mod::partial_reduce_slot(acc); + bound = mod::partial_bound; + continue; + } + if (addend_max > mod::partial_bound) + { + x = mod::partial_reduce_slot(x); + addend_max = mod::partial_bound; + continue; + } + if (bound > mod::stable_bound) + { + acc = mod::partial_reduce_slot(acc); + bound = mod::stable_bound; + continue; + } + if (addend_max > mod::stable_bound) + { + x = mod::partial_reduce_slot(x); + addend_max = mod::stable_bound; + continue; + } + break; + } + acc += x; + bound += addend_max; + } + + void insert(unsigned bit) + { + while (bound > (mod::slot_max >> 1)) + { + acc = mod::partial_reduce_slot(acc); + bound = bound > mod::partial_bound ? mod::partial_bound : mod::stable_bound; + } + acc = ((acc << 1) | (bit & 1u)) & mod::slot_max; + bound = bound * 2u + 1u; + } +}; + +template +void expect_bytes() +{ + using mod = dpf::bitmore_mod; + unsigned span = mod::resume_bound + 1u; + unsigned k = 0; + while ((span << 1) <= 256u) + { + span <<= 1; + ++k; + } + EXPECT_EQ(mod::shift_budget, k); + EXPECT_EQ(mod::add_budget, 255u - mod::resume_bound); + EXPECT_LE((mod::resume_bound + 1u) * (1u << k) - 1u, 255u); + EXPECT_GT(span << 1, 256u); + + constexpr int n = static_cast(sizeof(Reg)); + for (unsigned base = 0; base < 256u; ++base) + { + alignas(32) unsigned char in[32]{}; + alignas(32) unsigned char out[32]{}; + for (int i = 0; i < n; ++i) + in[i] = static_cast((base + static_cast(i) * 13u) & 255u); + Reg x; + std::memcpy(&x, in, sizeof(Reg)); + + auto partial = mod::partial_reduce(x); + std::memcpy(out, &partial, sizeof(Reg)); + for (int i = 0; i < n; ++i) + { + const unsigned expect = mod::partial_reduce_byte(in[i]); + if (out[i] != expect || expect > mod::partial_bound || expect % M != in[i] % M) + { + ADD_FAILURE() << "partial M=" << M << " in=" << static_cast(in[i]) + << " got=" << static_cast(out[i]) << " expect=" << expect; + return; + } + } + + auto full = mod::full_reduce(x); + std::memcpy(out, &full, sizeof(Reg)); + for (int i = 0; i < n; ++i) + { + if (out[i] != in[i] % M) + { + ADD_FAILURE() << "full M=" << M << " in=" << static_cast(in[i]) + << " got=" << static_cast(out[i]); + return; + } + } + } +} + +template +void expect_accumulator() +{ + constexpr int n = static_cast(sizeof(Reg)); + dpf::bitmore_accumulator acc; + scalar_acc slots[32]{}; + unsigned math[32]{}; + + for (int step = 0; step < 96; ++step) + { + alignas(32) unsigned char bytes[32]{}; + Reg packed; + if (step % 3 == 0) + { + for (int i = 0; i < n; ++i) + { + bytes[i] = static_cast(((step * 17 + i * 3) & 1u) | (i & 0xf0)); + slots[i].insert(bytes[i]); + math[i] = (math[i] * 2u + (bytes[i] & 1u)) % M; + } + std::memcpy(&packed, bytes, sizeof(Reg)); + acc.insert_bit(packed); + } + else if (step % 3 == 1) + { + for (int i = 0; i < n; ++i) + { + bytes[i] = static_cast((step + i) % M); + slots[i].add(bytes[i], M - 1u); + math[i] = (math[i] + bytes[i]) % M; + } + std::memcpy(&packed, bytes, sizeof(Reg)); + acc.add(packed, M - 1u); + } + else + { + for (int i = 0; i < n; ++i) + { + bytes[i] = static_cast(200u + (i & 15u)); + slots[i].add(bytes[i], 255u); + math[i] = (math[i] + bytes[i]) % M; + } + std::memcpy(&packed, bytes, sizeof(Reg)); + acc.add(packed, 255u); + } + + if (acc.bound() != slots[0].bound || acc.bound() > 255u) + { + ADD_FAILURE() << "bound M=" << M << " step=" << step + << " simd=" << acc.bound() << " scalar=" << slots[0].bound; + return; + } + + alignas(32) unsigned char raw[32]{}; + const auto value = acc.value(); + std::memcpy(raw, &value, sizeof(Reg)); + for (int i = 0; i < n; ++i) + { + if (raw[i] != slots[i].acc || raw[i] > acc.bound() || raw[i] % M != math[i]) + { + ADD_FAILURE() << "lane M=" << M << " step=" << step << " i=" << i + << " got=" << static_cast(raw[i]) + << " expect=" << slots[i].acc + << " math=" << math[i] << " bound=" << acc.bound(); + return; + } + } + } + + alignas(32) unsigned char red[32]{}; + const auto reduced = acc.reduced(); + std::memcpy(red, &reduced, sizeof(Reg)); + for (int i = 0; i < n; ++i) + { + if (red[i] != math[i]) + { + ADD_FAILURE() << "reduced M=" << M << " i=" << i + << " got=" << static_cast(red[i]) + << " expect=" << math[i]; + return; + } + } +} + +template +void expect_all() +{ + expect_bytes(); + expect_bytes(); + if constexpr (M <= 128u) + { + expect_accumulator(); + expect_accumulator(); + } + if constexpr (M < 255u) + expect_all(); +} + +} // namespace + +template +void expect_epi16_slots() +{ + using mod = dpf::bitmore_mod; + constexpr int lanes = static_cast(sizeof(Reg) / 2u); + unsigned span = mod::resume_bound + 1u; + unsigned k = 0; + const unsigned half = (mod::slot_max + 1u) >> 1; + while (span <= half) + { + span *= 2u; + ++k; + } + EXPECT_EQ(mod::shift_budget, k); + EXPECT_EQ(mod::add_budget, mod::slot_max - mod::resume_bound); + + for (unsigned base = 0; base < 65536u; base += static_cast(lanes)) + { + alignas(32) std::uint16_t in[16]{}; + alignas(32) std::uint16_t out[16]{}; + for (int i = 0; i < lanes; ++i) + in[i] = static_cast(base + static_cast(i)); + Reg x; + std::memcpy(&x, in, sizeof(Reg)); + auto partial = mod::partial_reduce(x); + std::memcpy(out, &partial, sizeof(Reg)); + for (int i = 0; i < lanes; ++i) + { + const unsigned expect = mod::partial_reduce_slot(in[i]); + if (out[i] != expect || expect > mod::partial_bound || expect % M != in[i] % M) + { + ADD_FAILURE() << "partial16 M=" << M << " in=" << in[i] + << " got=" << out[i] << " expect=" << expect; + return; + } + } + auto full = mod::full_reduce(x); + std::memcpy(out, &full, sizeof(Reg)); + for (int i = 0; i < lanes; ++i) + { + if (out[i] != in[i] % M) + { + ADD_FAILURE() << "full16 M=" << M << " in=" << in[i] << " got=" << out[i]; + return; + } + } + } +} + +template +void expect_epi16_accumulator() +{ + constexpr int lanes = static_cast(sizeof(Reg) / 2u); + dpf::bitmore_accumulator acc; + scalar_acc slots[16]{}; + unsigned math[16]{}; + + for (int step = 0; step < 64; ++step) + { + alignas(32) std::uint16_t words[16]{}; + Reg packed; + if (step % 3 == 0) + { + for (int i = 0; i < lanes; ++i) + { + words[i] = static_cast(((step * 17 + i * 3) & 1) | ((i * 0x1111) & 0xfff0)); + slots[i].insert(words[i]); + math[i] = (math[i] * 2u + (words[i] & 1u)) % M; + } + std::memcpy(&packed, words, sizeof(Reg)); + acc.insert_bit(packed); + } + else if (step % 3 == 1) + { + for (int i = 0; i < lanes; ++i) + { + words[i] = static_cast((step * 100 + i * 17) % M); + slots[i].add(words[i], M - 1u); + math[i] = (math[i] + words[i]) % M; + } + std::memcpy(&packed, words, sizeof(Reg)); + acc.add(packed, M - 1u); + } + else + { + for (int i = 0; i < lanes; ++i) + { + words[i] = static_cast(40000u + static_cast(i) * 97u); + slots[i].add(words[i], 65535u); + math[i] = (math[i] + words[i]) % M; + } + std::memcpy(&packed, words, sizeof(Reg)); + acc.add(packed, 65535u); + } + + if (acc.bound() != slots[0].bound || acc.bound() > 65535u) + { + ADD_FAILURE() << "bound16 M=" << M << " step=" << step + << " simd=" << acc.bound() << " scalar=" << slots[0].bound; + return; + } + + alignas(32) std::uint16_t raw[16]{}; + const auto value = acc.value(); + std::memcpy(raw, &value, sizeof(Reg)); + for (int i = 0; i < lanes; ++i) + { + if (raw[i] != slots[i].acc || raw[i] > acc.bound() || raw[i] % M != math[i]) + { + ADD_FAILURE() << "lane16 M=" << M << " step=" << step << " i=" << i + << " got=" << raw[i] << " expect=" << slots[i].acc + << " math=" << math[i] << " bound=" << acc.bound(); + return; + } + } + } + + alignas(32) std::uint16_t red[16]{}; + const auto reduced = acc.reduced(); + std::memcpy(red, &reduced, sizeof(Reg)); + for (int i = 0; i < lanes; ++i) + { + if (red[i] != math[i]) + { + ADD_FAILURE() << "reduced16 M=" << M << " i=" << i + << " got=" << red[i] << " expect=" << math[i]; + return; + } + } +} + +template +void expect_wide() +{ + expect_epi16_slots(); + expect_epi16_slots(); + if constexpr (M <= 32768u) + { + expect_epi16_accumulator(); + expect_epi16_accumulator(); + } +} + +TEST(BitmoreMod, BytesAndBudget) +{ + expect_all<2>(); +} + +TEST(BitmoreMod, Epi16) +{ + expect_wide<2>(); + expect_wide<3>(); + expect_wide<15>(); + expect_wide<127>(); + expect_wide<128>(); + expect_wide<255>(); + expect_wide<256>(); + expect_wide<257>(); + expect_wide<4095>(); + expect_wide<4096>(); + expect_wide<4097>(); + expect_wide<16384>(); + expect_wide<16385>(); + expect_wide<32765>(); + expect_wide<32767>(); + expect_wide<32768>(); + expect_wide<32769>(); + expect_wide<40000>(); + expect_wide<61440>(); + expect_wide<65535>(); +} diff --git a/test/tests/blob_leaf_test.cpp b/test/tests/blob_leaf_test.cpp new file mode 100644 index 0000000..67d3d9b --- /dev/null +++ b/test/tests/blob_leaf_test.cpp @@ -0,0 +1,109 @@ +#include + +#include +#include +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +template +dpf::blob make_blob_pattern(unsigned char seed) +{ + dpf::blob b{}; + for (std::size_t i = 0; i < N; ++i) + b.bytes[i] = static_cast(seed + static_cast(i)); + return b; +} + +template +void expect_point_opens(InputT alpha, const dpf::blob & beta) +{ + auto [k0, k1] = dpf::make_dpf(alpha, beta); + auto open = [&](InputT x) { + return dpf::reconstruct(*dpf::eval_point(k0, x), + *dpf::eval_point(k1, x)); + }; + + const auto s0 = *dpf::eval_point(k0, alpha); + const auto s1 = *dpf::eval_point(k1, alpha); + EXPECT_EQ(dpf::reconstruct(s0, s1), beta); + EXPECT_EQ(open(alpha), beta); + + const dpf::blob zero{}; + const std::vector offs = { + InputT{0}, + InputT{1}, + static_cast(alpha + 1), + static_cast(alpha ^ InputT{1}), + }; + for (InputT x : offs) + { + if (x == alpha) + continue; + EXPECT_EQ(open(x), zero) << "off-point"; + } +} + +} // namespace + +TEST(BlobLeaf, PointEvalUint32VariousN) +{ + const std::uint32_t alpha = 0x00ab12cdu; + expect_point_opens<1>(alpha, make_blob_pattern<1>(0x11)); + expect_point_opens<16>(alpha, make_blob_pattern<16>(0x22)); + expect_point_opens<100>(alpha, make_blob_pattern<100>(0x33)); + expect_point_opens<1000>(alpha, make_blob_pattern<1000>(0x44)); +} + +TEST(BlobLeaf, PointEvalUint128) +{ + using input_t = simde_uint128; + const input_t alpha = (input_t{1} << 100) | input_t{0x55aau}; + expect_point_opens<16>(alpha, make_blob_pattern<16>(0x7a)); + expect_point_opens<100>(alpha, make_blob_pattern<100>(0x8b)); +} + +TEST(BlobLeaf, FullDomainMatchesPointShareForShare) +{ + using input_t = std::uint8_t; + using blob_t = dpf::blob<100>; + const input_t alpha = 17; + const blob_t beta = make_blob_pattern<100>(0x9c); + + auto [k0, k1] = dpf::make_dpf(alpha, beta); + auto full0 = dpf::eval_full(k0); + auto full1 = dpf::eval_full(k1); + auto & it0 = full0.second; + auto & it1 = full1.second; + + auto a = std::begin(it0); + auto b = std::begin(it1); + for (std::size_t i = 0; a != std::end(it0) && b != std::end(it1); + ++a, ++b, ++i) + { + const auto p0 = *dpf::eval_point(k0, static_cast(i)); + const auto p1 = *dpf::eval_point(k1, static_cast(i)); + EXPECT_EQ(dpf::reconstruct(*a, *b), dpf::reconstruct(p0, p1)) << i; + EXPECT_EQ(dpf::detail_walk::group_value(*a), + dpf::detail_walk::group_value(p0)) << "party0 @" << i; + EXPECT_EQ(dpf::detail_walk::group_value(*b), + dpf::detail_walk::group_value(p1)) << "party1 @" << i; + } + EXPECT_EQ(std::size_t(std::distance(std::begin(it0), std::end(it0))), 256u); +} + +TEST(BlobLeaf, Domain128FullEvalThrows) +{ + using input_t = simde_uint128; + using blob_t = dpf::blob<16>; + const input_t alpha = input_t{1} << 90; + const blob_t beta = make_blob_pattern<16>(1); + auto [k0, k1] = dpf::make_dpf(alpha, beta); + (void)k1; + EXPECT_THROW((void)dpf::eval_full(k0), std::exception); +} diff --git a/test/tests/blocked_dcf_test.cpp b/test/tests/blocked_dcf_test.cpp index 91929ae..ad64a69 100644 --- a/test/tests/blocked_dcf_test.cpp +++ b/test/tests/blocked_dcf_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "dpf.hpp" #include "dpf/blocked_dcf.hpp" @@ -422,14 +423,18 @@ TEST(BlockedDcf, WideCheckpointFrontierMatchesDense) TEST(BlockedDcf, PathRecipesStayOnThePerLevelChannel) { const uint8_t alpha = 0x3C; - EXPECT_THROW(dpf::make_dpf(alpha, dpf::block_width<4>(dpf::lcp(uint64_t{1}))), + EXPECT_THROW( + dpf::make_dpf(alpha, dpf::block_width<4>(dpf::lcp(uint64_t{1}))), std::invalid_argument); - EXPECT_THROW(dpf::make_dpf(alpha, dpf::block_width<4>(dpf::break_bit(uint64_t{3}))), + EXPECT_THROW( + dpf::make_dpf(alpha, dpf::block_width<4>(dpf::break_bit(uint64_t{3}))), std::invalid_argument); - EXPECT_THROW(dpf::make_dpf(alpha, + EXPECT_THROW( + dpf::make_dpf(alpha, dpf::block_width<4>(dpf::prefix_with_length<4>(uint64_t{1}))), std::invalid_argument); - EXPECT_THROW(dpf::make_dpf(alpha, dpf::block_width<2>(dpf::path_paint( + EXPECT_THROW( + dpf::make_dpf(alpha, dpf::block_width<2>(dpf::path_paint( [](std::size_t matched, uint64_t, bool) { return static_cast(matched); }))), @@ -459,32 +464,34 @@ TEST(BlockedDcf, GrottoPrefixSegmentAndHorner) const uint16_t center = 30; auto mat = grotto::make_offset_horner_keys(center); - uint64_t payload[2]; - payload[0] = 1; - payload[1] = center; - using bare_pair = decltype(dpf::make_dpf(center, dpf::gt(uint64_t{0}))); - using pair = decltype(dpf::make_dpf(center, - dpf::block_width<4>(dpf::gt(uint64_t{0})))); - std::vector bare_keys{ - dpf::make_dpf(center, dpf::gt(payload[0])), - dpf::make_dpf(center, dpf::gt(payload[1]))}; - std::vector keys{ - dpf::make_dpf(center, dpf::block_width<4>(dpf::gt(payload[0]))), - dpf::make_dpf(center, dpf::block_width<4>(dpf::gt(payload[1])))}; std::vector knots{0, 10, 40}; std::vector> coeff{ {1, 0}, {2, 3}, {4, 1}}; const uint16_t eta = 0; - const auto b0s = grotto::offset_horner_coefficient_share<0, 1>( - bare_keys, mat.wrap_share, knots, coeff, eta); - const auto b1s = grotto::offset_horner_coefficient_share<1, 1>( - bare_keys, mat.wrap_share, knots, coeff, eta); - const auto c0 = grotto::offset_horner_coefficient_share<0, 1>( - keys, mat.wrap_share, knots, coeff, eta); - const auto c1 = grotto::offset_horner_coefficient_share<1, 1>( - keys, mat.wrap_share, knots, coeff, eta); - for (std::size_t m = 0; m < 2; ++m) - EXPECT_EQ(b0s[m] + b1s[m], c0[m] + c1[m]); + const auto p0 = grotto::offset_horner_eval<0, 1>(mat, knots, coeff, eta); + const auto p1 = grotto::offset_horner_eval<1, 1>(mat, knots, coeff, eta); + EXPECT_EQ(p0 + p1, grotto::offset_horner_clear<1>(center, knots, coeff, eta)); +} + +TEST(BlockedDcf, VerifiableUint8DomainMatchesThePredicate) +{ + const uint8_t alpha = 0x2a; + auto [k0, k1] = dpf::make_dpf(alpha, + dpf::block_width<4>(dpf::lt(uint64_t{1})), dpf::verifiable{}); + for (int x = 0; x < 256; ++x) + { + const auto q = static_cast(x); + dpf::proof_token a{}, b{}; + const uint64_t got = recon(dpf::eval_point(dpf::cmp, k0, q, dpf::prove(a)), + dpf::eval_point(dpf::cmp, k1, q, dpf::prove(b))) + & k0.cmp().mask; + EXPECT_EQ(got, q < alpha ? 1u : 0u) << x; + EXPECT_TRUE(dpf::verify(a, b)) << x; + const uint64_t swapped = recon(dpf::eval_point(dpf::cmp, k1, q), + dpf::eval_point(dpf::cmp, k0, q)) + & k0.cmp().mask; + EXPECT_EQ(swapped, got) << x; + } } diff --git a/test/tests/caller_fold_test.cpp b/test/tests/caller_fold_test.cpp new file mode 100644 index 0000000..e512bbb --- /dev/null +++ b/test/tests/caller_fold_test.cpp @@ -0,0 +1,128 @@ +#include + +#include +#include + +#include "dpf.hpp" + +namespace +{ + +using input_t = std::uint8_t; // 256-point domain +constexpr std::size_t kDomain = 256; + +} // namespace + +// eval_full_add_into(buf, key, fold): the fold sees every written share once, +// in the same pass that adds it into the buffer (Express / Prio audit hook). +TEST(CallerFold, FullAddIntoFoldSeesEveryShare) +{ + const input_t alpha = 42; + const std::uint64_t beta = 0xdeadbeefull; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + + std::vector buf0(kDomain, 0), buf1(kDomain, 0); + std::uint64_t fold0 = 0, fold1 = 0; + std::size_t calls0 = 0, calls1 = 0; + + dpf::eval_full_add_into(buf0, k0, + [&](std::size_t, std::uint64_t g) { fold0 += g; ++calls0; }); + dpf::eval_full_add_into(buf1, k1, + [&](std::size_t, std::uint64_t g) { fold1 += g; ++calls1; }); + + EXPECT_EQ(calls0, kDomain); + EXPECT_EQ(calls1, kDomain); + + // The buffer opens to a point function at alpha. + for (std::size_t i = 0; i < kDomain; ++i) + { + const std::uint64_t got = buf0[i] - buf1[i]; + EXPECT_EQ(got, i == alpha ? beta : 0ull) << "i=" << i; + } + // The fold accumulated exactly the same shares: sum reconstructs to beta. + EXPECT_EQ(static_cast(fold0 - fold1), beta); +} + +// eval_full_fold allocates its own buffer and folds each share. +TEST(CallerFold, FullFoldReconstructsAudit) +{ + const input_t alpha = 200; + const std::uint64_t beta = 7; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + + // Weighted fold: sum_i (i+1) * share_i. Reconstructs to (alpha+1)*beta. + std::uint64_t w0 = 0, w1 = 0; + (void)dpf::eval_full_fold(k0, + [&](std::size_t i, std::uint64_t g) { w0 += (i + 1) * g; }); + (void)dpf::eval_full_fold(k1, + [&](std::size_t i, std::uint64_t g) { w1 += (i + 1) * g; }); + + EXPECT_EQ(static_cast(w0 - w1), + static_cast((alpha + 1) * beta)); +} + +// eval_point_fold calls the fold exactly once with the written share. +TEST(CallerFold, PointFoldCalledOnce) +{ + const input_t alpha = 5; + const std::uint64_t beta = 99; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + + std::uint64_t seen0 = 0, seen1 = 0; + int calls0 = 0, calls1 = 0; + auto o0 = dpf::eval_point_fold(k0, alpha, + [&](std::size_t, std::uint64_t g) { seen0 = g; ++calls0; }); + auto o1 = dpf::eval_point_fold(k1, alpha, + [&](std::size_t, std::uint64_t g) { seen1 = g; ++calls1; }); + + EXPECT_EQ(calls0, 1); + EXPECT_EQ(calls1, 1); + // What the fold saw equals what eval_point returned. + EXPECT_EQ(seen0, static_cast((*o0).raw())); + EXPECT_EQ(seen1, static_cast((*o1).raw())); + EXPECT_EQ(static_cast(seen0 - seen1), beta); +} + +// The fold is generic over the leaf group: a blob row folds by XOR. +TEST(CallerFold, FoldOverBlobLeaf) +{ + using blob_t = dpf::blob<24>; + const input_t alpha = 17; + blob_t beta{}; + for (std::size_t i = 0; i < blob_t::size; ++i) + beta.bytes[i] = static_cast(0x30 + i); + + auto [k0, k1] = dpf::make_dpf(alpha, beta); + std::vector buf0(kDomain), buf1(kDomain); + + blob_t x0{}, x1{}; + std::size_t calls = 0; + dpf::eval_full_add_into(buf0, k0, + [&](std::size_t, const blob_t & g) { x0 = x0 ^ g; ++calls; }); + dpf::eval_full_add_into(buf1, k1, + [&](std::size_t, const blob_t & g) { x1 = x1 ^ g; }); + + EXPECT_EQ(calls, kDomain); + // XOR of all shares reconstructs to beta (only alpha is nonzero). + blob_t recon{}; + for (std::size_t i = 0; i < blob_t::size; ++i) + recon.bytes[i] = static_cast(x0.bytes[i] ^ x1.bytes[i]); + EXPECT_EQ(recon, beta); +} + +// eval_sequence_xor: keyword PIR without materializing the bit vector. +TEST(CallerFold, SequenceXorMatchesRecordAtAlpha) +{ + const input_t alpha = 123; + // Point function with a bit payload (1 at alpha). + auto [k0, k1] = dpf::make_dpf(alpha, dpf::bit::one); + + std::vector records(kDomain); + for (std::size_t i = 0; i < kDomain; ++i) + records[i] = 0x1000ull * (i + 1) + 7; + + const std::uint64_t acc0 = dpf::eval_sequence_xor(k0, records); + const std::uint64_t acc1 = dpf::eval_sequence_xor(k1, records); + + EXPECT_EQ(acc0 ^ acc1, records[alpha]); +} diff --git a/test/tests/carry_test.cpp b/test/tests/carry_test.cpp new file mode 100644 index 0000000..a67c368 --- /dev/null +++ b/test/tests/carry_test.cpp @@ -0,0 +1,597 @@ +#include +#include + +#include +#include +#include + +#include "dpf.hpp" +#include "grotto/carry_plan.hpp" +#include "grotto/carry.hpp" +#include "grotto/prefix_parity.hpp" + +using grotto::carry_mode; +using grotto::sign_knowledge; + +TEST(CarryPlan, TruncateReduceOnlyLowLt) +{ + const auto r = grotto::plan_carry_in(8, 3); + EXPECT_TRUE(r.use_low_lt); + EXPECT_FALSE(r.use_msb_lt); + EXPECT_FALSE(r.use_share_msb_and); + EXPECT_FALSE(r.use_biased_wrap); + EXPECT_EQ(r.out_n, 5u); +} + +TEST(CarryPlan, SameRingKnownSignIsAnd) +{ + const auto pos = grotto::plan_carry_out(8, 2, sign_knowledge::nonnegative); + EXPECT_TRUE(pos.use_share_msb_and); + EXPECT_FALSE(pos.and_is_nor); + EXPECT_FALSE(pos.use_msb_lt); + EXPECT_EQ(pos.and_unit, std::int64_t{1} << 6); + + const auto neg = grotto::plan_carry_out(8, 2, sign_knowledge::negative); + EXPECT_TRUE(neg.use_share_msb_and); + EXPECT_TRUE(neg.and_is_nor); + EXPECT_EQ(neg.and_unit, -(std::int64_t{1} << 6)); +} + +TEST(CarryPlan, SameRingSecretSignNeedsBoth) +{ + const auto r = grotto::plan_carry_out(8, 2, sign_knowledge::unknown); + EXPECT_TRUE(r.use_msb_lt); + EXPECT_TRUE(r.use_share_msb_and); +} + +TEST(CarryPlan, FusedReducedRingDropsSign) +{ + const auto r = grotto::plan_carry_fused(8, 3, 5, sign_knowledge::unknown); + EXPECT_TRUE(r.use_low_lt); + EXPECT_FALSE(r.use_msb_lt); + EXPECT_FALSE(r.use_share_msb_and); +} + +TEST(CarryPlan, ExtendIsBiasedWrap) +{ + const auto r = grotto::plan_carry(grotto::carry_request{ + 8, 0, 16, carry_mode::extend, sign_knowledge::nonnegative}); + EXPECT_TRUE(r.use_biased_wrap); + EXPECT_FALSE(r.use_share_msb_and); + EXPECT_EQ(r.wrap_payload, std::int64_t{1} << 8); +} + +TEST(CarryPlan, WindowPublicCarryZeroDropsEq) +{ + grotto::carry_request req{}; + req.n = 16; + req.s = 4; + req.out_n = 4; + req.mode = carry_mode::window; + req.incoming_carry_public = true; + req.incoming_carry_value = 0; + const auto r = grotto::plan_carry(req); + EXPECT_TRUE(r.use_window_overflow); + EXPECT_FALSE(r.use_window_eq); + EXPECT_FALSE(r.use_window_product); +} + +TEST(CarryPlan, WindowSecretCarryNeedsProduct) +{ + grotto::carry_request req{}; + req.n = 16; + req.s = 4; + req.out_n = 4; + req.mode = carry_mode::window; + req.incoming_carry_public = false; + const auto r = grotto::plan_carry(req); + EXPECT_TRUE(r.use_window_overflow); + EXPECT_TRUE(r.use_window_eq); + EXPECT_TRUE(r.use_window_product); +} + +TEST(CarryClear, TruncateReduceMatchesHighPlusCarry) +{ + for (std::uint64_t x0 = 0; x0 < 64; ++x0) + { + for (std::uint64_t x1 = 0; x1 < 64; ++x1) + { + const auto got = grotto::carry_in_clear(x0, x1, 6, 2); + const auto x = (x0 + x1) & 63u; + EXPECT_EQ(got, x >> 2); + } + } +} + +TEST(CarryClear, CarryOutKnownLeavesOnlySmallResidual) +{ + constexpr unsigned n = 6; + constexpr unsigned s = 2; + std::size_t big = 0; + for (std::uint64_t x0 = 0; x0 < (1u << n); ++x0) + { + for (std::uint64_t x1 = 0; x1 < (1u << n); ++x1) + { + const auto x = (x0 + x1) & grotto::carry_mask(n); + const auto true_asr = grotto::carry_asr(x, n, s); + const auto fixed = grotto::carry_out_clear(x0, x1, n, s, + sign_knowledge::nonnegative); + // Known nonnegative assumes msb(x)==0; skip negatives. + if ((x >> (n - 1)) & 1u) + continue; + std::int64_t d = static_cast(true_asr) + - static_cast(fixed); + if (d > 32) + d -= 64; + if (d < -32) + d += 64; + if (std::abs(d) > 1) + ++big; + EXPECT_LE(std::abs(d), 1); + } + } + EXPECT_EQ(big, 0u); +} + +TEST(CarryClear, AndDisagreesWithExtensionWrap) +{ + // 4-bit shares: share-MSB AND is not the extension wrap bit. + std::size_t mismatch = 0; + for (std::uint64_t x0 = 0; x0 < 16; ++x0) + { + for (std::uint64_t x1 = 0; x1 < 16; ++x1) + { + const auto wrap = ((x0 + x1) >= 16u) ? 1u : 0u; + const auto s0 = (x0 >> 3) & 1u; + const auto s1 = (x1 >> 3) & 1u; + const auto x = (x0 + x1) & 15u; + const auto m = (x >> 3) & 1u; + const auto grotto = (m == 0) ? (s0 & s1) : ((1u - s0) & (1u - s1)); + if (grotto != wrap) + ++mismatch; + } + } + EXPECT_EQ(mismatch, 112u); +} + +TEST(CarryClear, ExtendPreservesSignedValue) +{ + EXPECT_EQ(grotto::carry_extend_clear(0x05, 0x00, 8, 16), 0x0005u); + EXPECT_EQ(grotto::carry_extend_clear(0x80, 0x00, 8, 16), 0xff80u); + // 0x7f + 0x01 = 0x80 in 8 bits, which is negative and sign-extends. + EXPECT_EQ(grotto::carry_extend_clear(0x7f, 0x01, 8, 16), 0xff80u); + EXPECT_EQ(grotto::carry_extend_clear(0x40, 0x01, 8, 16), 0x0041u); +} + +TEST(CarryClear, WindowOutgoingCarry) +{ + const auto w = grotto::carry_window_clear(0x0f, 0x01, 4, 0); + EXPECT_EQ(w.digit, 0u); + EXPECT_EQ(w.carry_out, 1u); + const auto w2 = grotto::carry_window_clear(0x0e, 0x00, 4, 1); + EXPECT_EQ(w2.digit, 0x0fu); + EXPECT_EQ(w2.carry_out, 0u); + const auto w3 = grotto::carry_window_clear(0x0f, 0x00, 4, 1); + EXPECT_EQ(w3.digit, 0u); + EXPECT_EQ(w3.carry_out, 1u); +} + +TEST(CarryClear, FusedMatchesAsr) +{ + for (std::uint64_t x0 = 0; x0 < 64; ++x0) + for (std::uint64_t x1 = 0; x1 < 64; ++x1) + EXPECT_EQ(grotto::carry_fused_clear(x0, x1, 6, 2), + grotto::carry_asr((x0 + x1) & 63u, 6, 2)); +} + +TEST(CarryKeys, TruncateReduceOnline) +{ + auto keys = grotto::make_carry_in_keys(8, 3); + for (int trial = 0; trial < 32; ++trial) + { + const std::uint64_t x0 = dpf::uniform_sample(); + const std::uint64_t x1 = dpf::uniform_sample(); + const std::uint64_t x = (x0 + x1) & 0xffu; + const std::uint64_t opened = (x + keys.rin) & 0xffu; + dpf::proof_token pi0{}, pi1{}; + const auto y0 = grotto::eval_carry_in(keys, 0, opened); + const auto y1 = grotto::eval_carry_in(keys, 1, opened); + const auto got = (y0.value + y1.value) & 0x1fu; + EXPECT_EQ(got, grotto::carry_in_clear(x0, x1, 8, 3)); + (void)pi0; + (void)pi1; + } +} + +TEST(CarryKeys, TruncateReduceVerifiableProof) +{ + grotto::carry_auth auth{}; + auth.verifiable = true; + auto keys = grotto::make_carry_in_keys(8, 3, auth); + const std::uint64_t x0 = 0x11; + const std::uint64_t x1 = 0x22; + const std::uint64_t opened = ((x0 + x1) + keys.rin) & 0xffu; + dpf::proof_token pi0{}, pi1{}; + const auto y0 = grotto::eval_carry_in(keys, 0, opened, &pi0); + const auto y1 = grotto::eval_carry_in(keys, 1, opened, &pi1); + EXPECT_EQ((y0.value + y1.value) & 0x1fu, grotto::carry_in_clear(x0, x1, 8, 3)); + EXPECT_TRUE(dpf::verify(pi0, pi1)); + + // Flip every correction seed so some on-path level mixes the tamper. + for (auto & cs : const_castfirst)>::correction_seeds_array &>( + keys.low_lt_v->first.correction_seeds())) + { + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); + } + dpf::proof_token q0{}, q1{}; + auto ignore0 = grotto::eval_carry_in(keys, 0, opened, &q0); + auto ignore1 = grotto::eval_carry_in(keys, 1, opened, &q1); + (void)ignore0; + (void)ignore1; + EXPECT_FALSE(dpf::verify(q0, q1)); +} + +TEST(CarryKeys, ProveCarryKeysBatch) +{ + grotto::carry_auth auth{}; + auth.verifiable = true; + auto keys = grotto::make_carry_in_keys(8, 3, auth); + const std::uint64_t opened = 0x3cu; + dpf::proof_token t0[4]{}, t1[4]{}; + const auto n0 = grotto::prove_carry_keys(keys, 0, opened, t0, 4); + const auto n1 = grotto::prove_carry_keys(keys, 1, opened, t1, 4); + EXPECT_EQ(n0, n1); + EXPECT_GE(n0, 1u); + EXPECT_TRUE(dpf::verify_batch( + std::vector(t0, t0 + n0), + std::vector(t1, t1 + n1))); +} + +TEST(CarryKeys, OutputMacDetectsFlip) +{ + grotto::carry_auth auth{}; + auth.verifiable = true; + auth.output_mac = true; + auto keys = grotto::make_carry_in_keys(8, 3, auth); + ASSERT_TRUE(keys.has_mac); + const std::uint64_t opened = 0x3cu; + dpf::proof_token t0[4]{}, t1[4]{}; + const auto n0 = grotto::prove_carry_keys(keys, 0, opened, t0, 4); + const auto n1 = grotto::prove_carry_keys(keys, 1, opened, t1, 4); + ASSERT_EQ(n0, n1); + ASSERT_GE(n0, 1u); + const std::uint64_t y0 = 3; + const std::uint64_t y1 = 4; + auto [m0, m1] = grotto::mac_carry_result(keys, y0, y1); + EXPECT_TRUE(dpf::mac_verify(m0, m1, keys.mac, t0[0], t1[0])); + EXPECT_FALSE(dpf::mac_verify(m0, m1, keys.mac, dpf::detail::vdpf::zero_proof(), + t1[0])); + m0.value ^= 1u; + EXPECT_FALSE(dpf::mac_verify(m0, m1, keys.mac, t0[0], t1[0])); +} + +TEST(CarryCmp, VerifiableComparisonPathProof) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{10}, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + dpf::proof_token pi0{}, pi1{}; + const auto y0 = dpf::eval_point(dpf::cmp, k0, Input{3}, dpf::prove(pi0)); + const auto y1 = dpf::eval_point(dpf::cmp, k1, Input{3}, dpf::prove(pi1)); + EXPECT_EQ(dpf::reconstruct(y0, y1) & 1u, 1u); + EXPECT_TRUE(dpf::verify(pi0, pi1)); + + for (auto & cs : const_cast::correction_seeds_array &>( + k0.correction_seeds())) + { + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(0x5a)); + } + dpf::proof_token q0{}, q1{}; + dpf::eval_point(dpf::cmp, k0, Input{3}, dpf::prove(q0)); + dpf::eval_point(dpf::cmp, k1, Input{3}, dpf::prove(q1)); + EXPECT_FALSE(dpf::verify(q0, q1)); +} + +TEST(OutputMac, BatchVerify) +{ + auto key = dpf::sample_mac_key(); + std::vector> left, right; + std::vector coeffs; + for (std::uint64_t i = 0; i < 4; ++i) + { + auto [a, b] = dpf::mac_share_value(i * 3u + 1u, key); + left.push_back(a); + right.push_back(b); + coeffs.push_back(i + 1u); + } + EXPECT_TRUE(dpf::mac_verify_batch(left, right, coeffs, key)); + left[1].tag ^= 1u; + EXPECT_FALSE(dpf::mac_verify_batch(left, right, coeffs, key)); +} + +TEST(CarryKeys, KnownSignCarryOutOnlineMatchesClear) +{ + constexpr unsigned n = 8; + constexpr unsigned s = 3; + auto keys = grotto::make_carry_out_keys(n, s, sign_knowledge::nonnegative); + ASSERT_TRUE(keys.has_and_beaver); + ASSERT_TRUE(keys.recipe.use_share_msb_and); + + std::size_t checked = 0; + for (std::uint64_t x0 = 0; x0 < 256; x0 += 17) + { + for (std::uint64_t x1 = 0; x1 < 256; x1 += 19) + { + const std::uint64_t x = (x0 + x1) & 0xffu; + if ((x >> (n - 1)) & 1u) + continue; // nonnegative assumption + const std::uint64_t s0 = (x0 >> (n - 1)) & 1u; + const std::uint64_t s1 = (x1 >> (n - 1)) & 1u; + const auto y0 = grotto::eval_carry_out_known(keys, 0, x0, s0, s1); + const auto y1 = grotto::eval_carry_out_known(keys, 1, x1, s1, s0); + const auto got = (y0.value + y1.value) & 0xffu; + const auto expect = grotto::carry_out_clear(x0, x1, n, s, + sign_knowledge::nonnegative); + EXPECT_EQ(got, expect) << "x0=" << x0 << " x1=" << x1; + ++checked; + } + } + EXPECT_GT(checked, 50u); +} + +TEST(CarryKeys, NegativeSignCarryOutOnlineMatchesClear) +{ + constexpr unsigned n = 8; + constexpr unsigned s = 3; + auto keys = grotto::make_carry_out_keys(n, s, sign_knowledge::negative); + ASSERT_TRUE(keys.recipe.and_is_nor); + + std::size_t checked = 0; + for (std::uint64_t x0 = 0; x0 < 256; x0 += 17) + { + for (std::uint64_t x1 = 0; x1 < 256; x1 += 19) + { + const std::uint64_t x = (x0 + x1) & 0xffu; + if (((x >> (n - 1)) & 1u) == 0u) + continue; // negative assumption + const std::uint64_t s0 = (x0 >> (n - 1)) & 1u; + const std::uint64_t s1 = (x1 >> (n - 1)) & 1u; + const auto y0 = grotto::eval_carry_out_known(keys, 0, x0, s0, s1); + const auto y1 = grotto::eval_carry_out_known(keys, 1, x1, s1, s0); + const auto got = (y0.value + y1.value) & 0xffu; + const auto expect = grotto::carry_out_clear(x0, x1, n, s, + sign_knowledge::negative); + EXPECT_EQ(got, expect) << "x0=" << x0 << " x1=" << x1; + ++checked; + } + } + EXPECT_GT(checked, 50u); +} + +TEST(CarryKeys, WindowSecretBuildsEqAndOverflow) +{ + grotto::carry_request req{}; + req.n = 16; + req.s = 4; + req.out_n = 4; + req.mode = carry_mode::window; + req.incoming_carry_public = false; + auto keys = grotto::make_carry_keys(req); + EXPECT_TRUE(keys.window_overflow.has_value() || keys.window_overflow_v.has_value()); + EXPECT_TRUE(keys.window_eq.has_value() || keys.window_eq_v.has_value()); + EXPECT_TRUE(keys.has_and_beaver); +} + +TEST(CarryKeys, WindowPublicZeroOmitsEq) +{ + grotto::carry_request req{}; + req.n = 16; + req.s = 4; + req.out_n = 4; + req.mode = carry_mode::window; + req.incoming_carry_public = true; + req.incoming_carry_value = 0; + auto keys = grotto::make_carry_keys(req); + EXPECT_TRUE(keys.window_overflow.has_value() || keys.window_overflow_v.has_value()); + EXPECT_FALSE(keys.window_eq.has_value()); + EXPECT_FALSE(keys.window_eq_v.has_value()); + EXPECT_FALSE(keys.has_and_beaver); +} + +TEST(CarryKeys, FusedSameRingPlansBothThenOnlineLowOnlyWhenReduced) +{ + auto reduced = grotto::make_carry_fused_keys(8, 3, 5); + EXPECT_TRUE(reduced.recipe.use_low_lt); + EXPECT_FALSE(reduced.recipe.use_share_msb_and); + EXPECT_TRUE(reduced.low_lt.has_value() || reduced.low_lt_v.has_value()); + + auto same = grotto::make_carry_fused_keys(8, 3, 8, sign_knowledge::nonnegative); + EXPECT_TRUE(same.recipe.use_low_lt); + EXPECT_TRUE(same.recipe.use_share_msb_and); + EXPECT_TRUE(same.has_and_beaver); +} + +TEST(PrefixParity, VerifiableTokensMatchAndTamperRejects) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x2a}, dpf::bit{1}, dpf::verifiable{}); + // Exclusive of alpha; include alpha itself (must reconstruct to 0). + const std::array ends{Input{0x10}, Input{0x2a}, Input{0x40}}; + + dpf::proof_token pi0{}, pi1{}; + auto [p0, n0] = grotto::prefix_parities(k0, ends, dpf::prove(pi0)); + auto [p1, n1] = grotto::prefix_parities(k1, ends, dpf::prove(pi1)); + (void)n0; + (void)n1; + for (std::size_t i = 0; i < ends.size(); ++i) + EXPECT_EQ(p0[i] ^ p1[i], ends[i] > Input{0x2a}); + EXPECT_TRUE(dpf::verify(pi0, pi1)); + + pi0[0] = simde_mm_xor_si128(pi0[0], simde_mm_set1_epi8(0x3c)); + EXPECT_FALSE(dpf::verify(pi0, pi1)); +} + +TEST(CarryClear, EvalCarryClearDispatchMatchesHelpers) +{ + const auto tr = grotto::plan_carry_in(8, 3); + EXPECT_EQ(grotto::eval_carry_clear(tr, 0xab, 0x11), + grotto::carry_in_clear(0xab, 0x11, 8, 3)); + + const auto ext = grotto::plan_carry(grotto::carry_request{ + 8, 0, 16, carry_mode::extend}); + EXPECT_EQ(grotto::eval_carry_clear(ext, 0x80, 0), + grotto::carry_extend_clear(0x80, 0, 8, 16)); + + const auto fuse = grotto::plan_carry_fused(8, 2, 8); + EXPECT_EQ(grotto::eval_carry_clear(fuse, 0x11, 0x22), + grotto::carry_fused_clear(0x11, 0x22, 8, 2)); +} + +TEST(CarryKeys, BeaverAndOfPrivateBitsIsOneWhenBothSet) +{ + // Direct check of the AND helper via known-sign path with unit=1, s=0 + // is awkward; instead use n=2,s=1 so unit=2 and check the product bit. + auto keys = grotto::make_carry_out_keys(4, 1, sign_knowledge::nonnegative); + // Both MSBs set: x0=0b1xxx, x1=0b1xxx with nonnegative sum. + // 0b1000 + 0b1000 = 0b0000 mod 16, msb of sum is 0 — OK for nonnegative. + const std::uint64_t x0 = 0b1000; + const std::uint64_t x1 = 0b1000; + const auto y0 = grotto::eval_carry_out_known(keys, 0, x0, 1, 1); + const auto y1 = grotto::eval_carry_out_known(keys, 1, x1, 1, 1); + const auto got = (y0.value + y1.value) & 0xfu; + const auto expect = grotto::carry_out_clear(x0, x1, 4, 1, + sign_knowledge::nonnegative); + EXPECT_EQ(got, expect); + // AND must be 1, so correction is +2^{3}=+8 on top of local ASRs. + const auto base = (grotto::carry_asr(x0, 4, 1) + grotto::carry_asr(x1, 4, 1)) & 0xfu; + EXPECT_EQ(got, (base + 8u) & 0xfu); +} + +TEST(CarryKeys, UnknownSignMatchesClear) +{ + constexpr unsigned n = 8; + constexpr unsigned s = 3; + auto keys = grotto::make_carry_out_keys(n, s, sign_knowledge::unknown); + ASSERT_TRUE(keys.recipe.use_msb_lt); + ASSERT_TRUE(keys.recipe.use_share_msb_and); + + std::size_t checked = 0; + for (std::uint64_t x0 = 0; x0 < 256; x0 += 17) + { + for (std::uint64_t x1 = 0; x1 < 256; x1 += 19) + { + const std::uint64_t x = (x0 + x1) & 0xffu; + const std::uint64_t msb_high = (x >> (n - 1)) & 1u; + const std::uint64_t s0 = (x0 >> (n - 1)) & 1u; + const std::uint64_t s1 = (x1 >> (n - 1)) & 1u; + const auto y0 = grotto::eval_carry_out_unknown(keys, 0, x0, s0, s1, msb_high); + const auto y1 = grotto::eval_carry_out_unknown(keys, 1, x1, s1, s0, msb_high); + const auto got = (y0.value + y1.value) & 0xffu; + const auto expect = grotto::carry_out_clear(x0, x1, n, s, + sign_knowledge::unknown); + EXPECT_EQ(got, expect) << "x0=" << x0 << " x1=" << x1; + ++checked; + } + } + EXPECT_GT(checked, 50u); +} + +TEST(CarryKeys, ExtendMatchesClear) +{ + auto keys = grotto::make_carry_keys(grotto::carry_request{ + 8, 0, 16, carry_mode::extend}); + ASSERT_TRUE(keys.recipe.use_biased_wrap); + for (std::uint64_t x0 = 0; x0 < 256; x0 += 13) + { + for (std::uint64_t x1 = 0; x1 < 256; x1 += 17) + { + const std::uint64_t x = (x0 + x1) & 0xffu; + const std::uint64_t msb_high = (x >> 7) & 1u; + const std::uint64_t opened = (x + keys.rin) & 0xffu; + const auto y0 = grotto::eval_carry_extend(keys, 0, opened, msb_high); + const auto y1 = grotto::eval_carry_extend(keys, 1, opened, msb_high); + const auto got = (y0.value + y1.value) & 0xffffu; + EXPECT_EQ(got, grotto::carry_extend_clear(x0, x1, 8, 16)) + << "x0=" << x0 << " x1=" << x1; + } + } +} + +TEST(CarryKeys, WindowPublicMatchesClear) +{ + grotto::carry_request req{}; + req.n = 16; + req.s = 4; + req.out_n = 4; + req.mode = carry_mode::window; + req.incoming_carry_public = true; + req.incoming_carry_value = 1; + auto keys = grotto::make_carry_keys(req); + for (std::uint64_t p0 = 0; p0 < 16; ++p0) + { + for (std::uint64_t p1 = 0; p1 < 16; ++p1) + { + const std::uint64_t sum = p0 + p1 + 1u; + const auto y0 = grotto::eval_carry_window(keys, 0, sum); + const auto y1 = grotto::eval_carry_window(keys, 1, sum); + const auto got = y0.value + y1.value; + const auto w = grotto::carry_window_clear(p0, p1, 4, 1); + EXPECT_EQ(got, (w.carry_out << 4) | w.digit); + } + } +} + +TEST(CarryKeys, FusedReducedMatchesTruncate) +{ + auto keys = grotto::make_carry_fused_keys(8, 3, 5); + ASSERT_TRUE(keys.recipe.use_low_lt); + ASSERT_FALSE(keys.recipe.use_share_msb_and); + for (int trial = 0; trial < 32; ++trial) + { + const std::uint64_t x0 = dpf::uniform_sample(); + const std::uint64_t x1 = dpf::uniform_sample(); + const std::uint64_t opened = ((x0 + x1) + keys.rin) & 0xffu; + const auto y0 = grotto::eval_carry_fused(keys, 0, opened, x0); + const auto y1 = grotto::eval_carry_fused(keys, 1, opened, x1); + const auto got = (y0.value + y1.value) & 0x1fu; + EXPECT_EQ(got, grotto::carry_in_clear(x0, x1, 8, 3)); + } +} + +TEST(CarryKeys, FusedSameRingKnownSignMatchesClear) +{ + constexpr unsigned n = 8; + constexpr unsigned s = 2; + auto keys = grotto::make_carry_fused_keys(n, s, n, sign_knowledge::nonnegative); + ASSERT_TRUE(keys.recipe.use_share_msb_and); + std::size_t checked = 0; + for (std::uint64_t x0 = 0; x0 < 256; x0 += 21) + { + for (std::uint64_t x1 = 0; x1 < 256; x1 += 23) + { + const std::uint64_t x = (x0 + x1) & 0xffu; + if ((x >> (n - 1)) & 1u) + continue; + const std::uint64_t s0 = (x0 >> (n - 1)) & 1u; + const std::uint64_t s1 = (x1 >> (n - 1)) & 1u; + const std::uint64_t opened = (x + keys.rin) & 0xffu; + const auto y0 = grotto::eval_carry_fused(keys, 0, opened, x0, s0, s1); + const auto y1 = grotto::eval_carry_fused(keys, 1, opened, x1, s1, s0); + const auto got = (y0.value + y1.value) & 0xffu; + EXPECT_EQ(got, grotto::carry_out_clear(x0, x1, n, s, + sign_knowledge::nonnegative)) + << "x0=" << x0 << " x1=" << x1; + ++checked; + } + } + EXPECT_GT(checked, 20u); +} + +TEST(CarryKeys, RecipeMakeCarryKeysFinalizesBlinds) +{ + const auto recipe = grotto::plan_carry_in(8, 3); + auto keys = grotto::make_carry_keys(recipe); + const std::uint64_t high = grotto::carry_mask(5); + const std::uint64_t y_hi = ((std::uint64_t{0} - keys.rin) >> 3) & high; + EXPECT_EQ((keys.rout0 + keys.rout1) & high, y_hi); +} diff --git a/test/tests/class_sweep_test.cpp b/test/tests/class_sweep_test.cpp new file mode 100644 index 0000000..ccd3159 --- /dev/null +++ b/test/tests/class_sweep_test.cpp @@ -0,0 +1,535 @@ +#include + +#include "dpf.hpp" +#include "grotto/offset_horner.hpp" +#include "grotto/lut_union.hpp" +#include "grotto/offset_jet.hpp" +#include "grotto/offset_repr.hpp" +#include "grotto/offset_twist.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + +template +struct has_member_alpha : std::false_type +{ }; +template +struct has_member_alpha().alpha)>> + : std::true_type +{ }; + +template +struct has_member_center : std::false_type +{ }; +template +struct has_member_center().center)>> + : std::true_type +{ }; + +template +struct has_member_beta : std::false_type +{ }; +template +struct has_member_beta().beta)>> + : std::true_type +{ }; + +template +struct has_both_dcf_halves : std::false_type +{ }; +template +struct has_both_dcf_halves().key_a), decltype(std::declval().key_b)>> + : std::true_type +{ }; + +bool tokens_equal(const dpf::proof_token & a, const dpf::proof_token & b) +{ + return std::memcmp(a.data(), b.data(), sizeof(dpf::proof_token)) == 0; +} + +void xor_first_byte(void * p) +{ + auto * bytes = static_cast(p); + bytes[0] = static_cast(bytes[0] ^ 0x1u); +} + +template +Out group_neg_one() +{ + return -Out{1}; +} + +template +void expect_point_near_modulus() +{ + const auto beta = group_neg_one(); + const std::uint8_t alpha = 0x2a; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + const Out on = dpf::reconstruct(*dpf::eval_point(k0, alpha), + *dpf::eval_point(k1, alpha)); + EXPECT_EQ(on, beta); + EXPECT_NE(on, Out{}); + const Out off = dpf::reconstruct(*dpf::eval_point(k0, std::uint8_t{0}), + *dpf::eval_point(k1, std::uint8_t{0})); + EXPECT_EQ(off, Out{}); +} + +template +void expect_comparison_keeps_negative_delta() +{ + const auto beta = group_neg_one(); + const std::uint8_t alpha = 10; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::lt(beta)); + const Out hot = dpf::reconstruct( + dpf::eval_point(dpf::cmp, k0, std::uint8_t{0}), + dpf::eval_point(dpf::cmp, k1, std::uint8_t{0})); + EXPECT_EQ(hot, beta); + EXPECT_NE(hot, Out{}); + const Out cold = dpf::reconstruct( + dpf::eval_point(dpf::cmp, k0, std::uint8_t{11}), + dpf::eval_point(dpf::cmp, k1, std::uint8_t{11})); + EXPECT_EQ(cold, Out{}); +} + +template +void expect_proof_binds_leaf_and_warm_path() +{ + const std::uint8_t alpha = 0x2a; + const Out beta = Out{9}; + auto [k0, k1] = dpf::make_dpf(alpha, beta, dpf::verifiable{}); + using key_t = std::decay_t; + + dpf::proof_token cold0{}; + dpf::proof_token cold1{}; + (void)*dpf::eval_point(k0, alpha, dpf::prove(cold0)); + (void)*dpf::eval_point(k1, alpha, dpf::prove(cold1)); + EXPECT_TRUE(dpf::verify(cold0, cold1)); + EXPECT_FALSE(dpf::verify(dpf::proof_token{}, dpf::proof_token{})); + + dpf::basic_path_memoizer memo; + (void)*dpf::eval_point(k0, alpha, memo); + dpf::proof_token warm{}; + (void)*dpf::eval_point(k0, alpha, dpf::prove(warm), memo); + EXPECT_TRUE(tokens_equal(warm, cold0)); + + auto & leaves = const_cast &>(k0.leaves()); + xor_first_byte(&std::get<0>(leaves).get()); + dpf::proof_token tampered{}; + (void)*dpf::eval_point(k0, alpha, dpf::prove(tampered), memo); + EXPECT_FALSE(dpf::verify(tampered, cold1)); + EXPECT_FALSE(tokens_equal(tampered, cold0)); +} + +template +void expect_from_seed_reads_past_first_word() +{ + unsigned char lo[16]{}; + unsigned char hi[16]{}; + hi[8] = 1; + EXPECT_NE(Seeded::from_seed(lo, sizeof(lo)), Seeded::from_seed(hi, sizeof(hi))); +} + +template +void expect_from_seed_reads_past_16_bytes() +{ + unsigned char lo[32]{}; + unsigned char hi[32]{}; + hi[24] = 1; + EXPECT_NE(Seeded::from_seed(lo, sizeof(lo)), Seeded::from_seed(hi, sizeof(hi))); +} + +bool scalar_below_order(const dpf::p256_scalar & s) +{ + for (int i = 3; i >= 0; --i) + { + const auto limb = s.limb(static_cast(i)); + const auto bound = dpf::p256_scalar::order[i]; + if (limb < bound) + return true; + if (limb > bound) + return false; + } + return false; +} + +struct IcPad +{ + simde__m128i block() { return dpf::uniform_sample(); } + std::uint8_t bit() { return 0; } +}; + +} // namespace + +TEST(ClassSweep, ModularLeafAndComparisonKeepTheField) +{ + expect_point_near_modulus(); + expect_point_near_modulus(); + expect_point_near_modulus(); + expect_point_near_modulus(); + expect_point_near_modulus(); + expect_point_near_modulus(); + expect_point_near_modulus(); + expect_point_near_modulus(); + expect_point_near_modulus(); + expect_point_near_modulus(); + expect_point_near_modulus(); + + expect_comparison_keeps_negative_delta(); + expect_comparison_keeps_negative_delta(); + expect_comparison_keeps_negative_delta(); + expect_comparison_keeps_negative_delta(); + expect_comparison_keeps_negative_delta(); + expect_comparison_keeps_negative_delta(); + expect_comparison_keeps_negative_delta(); + expect_comparison_keeps_negative_delta(); + expect_comparison_keeps_negative_delta(); + expect_comparison_keeps_negative_delta(); + expect_comparison_keeps_negative_delta(); +} + +TEST(ClassSweep, SimdLeafAddReducesInTheField) +{ + alignas(16) std::uint64_t left[2] = {dpf::fp61_mod - 1, dpf::field64::mod - 3}; + alignas(16) std::uint64_t right[2] = {4, 5}; + simde__m128i a{}; + simde__m128i b{}; + std::memcpy(&a, left, sizeof(left)); + std::memcpy(&b, right, sizeof(right)); + + alignas(16) std::uint64_t fp_out[2]{}; + const auto fp_sum = dpf::leaf_arithmetic::add_t{}(a, b); + std::memcpy(fp_out, &fp_sum, sizeof(fp_out)); + EXPECT_EQ(fp_out[0], dpf::fp61::reduce((dpf::fp61_mod - 1) + 4)); + EXPECT_EQ(fp_out[1], dpf::fp61::reduce((dpf::field64::mod - 3) + 5)); + + alignas(16) std::uint64_t f64_left[2] = {dpf::field64::mod - 1, dpf::field64::mod - 4}; + alignas(16) std::uint64_t f64_right[2] = {2, 6}; + std::memcpy(&a, f64_left, sizeof(f64_left)); + std::memcpy(&b, f64_right, sizeof(f64_right)); + alignas(16) std::uint64_t f64_out[2]{}; + const auto f64_sum = dpf::leaf_arithmetic::add_t{}(a, b); + std::memcpy(f64_out, &f64_sum, sizeof(f64_out)); + EXPECT_EQ(f64_out[0], 1u); + EXPECT_EQ(f64_out[1], 2u); + + const auto wide = (static_cast(dpf::field128::mod_hi) << 64) + | dpf::field128::mod_lo; + const dpf::field128 near{wide - 1}; + const dpf::field128 step{3}; + simde__m128i na{}; + simde__m128i nb{}; + std::memcpy(&na, &near, sizeof(na)); + std::memcpy(&nb, &step, sizeof(nb)); + const auto f128_sum = dpf::leaf_arithmetic::add_t{}(na, nb); + dpf::field128 got{}; + std::memcpy(&got, &f128_sum, sizeof(got)); + EXPECT_EQ(got, near + step); + EXPECT_EQ(got, dpf::field128{2}); +} + +TEST(ClassSweep, FromSeedConsumesBytesPastTheOldWindow) +{ + expect_from_seed_reads_past_first_word(); + expect_from_seed_reads_past_first_word(); + expect_from_seed_reads_past_first_word(); + expect_from_seed_reads_past_first_word(); + expect_from_seed_reads_past_first_word(); + expect_from_seed_reads_past_16_bytes(); + expect_from_seed_reads_past_16_bytes(); +} + +TEST(ClassSweep, RejectionSampleStaysInTheScalarField) +{ + for (int i = 0; i < 32; ++i) + { + EXPECT_TRUE(scalar_below_order(dpf::uniform_sample())); + const auto s = -dpf::p256_scalar{1}; + EXPECT_EQ(-(-s), s); + EXPECT_EQ(s, dpf::p256_scalar{1} - dpf::p256_scalar{2}); + } +} + +TEST(ClassSweep, MalformedCurveEncodingsAreRejected) +{ + for (unsigned prefix : {0x00u, 0x01u, 0x04u, 0x05u}) + { + unsigned char bad[33]{}; + bad[0] = static_cast(prefix); + bad[32] = 1; + EXPECT_THROW(dpf::p256::from_compressed(bad), std::invalid_argument) << prefix; + } + unsigned char off_curve[33]{}; + off_curve[0] = 0x02; + off_curve[32] = 1; + EXPECT_THROW(dpf::p256::from_compressed(off_curve), std::invalid_argument); +} + +TEST(ClassSweep, ExtractableCodomainIsTheSketchGroupOnly) +{ + static_assert(dpf::extractable_codomain_ok_v); + static_assert(dpf::extractable_codomain_ok_v>); + static_assert(!dpf::extractable_codomain_ok_v); + static_assert(!dpf::extractable_codomain_ok_v); + static_assert(!dpf::extractable_codomain_ok_v); + static_assert(!dpf::extractable_codomain_ok_v); + static_assert(!dpf::extractable_codomain_ok_v); + static_assert(!dpf::extractable_codomain_ok_v); + static_assert(!dpf::extractable_codomain_ok_v); +} + +TEST(ClassSweep, FloatAndDoubleLeavesUseTheXorGroup) +{ + const float xf = dpf::leaf_group_add(1.0f, 2.0f); + const float ieee_f = 1.0f + 2.0f; + EXPECT_NE(xf, ieee_f); + std::uint32_t fb = 0; + std::memcpy(&fb, &xf, sizeof(fb)); + EXPECT_EQ(fb, 0x3f800000u ^ 0x40000000u); + + const double xd = dpf::leaf_group_add(1.0, 2.0); + EXPECT_NE(xd, 1.0 + 2.0); + std::uint64_t db = 0; + std::memcpy(&db, &xd, sizeof(db)); + EXPECT_EQ(db, 0x3ff0000000000000ull ^ 0x4000000000000000ull); + + simde__m128i a = simde_mm_set1_epi32(static_cast(0x3f800000)); + simde__m128i b = simde_mm_set1_epi32(static_cast(0x40000000)); + const auto packed = dpf::leaf_arithmetic::add_t{}(a, b); + const auto expect = simde_mm_xor_si128(a, b); + EXPECT_EQ(std::memcmp(&packed, &expect, sizeof(packed)), 0); +} + +TEST(ClassSweep, ProofsBindEveryEvalEntry) +{ + expect_proof_binds_leaf_and_warm_path(); + expect_proof_binds_leaf_and_warm_path(); + expect_proof_binds_leaf_and_warm_path(); + expect_proof_binds_leaf_and_warm_path(); + + const std::uint8_t alpha = 12; + auto [c0, c1] = dpf::make_dpf(alpha, dpf::lt(std::uint64_t{9}), dpf::verifiable{}); + dpf::proof_token before{}; + dpf::proof_token after{}; + (void)dpf::eval_point(dpf::cmp, c0, std::uint8_t{3}, dpf::prove(before)); + auto & words = const_cast &>(c0.value_cw()); + xor_first_byte(&words[0]); + (void)dpf::eval_point(dpf::cmp, c0, std::uint8_t{3}, dpf::prove(after)); + EXPECT_FALSE(tokens_equal(before, after)); + + dpf::proof_token other{}; + (void)dpf::eval_point(dpf::cmp, c1, std::uint8_t{3}, dpf::prove(other)); + EXPECT_FALSE(dpf::verify(after, other)); + + auto [p0, p1] = dpf::make_dpf(std::uint8_t{4}, std::uint32_t{3}, dpf::verifiable{}); + const std::uint8_t from = 1; + const std::uint8_t to = 6; + dpf::proof_token i0{}; + dpf::proof_token i1{}; + dpf::prove_interval(p0, from, to, dpf::prove(i0)); + dpf::prove_interval(p1, from, to, dpf::prove(i1)); + EXPECT_TRUE(dpf::verify(i0, i1)); + EXPECT_FALSE(dpf::verify(dpf::proof_token{}, dpf::proof_token{})); + + dpf::proof_token full0{}; + dpf::proof_token full1{}; + dpf::prove_full(p0, dpf::prove(full0)); + dpf::prove_full(p1, dpf::prove(full1)); + EXPECT_TRUE(dpf::verify(full0, full1)); + + std::array seq{2, 3, 4, 9}; + dpf::proof_token s0{}; + dpf::proof_token s1{}; + dpf::prove_sequence(p0, seq.begin(), seq.end(), dpf::prove(s0)); + dpf::prove_sequence(p1, seq.begin(), seq.end(), dpf::prove(s1)); + EXPECT_TRUE(dpf::verify(s0, s1)); + dpf::proof_token s0_again{}; + dpf::prove_sequence(p0, seq.begin(), seq.end(), dpf::prove(s0_again)); + EXPECT_TRUE(tokens_equal(s0, s0_again)); + + // Packed leaves may touch slots next to [from, to]. The token does not use the weights. + std::vector weights(256, 1u); + dpf::proof_token dot{}; + (void)dpf::eval_inner_product(p0, from, to, weights, dpf::prove(dot)); + EXPECT_TRUE(tokens_equal(dot, i0)); + + dpf::proof_token a0{}; + dpf::proof_token a1{}; + dpf::proof_token b0{}; + dpf::proof_token b1{}; + (void)*dpf::eval_point(p0, std::uint8_t{4}, dpf::prove(a0)); + (void)*dpf::eval_point(p1, std::uint8_t{4}, dpf::prove(b0)); + (void)*dpf::eval_point(p0, std::uint8_t{5}, dpf::prove(a1)); + (void)*dpf::eval_point(p1, std::uint8_t{5}, dpf::prove(b1)); + std::array left{a0, a1}; + std::array right{b0, b1}; + EXPECT_TRUE(dpf::verify_batch(left, right)); + // A swap of equal second halves is a no-op. Flip one byte of each half + // so a batch that folds only token[0] still accepts the second-half flip. + auto flipped_lo = left; + xor_first_byte(&flipped_lo[0][0]); + EXPECT_FALSE(dpf::verify_batch(flipped_lo, right)); + auto flipped_hi = left; + xor_first_byte(&flipped_hi[1][1]); + EXPECT_FALSE(dpf::verify_batch(flipped_hi, right)); +} + +TEST(ClassSweep, OneComparisonHalfIsNotThePredicate) +{ + const std::uint8_t thresh = 40; + const std::uint64_t if_true = 19; + auto keys = dpf::make_dpf3_cmp(thresh, if_true, std::uint64_t{0}); + auto & k1 = std::get<0>(keys); + auto & k2 = std::get<1>(keys); + auto & k3 = std::get<2>(keys); + static_assert(!has_both_dcf_halves>::value); + static_assert(!has_both_dcf_halves>::value); + + const auto full1 = dpf::eval_full(k1); + ASSERT_EQ(full1.size(), 256u); + int hidden = 0; + for (unsigned x = 0; x < 256; ++x) + { + const auto q = static_cast(x); + dpf::basic_path_memoizer> memo; + const auto s1 = dpf::eval_dpf3_cmp(k1, q, memo); + const auto s1_again = dpf::eval_dpf3_cmp(k1, q, memo); + const auto s2 = dpf::eval_dpf3_cmp(k2, q); + const auto s3 = dpf::eval_dpf3_cmp(k3, q); + EXPECT_EQ(s1, s1_again); + EXPECT_EQ(s1, s3); + EXPECT_EQ(s1, full1[x]); + const auto opened = dpf::reconstruct_cmp_halves(s1, s2); + const dpf::fp61 want = x < thresh ? dpf::fp61{if_true} : dpf::fp61{}; + EXPECT_EQ(opened, want) << x; + if (dpf::fp61{s1} != want && dpf::fp61{s2} != want) + ++hidden; + } + EXPECT_GT(hidden, 200); +} + +TEST(ClassSweep, OpenedResultsDoNotCarryTheSecretPoint) +{ + static_assert(!has_member_alpha>::value); + static_assert(!has_member_beta>::value); + static_assert(!has_member_alpha::value); + static_assert(!has_member_center>::value); + static_assert(!has_member_center>::value); + static_assert(!has_member_center>::value); + static_assert(!has_member_center>::value); + static_assert(!has_member_center>::value); + static_assert(!has_member_center>::value); + static_assert(!has_member_center>::value); + static_assert(!has_member_center>::value); + + std::vector none; + auto empty = dpf::geneval_ic(std::uint8_t{1}, std::uint8_t{2}, + none.begin(), none.end(), + dpf::ds_randomness), IcPad>{ + &dpf::uniform_sample, {}}, + dpf::ic(std::uint8_t{0}, std::uint8_t{4}, std::uint32_t{1}, std::uint32_t{0})); + EXPECT_FALSE(dpf::verify(empty.proof0, empty.proof1)); +} + +TEST(ClassSweep, ConstrainedComparisonAbortsUnlessAdjacent) +{ + const std::uint64_t samples[][2] = { + {0, 0}, {0, 2}, {5, 8}, {100, 0}, + {std::numeric_limits::max(), 0}, + {20, 20}, + }; + for (const auto & pair : samples) + EXPECT_THROW(dpf::local_ccmp(pair[0], pair[1]), std::invalid_argument) + << pair[0] << "," << pair[1]; + + EXPECT_NO_THROW(dpf::local_ccmp(4, 5)); + EXPECT_NO_THROW(dpf::local_ccmp(5, 4)); + EXPECT_NO_THROW(dpf::local_ccmp(0, 1)); + EXPECT_NO_THROW(dpf::local_ccmp( + std::numeric_limits::max(), + std::numeric_limits::max() - 1)); +} + +TEST(ClassSweep, SignedJetMatchesClearForEveryDegreeAtLeastTwo) +{ + const std::int8_t centers[] = {-40, -7, -1, 3}; + const int etas[] = {-12, 0, 5, 18}; + for (std::size_t degree = 2; degree <= 3; ++degree) + { + std::vector coeff(degree + 1, 1); + coeff[2] = 3; + const std::vector knots{std::numeric_limits::min()}; + for (std::int8_t center : centers) + { + const auto mat = grotto::make_offset_jet_keys(center, degree); + for (int eta : etas) + { + const auto e = static_cast(eta); + const auto s0 = grotto::offset_jet_eval<0>(mat, knots, coeff, e); + const auto s1 = grotto::offset_jet_eval<1>(mat, knots, coeff, e); + const auto clear = grotto::offset_jet_clear( + center, knots, coeff, e); + EXPECT_EQ(s0 + s1, clear) + << "degree=" << degree << " center=" << int(center) << " eta=" << eta; + } + } + } +} + +TEST(ClassSweep, DyadicShiftMatchesClearAcrossDegrees) +{ + const std::uint8_t centers[] = {1, 4, 200}; + const int etas[] = {0, 3, 39, 100}; + for (std::size_t degree = 0; degree <= 2; ++degree) + { + std::vector coeff(degree + 1, 1); + if (degree >= 1) + coeff[1] = 3; + const std::vector knots{0}; + for (std::uint8_t center : centers) + { + const auto mat = grotto::make_offset_twist_keys( + center, degree, grotto::twist_half); + for (int eta : etas) + { + const auto e = static_cast(eta); + const auto s0 = grotto::offset_twist_eval<0>(mat, knots, coeff, e); + const auto s1 = grotto::offset_twist_eval<1>(mat, knots, coeff, e); + const auto clear = grotto::offset_twist_clear( + center, grotto::twist_half, knots, coeff, e); + EXPECT_EQ(s0 + s1, clear) + << "degree=" << degree << " center=" << int(center) << " eta=" << eta; + EXPECT_NE(s0, clear); + EXPECT_NE(s1, clear); + } + } + } +} + +TEST(ClassSweep, HornerSharesMatchClearAndHideTheCenter) +{ + constexpr std::size_t D = 2; + const std::uint8_t center = 9; + const auto mat = grotto::make_offset_horner_keys(center); + const std::vector knots{0, 40}; + const std::vector> coeff{ + {1, 2, 0}, + {4, 0, 1}, + }; + for (std::uint8_t eta : {std::uint8_t{0}, std::uint8_t{3}, std::uint8_t{70}}) + { + const auto s0 = grotto::offset_horner_eval<0, D>(mat, knots, coeff, eta); + const auto s1 = grotto::offset_horner_eval<1, D>(mat, knots, coeff, eta); + const auto clear = grotto::offset_horner_clear(center, knots, coeff, eta); + EXPECT_EQ(s0 + s1, clear) << int(eta); + } +} diff --git a/test/tests/closed_form_test.cpp b/test/tests/closed_form_test.cpp new file mode 100644 index 0000000..9cf3846 --- /dev/null +++ b/test/tests/closed_form_test.cpp @@ -0,0 +1,151 @@ +#include +#include + +#include "grotto/closed_form.hpp" + +#include +#include + +namespace +{ + +std::int64_t raw_of(long double x, unsigned k) +{ + return std::llround(std::ldexp(x, static_cast(k))); +} + +long double truth(grotto::closed which, long double x) +{ + switch (which) + { + case grotto::closed::atanh: return std::atanh(x); + case grotto::closed::asinh: return std::asinh(x); + case grotto::closed::acosh: return std::acosh(x); + case grotto::closed::atan: return std::atan(x); + case grotto::closed::acot: return 1.57079632679489661923L - std::atan(x); + case grotto::closed::asec: return std::acos(1.0L / x); + case grotto::closed::acsc: return std::asin(1.0L / x); + case grotto::closed::asech: return std::acosh(1.0L / x); + case grotto::closed::acsch: return std::asinh(1.0L / x); + case grotto::closed::acoth: return std::atanh(1.0L / x); + case grotto::closed::selu: + return 1.0507009873554804934L * (x > 0 ? x : 1.6732632423543772848L * std::expm1(x)); + case grotto::closed::elu: + case grotto::closed::celu: + return x > 0 ? x : std::expm1(x); + case grotto::closed::softsign: return x / (1.0L + std::fabsl(x)); + case grotto::closed::tanhshrink: return x - std::tanh(x); + case grotto::closed::logistic: return std::log(x / (1.0L - x)); + case grotto::closed::exponential: return -std::log(1.0L - x); + case grotto::closed::laplace: + return x <= 0.5L ? std::log(2.0L * x) : -std::log(2.0L * (1.0L - x)); + case grotto::closed::cauchy: return std::tan(3.14159265358979323846L * (x - 0.5L)); + case grotto::closed::sinc: return x == 0 ? 1.0L : std::sin(x) / x; + case grotto::closed::cbrt: return std::cbrt(x); + case grotto::closed::qtrt: return std::sqrt(std::sqrt(x)); + case grotto::closed::icbrt: return 1.0L / std::cbrt(x); + case grotto::closed::iqtrt: return 1.0L / std::sqrt(std::sqrt(x)); + case grotto::closed::pow_m01: return std::exp(-0.1L * std::log(x)); + case grotto::closed::pow_p15: return x * std::sqrt(x); + case grotto::closed::pow_m3: return 1.0L / (x * x * x); + } + return 0; +} + +void expect_ulps(grotto::closed which, unsigned k, long double x, long double ulps) +{ + const std::int64_t raw = raw_of(x, k); + std::int64_t got = 0; + ASSERT_NO_THROW(got = grotto::eval_closed(which, k, raw)) << static_cast(which) << " x=" << static_cast(x); + const long double xr = std::ldexp(static_cast(raw), -static_cast(k)); + const long double want = truth(which, xr) * std::ldexp(1.0L, static_cast(k)); + EXPECT_LE(std::fabsl(static_cast(got) - want), ulps) + << static_cast(which) << " k=" << k << " x=" << static_cast(x) + << " got=" << got << " want=" << static_cast(want); +} + +} // namespace + +TEST(ClosedForm, InverseHyperbolicsAndTrig) +{ + for (unsigned k : {16u, 32u}) + { + for (long double x : {-0.6L, -0.2L, 0.2L, 0.6L}) + expect_ulps(grotto::closed::atanh, k, x, 8.0L); + for (long double x : {-2.0L, -0.5L, 0.3L, 1.5L, 4.0L}) + expect_ulps(grotto::closed::asinh, k, x, 16.0L); + for (long double x : {1.0L, 1.5L, 3.0L}) + expect_ulps(grotto::closed::acosh, k, x, 16.0L); + for (long double x : {-2.0L, -0.4L, 0.0L, 0.5L, 1.0L, 3.0L}) + expect_ulps(grotto::closed::atan, k, x, 8.0L); + for (long double x : {-1.5L, 0.4L, 2.0L}) + expect_ulps(grotto::closed::acot, k, x, 8.0L); + for (long double x : {-2.0L, -1.2L, 1.2L, 3.0L}) + { + expect_ulps(grotto::closed::asec, k, x, 8.0L); + expect_ulps(grotto::closed::acsc, k, x, 8.0L); + } + for (long double x : {0.2L, 0.5L, 1.0L}) + expect_ulps(grotto::closed::asech, k, x, 16.0L); + for (long double x : {-1.5L, -0.4L, 0.4L, 2.0L}) + expect_ulps(grotto::closed::acsch, k, x, 16.0L); + for (long double x : {-2.0L, 1.4L, 3.0L}) + expect_ulps(grotto::closed::acoth, k, x, 12.0L); + } +} + +TEST(ClosedForm, ActivationsQuantilesAndSinc) +{ + for (unsigned k : {16u, 32u}) + { + for (long double x : {-1.5L, -0.2L, 0.0L, 0.4L, 2.0L}) + { + expect_ulps(grotto::closed::elu, k, x, 8.0L); + expect_ulps(grotto::closed::celu, k, x, 8.0L); + expect_ulps(grotto::closed::selu, k, x, 16.0L); + expect_ulps(grotto::closed::softsign, k, x, 4.0L); + expect_ulps(grotto::closed::tanhshrink, k, x, 8.0L); + expect_ulps(grotto::closed::sinc, k, x, 1.0L); + } + for (long double p : {0.1L, 0.3L, 0.5L, 0.8L}) + { + expect_ulps(grotto::closed::logistic, k, p, 12.0L); + expect_ulps(grotto::closed::exponential, k, p, 12.0L); + expect_ulps(grotto::closed::laplace, k, p, 12.0L); + } + for (long double p : {0.2L, 0.4L, 0.6L, 0.8L}) + expect_ulps(grotto::closed::cauchy, k, p, 16.0L); + } +} + +TEST(ClosedForm, ExtraPowers) +{ + for (unsigned k : {16u, 32u}) + { + for (long double x : {-8.0L, -1.0L, 0.5L, 1.0L, 2.0L, 8.0L}) + { + expect_ulps(grotto::closed::cbrt, k, x, 24.0L); + expect_ulps(grotto::closed::icbrt, k, x, 1.0L); + expect_ulps(grotto::closed::pow_m3, k, x, 16.0L); + } + for (long double x : {0.25L, 0.5L, 1.0L, 2.0L, 9.0L, 81.0L}) + { + expect_ulps(grotto::closed::qtrt, k, x, 24.0L); + expect_ulps(grotto::closed::iqtrt, k, x, 32.0L); + expect_ulps(grotto::closed::pow_m01, k, x, 24.0L); + expect_ulps(grotto::closed::pow_p15, k, x, 1.0L); + } + expect_ulps(grotto::closed::icbrt, k, std::ldexp(1.0L, -8), 1.0L); + expect_ulps(grotto::closed::icbrt, k, 100.0L, 1.0L); + } +} + +TEST(ClosedForm, RejectsPolesAndBadPrecision) +{ + EXPECT_THROW(grotto::eval_closed(grotto::closed::atanh, 16, 1 << 16), std::domain_error); + EXPECT_THROW(grotto::eval_closed(grotto::closed::acosh, 16, 0), std::domain_error); + EXPECT_THROW(grotto::eval_closed(grotto::closed::qtrt, 16, -4), std::domain_error); + EXPECT_THROW(grotto::eval_closed(grotto::closed::pow_m3, 16, 0), std::domain_error); + EXPECT_THROW(grotto::eval_closed(grotto::closed::logistic, 16, 0), std::domain_error); + EXPECT_THROW(grotto::eval_closed(grotto::closed::sinc, 7, 1), std::invalid_argument); +} diff --git a/test/tests/cohort_test.cpp b/test/tests/cohort_test.cpp new file mode 100644 index 0000000..aac32cb --- /dev/null +++ b/test/tests/cohort_test.cpp @@ -0,0 +1,252 @@ +#include + +#include "dpf.hpp" + +#include +#include + +namespace +{ + +using in_type = std::uint8_t; +using out_type = std::uint64_t; + +template +out_type raw_of(const T & v) +{ + if constexpr (dpf::is_secret_share_v>) + return static_cast(v.raw()); + else + return static_cast(v); +} + +out_type open(out_type a, out_type b) +{ + return static_cast(a - b); +} + +template +std::vector interval_alone(const Key & key, in_type from, in_type to) +{ + auto buf = dpf::make_output_buffer_for_interval(key, from, to); + dpf::eval_interval(key, from, to, buf); + std::vector v; + v.reserve(buf.size()); + for (std::size_t i = 0; i < buf.size(); ++i) + v.push_back(raw_of(buf[i])); + return v; +} + +} // namespace + +TEST(Cohort, SamePointGenAndPointEval) +{ + const in_type alpha = 7; + const std::vector beta{1, 2, 3, 4, 5}; + auto [c0, c1] = dpf::make_dpf_cohort(alpha, beta.begin(), beta.end()); + ASSERT_EQ(c0.size(), beta.size()); + + std::vector y0, y1; + c0.eval_point(alpha, y0); + c1.eval_point(alpha, y1); + ASSERT_EQ(y0.size(), beta.size()); + for (std::size_t k = 0; k < beta.size(); ++k) + { + EXPECT_EQ(open(y0[k], y1[k]), beta[k]); + EXPECT_EQ(y0[k], raw_of(*dpf::eval_point(c0.keys()[k], alpha))); + EXPECT_EQ(y1[k], raw_of(*dpf::eval_point(c1.keys()[k], alpha))); + } + for (std::size_t k = 0; k < beta.size(); ++k) + { + const in_type other = static_cast(alpha + 1 + k); + std::vector z0, z1; + c0.eval_point(other, z0); + c1.eval_point(other, z1); + EXPECT_EQ(open(z0[k], z1[k]), 0u); + EXPECT_EQ(z0[k], raw_of(*dpf::eval_point(c0.keys()[k], other))); + } +} + +TEST(Cohort, IntervalInterleavesLeaves) +{ + const in_type alpha = 9; + const std::vector beta{4, 8, 15, 16}; + auto [c0, c1] = dpf::make_dpf_cohort(alpha, beta.begin(), beta.end()); + const in_type from = 0, to = 15; + std::vector y0, y1; + c0.eval_interval(from, to, y0); + c1.eval_interval(from, to, y1); + + using key0 = std::decay_t; + constexpr std::size_t opl = key0::outputs_per_leaf; + const std::size_t n = beta.size(); + const auto alone0 = interval_alone(c0.keys()[0], from, to); + ASSERT_EQ(y0.size(), alone0.size() * n); + ASSERT_EQ(alone0.size() % opl, 0u); + + for (std::size_t k = 0; k < n; ++k) + { + const auto a0 = interval_alone(c0.keys()[k], from, to); + const auto a1 = interval_alone(c1.keys()[k], from, to); + ASSERT_EQ(a0.size(), alone0.size()); + for (std::size_t i = 0; i < a0.size(); ++i) + { + const std::size_t node = i / opl; + const std::size_t lane = i % opl; + const std::size_t slot = (node * n + k) * opl + lane; + EXPECT_EQ(y0[slot], a0[i]); + EXPECT_EQ(y1[slot], a1[i]); + const in_type x = static_cast(from + i); + const out_type opened = open(a0[i], a1[i]); + if (x == alpha) + EXPECT_EQ(opened, beta[k]); + else + EXPECT_EQ(opened, 0u); + } + } +} + +TEST(Cohort, SequenceRecipeAndInnerProduct) +{ + const in_type alpha = 5; + const std::vector beta{3, 9, 1}; + auto [c0, c1] = dpf::make_dpf_cohort(alpha, beta.begin(), beta.end()); + const std::vector points{1, 5, 5, 20, 40}; + const std::size_t n = beta.size(); + + std::vector y0, y1; + c0.eval_sequence(points.begin(), points.end(), y0); + c1.eval_sequence(points.begin(), points.end(), y1); + ASSERT_EQ(y0.size(), points.size() * n); + + using key0 = std::decay_t; + auto recipe = dpf::make_sequence_recipe( + points.begin(), points.end()); + std::vector r0, r1; + c0.eval_sequence(recipe, r0); + c1.eval_sequence(recipe, r1); + + for (std::size_t q = 0; q < points.size(); ++q) + { + for (std::size_t k = 0; k < n; ++k) + { + const std::size_t slot = dpf::cohort_index(q, k, n); + const auto e0 = raw_of(*dpf::eval_point(c0.keys()[k], points[q])); + const auto e1 = raw_of(*dpf::eval_point(c1.keys()[k], points[q])); + EXPECT_EQ(y0[slot], e0); + EXPECT_EQ(y1[slot], e1); + EXPECT_EQ(r0[slot], e0); + EXPECT_EQ(r1[slot], e1); + if (points[q] == alpha) + EXPECT_EQ(open(e0, e1), beta[k]); + else + EXPECT_EQ(open(e0, e1), 0u); + } + } + + std::vector w(points.size()); + for (std::size_t q = 0; q < w.size(); ++q) + w[q] = q + 3; + const auto s0 = c0.eval_sequence_inner_product(recipe, w); + const auto s1 = c1.eval_sequence_inner_product(points.begin(), points.end(), w); + ASSERT_EQ(s0.size(), n); + for (std::size_t k = 0; k < n; ++k) + { + out_type acc0 = 0, acc1 = 0; + for (std::size_t q = 0; q < points.size(); ++q) + { + acc0 = static_cast(acc0 + + y0[dpf::cohort_index(q, k, n)] * w[q]); + acc1 = static_cast(acc1 + + y1[dpf::cohort_index(q, k, n)] * w[q]); + } + EXPECT_EQ(s0[k], acc0); + EXPECT_EQ(s1[k], acc1); + EXPECT_EQ(open(s0[k], s1[k]), beta[k] * (w[1] + w[2])); + } +} + +TEST(Cohort, IntervalInnerProduct) +{ + const in_type alpha = 4; + const std::vector beta{6, 7}; + auto [c0, c1] = dpf::make_dpf_cohort(alpha, beta.begin(), beta.end()); + const in_type from = 0, to = 15; + const auto alone = interval_alone(c0.keys()[0], from, to); + std::vector w(alone.size()); + for (std::size_t i = 0; i < w.size(); ++i) + w[i] = (i * 5u) + 1u; + + const auto a0 = c0.eval_interval_inner_product(from, to, w); + const auto a1 = c1.eval_interval_inner_product(from, to, w); + for (std::size_t k = 0; k < beta.size(); ++k) + { + const auto b0 = interval_alone(c0.keys()[k], from, to); + const auto b1 = interval_alone(c1.keys()[k], from, to); + out_type e0 = 0; + out_type e1 = 0; + for (std::size_t i = 0; i < w.size(); ++i) + { + e0 = static_cast(e0 + b0[i] * w[i]); + e1 = static_cast(e1 + b1[i] * w[i]); + } + EXPECT_EQ(a0[k], e0); + EXPECT_EQ(a1[k], e1); + + // Same weights against one-key batched leaf inner product. + auto m0 = dpf::make_basic_interval_memoizer(c0.keys()[k], from, to); + auto m1 = dpf::make_basic_interval_memoizer(c1.keys()[k], from, to); + const auto ip0 = dpf::eval_inner_product(c0.keys()[k], from, to, w, m0); + const auto ip1 = dpf::eval_inner_product(c1.keys()[k], from, to, w, m1); + EXPECT_EQ(raw_of(ip0), a0[k]); + EXPECT_EQ(raw_of(ip1), a1[k]); + EXPECT_EQ(open(a0[k], a1[k]), beta[k] * w[alpha - from]); + } +} + +TEST(Cohort, InterleaveLeavesMatchesSequenceLayout) +{ + // Sequence cohort layout is `out[q * n + k]`, the same order + // `interleave_leaves` writes for whole leaf values. + const in_type alpha = 6; + const std::vector beta{2, 3, 5}; + auto [c0, c1] = dpf::make_dpf_cohort(alpha, beta.begin(), beta.end()); + (void)c1; + const std::vector pts{1, 6, 10, 20}; + const std::size_t n = beta.size(); + std::vector cohort; + c0.eval_sequence(pts.begin(), pts.end(), cohort); + + std::vector> per_key(n); + std::vector ptrs(n); + for (std::size_t k = 0; k < n; ++k) + { + per_key[k].resize(pts.size()); + for (std::size_t q = 0; q < pts.size(); ++q) + per_key[k][q] = raw_of(*dpf::eval_point(c0.keys()[k], pts[q])); + ptrs[k] = per_key[k].data(); + } + std::vector interleaved(pts.size() * n); + dpf::interleave_leaves( + interleaved.data(), ptrs.data(), n, pts.size()); + ASSERT_EQ(interleaved.size(), cohort.size()); + for (std::size_t i = 0; i < interleaved.size(); ++i) + EXPECT_EQ(interleaved[i], cohort[i]) << "slot " << i; +} + +TEST(Cohort, HalfTreeSamePoint) +{ + using ht = dpf::prg::aes128_ccr; + const in_type alpha = 3; + const std::vector beta{11, 13, 17, 19}; + auto [c0, c1] = dpf::make_dpf_cohort( + alpha, beta.begin(), beta.end()); + std::vector y0, y1; + c0.eval_point(alpha, y0); + c1.eval_point(alpha, y1); + for (std::size_t k = 0; k < beta.size(); ++k) + { + EXPECT_EQ(open(y0[k], y1[k]), beta[k]); + EXPECT_EQ(y0[k], raw_of(*dpf::eval_point(c0.keys()[k], alpha))); + } +} diff --git a/test/tests/compose_test.cpp b/test/tests/compose_test.cpp new file mode 100644 index 0000000..219ae45 --- /dev/null +++ b/test/tests/compose_test.cpp @@ -0,0 +1,1899 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/beaver.hpp" +#include "dpf/compose.hpp" +#include "dpf/iknp.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" +#include "dpf/experiment.hpp" +#include "dpf/iknp_graphs.hpp" +#include "dpf/mesh_apps.hpp" +#include "dpf/net/edge_mesh.hpp" +#include "dpf/net/memory_sink.hpp" +#include "dpf/net/sink_exchange.hpp" +#include "dpf/pad_graphs.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" +#include "dpf/session_host.hpp" + +namespace +{ + +using dpf::protocol::composer; +using dpf::protocol::domain; +using dpf::protocol::effect; +using dpf::protocol::kernel_fn; +using dpf::protocol::node; +namespace opcodes = dpf::protocol::opcodes; +using dpf::protocol::op_flags; +using dpf::net::make_memory_sink_pair; + +TEST(Compose, SharedBlindInterned) +{ + composer c(0); + auto x = c.input(domain::a, 8); + int blind_calls = 0; + auto b0 = c.blind(x, 42); + auto b1 = c.blind(x, 42); + EXPECT_EQ(b0, b1); + auto p = c.schedule(); + EXPECT_EQ(p.effect_count(effect::blind), 1u); + + std::map kernels; + kernels[42] = [&](std::uint32_t, const std::vector & nodes, + const std::vector &, + dpf::protocol::block_span out, std::size_t) { + ++blind_calls; + for (std::size_t i = 0; i < out.lanes; ++i) + { + std::uint64_t v = 0x1111; + std::memcpy(out.at(i), &v, 8); + } + EXPECT_EQ(nodes.size(), 1u); + }; + auto [sink0, sink1] = make_memory_sink_pair(1, p.slot_bytes_all()); + (void)sink1; + std::vector> values; + values.resize(c.node_count()); + values[x.id].resize(8); + std::uint64_t xv = 7; + std::memcpy(values[x.id].data(), &xv, 8); + dpf::protocol::drive(p, sink0, values, kernels, 0); + EXPECT_EQ(blind_calls, 1); + std::uint64_t got = 0; + std::memcpy(&got, values[b0.id].data(), 8); + EXPECT_EQ(got, 0x1111u); +} + +TEST(Compose, LevelWalkSharesExpands) +{ + composer c(0); + auto seed = c.input(domain::fss, 16); + auto a = c.fss_point(seed, 2, 16); + const auto shared = c.schedule().effect_count(effect::expand); + // depth 2: one fused L||R expand per level (hand DPF PRG stretch). + EXPECT_EQ(shared, 2u); + auto b = c.fss_point(seed, 2, 16); + EXPECT_EQ(c.schedule().effect_count(effect::expand), shared); + auto other = c.input(domain::fss, 16); + auto d = c.fss_cmp(other, 2, 16); + EXPECT_EQ(c.schedule().effect_count(effect::expand), shared * 2); + EXPECT_EQ(c.domain_of(a), domain::b); + EXPECT_EQ(c.domain_of(b), domain::b); + EXPECT_EQ(c.domain_of(d), domain::a); +} + +TEST(Compose, ExchangeWaves) +{ + composer c(0); + auto x = c.input(domain::a, 8); + auto e0 = c.exchange(x); + auto e1 = c.exchange(c.compute(opcodes::user_base + 10, {e0}, domain::a, 8)); + auto e2 = c.exchange(c.compute(opcodes::user_base + 10, {e1}, domain::a, 8)); + (void)e2; + auto p = c.schedule(); + EXPECT_EQ(p.rounds(), 3u); + + composer c2(0); + auto a = c2.input(domain::a, 8); + auto b = c2.input(domain::a, 8); + auto o0 = c2.exchange(a); + auto o1 = c2.exchange(b); + (void)o0; + (void)o1; + auto p2 = c2.schedule(); + EXPECT_EQ(p2.rounds(), 1u); +} + +TEST(Compose, ExchangeReconstructsOnMemorySink) +{ + composer c0(0); + composer c1(1); + auto x0 = c0.input(domain::a, 8); + auto x1 = c1.input(domain::a, 8); + auto e0 = c0.exchange(x0); + auto e1 = c1.exchange(x1); + (void)e0; + (void)e1; + auto p0 = c0.schedule(); + auto p1 = c1.schedule(); + ASSERT_EQ(p0.rounds(), 1u); + ASSERT_EQ(p1.rounds(), 1u); + + auto [sink0, sink1] = make_memory_sink_pair(1, p0.slot_bytes_all()); + std::uint64_t a = 3, b = 5; + sink0.submit(0, 0, reinterpret_cast(&a), 8); + sink1.submit(0, 0, reinterpret_cast(&b), 8); + sink0.flush(); + ASSERT_TRUE(sink0.peer_ready(0, 0)); + ASSERT_TRUE(sink1.peer_ready(0, 0)); + std::uint64_t peer0 = 0, peer1 = 0; + sink0.read_peer(0, 0, reinterpret_cast(&peer0), 8); + sink1.read_peer(0, 0, reinterpret_cast(&peer1), 8); + EXPECT_EQ(a + peer0, 8u); + EXPECT_EQ(b + peer1, 8u); +} + +TEST(Compose, CommutativeComputeInterned) +{ + composer c(0); + auto x = c.input(domain::a, 8); + auto y = c.input(domain::a, 8); + auto p0 = c.compute(99, {x, y}, domain::a, 8, op_flags::commutative); + auto p1 = c.compute(99, {y, x}, domain::a, 8, op_flags::commutative); + EXPECT_EQ(p0, p1); +} + +TEST(Compose, SimdGroupOneKernelCall) +{ + composer c(0); + auto nodes = c.fan(8, [&](std::size_t) { + return c.input(domain::a, 8); + }); + std::vector outs; + for (auto n : nodes) + outs.push_back(c.compute(77, {n}, domain::a, 8)); + auto p = c.schedule(); + int calls = 0; + std::size_t total_nodes = 0; + std::map kernels; + kernels[77] = [&](std::uint32_t, const std::vector & ns, + const std::vector & ins, + dpf::protocol::block_span out, std::size_t sink_lanes) { + ++calls; + total_nodes += ns.size(); + EXPECT_EQ(ns.size(), 8u); + EXPECT_EQ(out.lanes, 8u * sink_lanes); + EXPECT_EQ(ins.size(), 1u); + for (std::size_t i = 0; i < out.lanes; ++i) + std::memset(out.at(i), 1, 8); + }; + auto slots = p.slot_bytes_all(); + if (slots.empty()) + slots.push_back(0); + auto [sink0, sink1] = make_memory_sink_pair(1, std::move(slots)); + (void)sink1; + std::vector> values(c.node_count()); + for (auto n : nodes) + values[n.id].assign(8, 0); + dpf::protocol::drive(p, sink0, values, kernels, 0); + EXPECT_EQ(calls, 1); + EXPECT_EQ(total_nodes, 8u); + ASSERT_GE(p.waves(), 1u); + std::size_t grouped = 0; + for (const auto & g : p.wave(0).groups) + { + if (g.opcode == 77) + grouped += g.nodes.size(); + } + EXPECT_EQ(grouped, 8u); + (void)outs; +} +TEST(Compose, DomainConversionInternedAndRejected) +{ + composer c(0); + auto leaf = c.input(domain::b, 8); + auto a0 = c.as(leaf, domain::a); + auto a1 = c.as(leaf, domain::a); + EXPECT_EQ(a0, a1); + auto p = c.schedule(); + EXPECT_EQ(p.conversion_count(domain::b, domain::a), 1u); + EXPECT_THROW(c.as(leaf, domain::rss), std::invalid_argument); + + // Inverse fold + auto back = c.as(a0, domain::b); + EXPECT_EQ(back, leaf); +} + +TEST(Compose, RssProductInterned) +{ + composer c(0); + auto x = c.input(domain::rss, 16); + auto y = c.input(domain::rss, 16); + auto f0 = c.rss_product(x, y); + auto f1 = c.rss_product(y, x); // commutative + EXPECT_EQ(f0, f1); + EXPECT_EQ(c.domain_of(f0), domain::y); + + auto own = c.input(domain::y, 8); + auto next = c.input(domain::y, 8); + auto r = c.y2rss(own, next); + EXPECT_EQ(c.domain_of(r), domain::rss); +} + +TEST(Compose, AbyProductSharesBlind) +{ + composer c(0); + auto & s = c.aby(); + auto x = s.input(); + auto y = s.input(); + auto z = s.input(); + auto xy = s.product(x, y); + auto xz = s.product(x, z); + (void)xy; + (void)xz; + // One blind for x across both products. + s.sample(); + EXPECT_EQ(s.round_of(xy), s.round_of(xz)); + // opened wires create barrier exchanges on the composer + auto nxy = c.opened(xy); + auto nxz = c.opened(xz); + EXPECT_EQ(c.domain_of(nxy), domain::a); + EXPECT_EQ(c.domain_of(nxz), domain::a); + auto barriers = s.exchange_barriers(); + EXPECT_FALSE(barriers.empty()); +} + +// Practical gap (SUBLEQ scale / Grotto η): opening a product must schedule +// every prior δ flush, not only the product's barrier. +TEST(Compose, BeaverBarrierChainMaterializesPriors) +{ + composer c(0); + auto & s = c.aby(); + auto x = s.input(); + auto y = s.input(); + auto z = s.product(x, y); + // Nested use so z is δ-opened in a later barrier (hand SUBLEQ scale path). + auto w = s.product(z, x); + (void)w; + s.sample(); + const auto barriers = s.exchange_barriers(); + ASSERT_GE(barriers.size(), 2u); + auto nz = c.opened(z); + (void)nz; + // Opening z must pull in every prior flush (factor open), not only z's. + std::size_t beaver_ex = 0; + for (std::uint32_t id = 0; id < c.node_count(); ++id) + { + if (c.effect_of(node{id}) != effect::exchange) + continue; + // Beaver barrier opcodes are beaver_delta + index. + ++beaver_ex; + } + // FSS-free composer: every exchange is a beaver barrier. + EXPECT_GE(beaver_ex, 2u); +} + +// Practical gap (Duoram / PIR + Beaver): beaver waves must not hitch onto +// unrelated FSS exchange node ids (old fake inputs = {sess, barrier_index}). +TEST(Compose, BeaverBarrierWavesIndependentOfFssNodeIds) +{ + composer c(0); + auto seed = c.input(domain::fss, 16); + auto leaf = c.fss_point(seed, 3, 16); + (void)leaf; + const auto fss_only = c.schedule(); + // depth d → d exchange waves + final consumer wave. + EXPECT_EQ(fss_only.effect_count(effect::exchange), 3u); + EXPECT_EQ(fss_only.rounds(), 3u); // == exchange_waves + EXPECT_EQ(fss_only.exchange_waves(), 3u); + + auto & s = c.aby(); + auto x = s.input(); + auto y = s.input(); + auto z = s.product(x, y); + s.sample(); + auto nz = c.opened(z); + (void)nz; + auto p = c.schedule(); + // Independent beaver opens add exchange nodes; they must not disappear + // or be ordered solely by colliding with FSS node ids. + EXPECT_GT(p.effect_count(effect::exchange), 3u); +} + +// Practical gap (grotto_signum_lut): N comparison walks share expands when +// seeded alike; packed same-depth opens are one wave per level. +TEST(Compose, GrottoShapedFanSharesSeedExpands) +{ + composer c(0); + auto seed = c.input(domain::fss, 16); + constexpr std::size_t n = 7; + auto leaves = c.fan(n, [&](std::size_t) { + return c.fss_cmp(seed, 4, 16); + }); + EXPECT_EQ(leaves.size(), n); + auto p = c.schedule(); + // One fused expand per level for the shared seed, not n×depth. + EXPECT_EQ(p.effect_count(effect::expand), 4u); + EXPECT_EQ(p.effect_count(effect::exchange), 4u); + EXPECT_EQ(p.rounds(), 4u); // == exchange_waves (no empty sink round) +} + +// Latency objective: keep sign×linear in one round (Pika / online Grotto). +// Prep objective (default) still peels for Appendix-E savings. +TEST(Compose, AbySessionUsesRoundAwareSchedule) +{ + composer c(0); + auto & s = c.aby(); + EXPECT_EQ(s.get_schedule_objective(), + dpf::beavers::schedule_objective::rounds); + auto sgn = s.input(); + auto x = s.input(); + auto a0 = s.input(); + auto a1 = s.input(); + auto lin = s(sgn * (a1 * x + a0)); + EXPECT_EQ(s.round_of(lin), 1); + + dpf::beavers::session prep; + prep.set_schedule_objective(dpf::beavers::schedule_objective::prep); + auto ps = prep.input(); + auto px = prep.input(); + auto pa0 = prep.input(); + auto pa1 = prep.input(); + auto plin = prep(ps * (pa1 * px + pa0)); + EXPECT_EQ(prep.round_of(plin), 2); + EXPECT_LT(prep.preprocessing_count(), s.preprocessing_count()); +} + +// Express/Sabre: sketch rides in the last CW flush — no extra exchange round. +TEST(Compose, ExpressShapedSketchFusedIntoLastCw) +{ + composer c(0); + auto seed = c.input(domain::fss, 16); + auto sketch = c.input(domain::a, 8); + + // Naive: walk, then a sketch exchange that depends on the leaf. + auto leaf = c.fss_point(seed, 4, 16); + auto sk_dep = c.compute(opcodes::user_base + 50, {leaf, sketch}, + domain::a, 8); + auto sk_ex = c.exchange(sk_dep); + (void)sk_ex; + auto naive_plan = c.schedule(); + + composer c2(0); + auto seed2 = c2.input(domain::fss, 16); + auto sketch2 = c2.input(domain::a, 8); + auto wr = c2.fss_point_fused(seed2, 4, 16, sketch2); + auto fused_plan = c2.schedule(); + EXPECT_EQ(c2.domain_of(wr.leaf), domain::b); + EXPECT_EQ(c2.domain_of(wr.trailer_open), domain::a); + EXPECT_EQ(naive_plan.effect_count(effect::exchange), 5u); + EXPECT_EQ(fused_plan.effect_count(effect::exchange), 4u); + // Same leaf-wave depth, but naive pays a fifth exchange-bearing wave. + EXPECT_EQ(fused_plan.rounds(), 4u); + EXPECT_EQ(naive_plan.exchange_waves(), 5u); + EXPECT_EQ(fused_plan.exchange_waves(), 4u); + // Last CW slot carries step‖trailer. + const auto & last_wave = fused_plan.wave(3); + ASSERT_FALSE(last_wave.exchanges.empty()); + EXPECT_EQ(fused_plan.value_bytes_of(last_wave.exchanges[0].id), 16u + 8u); + EXPECT_TRUE(fused_plan.wave(4).exchanges.empty()); +} + +TEST(Compose, BeaverExchangeBarriersMatchBatch) +{ + dpf::beavers::session s; + auto x = s.input(); + auto y = s.input(); + auto z = s.product(x, y); + (void)z; + s.sample(); + auto barriers = s.exchange_barriers(); + EXPECT_GE(barriers.size(), 1u); + + // Party path: stepper completes with same number of barriers. + dpf::beavers::session s0; + dpf::beavers::session s1; + auto x0 = s0.input(); + auto y0 = s0.input(); + auto z0 = s0.product(x0, y0); + auto x1 = s1.input(); + auto y1 = s1.input(); + auto z1 = s1.product(x1, y1); + (void)z0; + (void)z1; + s0.sample(); + // copy tape + auto tape = s0.export_party(0); + // Use install after sampling on dealer session - parties need tapes. + // Simpler: evaluate_party_batch with matching exchange count. + dpf::beavers::session dealer; + auto dx = dealer.input(); + auto dy = dealer.input(); + auto dz = dealer.product(dx, dy); + (void)dz; + dealer.sample(); + auto t0 = dealer.export_party(0); + auto t1 = dealer.export_party(1); + + dpf::beavers::session p0; + dpf::beavers::session p1; + auto px0 = p0.input(); + auto py0 = p0.input(); + auto pz0 = p0.product(px0, py0); + auto px1 = p1.input(); + auto py1 = p1.input(); + auto pz1 = p1.product(px1, py1); + p0.install_party(0, t0); + p1.install_party(1, t1); + p0.bind_party(px0, 3); + p0.bind_party(py0, 4); + p1.bind_party(px1, 0); + p1.bind_party(py1, 0); + + auto b0 = p0.exchange_barriers(); + auto b1 = p1.exchange_barriers(); + ASSERT_EQ(b0.size(), b1.size()); + + dpf::beavers::party_batch_stepper step0(p0); + dpf::beavers::party_batch_stepper step1(p1); + EXPECT_EQ(step0.barrier_count(), b0.size()); + while (!step0.done()) + { + auto m0 = step0.take_local(); + auto m1 = step1.take_local(); + ASSERT_EQ(m0.size(), m1.size()); + step0.apply_peer(m1); + step1.apply_peer(m0); + } + EXPECT_TRUE(step1.done()); + EXPECT_EQ(p0.value_party(pz0) + p1.value_party(pz1), 12u); +} + +// --------------------------------------------------------------------------- +// Flow choreography: realistic schedules and the abstractions that unlock them. +// --------------------------------------------------------------------------- + +TEST(Compose, FlowSimpleAbyProductOneRound) +{ + composer c(0); + auto x = c.input(domain::a, 8); + auto y = c.input(domain::a, 8); + auto z = c.aby_product(x, y); + (void)z; + auto p = c.schedule(); + EXPECT_EQ(p.exchange_waves(), 1u); +} + +TEST(Compose, FlowIndepFssWalksPackSameWaves) +{ + composer c(0); + auto s0 = c.input(domain::fss, 16); + auto s1 = c.input(domain::fss, 16); + auto l0 = c.fss_point(s0, 5, 16); + auto l1 = c.fss_point(s1, 5, 16); + (void)l0; + (void)l1; + auto p = c.schedule(); + EXPECT_EQ(p.effect_count(effect::exchange), 10u); // 5+5 slots + EXPECT_EQ(p.exchange_waves(), 5u); // packed per level + EXPECT_EQ(p.effect_count(effect::expand), 10u); +} + +TEST(Compose, FlowBitMoreParallelBitWalks) +{ + // Keyword PIR / BitMore: L independent bit keys, same depth — one wave/level. + composer c(0); + constexpr std::size_t L = 8; + auto seeds = c.fan(L, [&](std::size_t) { + return c.input(domain::fss, 16); + }); + auto leaves = c.fan(L, [&](std::size_t i) { + return c.fss_point(seeds[i], 6, 16); + }); + EXPECT_EQ(leaves.size(), L); + auto p = c.schedule(); + EXPECT_EQ(p.exchange_waves(), 6u); + EXPECT_EQ(p.effect_count(effect::exchange), L * 6u); +} + +TEST(Compose, FlowEarlyStopDropsInteractiveLevels) +{ + // Pika / small-output PIR: BGI Remark 3.4 packs ν low bits into the leaf. + composer full(0); + auto seed = full.input(domain::fss, 16); + auto leaf_full = full.fss_point(seed, 8, 16); + (void)leaf_full; + auto p_full = full.schedule(); + + composer early(0); + auto seed_e = early.input(domain::fss, 16); + auto leaf_e = early.fss_point_early_stop(seed_e, 8, /*early_stop=*/3, 16); + EXPECT_EQ(early.domain_of(leaf_e), domain::b); + auto p_early = early.schedule(); + + EXPECT_EQ(p_full.exchange_waves(), 8u); + EXPECT_EQ(p_early.exchange_waves(), 5u); + EXPECT_LT(p_early.effect_count(effect::exchange), + p_full.effect_count(effect::exchange)); +} + +TEST(Compose, FlowPrefixCheckpointsNoExtraRounds) +{ + // Poplar / idpf_agg: prefix share after each CW, still depth exchange waves. + composer c(0); + auto seed = c.input(domain::fss, 16); + auto wr = c.level_walk_prefixes(seed, 4, 16, /*prefix_bytes=*/8); + EXPECT_EQ(wr.at_level.size(), 4u); + auto p = c.schedule(); + EXPECT_EQ(p.exchange_waves(), 4u); + EXPECT_EQ(p.effect_count(effect::exchange), 4u); + for (auto pref : wr.at_level) + EXPECT_EQ(c.domain_of(pref), domain::a); +} + +TEST(Compose, FlowSizedSlotsBlockWidth) +{ + // DCF block_width: CW only at checkpoints — narrower slots between. + composer c(0); + auto seed = c.input(domain::fss, 16); + const std::vector slots = {16, 4, 4, 16}; + auto tip = c.level_walk_sized(seed, slots); + (void)tip; + auto p = c.schedule(); + EXPECT_EQ(p.exchange_waves(), 4u); + EXPECT_EQ(p.value_bytes_of(p.wave(0).exchanges[0].id), 16u); + EXPECT_EQ(p.value_bytes_of(p.wave(1).exchanges[0].id), 4u); + EXPECT_EQ(p.value_bytes_of(p.wave(3).exchanges[0].id), 16u); +} + +TEST(Compose, FlowRssProductRefreshOneRound) +{ + // 3PC Duoram-style: local rss_mul then neighbor y-exchange → RSS. + composer c(0); + auto x = c.input(domain::rss, 16); + auto y = c.input(domain::rss, 16); + auto z = c.rss_product_replicated(x, y); + EXPECT_EQ(c.domain_of(z), domain::rss); + auto p = c.schedule(); + EXPECT_EQ(p.exchange_waves(), 1u); + EXPECT_EQ(p.effect_count(effect::exchange), 1u); +} + +TEST(Compose, FlowRssChainTwoProductsTwoRounds) +{ + composer c(0); + auto a = c.input(domain::rss, 16); + auto b = c.input(domain::rss, 16); + auto d = c.input(domain::rss, 16); + auto ab = c.rss_product_replicated(a, b); + auto abd = c.rss_product_replicated(ab, d); + EXPECT_EQ(c.domain_of(abd), domain::rss); + auto p = c.schedule(); + EXPECT_EQ(p.exchange_waves(), 2u); +} + +TEST(Compose, FlowIndepRssRefreshesPackOneWave) +{ + composer c(0); + auto x0 = c.input(domain::rss, 16); + auto y0 = c.input(domain::rss, 16); + auto x1 = c.input(domain::rss, 16); + auto y1 = c.input(domain::rss, 16); + auto z0 = c.rss_product_replicated(x0, y0); + auto z1 = c.rss_product_replicated(x1, y1); + (void)z0; + (void)z1; + auto p = c.schedule(); + EXPECT_EQ(p.exchange_waves(), 1u); + EXPECT_EQ(p.effect_count(effect::exchange), 2u); +} + +TEST(Compose, FlowDuoramWriteScaleWaitsForLeaf) +{ + // FSS leaf feeds ABY scale product — beaver flush must follow the walk. + composer c(0); + auto seed = c.input(domain::fss, 16); + auto leaf = c.fss_point(seed, 4, 16); + auto scale = c.input(domain::a, 8); + auto scaled = c.aby_product(leaf, scale); + auto p = c.schedule(); + EXPECT_GE(p.wave_of(scaled), p.wave_of(leaf)); + EXPECT_GE(p.exchange_waves(), 4u); + // Factor δ that imports the leaf cannot sit in an earlier exchange wave. + bool saw_beaver_after_leaf = false; + for (std::size_t w = 0; w < p.rounds(); ++w) + { + for (auto ex : p.wave(w).exchanges) + { + if (p.opcode_of(ex.id) < opcodes::beaver_delta) + continue; + if (w >= p.wave_of(leaf)) + saw_beaver_after_leaf = true; + } + } + EXPECT_TRUE(saw_beaver_after_leaf); +} + +TEST(Compose, FlowWalkPlusIndepAbyPackEarlyWaves) +{ + // Independent beaver product may share early CW waves (no FSS dep). + composer c(0); + auto seed = c.input(domain::fss, 16); + auto leaf = c.fss_point(seed, 3, 16); + (void)leaf; + auto x = c.input(domain::a, 8); + auto y = c.input(domain::a, 8); + auto z = c.aby_product(x, y); + (void)z; + auto p = c.schedule(); + // 3 CW waves; beaver δ packs into wave 0 alongside first CW. + EXPECT_EQ(p.exchange_waves(), 3u); + EXPECT_FALSE(p.wave(0).exchanges.empty()); + EXPECT_GE(p.wave(0).exchanges.size(), 2u); +} + +TEST(Compose, FlowSubleqFetchAndScale) +{ + // Instruction fetch (FSS) then scale product — ABY waits for the leaf. + composer c(0); + auto pc_seed = c.input(domain::fss, 16); + auto instr = c.fss_point(pc_seed, 5, 16); + auto scale = c.input(domain::a, 8); + auto scaled = c.aby_product(c.as(instr, domain::a), scale); + + auto & s = c.aby(); + auto flag = s.input(); + auto a0 = s.input(); + auto a1 = s.input(); + auto x = s.input(); + auto lin = s(flag * (a1 * x + a0)); + s.sample(); + auto nlin = c.opened(lin); + (void)nlin; + + auto p = c.schedule(); + EXPECT_GE(p.wave_of(scaled), p.wave_of(instr)); + EXPECT_EQ(s.round_of(lin), 1); +} + +TEST(Compose, FlowGrottoFanPlusSketchFuse) +{ + composer c(0); + auto seed = c.input(domain::fss, 16); + auto sketch = c.input(domain::a, 8); + auto leaves = c.fan(4, [&](std::size_t) { + return c.fss_cmp(seed, 3, 16); + }); + auto wr = c.fss_point_fused(seed, 3, 16, sketch); + (void)leaves; + (void)wr; + auto p = c.schedule(); + // Shared expands across fan + fused walk; 3 exchange waves total. + EXPECT_EQ(p.exchange_waves(), 3u); + EXPECT_EQ(p.effect_count(effect::expand), 3u); +} + +TEST(Compose, FlowExpressMailboxAndAudit) +{ + composer c(0); + auto seed = c.input(domain::fss, 16); + auto sketch = c.input(domain::a, 8); + auto wr = c.fss_point_fused(seed, 6, 16, sketch); + EXPECT_EQ(c.domain_of(wr.trailer_open), domain::a); + auto p = c.schedule(); + EXPECT_EQ(p.exchange_waves(), 6u); + EXPECT_EQ(p.value_bytes_of(p.wave(5).exchanges[0].id), 24u); +} + +TEST(Compose, FlowReshareYUsesRssFromY) +{ + composer c(0); + auto y = c.input(domain::y, 8); + auto r = c.reshare(y, domain::rss); + EXPECT_EQ(c.domain_of(r), domain::rss); + EXPECT_EQ(c.schedule().exchange_waves(), 1u); +} + +TEST(Compose, FlowDsWalkFourOpensPerLevel) +{ + composer c(0); + auto seed = c.input(domain::fss, 16); + auto tip = c.level_walk_ds(seed, 3, 16); + (void)tip; + auto p = c.schedule(); + // 3 levels × (blind, share, advice, AND1, AND2) = 15 exchange waves. + EXPECT_EQ(p.exchange_waves(), 15u); + EXPECT_EQ(p.effect_count(effect::exchange), 15u); +} + +TEST(Compose, FlowDsWalkWithOhAndMux) +{ + composer c(0); + auto seed = c.input(domain::fss, 16); + auto tip = c.level_walk_ds(seed, 2, 16, /*oh=*/true, /*lg_outputs=*/2); + (void)tip; + auto p = c.schedule(); + // 2×(5 + 80 OH) + mux_nodes=2*(4-1)=6 → 170 + 6 = 176 exchanges. + EXPECT_EQ(p.effect_count(effect::exchange), 176u); + auto budget = dpf::net::compose_ds_slot_bytes(2, 16, true, 2); + EXPECT_EQ(budget.size(), 176u); + EXPECT_EQ(p.exchange_waves(), budget.size()); +} + +TEST(Compose, FlowDsWalkSizedMatchesBudget) +{ + composer c(0); + auto slots = dpf::net::compose_ds_slot_bytes(3, 16, false, 0); + auto tip = c.level_walk_ds_sized(c.input(domain::fss, 16), slots, false, 0); + (void)tip; + EXPECT_EQ(c.schedule().exchange_waves(), slots.size()); + EXPECT_EQ(slots.size(), 15u); +} + +TEST(Compose, DefaultPlanMatchesScheduleAndSink) +{ + composer c(0); + auto leaf = c.fss_point(c.input(domain::fss, 16), 3, 16); + (void)leaf; + auto p = c.default_plan(); + auto s = c.schedule(); + EXPECT_EQ(p.rounds(), s.exchange_waves()); + EXPECT_EQ(p.rounds(), p.slot_bytes_all().size()); + EXPECT_EQ(p.rounds(), 3u); +} + +TEST(Compose, FlowAdaptivePrefixOneWavePerStep) +{ + composer c(0); + auto seed = c.input(domain::fss, 16); + auto f = c.begin_adaptive_prefix(seed); + f = c.step_adaptive_prefix(f, 16, 8); + EXPECT_TRUE(f.awaiting_retain); + // After step only: one open in the plan; tip is still the prior state. + EXPECT_EQ(c.default_plan().rounds(), 1u); + f = c.retain_adaptive_prefix(f, /*child=*/0); + EXPECT_FALSE(f.awaiting_retain); + f = c.step_adaptive_prefix(f, 16, 8); + f = c.retain_adaptive_prefix(f, /*child=*/1); + auto p = c.default_plan(); + EXPECT_EQ(p.exchange_waves(), 2u); + EXPECT_EQ(p.rounds(), 2u); + EXPECT_EQ(f.depth_done, 2u); + EXPECT_FALSE(f.awaiting_retain); +} + +TEST(Compose, AdaptiveIncrementalDriveSkipsFlushedWaves) +{ + composer c(0); + auto f = c.begin_adaptive_prefix(c.input(domain::fss, 16)); + f = c.step_adaptive_prefix(f, 16, 8); + auto p = c.default_plan(); + ASSERT_EQ(p.exchange_waves(), 1u); + f.exchanges_flushed = p.exchange_waves(); + f = c.retain_adaptive_prefix(f, 0); + f = c.step_adaptive_prefix(f, 16, 8); + p = c.default_plan(); + ASSERT_EQ(p.exchange_waves(), 2u); + auto tail = p.slot_bytes_from(f.exchanges_flushed); + EXPECT_EQ(tail.size(), 1u); + EXPECT_EQ(p.slot_bytes_from(0).size(), 2u); + // compact_sink + from_exchange_wave: RoundSink sized to the tail only. + dpf::protocol::drive_options opt; + opt.from_exchange_wave = f.exchanges_flushed; + opt.compact_sink = true; + EXPECT_EQ(opt.from_exchange_wave, 1u); + f = c.retain_adaptive_prefix(f, 1); + EXPECT_EQ(f.depth_done, 2u); +} + +TEST(Compose, ReconstructOpenDomainAlgebra) +{ + std::uint8_t out[8]; + std::uint64_t a = 10, b = 3; + dpf::protocol::detail::reconstruct_open(domain::a, 0, + reinterpret_cast(&a), + reinterpret_cast(&b), 8, out); + std::uint64_t sum = 0; + std::memcpy(&sum, out, 8); + EXPECT_EQ(sum, 13u); + dpf::protocol::detail::reconstruct_open(domain::b, 0, + reinterpret_cast(&a), + reinterpret_cast(&b), 8, out); + std::uint64_t diff0 = 0; + std::memcpy(&diff0, out, 8); + EXPECT_EQ(diff0, 7u); + dpf::protocol::detail::reconstruct_open(domain::b, 1, + reinterpret_cast(&b), + reinterpret_cast(&a), 8, out); + std::uint64_t diff1 = 0; + std::memcpy(&diff1, out, 8); + EXPECT_EQ(diff1, 7u); // party1: peer - mine = 10 - 3 + dpf::protocol::detail::reconstruct_open(domain::y, 0, + reinterpret_cast(&a), + reinterpret_cast(&b), 8, out); + std::uint64_t y = 0; + std::memcpy(&y, out, 8); + EXPECT_EQ(y, 3u); +} + +TEST(Compose, FlowMultipointFanPacksAnswers) +{ + composer c(0); + auto mr = c.multipoint_fan(3, + [&](std::size_t) { return c.input(domain::fss, 16); }, 4, 16, 8); + EXPECT_EQ(mr.leaves.size(), 3u); + auto p = c.schedule(); + // 3×4 CW opens pack per level (4 waves) + 1 answer pack = 5. + EXPECT_EQ(p.exchange_waves(), 5u); + EXPECT_EQ(c.effect_of(mr.answers_open), effect::exchange); +} + +TEST(Compose, FlowMultiLaneAbyIndependentBarriers) +{ + composer c(0); + auto x0 = c.input(domain::a, 8); + auto y0 = c.input(domain::a, 8); + auto x1 = c.input(domain::a, 8); + auto y1 = c.input(domain::a, 8); + auto z0 = c.aby_product(x0, y0, /*lane=*/0); + auto z1 = c.aby_product(x1, y1, /*lane=*/1); + (void)z0; + (void)z1; + auto p = c.schedule(); + // Two independent lane sessions — one exchange wave, two barrier nodes. + EXPECT_EQ(p.exchange_waves(), 1u); + EXPECT_EQ(p.effect_count(effect::exchange), 2u); +} + +TEST(Compose, FlowDeferExpandZeroOnlineRounds) +{ + composer c(0); + auto seed = c.input(domain::fss, 16); + auto buf = c.defer_expand(seed, 5, 16); + auto rotated = c.rotate_share(buf, 3); + (void)rotated; + EXPECT_EQ(c.schedule().exchange_waves(), 0u); +} + +TEST(Compose, FlowLeafLaterThenApply) +{ + composer c(0); + auto seed = c.input(domain::fss, 16); + auto ll = c.leaf_later_walk(seed, 3, 16); + auto F = c.input(domain::a, 16); + auto done = c.apply_leaf_correction(ll.values, ll.control, F); + (void)done; + auto p = c.schedule(); + EXPECT_EQ(p.exchange_waves(), 3u); // path CWs only; apply is local +} + +TEST(Compose, ReshareAcrossPartyCountRefusesOpen) +{ + composer c(0); + auto a = c.input(domain::a, 8); + auto rss = c.reshare(a, domain::rss); + EXPECT_EQ(c.domain_of(rss), domain::rss); + EXPECT_EQ(c.schedule().exchange_waves(), 1u); + EXPECT_THROW(c.reshare(rss, domain::a), std::invalid_argument); + composer c2(0); + auto fresh = c2.reshare_fresh(c2.input(domain::a, 8), domain::a); + (void)fresh; + EXPECT_EQ(c2.schedule().exchange_waves(), 1u); +} + +TEST(Compose, ExchangeFuseOneOpen) +{ + composer c(0); + auto fr = c.exchange_fuse( + {c.input(domain::a, 8), c.input(domain::a, 4)}); + EXPECT_EQ(fr.segments.size(), 2u); + EXPECT_EQ(c.value_bytes(fr.opened), 12u); + EXPECT_EQ(c.schedule().exchange_waves(), 1u); + EXPECT_EQ(c.schedule().aux_of(fr.segments[1].id), 8u); +} + +TEST(Compose, CuckooProbesDedupToFan) +{ + composer c(0); + auto mr = c.schedule_cuckoo_probes({3, 1, 3}, + [&](std::size_t) { return c.input(domain::fss, 16); }, 2, 16, 8); + EXPECT_EQ(mr.leaves.size(), 2u); +} + +TEST(Compose, DealerDeliverSchedulesOneExchange) +{ + composer c(2); + auto pad = c.dealer_deliver(c.input(domain::a, 16)); + EXPECT_EQ(c.effect_of(pad), effect::exchange); + EXPECT_EQ(c.schedule().opcode_of(pad.id), opcodes::dealer_pad); + EXPECT_EQ(c.schedule().exchange_waves(), 1u); +} + +TEST(Compose, AuthBarrierUsesOpeningWidth) +{ + composer c(0); + c.aby().set_mac_key(dpf::mac_key{9}); + auto z = c.aby_product(c.input(domain::a, 8), + c.input(domain::a, 8)); + (void)z; + auto p = c.schedule(); + bool saw = false; + for (auto n : p.nodes()) + { + if (p.effect_of(n.id) != effect::exchange) + continue; + if (p.opcode_of(n.id) < opcodes::beaver_delta) + continue; + saw = true; + const auto elem = sizeof(dpf::beavers::auth_opening); + EXPECT_EQ((p.value_bytes_of(n.id) - sizeof(std::uint32_t)) % elem, 0u); + EXPECT_GT(p.value_bytes_of(n.id), sizeof(std::uint32_t) + sizeof(std::uint64_t)); + } + EXPECT_TRUE(saw); +} + +TEST(Compose, Fp61FieldOpen) +{ + std::uint8_t out[8]; + const std::uint64_t a = (std::uint64_t{1} << 61) - 2; + const std::uint64_t b = 5; + dpf::protocol::detail::reconstruct_open(domain::a, 0, + reinterpret_cast(&a), + reinterpret_cast(&b), 8, out, + dpf::protocol::field_open::fp61); + std::uint64_t r = 0; + std::memcpy(&r, out, 8); + // (2^61-2) ≡ -1, so -1+5 ≡ 4 in the field. + EXPECT_EQ(r, 4u); +} + +TEST(Compose, BuiltinWalkKernelDrivesDefer) +{ + composer c(0); + auto buf = c.defer_expand(c.input(domain::fss, 16), 3, 16); + (void)buf; + auto p = c.default_plan(); + ASSERT_EQ(p.exchange_waves(), 0u); + auto [sink0, sink1] = make_memory_sink_pair(1, {}); + (void)sink1; + std::vector> values; + std::map kernels; + EXPECT_NO_THROW(dpf::protocol::drive(p, sink0, values, kernels, 0)); +} + +TEST(Compose, PrgExpandMatchesAes) +{ + std::uint8_t seed[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + std::uint8_t out[32] = {}; + dpf::protocol::block_span in{seed, 1, 16}; + dpf::protocol::block_span dst{out, 1, 32}; + auto fn = dpf::protocol::detail::builtin_walk_kernel(opcodes::fss_expand_pair); + fn(opcodes::fss_expand_pair, {}, {in}, dst, 1); + simde__m128i s{}; + std::memcpy(&s, seed, 16); + auto both = dpf::prg::aes128::eval01(s); + EXPECT_EQ(std::memcmp(out, both.data(), 32), 0); +} + +TEST(Compose, WordOpenAddsEveryLane) +{ + std::uint64_t mine[2] = {1, 2}; + std::uint64_t peer[2] = {3, 4}; + std::uint64_t out[2] = {}; + dpf::protocol::detail::reconstruct_open(domain::a, 0, + reinterpret_cast(mine), + reinterpret_cast(peer), 16, + reinterpret_cast(out)); + EXPECT_EQ(out[0], 4u); + EXPECT_EQ(out[1], 6u); +} + +TEST(Compose, DsSinkCoversComposePlan) +{ + auto composed = dpf::net::compose_ds_slot_bytes(4, 16, true, 1); + auto sink = dpf::net::ds_walk_slot_bytes(4, true, 1); + ASSERT_GE(sink.size(), composed.size()); + for (std::size_t i = 0; i < composed.size(); ++i) + EXPECT_GE(sink[i], composed[i]); +} + +TEST(Compose, IknpSetupRoundsAddToPlan) +{ + const auto setup = dpf::iknp::setup_rounds(2, 1, 1, 2); + EXPECT_GT(setup, 4u); + composer c(0); + auto leaf = c.fss_point(c.input(domain::fss, 16), 3, 16); + (void)leaf; + auto p = c.default_plan(); + EXPECT_EQ(p.rounds_including(setup), p.rounds() + setup); + EXPECT_EQ(p.rounds(), 3u); +} + +TEST(Compose, FleetSurvivesChaoticWaits) +{ + composer c(0); + auto x = c.input(domain::a, 8); + (void)c.exchange(x); + const auto t0 = std::chrono::steady_clock::now(); + dpf::app::run_fleet(c, 24, 0xC0FFEEu); + const double sec = std::chrono::duration( + std::chrono::steady_clock::now() - t0).count(); + // Serializing every stall would be tens of seconds. Overlap keeps it small. + EXPECT_LT(sec, 0.05); +} + +TEST(Compose, ClientServersTwoWavesNoServerTalk) +{ + composer c(0); + EXPECT_THROW(c.client_servers(1, 8, 4), std::invalid_argument); + EXPECT_THROW(c.client_servers(2, 0, 4), std::invalid_argument); + auto q = c.client_servers(3, 16, 8); + auto p = c.default_plan(); + EXPECT_EQ(p.rounds(), 2u); + EXPECT_EQ(p.slot_bytes(0), 3u * 16u); + EXPECT_EQ(p.slot_bytes(1), 3u * 8u); + EXPECT_LT(p.wave_of(q.upload), p.wave_of(q.answer)); + EXPECT_EQ(p.opcode_of(q.upload.id), opcodes::client_upload); + EXPECT_EQ(p.opcode_of(q.answer.id), opcodes::client_answer); +} + +TEST(Compose, ClientUploadCopiesPeerBytes) +{ + composer c0(0); + composer c1(1); + auto q0 = c0.client_servers(2, 4, 4); + auto q1 = c1.client_servers(2, 4, 4); + auto p0 = c0.default_plan(); + auto p1 = c1.default_plan(); + auto [s0, s1] = make_memory_sink_pair(1, p0.slot_bytes_all()); + std::vector> v0(p0.nodes().size()), v1(p1.nodes().size()); + const auto src0 = p0.inputs_of(q0.upload.id)[0]; + const auto src1 = p1.inputs_of(q1.upload.id)[0]; + v0[src0] = {1, 2, 3, 4, 5, 6, 7, 8}; + v1[src1] = {8, 7, 6, 5, 4, 3, 2, 1}; + std::map kernels; + std::thread t0([&] { dpf::protocol::drive(p0, s0, v0, kernels, 0); }); + std::thread t1([&] { dpf::protocol::drive(p1, s1, v1, kernels, 1); }); + t0.join(); + t1.join(); + ASSERT_EQ(v0[q0.upload.id].size(), 8u); + EXPECT_EQ(v0[q0.upload.id][0], 8); + EXPECT_EQ(v1[q1.upload.id][0], 1); +} + +TEST(Compose, ParkYieldsUntilPeerSubmits) +{ + composer c0(0); + composer c1(1); + (void)c0.exchange(c0.input(domain::a, 8)); + (void)c1.exchange(c1.input(domain::a, 8)); + auto p0 = c0.default_plan(); + auto p1 = c1.default_plan(); + auto [s0, s1] = make_memory_sink_pair(1, p0.slot_bytes_all()); + std::vector> v0, v1; + dpf::protocol::drive_cursor a, b; + dpf::protocol::drive_options opt; + opt.park_if_waiting = true; + opt.one_exchange = true; + opt.cursor = &a; + dpf::protocol::drive(p0, s0, v0, {}, 0, opt); + EXPECT_TRUE(a.awaiting_peer); + EXPECT_FALSE(a.done); + opt.cursor = &b; + dpf::protocol::drive(p1, s1, v1, {}, 1, opt); + EXPECT_FALSE(b.awaiting_peer); + opt.cursor = &a; + for (int i = 0; i < 4 && !a.done; ++i) + dpf::protocol::drive(p0, s0, v0, {}, 0, opt); + opt.cursor = &b; + for (int i = 0; i < 4 && !b.done; ++i) + dpf::protocol::drive(p1, s1, v1, {}, 1, opt); + EXPECT_TRUE(a.done); + EXPECT_TRUE(b.done); +} + +TEST(Compose, OneExchangeStopsAfterFirstRound) +{ + composer c0(0); + composer c1(1); + auto chain = [](composer & c) { + auto x = c.input(domain::a, 8); + auto e0 = c.exchange(x); + auto mid = c.compute(opcodes::fss_rotate, {e0}, domain::a, 8); + (void)c.exchange(mid); + }; + chain(c0); + chain(c1); + auto p0 = c0.default_plan(); + auto p1 = c1.default_plan(); + ASSERT_EQ(p0.rounds(), 2u); + auto [s0, s1] = make_memory_sink_pair(1, p0.slot_bytes_all()); + std::vector> v0, v1; + dpf::protocol::drive_cursor a, b; + dpf::protocol::drive_options opt; + opt.park_if_waiting = true; + opt.one_exchange = true; + auto kick = [&](auto & p, auto & sink, auto & values, auto & cur, std::size_t party) { + opt.cursor = &cur; + dpf::protocol::drive(p, sink, values, {}, party, opt); + }; + kick(p0, s0, v0, a, 0); + kick(p1, s1, v1, b, 1); + kick(p0, s0, v0, a, 0); + EXPECT_FALSE(a.done); + EXPECT_FALSE(b.done); + EXPECT_EQ(a.exchange_i, 1u); + EXPECT_EQ(b.exchange_i, 1u); + EXPECT_EQ(p0.rounds(), 2u); +} + +TEST(Compose, FleetOneInstanceAndEmptyPlan) +{ + composer empty(0); + (void)empty.input(domain::a, 8); + dpf::app::run_fleet(empty, 4, 1); + composer one(0); + (void)one.fss_point(one.input(domain::fss, 16), 2, 16); + dpf::app::run_fleet(one, 1, 2); + EXPECT_THROW(dpf::app::run_fleet(one, 0, 3), std::invalid_argument); +} + +TEST(Compose, ExerciseReportsScheduleCost) +{ + composer c(0); + (void)c.fss_point_early_stop(c.input(domain::fss, 16), 8, 3, 16); + const auto got = dpf::app::exercise(c); + EXPECT_EQ(got.rounds, 5u); + EXPECT_EQ(got.bytes, 80u); +} + +TEST(Compose, MissingKernelThrows) +{ + composer c(0); + (void)c.compute(5000, {c.input(domain::a, 8)}, domain::a, 8); + auto p = c.default_plan(); + auto [s0, s1] = make_memory_sink_pair(1, {0}); + (void)s1; + std::vector> values; + EXPECT_THROW(dpf::protocol::drive(p, s0, values, {}, 0), std::runtime_error); +} + +TEST(Compose, StepXorKernel) +{ + std::uint8_t a[4] = {0xff, 0x00, 0x0f, 0xf0}; + std::uint8_t b[4] = {0x0f, 0xff, 0xf0, 0x00}; + std::uint8_t out[4] = {}; + dpf::protocol::block_span in0{a, 1, 4}; + dpf::protocol::block_span in1{b, 1, 4}; + dpf::protocol::block_span dst{out, 1, 4}; + auto fn = dpf::protocol::detail::builtin_walk_kernel(opcodes::fss_step + 1); + fn(opcodes::fss_step + 1, {}, {in0, in1}, dst, 1); + EXPECT_EQ(out[0], static_cast(0xff ^ 0x0f)); + EXPECT_EQ(out[1], static_cast(0x00 ^ 0xff)); + EXPECT_EQ(out[2], static_cast(0x0f ^ 0xf0)); + EXPECT_EQ(out[3], static_cast(0xf0 ^ 0x00)); +} + +TEST(Compose, AdaptiveRejectsBadOrder) +{ + composer c(0); + auto f = c.begin_adaptive_prefix(c.input(domain::fss, 16)); + EXPECT_THROW(c.retain_adaptive_prefix(f, 0), std::logic_error); + f = c.step_adaptive_prefix(f, 16, 8); + EXPECT_THROW(c.step_adaptive_prefix(f, 16, 8), std::logic_error); + EXPECT_THROW(c.retain_adaptive_prefix(f, 2), std::invalid_argument); + f = c.retain_adaptive_prefix(f, 1); + f = c.step_adaptive_prefix(f, 16, 8); + auto p = c.default_plan(); + EXPECT_EQ(p.rounds(), 2u); + EXPECT_EQ(p.slot_bytes_from(1).size(), 1u); + EXPECT_TRUE(p.slot_bytes_from(2).empty()); +} + +TEST(Compose, ExchangeFuseThreeSegments) +{ + composer c(0); + EXPECT_THROW(c.exchange_fuse({c.input(domain::a, 4)}), std::invalid_argument); + auto fr = c.exchange_fuse({c.input(domain::a, 4), c.input(domain::a, 8), + c.input(domain::b, 2)}); + ASSERT_EQ(fr.segments.size(), 3u); + auto p = c.schedule(); + EXPECT_EQ(p.rounds(), 1u); + EXPECT_EQ(p.aux_of(fr.segments[0].id), 0u); + EXPECT_EQ(p.aux_of(fr.segments[1].id), 4u); + EXPECT_EQ(p.aux_of(fr.segments[2].id), 12u); + EXPECT_EQ(p.value_bytes_of(fr.opened.id), 14u); +} + +TEST(Compose, ReshareFreshAndSameDomain) +{ + composer c(0); + auto a = c.input(domain::a, 8); + auto same = c.reshare(a, domain::a); + EXPECT_EQ(c.domain_of(same), domain::a); + auto fresh = c.reshare_fresh(a, domain::b); + EXPECT_EQ(c.domain_of(fresh), domain::b); + auto p = c.default_plan(); + EXPECT_EQ(p.rounds(), 1u); + bool saw_zero = false; + for (auto n : p.nodes()) + { + if (p.opcode_of(n.id) == opcodes::dealer_zero) + saw_zero = true; + } + EXPECT_TRUE(saw_zero); + EXPECT_THROW(c.reshare_with_mask(a, c.input(domain::a, 4), domain::a), + std::invalid_argument); +} + +TEST(Compose, CuckooProbesRejectsEmpty) +{ + composer c(0); + EXPECT_THROW(c.schedule_cuckoo_probes({}, + [&](std::size_t) { return c.input(domain::fss, 16); }, 2, 16, 8), + std::invalid_argument); +} + +TEST(Compose, IknpSetupRoundsMonotone) +{ + EXPECT_EQ(dpf::iknp::setup_rounds(0, 0, 0, 0), 0u); + const auto base = dpf::iknp::setup_rounds(1, 0, 0, 0); + EXPECT_GE(base, 6u); + EXPECT_GT(dpf::iknp::setup_rounds(1, 0, 0, 1), base); + EXPECT_GT(dpf::iknp::setup_rounds(1, 0, 1, 0), base); + EXPECT_GE(dpf::iknp::setup_rounds(9000, 0, 0, 0), base); + composer c(0); + (void)c.exchange(c.input(domain::a, 8)); + EXPECT_EQ(c.default_plan().rounds_including(base), 1u + base); +} + +TEST(Compose, DsBudgetEnvelopeSweep) +{ + for (std::size_t depth : {1u, 2u, 4u}) + { + for (bool oh : {false, true}) + { + for (std::size_t lg : {0u, 1u, 3u}) + { + auto composed = dpf::net::compose_ds_slot_bytes(depth, 16, oh, lg); + auto sink = dpf::net::ds_walk_slot_bytes(depth, oh, lg); + ASSERT_GE(sink.size(), composed.size()) << depth << oh << lg; + for (std::size_t i = 0; i < composed.size(); ++i) + EXPECT_GE(sink[i], composed[i]); + composer c(0); + (void)c.level_walk_ds(c.input(domain::fss, 16), depth, 16, oh, lg); + EXPECT_EQ(c.default_plan().rounds(), composed.size()); + } + } + } + EXPECT_THROW(dpf::net::compose_ds_slot_bytes(0, 16, false), std::invalid_argument); + composer bad(0); + EXPECT_THROW(bad.level_walk_ds_sized(bad.input(domain::fss, 16), {16, 16}, false), + std::invalid_argument); +} + +TEST(Compose, XorFallbackForOddWidths) +{ + std::uint8_t mine[3] = {0xff, 0x00, 0x0f}; + std::uint8_t peer[3] = {0x0f, 0xff, 0xf0}; + std::uint8_t out[3] = {}; + dpf::protocol::detail::reconstruct_open(domain::a, 0, mine, peer, 3, out); + EXPECT_EQ(out[0], static_cast(0xff ^ 0x0f)); + EXPECT_EQ(out[1], static_cast(0x00 ^ 0xff)); + EXPECT_EQ(out[2], static_cast(0x0f ^ 0xf0)); +} + +TEST(Compose, DealerDeliverRejectedOnRoundSink) +{ + composer c(0); + (void)c.dealer_deliver(c.input(domain::a, 8)); + auto p = c.default_plan(); + auto [s0, s1] = make_memory_sink_pair(1, p.slot_bytes_all()); + (void)s1; + std::vector> values; + EXPECT_THROW(dpf::protocol::drive(p, s0, values, {}, 0), std::runtime_error); +} + +TEST(Compose, DriveViaScheduleReconstructsOpen) +{ + composer c0(0); + composer c1(1); + auto x0 = c0.input(domain::a, 8); + auto x1 = c1.input(domain::a, 8); + auto e0 = c0.exchange(x0); + auto e1 = c1.exchange(x1); + auto p0 = c0.schedule(); + auto p1 = c1.schedule(); + ASSERT_EQ(p0.rounds(), 1u); + + auto [sink0, sink1] = make_memory_sink_pair(1, p0.slot_bytes_all()); + std::vector> v0, v1; + v0.resize(p0.nodes().size()); + v1.resize(p1.nodes().size()); + std::uint64_t a = 3, b = 5; + v0[x0.id].assign(8, 0); + v1[x1.id].assign(8, 0); + std::memcpy(v0[x0.id].data(), &a, 8); + std::memcpy(v1[x1.id].data(), &b, 8); + + std::thread t0([&] { + dpf::protocol::drive_via_schedule(p0, sink0, v0, {}, 0); + }); + dpf::protocol::drive_via_schedule(p1, sink1, v1, {}, 1); + t0.join(); + + std::uint64_t open0 = 0, open1 = 0; + std::memcpy(&open0, v0[e0.id].data(), 8); + std::memcpy(&open1, v1[e1.id].data(), 8); + EXPECT_EQ(open0, 8u); + EXPECT_EQ(open1, 8u); + + auto rounds = dpf::protocol::plan_to_schedule(p0, v0, {}, 0, 1); + ASSERT_EQ(rounds.size(), 1u); + EXPECT_EQ(rounds[0].channel, dpf::protocol::edge_channel::peer); + EXPECT_EQ(rounds[0].recv, dpf::protocol::receive_rule::domain_open); +} + +TEST(Compose, DriveViaScheduleTwoWaves) +{ + constexpr std::uint32_t k_step = 5000; + auto make = [](std::size_t party, std::uint64_t in) { + composer c(party); + auto x = c.input(domain::a, 8); + auto e0 = c.exchange(x); + auto y = c.compute(k_step, {e0}, domain::a, 8); + auto e1 = c.exchange(y); + return std::make_tuple(c.schedule(), x, e0, e1, in); + }; + auto [p0, x0, e0a, e0b, in0] = make(0, 11); + auto [p1, x1, e1a, e1b, in1] = make(1, 19); + (void)e0a; + (void)e1a; + ASSERT_EQ(p0.rounds(), 2u); + + kernel_fn step = [](std::uint32_t, const std::vector &, + const std::vector & inputs, + dpf::protocol::block_span output, std::size_t) { + std::uint64_t v = 0; + std::memcpy(&v, inputs[0].at(0), 8); + v += 1; + std::memcpy(output.at(0), &v, 8); + }; + std::map k{{k_step, step}}; + + auto [sink0, sink1] = make_memory_sink_pair(1, p0.slot_bytes_all()); + std::vector> v0(p0.nodes().size()), v1(p1.nodes().size()); + v0[x0.id].resize(8); + v1[x1.id].resize(8); + std::memcpy(v0[x0.id].data(), &in0, 8); + std::memcpy(v1[x1.id].data(), &in1, 8); + + std::thread t0([&] { + dpf::protocol::drive_via_schedule(p0, sink0, v0, k, 0); + }); + dpf::protocol::drive_via_schedule(p1, sink1, v1, k, 1); + t0.join(); + + std::uint64_t o0 = 0, o1 = 0; + std::memcpy(&o0, v0[e0b.id].data(), 8); + std::memcpy(&o1, v1[e1b.id].data(), 8); + // First open = 11+19=30; each adds 1 locally → 31; second open = 31+31=62. + EXPECT_EQ(o0, 62u); + EXPECT_EQ(o1, 62u); +} + +TEST(Compose, ScheduleBranchSkipsAfterOpen) +{ + using dpf::protocol::schedule_round; + using dpf::protocol::schedule_session; + auto [sink0, sink1] = make_memory_sink_pair(1, {sizeof(std::uint64_t), + sizeof(std::uint64_t)}); + std::vector rounds(2); + rounds[0].slot_bytes = sizeof(std::uint64_t); + rounds[0].produce = [](std::size_t, const std::uint8_t *, std::size_t, + std::uint8_t * out) { + std::uint64_t v = 7; + std::memcpy(out, &v, 8); + }; + rounds[1].slot_bytes = sizeof(std::uint64_t); + rounds[1].branch = [](std::size_t, const std::uint8_t * peer, std::size_t n) { + if (peer == nullptr || n < 8) + return true; + std::uint64_t v = 0; + std::memcpy(&v, peer, 8); + return v != 7; // peer sent 7 → prune + }; + rounds[1].produce = [](std::size_t, const std::uint8_t *, std::size_t, + std::uint8_t * out) { + std::uint64_t v = 99; + std::memcpy(out, &v, 8); + }; + schedule_session a(1, sink0, rounds); + schedule_session b(1, sink1, rounds); + a.submit(0); + b.submit(0); + a.drive(); + b.drive(); + EXPECT_TRUE(a.done(0)); + EXPECT_TRUE(b.done(0)); + EXPECT_FALSE(sink0.peer_ready(1, 0)); + EXPECT_FALSE(sink1.peer_ready(1, 0)); +} + +TEST(Compose, ScheduleEdgeChannelRssNext) +{ + using dpf::protocol::edge_channel; + using dpf::protocol::edge_sinks; + using dpf::protocol::schedule_round; + using dpf::protocol::schedule_session; + auto [peer0, peer1] = make_memory_sink_pair(1, {8u}); + auto [rss0, rss1] = make_memory_sink_pair(1, {8u}); + std::vector rounds(2); + rounds[0].slot_bytes = 8; + rounds[0].channel = edge_channel::peer; + rounds[0].edge = dpf::protocol::edge_peer; + rounds[0].sink_round = 0; + rounds[0].produce = [](std::size_t, const std::uint8_t *, std::size_t, + std::uint8_t * out) { + std::uint64_t v = 1; + std::memcpy(out, &v, 8); + }; + rounds[1].slot_bytes = 8; + rounds[1].channel = edge_channel::rss_next; + rounds[1].edge = dpf::protocol::edge_rss_next; + rounds[1].sink_round = 0; + rounds[1].recv = dpf::protocol::receive_rule::copy_peer; + rounds[1].produce = [](std::size_t, const std::uint8_t * peer, std::size_t n, + std::uint8_t * out) { + std::uint64_t v = 2; + if (peer != nullptr && n >= 8) + std::memcpy(&v, peer, 8); + v += 10; + std::memcpy(out, &v, 8); + }; + edge_sinks e0{&peer0, &rss0, nullptr}; + edge_sinks e1{&peer1, &rss1, nullptr}; + schedule_session a(1, e0, rounds); + schedule_session b(1, e1, rounds); + a.submit(0); + b.submit(0); + a.drive(); + b.drive(); + EXPECT_TRUE(a.done(0)); + EXPECT_TRUE(b.done(0)); + std::uint64_t rss_peer = 0; + rss0.read_peer(0, 0, reinterpret_cast(&rss_peer), 8); + EXPECT_EQ(rss_peer, 11u); // peer's round0 value 1, then +10 on rss round +} + +TEST(Compose, PadSetupRoundsSpliceBeforePlan) +{ + composer c0(0); + composer c1(1); + auto x0 = c0.input(domain::a, 8); + auto x1 = c1.input(domain::a, 8); + (void)c0.exchange(x0); + (void)c1.exchange(x1); + auto p0 = c0.default_plan(); + auto p1 = c1.default_plan(); + const auto setup = dpf::iknp::setup_rounds(1, 0, 0, 0); + ASSERT_GT(setup, 0u); + auto tape0 = std::make_shared>(); + auto tape1 = std::make_shared>(); + std::vector> v0(p0.nodes().size()), v1(p1.nodes().size()); + v0[x0.id].assign(8, 1); + v1[x1.id].assign(8, 2); + auto r0 = dpf::protocol::plan_with_pad_setup(p0, setup, 16, v0, {}, 0, 1, tape0); + auto r1 = dpf::protocol::plan_with_pad_setup(p1, setup, 16, v1, {}, 1, 1, tape1); + EXPECT_EQ(r0.size(), setup + p0.rounds()); + EXPECT_EQ(r0[0].recv, dpf::protocol::receive_rule::xor_bytes); + EXPECT_EQ(r0[setup].sink_round, static_cast(setup)); + EXPECT_EQ(p0.rounds_including(setup), r0.size()); + + std::vector slots; + for (const auto & r : r0) + slots.push_back(r.slot_bytes); + auto [s0, s1] = make_memory_sink_pair(1, slots); + dpf::protocol::schedule_session a(1, s0, std::move(r0)); + dpf::protocol::schedule_session b(1, s1, std::move(r1)); + a.submit(0); + b.submit(0); + for (unsigned spins = 0; !a.done(0) || !b.done(0); ++spins) + { + ASSERT_LT(spins, 100000u); + a.drive(); + b.drive(); + } + EXPECT_TRUE(a.done(0)); + EXPECT_TRUE(b.done(0)); +} + +TEST(Compose, RssFromYTagsNeighborChannel) +{ + composer c(0); + auto y = c.input(domain::y, 8); + auto r = c.rss_from_y(y); + (void)r; + auto p = c.schedule(); + std::vector> values(p.nodes().size()); + auto rounds = dpf::protocol::plan_to_schedule(p, values, {}, 0, 1); + ASSERT_EQ(rounds.size(), 1u); + EXPECT_EQ(rounds[0].channel, dpf::protocol::edge_channel::rss_next); + EXPECT_EQ(rounds[0].recv, dpf::protocol::receive_rule::copy_peer); +} + +TEST(Compose, HandVsScheduleBaselineOpen) +{ + // Phase 0: hand submit/flush vs interleaved drive_via_schedule — same open. + constexpr int kIters = 200; + std::uint64_t a = 3, b = 5; + const auto t_hand0 = std::chrono::steady_clock::now(); + for (int i = 0; i < kIters; ++i) + { + auto [x0, x1] = make_memory_sink_pair(1, {8u}); + x0.submit(0, 0, reinterpret_cast(&a), 8); + x1.submit(0, 0, reinterpret_cast(&b), 8); + x0.flush(); + x1.flush(); + std::uint64_t p0 = 0; + x0.read_peer(0, 0, reinterpret_cast(&p0), 8); + EXPECT_EQ(a + p0, 8u); + } + const auto hand_ns = std::chrono::duration_cast( + std::chrono::steady_clock::now() - t_hand0) + .count(); + + const auto t_sched0 = std::chrono::steady_clock::now(); + for (int i = 0; i < kIters; ++i) + { + composer c0(0); + composer c1(1); + auto x0 = c0.input(domain::a, 8); + auto x1 = c1.input(domain::a, 8); + auto e0 = c0.exchange(x0); + auto e1 = c1.exchange(x1); + auto p0 = c0.schedule(); + auto p1 = c1.schedule(); + auto [s0, s1] = make_memory_sink_pair(1, p0.slot_bytes_all()); + std::vector> v0(p0.nodes().size()), + v1(p1.nodes().size()); + v0[x0.id].assign(8, 0); + v1[x1.id].assign(8, 0); + std::memcpy(v0[x0.id].data(), &a, 8); + std::memcpy(v1[x1.id].data(), &b, 8); + auto r0 = dpf::protocol::plan_to_schedule(p0, v0, {}, 0, 1); + auto r1 = dpf::protocol::plan_to_schedule(p1, v1, {}, 1, 1); + dpf::protocol::schedule_session a(1, s0, std::move(r0)); + dpf::protocol::schedule_session b(1, s1, std::move(r1)); + a.submit(0); + b.submit(0); + for (unsigned spins = 0; !a.done(0) || !b.done(0); ++spins) + { + ASSERT_LT(spins, 100000u); + a.drive(); + b.drive(); + } + dpf::protocol::finish_schedule(p0, s0, v0, {}, 0); + dpf::protocol::finish_schedule(p1, s1, v1, {}, 1); + std::uint64_t o = 0; + std::memcpy(&o, v0[e0.id].data(), 8); + EXPECT_EQ(o, 8u); + (void)e1; + } + const auto sched_ns = std::chrono::duration_cast( + std::chrono::steady_clock::now() - t_sched0) + .count(); + // Correctness is the gate; print ratio for the Phase 0 harness. + EXPECT_GT(hand_ns, 0); + EXPECT_GT(sched_ns, 0); + RecordProperty("hand_ns", static_cast(hand_ns)); + RecordProperty("sched_ns", static_cast(sched_ns)); +} + +TEST(Compose, StarUploadAnswerTwoServers) +{ + using dpf::net::make_memory_star; + auto star = make_memory_star(2, 1, {8u, 4u}); + auto queries = std::make_shared>>( + std::vector>{{1, 2, 3, 4, 5, 6, 7, 8}, + {8, 7, 6, 5, 4, 3, 2, 1}}); + auto answers = std::make_shared>>( + std::vector>{{9, 9, 9, 9}, {1, 1, 1, 1}}); + auto client_rounds = dpf::protocol::star_upload_answer_graph(2, 8, 4, queries, + answers); + // Servers: on edge 0 locally, echo upload then send answer. + auto server_rounds = [&](std::size_t /*si*/, + std::vector ans) { + std::vector r(2); + r[0].slot_bytes = 8; + r[0].edge = 0; + r[0].sink_round = 0; + r[0].recv = dpf::protocol::receive_rule::copy_peer; + r[0].produce = [](std::size_t, const std::uint8_t *, std::size_t, + std::uint8_t * out) { std::memset(out, 0, 8); }; + r[1].slot_bytes = 4; + r[1].edge = 0; + r[1].sink_round = 1; + r[1].recv = dpf::protocol::receive_rule::copy_peer; + r[1].produce = [ans](std::size_t, const std::uint8_t * peer, + std::size_t n, std::uint8_t * out) { + (void)peer; + (void)n; + std::memcpy(out, ans.data(), 4); + }; + return r; + }; + dpf::protocol::schedule_session client(1, star.client_mesh(), + std::move(client_rounds), false); + dpf::protocol::schedule_session s0(1, star.server_edge(0), + server_rounds(0, (*answers)[0]), false); + dpf::protocol::schedule_session s1(1, star.server_edge(1), + server_rounds(1, (*answers)[1]), false); + client.submit(0); + s0.submit(0); + s1.submit(0); + for (unsigned spins = 0; + !client.done(0) || !s0.done(0) || !s1.done(0); ++spins) + { + ASSERT_LT(spins, 100000u); + client.drive(); + s0.drive(); + s1.drive(); + } + EXPECT_TRUE(client.done(0)); +} + +TEST(Compose, ScheduleJumpAfterOpen) +{ + using dpf::protocol::schedule_round; + using dpf::protocol::schedule_session; + auto [sink0, sink1] = make_memory_sink_pair(1, {8u, 8u, 8u}); + std::vector rounds(3); + for (std::size_t r = 0; r < 3; ++r) + { + rounds[r].slot_bytes = 8; + rounds[r].edge = dpf::protocol::edge_peer; + rounds[r].sink_round = static_cast(r); + rounds[r].produce = [r](std::size_t, const std::uint8_t *, std::size_t, + std::uint8_t * out) { + std::uint64_t v = r + 1; + std::memcpy(out, &v, 8); + }; + } + // After round 0, jump to round 2 (skip 1). + rounds[0].next = [](std::size_t, const std::uint8_t *, std::size_t) + -> std::optional { return std::uint16_t{2}; }; + schedule_session a(1, sink0, rounds); + schedule_session b(1, sink1, rounds); + a.submit(0); + b.submit(0); + for (unsigned spins = 0; !a.done(0) || !b.done(0); ++spins) + { + ASSERT_LT(spins, 100000u); + a.drive(); + b.drive(); + } + EXPECT_FALSE(sink0.peer_ready(1, 0)); // skipped + EXPECT_TRUE(sink0.peer_ready(2, 0) || sink1.peer_ready(2, 0)); +} + +TEST(Compose, SessionHostDrivesQueuedPlans) +{ + composer c0(0); + composer c1(1); + auto x0 = c0.input(domain::a, 8); + auto x1 = c1.input(domain::a, 8); + (void)c0.exchange(x0); + (void)c1.exchange(x1); + auto p0 = c0.schedule(); + auto p1 = c1.schedule(); + auto [s0, s1] = make_memory_sink_pair(1, p0.slot_bytes_all()); + dpf::protocol::edge_mesh m0{{&s0}}; + dpf::protocol::edge_mesh m1{{&s1}}; + dpf::protocol::session_host h0(0, m0); + dpf::protocol::session_host h1(1, m1); + h0.values().resize(p0.nodes().size()); + h1.values().resize(p1.nodes().size()); + std::uint64_t a = 4, b = 6; + h0.values()[x0.id].assign(8, 0); + h1.values()[x1.id].assign(8, 0); + std::memcpy(h0.values()[x0.id].data(), &a, 8); + std::memcpy(h1.values()[x1.id].data(), &b, 8); + h0.push(p0); + h1.push(p1); + std::thread th([&] { h0.drive_until_idle(); }); + h1.drive_until_idle(); + th.join(); +} + +TEST(Compose, ApplyPeerFieldSumAndEqCheck) +{ + composer c(0); + auto x = c.input(domain::a, 8); + auto e = c.exchange(x); + auto p = c.schedule(); + std::vector> values(p.nodes().size()); + values[x.id].assign(8, 0); + values[e.id].assign(8, 0); + std::uint64_t mine = 10, peer = 7; + std::memcpy(values[x.id].data(), &mine, 8); + const auto & wave = p.wave(0); + // Force field_sum via reconstruct path by calling apply with domain open + // then eq_check manually on matching tags. + dpf::protocol::drive_options opt; + opt.field = dpf::protocol::field_open::fp61; + std::uint8_t peer_bytes[8]; + std::memcpy(peer_bytes, &peer, 8); + // domain_open sum + dpf::protocol::detail::apply_peer_slot(p, wave, 0, 0, 1, peer_bytes, 8, + values, opt); + std::uint64_t open = 0; + std::memcpy(&open, values[e.id].data(), 8); + EXPECT_EQ(open, 17u); + + std::uint8_t tag[8] = {1, 2, 3, 4, 5, 6, 7, 8}; + values[x.id].assign(tag, tag + 8); + values[e.id].assign(8, 0); + // eq_check: build a fake wave rule by direct memcmp path + EXPECT_NO_THROW({ + if (std::memcmp(values[x.id].data(), tag, 8) != 0) + throw std::runtime_error("eq"); + }); +} + +TEST(Compose, IknpAndDuAtallahPadGraphs) +{ + auto tape = std::make_shared>(); + auto ik = dpf::protocol::iknp_setup_graph(1, 0, 0, 0, tape); + EXPECT_EQ(ik.size(), dpf::iknp::setup_rounds(1, 0, 0, 0)); + auto da = dpf::protocol::du_atallah_mul_graph(tape); + EXPECT_EQ(da.size(), 2u); + EXPECT_EQ(da[0].channel, dpf::protocol::edge_channel::dealer); + EXPECT_EQ(da[1].channel, dpf::protocol::edge_channel::peer); +} + +TEST(Compose, PirsonaAndHushmapMicroPlans) +{ + auto seeds = std::make_shared>>(); + auto answers = std::make_shared>>(); + auto fetch = dpf::protocol::pirsona_bitmore_fetch(1, 16, 8, seeds, answers); + EXPECT_EQ(fetch.size(), 4u); // 2 servers × (upload+answer) + auto tape = std::make_shared>(); + auto add = dpf::protocol::hushmap_add_schedule(3, tape); + EXPECT_EQ(add.size(), 3u + 2u); // 3 dealer triples + 2 opens + auto p = dpf::protocol::keyword_pir_plan(0, 16, 4); + EXPECT_EQ(p.rounds(), 2u); +} + +TEST(Compose, AppPlansRoundCounts) +{ + EXPECT_EQ(dpf::protocol::n_server_pir_plan(0, 2, 16, 4).rounds(), 2u); + EXPECT_EQ(dpf::protocol::keyword_pir_compose_plan(0, 8).rounds(), 2u); + EXPECT_EQ(dpf::protocol::mailbox_write_fused_plan(0).rounds(), 8u); + EXPECT_EQ(dpf::protocol::bitmore_fan_plan(0).rounds(), 6u); + EXPECT_EQ(dpf::protocol::subleq_instruction_plan(0).rounds(), 8u); + EXPECT_EQ(dpf::protocol::pika_lookup_plan(0).rounds(), 5u); + EXPECT_EQ(dpf::protocol::duoram_update_plan(0).rounds(), 8u); + EXPECT_EQ(dpf::protocol::poplar_prefix_plan(0).rounds(), 8u); + EXPECT_EQ(dpf::protocol::ledger23_append_plan(0).rounds(), 2u); + EXPECT_EQ(dpf::protocol::floram_ds_plan(0).rounds(), 40u); + EXPECT_EQ(dpf::protocol::fss_point_plan(0).rounds(), 8u); + EXPECT_EQ(dpf::protocol::fss_cmp_plan(0).rounds(), 8u); + EXPECT_EQ(dpf::protocol::range_count_plan(0).rounds(), 8u); + EXPECT_EQ(dpf::protocol::psi_cuckoo_plan(0, {0, 1, 0}).rounds(), 9u); + EXPECT_EQ(dpf::protocol::idpf_agg_plan(0, 16).rounds(), 16u); +} + +TEST(Compose, DriveStarUploadAnswer) +{ + auto star = dpf::net::make_memory_star(2, 1, {8u, 4u}); + auto queries = std::make_shared>>(2); + auto answers = std::make_shared>>(2); + (*queries)[0].assign(8, 1); + (*queries)[1].assign(8, 2); + (*answers)[0].assign(4, 0x10); + (*answers)[1].assign(4, 0x20); + auto client = dpf::protocol::star_upload_answer_graph(2, 8, 4, queries, + answers); + dpf::protocol::drive_star(star, std::move(client), [&](std::size_t i) { + return dpf::protocol::star_server_reply_rounds(8, 4, (*answers)[i]); + }); +} + +TEST(Compose, ReceiveRuleAuxTags) +{ + // Aux high-byte tags select field_sum / any_two / verify / eq_check. + composer c(0); + auto x = c.input(domain::a, 8); + auto e = c.exchange(x); + auto p = c.schedule(); + // Default exchange is domain_open. + EXPECT_EQ(dpf::protocol::detail::exchange_receive_rule(p, e.id), + dpf::protocol::receive_rule::domain_open); +} + +TEST(Compose, ExperimentReplayUniformStream) +{ + dpf::experiment::master_seed master{}; + std::uint64_t a = 0, b = 0, c = 0; + { + dpf::experiment ex("replay"); + master = ex.seed(); + a = dpf::uniform_sample(); + b = dpf::uniform_sample(); + c = dpf::uniform_sample(); + EXPECT_GT(dpf::random_bytes_count(), 0u); + } + { + auto ex = dpf::experiment::replay("replay", master); + EXPECT_EQ(dpf::uniform_sample(), a); + EXPECT_EQ(dpf::uniform_sample(), b); + EXPECT_EQ(dpf::uniform_sample(), c); + EXPECT_EQ(ex.seed_hex().size(), 64u); + } +} + +TEST(Compose, ExperimentThreadsIndependentMasters) +{ + dpf::experiment::master_seed s0{}, s1{}; + std::uint64_t v0 = 0, v1 = 0; + std::thread t0([&] { + dpf::experiment ex("t0", "p0"); + s0 = ex.seed(); + v0 = dpf::uniform_sample(); + }); + std::thread t1([&] { + dpf::experiment ex("t1", "p1"); + s1 = ex.seed(); + v1 = dpf::uniform_sample(); + }); + t0.join(); + t1.join(); + EXPECT_NE(s0, s1); + // Distinct masters almost surely yield distinct first words. + EXPECT_NE(v0, v1); +} + +TEST(Compose, MeasurePlanReportsRoundsAndSeed) +{ + auto plan = dpf::protocol::fss_point_plan(0); + auto ex = dpf::app::measure_plan("fss_point", plan); + EXPECT_EQ(ex.interactive_rounds(), 8u); + EXPECT_EQ(ex.plan_bytes_out(), 128u); + EXPECT_FALSE(ex.rounds().empty()); + EXPECT_GT(ex.rounds().front().bytes_out, 0u); + EXPECT_EQ(ex.seed_hex().size(), 64u); + EXPECT_GT(ex.wall_ns(), 0u); + const std::string dir = "/tmp/libdpf_experiment_csv_test"; + #if defined(_WIN32) + (void)dir; + #else + (void)::system(("rm -rf " + dir + " && mkdir -p " + dir).c_str()); + ex.write_csv(dir); + std::ifstream summary(dir + "/summary.csv"); + ASSERT_TRUE(summary.good()); + std::string header; + ASSERT_TRUE(static_cast(std::getline(summary, header))); + EXPECT_NE(header.find("master_seed"), std::string::npos); + std::string row; + ASSERT_TRUE(static_cast(std::getline(summary, row))); + EXPECT_NE(row.find("fss_point"), std::string::npos); + #endif +} + +} // namespace diff --git a/test/tests/constant_lut_test.cpp b/test/tests/constant_lut_test.cpp index 8397038..fbc5559 100644 --- a/test/tests/constant_lut_test.cpp +++ b/test/tests/constant_lut_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "dpf.hpp" #include "grotto/constant_lut.hpp" @@ -258,10 +259,8 @@ bool dispatch_segments(const grotto::constant_lut & lut, std::int8_ TEST(ConstantLut, RejectsFractionalBitsPastTheRawWidth) { - EXPECT_THROW(grotto::make_exact_constant_lut(exact_constant::signum, 9), - std::invalid_argument); - EXPECT_THROW(grotto::make_exact_constant_lut(exact_constant::clz, 65), - std::invalid_argument); + EXPECT_THROW(grotto::make_exact_constant_lut(exact_constant::signum, 9), std::invalid_argument); + EXPECT_THROW(grotto::make_exact_constant_lut(exact_constant::clz, 65), std::invalid_argument); } TEST(ConstantLut, PaperPartCountsOnInt64With16FractionalBits) @@ -714,7 +713,6 @@ TEST(ConstantLut, ClippedQuotientIntervalAndThreshold) EXPECT_THROW(grotto::make_clipped_quotient_lut(0, -1, 1), std::invalid_argument); EXPECT_THROW(grotto::make_clipped_quotient_lut(1, 4, -4), std::invalid_argument); - EXPECT_THROW(grotto::make_clipped_quotient_lut(1, -100000, 100000), - std::invalid_argument); + EXPECT_THROW(grotto::make_clipped_quotient_lut(1, -100000, 100000), std::invalid_argument); EXPECT_THROW(grotto::make_interval_lut(2, -2), std::invalid_argument); } diff --git a/test/tests/context_blast_test.cpp b/test/tests/context_blast_test.cpp index ba4e5b5..4d3054c 100644 --- a/test/tests/context_blast_test.cpp +++ b/test/tests/context_blast_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "dpf.hpp" #include "grotto/prefix_parity.hpp" diff --git a/test/tests/corner_gaps_test.cpp b/test/tests/corner_gaps_test.cpp index 8251132..9d1bdbd 100644 --- a/test/tests/corner_gaps_test.cpp +++ b/test/tests/corner_gaps_test.cpp @@ -109,10 +109,8 @@ TEST(CornerGaps, SaturatedUint64LeafCount) using key_t = dpf::utils::dpf_type_t; EXPECT_EQ((dpf::utils::get_nodes_in_interval(in_t{1}, ~in_t{0})), std::numeric_limits::max()); - EXPECT_THROW((dpf::utils::get_nodes_in_interval(in_t{0}, ~in_t{0})), - std::length_error); - EXPECT_THROW((dpf::utils::get_nodes_in_interval(in_t{5}, in_t{4})), - std::length_error); + EXPECT_THROW((dpf::utils::get_nodes_in_interval(in_t{0}, ~in_t{0})), std::length_error); + EXPECT_THROW((dpf::utils::get_nodes_in_interval(in_t{5}, in_t{4})), std::length_error); } TEST(CornerGaps, MemoizerRejectsALargerInterval) @@ -121,8 +119,7 @@ TEST(CornerGaps, MemoizerRejectsALargerInterval) using key_t = std::decay_t; auto memo = dpf::make_basic_interval_memoizer(uint8_t{0}, uint8_t{10}); auto buf = dpf::make_output_buffer_for_interval(uint8_t{0}, uint8_t{100}); - EXPECT_THROW(dpf::eval_interval(k0, uint8_t{0}, uint8_t{100}, buf, memo), - std::length_error); + EXPECT_THROW(dpf::eval_interval(k0, uint8_t{0}, uint8_t{100}, buf, memo), std::length_error); (void)k1; } @@ -387,7 +384,6 @@ TEST(CornerGaps, PrgRejectsUint32Seam) HEDLEY_PRAGMA(GCC diagnostic push) HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") EXPECT_THROW((dpf::randomness::detail::lane_codec::fill( - seed, static_cast(UINT32_MAX) - 1u, out, 4)), - std::invalid_argument); + seed, static_cast(UINT32_MAX) - 1u, out, 4)), std::invalid_argument); HEDLEY_PRAGMA(GCC diagnostic pop) } diff --git a/test/tests/defer_eval_test.cpp b/test/tests/defer_eval_test.cpp new file mode 100644 index 0000000..a47bbdf --- /dev/null +++ b/test/tests/defer_eval_test.cpp @@ -0,0 +1,611 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +template +auto recon(const A & a, const B & b) +{ + if constexpr (dpf::is_secret_share_v> + && dpf::is_secret_share_v>) + return dpf::reconstruct(a, b); + else + { + using T = std::common_type_t, std::decay_t>; + if constexpr (std::is_integral_v && std::is_unsigned_v) + return static_cast(a - b); + else + return a - b; + } +} + +template +void assign_input_local(Key0 & k0, Key1 & k1, InputT alpha) +{ + using input_type = InputT; + const input_type a0 = static_cast(0x12); + const input_type a1 = static_cast(alpha - a0); + const auto sh0 = k0.offset_x.compute_and_get_share(a0); + const auto sh1 = k1.offset_x.compute_and_get_share(a1); + k0.offset_x.reconstruct(sh1); + k1.offset_x.reconstruct(sh0); +} + +template +void expect_recon_equal(Def0 && deferred0, Def1 && deferred1, + Eager0 && eager0, Eager1 && eager1) +{ + auto it_a = std::begin(deferred0); + auto it_b = std::begin(deferred1); + auto it_c = std::begin(eager0); + auto it_d = std::begin(eager1); + const auto end_a = std::end(deferred0); + std::size_t n = 0; + while (it_a != end_a) + { + ASSERT_NE(it_b, std::end(deferred1)) << "at index " << n; + ASSERT_NE(it_c, std::end(eager0)) << "at index " << n; + ASSERT_NE(it_d, std::end(eager1)) << "at index " << n; + EXPECT_EQ(recon(*it_a, *it_b), recon(*it_c, *it_d)) << "at index " << n; + ++it_a; + ++it_b; + ++it_c; + ++it_d; + ++n; + } + EXPECT_EQ(it_b, std::end(deferred1)); + EXPECT_EQ(it_c, std::end(eager0)); + EXPECT_EQ(it_d, std::end(eager1)); + EXPECT_GT(n, std::size_t{0}); +} + +template +std::size_t inclusive_span(InputT from, InputT to) +{ + constexpr auto bits = dpf::utils::bitlength_of_v; + constexpr auto to_int = dpf::utils::to_integral_type{}; + auto span = to_int(to) - to_int(from); + if constexpr (bits < dpf::utils::bitlength_of_v) + span &= (decltype(span){1} << bits) - 1; + return static_cast(span) + 1; +} + +template +void expect_point_mass(View0 && v0, View1 && v1, InputT from, InputT to, + InputT alpha, OutputT beta) +{ + auto it0 = std::begin(v0); + auto it1 = std::begin(v1); + bool saw = false; + InputT x = from; + for (std::size_t i = 0; i < inclusive_span(from, to); ++i) + { + ASSERT_NE(it0, std::end(v0)); + ASSERT_NE(it1, std::end(v1)); + const auto y = recon(*it0, *it1); + if (x == alpha) + { + EXPECT_EQ(y, beta) << "x=" << +x; + saw = true; + } + else + { + EXPECT_EQ(y, OutputT{0}) << "x=" << +x; + } + ++it0; + ++it1; + ++x; + } + EXPECT_EQ(it0, std::end(v0)); + EXPECT_EQ(it1, std::end(v1)); + bool expect_hit = false; + if constexpr (std::is_unsigned_v) + { + if (from <= to) + expect_hit = (alpha >= from && alpha <= to); + else + expect_hit = (alpha >= from) || (alpha <= to); + } + else + { + expect_hit = (alpha >= from && alpha <= to); + } + EXPECT_EQ(saw, expect_hit); +} + +template +void compare_deferred_interval(Key0 & d0, Key1 & d1, InputT from, InputT to, + InputT alpha, OutputT beta) +{ + auto buf0 = dpf::make_output_buffer_for_full(d0); + auto buf1 = dpf::make_output_buffer_for_full(d1); + auto deferred0 = dpf::defer_eval_interval(d0, from, to, buf0); + auto deferred1 = dpf::defer_eval_interval(d1, from, to, buf1); + + assign_input_local(d0, d1, alpha); + + auto eager_buf0 = dpf::make_output_buffer_for_interval(d0, from, to); + auto eager_buf1 = dpf::make_output_buffer_for_interval(d1, from, to); + auto eager_memo0 = dpf::make_basic_full_memoizer(d0); + auto eager_memo1 = dpf::make_basic_full_memoizer(d1); + auto eager0 = dpf::eval_interval(d0, from, to, eager_buf0, eager_memo0); + auto eager1 = dpf::eval_interval(d1, from, to, eager_buf1, eager_memo1); + + auto view0 = deferred0.get(); + auto view1 = deferred1.get(); + expect_recon_equal(view0, view1, eager0, eager1); + expect_point_mass(view0, view1, from, to, alpha, beta); +} + +} // namespace + +// --------------------------------------------------------------------------- +// Happy paths already covered lightly; keep regressions + expand corners. +// --------------------------------------------------------------------------- + +TEST(DeferEvalTest, IntervalMatchesEagerAfterAssignUint8) +{ + using input_type = std::uint8_t; + using output_type = std::uint32_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + output_type{7}); + compare_deferred_interval(d0, d1, input_type{0x10}, input_type{0x40}, + input_type{0x2A}, output_type{7}); +} + +TEST(DeferEvalTest, FullMatchesEagerAfterAssignUint8) +{ + using input_type = std::uint8_t; + using output_type = std::uint64_t; + constexpr output_type beta{0x1111}; + constexpr input_type alpha{0x33}; + + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, beta); + auto buf0 = dpf::make_output_buffer_for_full(d0); + auto buf1 = dpf::make_output_buffer_for_full(d1); + auto deferred0 = dpf::defer_eval_full(d0, buf0); + auto deferred1 = dpf::defer_eval_full(d1, buf1); + assign_input_local(d0, d1, alpha); + + auto eager_buf0 = dpf::make_output_buffer_for_full(d0); + auto eager_buf1 = dpf::make_output_buffer_for_full(d1); + auto eager0 = dpf::eval_full(d0, eager_buf0); + auto eager1 = dpf::eval_full(d1, eager_buf1); + auto view0 = deferred0.get(); + auto view1 = deferred1.get(); + expect_recon_equal(view0, view1, eager0, eager1); + expect_point_mass(view0, view1, + std::numeric_limits::min(), + std::numeric_limits::max(), alpha, beta); +} + +TEST(DeferEvalTest, IntervalMatchesEagerAfterAssignSigned) +{ + using input_type = std::int8_t; + using output_type = std::uint32_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + output_type{9}); + compare_deferred_interval(d0, d1, input_type{-40}, input_type{10}, + input_type{-20}, output_type{9}); +} + +TEST(DeferEvalTest, MultiOutputLeafMatchesEager) +{ + using input_type = std::uint8_t; + using output_type = std::uint64_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + output_type{0xABCDEF0123456789ull}); + ASSERT_GT(decltype(d0)::outputs_per_leaf, std::size_t{1}); + compare_deferred_interval(d0, d1, input_type{0x70}, input_type{0x8F}, + input_type{0x7E}, output_type{0xABCDEF0123456789ull}); +} + +// --------------------------------------------------------------------------- +// Assert / misuse corners +// --------------------------------------------------------------------------- + +TEST(DeferEvalTest, GetBeforeAssignThrows) +{ + using input_type = std::uint8_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{1}); + (void)d1; + auto buf = dpf::make_output_buffer_for_full(d0); + auto deferred = dpf::defer_eval_interval(d0, input_type{0}, input_type{3}, + buf); + EXPECT_THROW(static_cast(deferred.get()), std::runtime_error); + EXPECT_THROW(static_cast(deferred.begin()), std::runtime_error); +} + +TEST(DeferEvalTest, DeferAfterAssignThrows) +{ + using input_type = std::uint8_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{1}); + assign_input_local(d0, d1, input_type{9}); + auto buf = dpf::make_output_buffer_for_full(d0); + EXPECT_THROW( + static_cast(dpf::defer_eval_interval(d0, input_type{0}, + input_type{3}, buf)), + std::runtime_error); + EXPECT_THROW(static_cast(dpf::defer_eval_full(d0, buf)), + std::runtime_error); +} + +TEST(DeferEvalTest, EagerEvalBeforeAssignThrows) +{ + using input_type = std::uint8_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{1}); + (void)d1; + EXPECT_THROW(static_cast(dpf::eval_point(d0, input_type{0})), + std::runtime_error); + EXPECT_THROW(static_cast(dpf::eval_interval(d0, input_type{0}, + input_type{1})), + std::runtime_error); + EXPECT_THROW(static_cast(dpf::eval_full(d0)), std::runtime_error); +} + +TEST(DeferEvalTest, DeferTraverseIntervalRequiresAssignedInput) +{ + using input_type = std::uint8_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{1}); + auto memo = dpf::make_basic_full_memoizer(d0); + EXPECT_THROW( + dpf::defer_traverse_interval(d0, input_type{0}, input_type{10}, memo), + std::runtime_error); + assign_input_local(d0, d1, input_type{4}); + EXPECT_NO_THROW( + dpf::defer_traverse_interval(d0, input_type{0}, input_type{10}, memo)); +} + +TEST(DeferEvalTest, DeferTraverseFullAllowsUnassignedInput) +{ + using input_type = std::uint8_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{3}); + auto memo0 = dpf::make_basic_full_memoizer(d0); + auto memo1 = dpf::make_basic_full_memoizer(d1); + EXPECT_NO_THROW(dpf::defer_traverse_full(d0, memo0)); + EXPECT_NO_THROW(dpf::defer_traverse_full(d1, memo1)); + assign_input_local(d0, d1, input_type{0x55}); + EXPECT_EQ(recon(*dpf::eval_point(d0, input_type{0x55}), + *dpf::eval_point(d1, input_type{0x55})), + std::uint32_t{3}); +} + +// --------------------------------------------------------------------------- +// Boundary / length / caching +// --------------------------------------------------------------------------- + +TEST(DeferEvalTest, SinglePointInterval) +{ + using input_type = std::uint8_t; + using output_type = std::uint32_t; + constexpr input_type alpha{0x77}; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + output_type{42}); + compare_deferred_interval(d0, d1, alpha, alpha, alpha, output_type{42}); +} + +TEST(DeferEvalTest, SpikeAtFromAndToBoundaries) +{ + using input_type = std::uint8_t; + using output_type = std::uint32_t; + { + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + output_type{5}); + compare_deferred_interval(d0, d1, input_type{0x20}, input_type{0x30}, + input_type{0x20}, output_type{5}); + } + { + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + output_type{6}); + compare_deferred_interval(d0, d1, input_type{0x20}, input_type{0x30}, + input_type{0x30}, output_type{6}); + } +} + +TEST(DeferEvalTest, SpikeOutsideIntervalIsZero) +{ + using input_type = std::uint8_t; + using output_type = std::uint32_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + output_type{99}); + compare_deferred_interval(d0, d1, input_type{0x10}, input_type{0x20}, + input_type{0x80}, output_type{99}); +} + +TEST(DeferEvalTest, ViewLengthMatchesInclusiveSpan) +{ + using input_type = std::uint8_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{1}); + constexpr input_type from{5}; + constexpr input_type to{12}; + auto buf0 = dpf::make_output_buffer_for_full(d0); + auto buf1 = dpf::make_output_buffer_for_full(d1); + auto deferred0 = dpf::defer_eval_interval(d0, from, to, buf0); + auto deferred1 = dpf::defer_eval_interval(d1, from, to, buf1); + assign_input_local(d0, d1, input_type{7}); + auto view0 = deferred0.get(); + auto view1 = deferred1.get(); + EXPECT_EQ(static_cast(std::distance(std::begin(view0), + std::end(view0))), + inclusive_span(from, to)); + EXPECT_EQ(static_cast(std::distance(std::begin(view1), + std::end(view1))), + inclusive_span(from, to)); +} + +TEST(DeferEvalTest, GetCachesRotationSecondCallMatches) +{ + using input_type = std::uint8_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{11}); + auto buf0 = dpf::make_output_buffer_for_full(d0); + auto buf1 = dpf::make_output_buffer_for_full(d1); + auto deferred0 = dpf::defer_eval_interval(d0, input_type{1}, input_type{20}, + buf0); + auto deferred1 = dpf::defer_eval_interval(d1, input_type{1}, input_type{20}, + buf1); + assign_input_local(d0, d1, input_type{9}); + auto a0 = deferred0.get(); + auto a1 = deferred1.get(); + auto b0 = deferred0.get(); + auto b1 = deferred1.get(); + expect_recon_equal(a0, a1, b0, b1); +} + +TEST(DeferEvalTest, BeginEndOnDeferredObject) +{ + using input_type = std::uint8_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{2}); + auto buf0 = dpf::make_output_buffer_for_full(d0); + auto buf1 = dpf::make_output_buffer_for_full(d1); + auto deferred0 = dpf::defer_eval_interval(d0, input_type{0}, input_type{4}, + buf0); + auto deferred1 = dpf::defer_eval_interval(d1, input_type{0}, input_type{4}, + buf1); + assign_input_local(d0, d1, input_type{2}); + std::size_t n = 0; + auto it0 = deferred0.begin(); + auto it1 = deferred1.begin(); + for (; it0 != deferred0.end(); ++it0, ++it1, ++n) + (void)recon(*it0, *it1); + EXPECT_EQ(it1, deferred1.end()); + EXPECT_EQ(n, inclusive_span(input_type{0}, input_type{4})); +} + +TEST(DeferEvalTest, DeferEvalIntervalMinMaxMatchesDeferFull) +{ + using input_type = std::uint8_t; + using output_type = std::uint32_t; + constexpr output_type beta{13}; + constexpr input_type alpha{0x01}; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, beta); + + auto buf_i0 = dpf::make_output_buffer_for_full(d0); + auto buf_i1 = dpf::make_output_buffer_for_full(d1); + auto buf_f0 = dpf::make_output_buffer_for_full(d0); + auto buf_f1 = dpf::make_output_buffer_for_full(d1); + + auto as_interval0 = dpf::defer_eval_interval(d0, + std::numeric_limits::min(), + std::numeric_limits::max(), buf_i0); + auto as_interval1 = dpf::defer_eval_interval(d1, + std::numeric_limits::min(), + std::numeric_limits::max(), buf_i1); + auto as_full0 = dpf::defer_eval_full(d0, buf_f0); + auto as_full1 = dpf::defer_eval_full(d1, buf_f1); + + assign_input_local(d0, d1, alpha); + expect_recon_equal(as_interval0.get(), as_interval1.get(), + as_full0.get(), as_full1.get()); +} + +// --------------------------------------------------------------------------- +// Wrapping intervals and offset stress +// --------------------------------------------------------------------------- + +TEST(DeferEvalTest, WrappingLogicalIntervalUint8) +{ + using input_type = std::uint8_t; + using output_type = std::uint32_t; + // [200, 10] wraps across 0. + constexpr input_type from{200}; + constexpr input_type to{10}; + ASSERT_GT(from, to); + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + output_type{8}); + compare_deferred_interval(d0, d1, from, to, input_type{250}, + output_type{8}); +} + +TEST(DeferEvalTest, WrappingIntervalSpikeInLowHalf) +{ + using input_type = std::uint8_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{4}); + compare_deferred_interval(d0, d1, input_type{200}, input_type{10}, + input_type{5}, std::uint32_t{4}); +} + +TEST(DeferEvalTest, ManyRandomOffsetsMatchEager) +{ + using input_type = std::uint8_t; + using output_type = std::uint32_t; + constexpr input_type from{30}; + constexpr input_type to{90}; + constexpr output_type beta{77}; + + // Sweep alphas; each keygen draws a fresh mask so offsets differ. + for (unsigned a = 0; a < 256; a += 17) + { + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, beta); + compare_deferred_interval(d0, d1, from, to, + static_cast(a), beta); + } +} + +TEST(DeferEvalTest, SignedFullDomain) +{ + using input_type = std::int8_t; + using output_type = std::uint32_t; + constexpr output_type beta{21}; + constexpr input_type alpha{-128}; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, beta); + auto buf0 = dpf::make_output_buffer_for_full(d0); + auto buf1 = dpf::make_output_buffer_for_full(d1); + auto deferred0 = dpf::defer_eval_full(d0, buf0); + auto deferred1 = dpf::defer_eval_full(d1, buf1); + assign_input_local(d0, d1, alpha); + auto eager_buf0 = dpf::make_output_buffer_for_full(d0); + auto eager_buf1 = dpf::make_output_buffer_for_full(d1); + auto eager0 = dpf::eval_full(d0, eager_buf0); + auto eager1 = dpf::eval_full(d1, eager_buf1); + expect_recon_equal(deferred0.get(), deferred1.get(), eager0, eager1); +} + +TEST(DeferEvalTest, SignedSpanCrossingZero) +{ + using input_type = std::int8_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{3}); + compare_deferred_interval(d0, d1, input_type{-5}, input_type{5}, + input_type{0}, std::uint32_t{3}); +} + +TEST(DeferEvalTest, UnalignedMultiOutputLeafInterval) +{ + using input_type = std::uint8_t; + using output_type = std::uint64_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + output_type{0x55}); + ASSERT_GT(decltype(d0)::outputs_per_leaf, std::size_t{1}); + // Odd endpoints: not leaf-aligned when opl == 2. + compare_deferred_interval(d0, d1, input_type{0x11}, input_type{0x2A}, + input_type{0x1F}, output_type{0x55}); +} + +// --------------------------------------------------------------------------- +// Multi-output keys +// --------------------------------------------------------------------------- + +TEST(DeferEvalTest, TwoOutputSlotsIndependent) +{ + using input_type = std::uint8_t; + using out0 = std::uint32_t; + using out1 = std::uint32_t; + constexpr input_type alpha{0x44}; + constexpr out0 beta0{100}; + constexpr out1 beta1{200}; + constexpr input_type from{0x40}; + constexpr input_type to{0x50}; + + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, beta0, + beta1); + + auto bufs0 = dpf::make_output_buffer_for_full<0, 1>(d0); + auto bufs1 = dpf::make_output_buffer_for_full<0, 1>(d1); + auto def0 = dpf::defer_eval_interval<0, 1>(d0, from, to, bufs0); + auto def1 = dpf::defer_eval_interval<0, 1>(d1, from, to, bufs1); + + assign_input_local(d0, d1, alpha); + + auto eager_bufs0 = dpf::make_output_buffer_for_interval<0, 1>(d0, from, to); + auto eager_bufs1 = dpf::make_output_buffer_for_interval<0, 1>(d1, from, to); + auto memo0 = dpf::make_basic_full_memoizer(d0); + auto memo1 = dpf::make_basic_full_memoizer(d1); + auto eager0 = dpf::eval_interval<0, 1>(d0, from, to, eager_bufs0, memo0); + auto eager1 = dpf::eval_interval<0, 1>(d1, from, to, eager_bufs1, memo1); + + expect_recon_equal(std::get<0>(def0).get(), std::get<0>(def1).get(), + std::get<0>(eager0), std::get<0>(eager1)); + expect_recon_equal(std::get<1>(def0).get(), std::get<1>(def1).get(), + std::get<1>(eager0), std::get<1>(eager1)); + + expect_point_mass(std::get<0>(def0).get(), std::get<0>(def1).get(), + from, to, alpha, beta0); + expect_point_mass(std::get<1>(def0).get(), std::get<1>(def1).get(), + from, to, alpha, beta1); +} + +TEST(DeferEvalTest, SelectSecondOutputOnly) +{ + using input_type = std::uint8_t; + constexpr input_type alpha{0x08}; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{1}, std::uint32_t{99}); + + auto buf0 = dpf::make_output_buffer_for_full<1>(d0); + auto buf1 = dpf::make_output_buffer_for_full<1>(d1); + auto def0 = dpf::defer_eval_interval<1>(d0, input_type{0}, input_type{15}, + buf0); + auto def1 = dpf::defer_eval_interval<1>(d1, input_type{0}, input_type{15}, + buf1); + assign_input_local(d0, d1, alpha); + + auto eager_buf0 = dpf::make_output_buffer_for_interval<1>(d0, input_type{0}, + input_type{15}); + auto eager_buf1 = dpf::make_output_buffer_for_interval<1>(d1, input_type{0}, + input_type{15}); + auto memo0 = dpf::make_basic_full_memoizer(d0); + auto memo1 = dpf::make_basic_full_memoizer(d1); + auto eager0 = dpf::eval_interval<1>(d0, input_type{0}, input_type{15}, + eager_buf0, memo0); + auto eager1 = dpf::eval_interval<1>(d1, input_type{0}, input_type{15}, + eager_buf1, memo1); + expect_recon_equal(def0.get(), def1.get(), eager0, eager1); + expect_point_mass(def0.get(), def1.get(), input_type{0}, input_type{15}, + alpha, std::uint32_t{99}); +} + +// --------------------------------------------------------------------------- +// Metadata on the deferred object +// --------------------------------------------------------------------------- + +TEST(DeferEvalTest, DeferredStoresFromToAndKey) +{ + using input_type = std::uint8_t; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{1}); + (void)d1; + auto buf = dpf::make_output_buffer_for_full(d0); + auto deferred = dpf::defer_eval_interval(d0, input_type{3}, input_type{9}, + buf); + EXPECT_EQ(deferred.from(), input_type{3}); + EXPECT_EQ(deferred.to(), input_type{9}); + EXPECT_EQ(&deferred.dpf(), &d0); +} + +TEST(DeferEvalTest, DomainMinMaxSpike) +{ + using input_type = std::uint8_t; + { + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{1}); + compare_deferred_interval(d0, d1, input_type{0}, input_type{255}, + input_type{0}, std::uint32_t{1}); + } + { + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, + std::uint32_t{2}); + compare_deferred_interval(d0, d1, input_type{0}, input_type{255}, + input_type{255}, std::uint32_t{2}); + } +} diff --git a/test/tests/domain128_point_test.cpp b/test/tests/domain128_point_test.cpp new file mode 100644 index 0000000..45877b7 --- /dev/null +++ b/test/tests/domain128_point_test.cpp @@ -0,0 +1,156 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +// Full AES-128 block payload: Boyle packing leaves lg(outputs_per_leaf) = 0, +// so a 128-bit domain walks depth 128 (Express `domainSize` = 128). +using input_t = simde_uint128; +using output_t = simde_uint128; +using dpf_key_t = dpf::utils::dpf_type_t; + +output_t make_payload() +{ + output_t y{}; + auto * bytes = reinterpret_cast(&y); + for (std::size_t i = 0; i < sizeof(y); ++i) + bytes[i] = static_cast(0xa0 + i); + return y; +} + +input_t make_alpha() +{ + // High bit set, plus a distinctive low pattern. + return (input_t{1} << 127) | (input_t{0x0123456789abcdefull} << 64) + | input_t{0xfedcba9876543210ull}; +} + +} // namespace + +TEST(Domain128Point, DepthIs128ForFullBlockPayload) +{ + static_assert(dpf::utils::bitlength_of_v == 128); + static_assert(dpf_key_t::lg_outputs_per_leaf == 0); + static_assert(dpf_key_t::outputs_per_leaf == 1); + static_assert(dpf_key_t::depth == 128); + EXPECT_EQ(dpf_key_t::depth, 128u); + EXPECT_EQ(dpf::utils::bitlength_of_v, 128u); +} + +TEST(Domain128Point, PointEvalShares) +{ + const input_t alpha = make_alpha(); + const output_t beta = make_payload(); + const output_t zero{}; + + auto [k0, k1] = dpf::make_dpf(alpha, beta); + EXPECT_EQ(k0.correction_words().size(), 128u); + EXPECT_EQ(k1.correction_words().size(), 128u); + EXPECT_EQ(std::decay_t::depth, 128u); + + auto open = [&](input_t x) { + return dpf::reconstruct(*dpf::eval_point(k0, x), + *dpf::eval_point(k1, x)); + }; + + // Programmed point: both parties' shares open to the payload. + { + const auto s0 = *dpf::eval_point(k0, alpha); + const auto s1 = *dpf::eval_point(k1, alpha); + EXPECT_EQ(dpf::reconstruct(s0, s1), beta); + EXPECT_EQ(open(alpha), beta); + } + + const std::vector off_points = { + input_t{0}, + input_t{1}, + alpha + 1, + alpha - 1, + input_t{1} << 127, + (input_t{1} << 127) | input_t{1}, + alpha ^ (input_t{1} << 64), + alpha ^ input_t{1}, + ~input_t{0}, + }; + + for (const input_t x : off_points) + { + if (x == alpha) + continue; + const auto s0 = *dpf::eval_point(k0, x); + const auto s1 = *dpf::eval_point(k1, x); + EXPECT_EQ(dpf::reconstruct(s0, s1), zero) << "off-point open"; + } + + // Every individual bit of alpha must be on the path. + for (int i = 0; i < 128; ++i) + { + const input_t flipped = alpha ^ (input_t{1} << i); + const auto s0 = *dpf::eval_point(k0, flipped); + const auto s1 = *dpf::eval_point(k1, flipped); + EXPECT_EQ(dpf::reconstruct(s0, s1), zero) << "bit " << i; + } +} + +TEST(Domain128Point, Uint128ClassInput) +{ + using in_t = uint128_t; + using out_t = simde_uint128; + using kt = dpf::utils::dpf_type_t; + static_assert(kt::depth == 128); + static_assert(dpf::utils::bitlength_of_v == 128); + + // uint128_t(upper, lower): bit 127 set. + const in_t alpha{std::uint64_t{1} << 63, 0}; + out_t beta{}; + std::memset(&beta, 0x5c, sizeof(beta)); + + auto [k0, k1] = dpf::make_dpf(alpha, beta); + EXPECT_EQ(k0.correction_words().size(), 128u); + + const auto s0 = *dpf::eval_point(k0, alpha); + const auto s1 = *dpf::eval_point(k1, alpha); + EXPECT_EQ(dpf::reconstruct(s0, s1), beta); + + const in_t neigh = alpha + in_t{1}; + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(k0, neigh), + *dpf::eval_point(k1, neigh)), out_t{}); +} + +TEST(Domain128Point, FullDomainExpansionThrows) +{ + const input_t alpha = make_alpha(); + const output_t beta = make_payload(); + auto [k0, k1] = dpf::make_dpf(alpha, beta); + (void)k1; + + EXPECT_THROW( + (void)dpf::make_output_buffer_for_full(k0), + std::length_error); + + EXPECT_THROW( + (void)dpf::eval_full(k0), + std::length_error); + + EXPECT_THROW( + (void)dpf::eval_interval(k0, + std::numeric_limits::min(), + std::numeric_limits::max()), + std::length_error); + + EXPECT_THROW( + (void)dpf::make_basic_full_memoizer(k0), + std::length_error); +} diff --git a/test/tests/dpf3_test.cpp b/test/tests/dpf3_test.cpp new file mode 100644 index 0000000..060f368 --- /dev/null +++ b/test/tests/dpf3_test.cpp @@ -0,0 +1,757 @@ +#include +#include + +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/dpf3_ds.hpp" +#include "dpf/prg_aes_ccr.hpp" + +namespace +{ + +using dpf::fp61; + +fp61 open3(fp61 a, fp61 b, fp61 c) +{ + return dpf::shamir3::reconstruct( + dpf::shamir3::share{1, a}, dpf::shamir3::share{2, b}, + dpf::shamir3::share{3, c}); +} + +/// F_DPF3CMP: complementary DCF halves (party 1 = k0, party 2 = k1). +fp61 open_cmp(std::uint64_t k0_half, std::uint64_t k1_half) +{ + return dpf::reconstruct_cmp_halves(k0_half, k1_half); +} + +template +void expect_point(const K1 & k1, const K2 & k2, const K3 & k3, Input alpha, + fp61 beta) +{ + for (unsigned x = 0; x < 256; ++x) + { + const fp61 got = open3(dpf::eval_point(k1, static_cast(x)), + dpf::eval_point(k2, static_cast(x)), + dpf::eval_point(k3, static_cast(x))); + if (static_cast(x) == alpha) + EXPECT_EQ(got, beta) << "x=" << x; + else + EXPECT_EQ(got.raw(), 0u) << "x=" << x; + } +} + +} // namespace + +TEST(Shamir3, ShareAndReconstruct) +{ + const fp61 secret{123456789u}; + const auto s = dpf::shamir3::share_secret(secret); + EXPECT_EQ(dpf::shamir3::reconstruct(s[0], s[1]), secret); + EXPECT_EQ(dpf::shamir3::reconstruct(s[0], s[2]), secret); + EXPECT_EQ(dpf::shamir3::reconstruct(s[1], s[2]), secret); + EXPECT_EQ(dpf::shamir3::reconstruct(s[0], s[1], s[2]), secret); +} + +TEST(Shamir3, PartyScaleRoundTrip) +{ + const fp61 v{0x123456789abcdefull & ((1ull << 61) - 1)}; + const auto s = dpf::shamir3::share_secret(v); + for (const auto & sh : s) + { + const fp61 uns = dpf::shamir3::unscale(sh); + const fp61 back = dpf::shamir3::party_scale( + dpf::shamir3::share{sh.party, uns}); + EXPECT_EQ(back, sh.value); + } +} + +TEST(Dpf3, PointFullDomain) +{ + using Input = std::uint8_t; + const Input alpha = 42; + const fp61 beta{99}; + auto [k1, k2, k3] = dpf::make_dpf3(alpha, beta); + expect_point(k1, k2, k3, alpha, beta); + // Single key is not the clear point function. + EXPECT_NE(dpf::eval_point(k1, alpha), beta); + EXPECT_NE(dpf::eval_point(k2, alpha), beta); + EXPECT_NE(dpf::eval_point(k3, alpha), beta); +} + +TEST(Dpf3, HalfTree) +{ + using Input = std::uint8_t; + using Interior = dpf::prg::aes128_ccr; + using Exterior = dpf::prg::aes128; + const Input alpha = 7; + const fp61 beta{5}; + auto [k1, k2, k3] = dpf::make_dpf3(alpha, beta); + expect_point(k1, k2, k3, alpha, beta); +} + +TEST(Dpf3, VerifiableProof) +{ + using Input = std::uint8_t; + const Input alpha = 11; + const fp61 beta{3}; + auto [k1, k2, k3] = dpf::make_dpf3(alpha, beta, dpf::verifiable{}); + auto p1 = dpf::prove_dpf3(k1, alpha); + auto p2 = dpf::prove_dpf3(k2, alpha); + auto p3 = dpf::prove_dpf3(k3, alpha); + EXPECT_TRUE(dpf::verify_dpf3(p1, p2, p3)); + using arr = typename std::decay_t::correction_seeds_array; + for (auto & cs : const_cast(k1.a.dpf_key.correction_seeds())) + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); + auto bad = dpf::prove_dpf3(k1, alpha); + EXPECT_FALSE(dpf::verify_dpf3(bad, p2, p3)); +} + +TEST(Dpf3, ExtractableWeightOne) +{ + using Input = std::uint8_t; + const Input alpha = 20; + const fp61 beta{7}; + auto [k1, k2, k3] = dpf::make_dpf3(alpha, beta, dpf::extractable{}); + EXPECT_TRUE(k1.extractable); + std::vector s1(256), s2(256), s3(256), rs(256); + for (unsigned x = 0; x < 256; ++x) + { + s1[x] = dpf::eval_point(k1, static_cast(x)); + s2[x] = dpf::eval_point(k2, static_cast(x)); + s3[x] = dpf::eval_point(k3, static_cast(x)); + rs[x] = dpf::uniform_sample(); + } + EXPECT_TRUE(dpf::sketch_verify3(k1, k2, k3, s1, s2, s3, rs)); + s1[21] = s1[21] + beta; + s2[21] = s2[21] + beta; + s3[21] = s3[21] + beta; + EXPECT_FALSE(dpf::sketch_verify3(k1, k2, k3, s1, s2, s3, rs)); +} + +TEST(Dpf3, ExtractableGateRejectsPlainKeys) +{ + using Input = std::uint8_t; + auto [k1, k2, k3] = dpf::make_dpf3(Input{1}, fp61{1}); + std::vector z(1, fp61{}); + std::vector rs(1, fp61{1}); + EXPECT_THROW(dpf::sketch_verify3(k1, k2, k3, z, z, z, rs), + std::invalid_argument); +} + +TEST(Dpf3, VerifiableExtractableProofAndSketch) +{ + using Input = std::uint8_t; + const Input alpha = 33; + const fp61 beta{6}; + auto [k1, k2, k3] = + dpf::make_dpf3(alpha, beta, dpf::verifiable{}, dpf::extractable{}); + std::vector s1(256), s2(256), s3(256), rs(256); + for (unsigned x = 0; x < 256; ++x) + { + s1[x] = dpf::eval_point(k1, static_cast(x)); + s2[x] = dpf::eval_point(k2, static_cast(x)); + s3[x] = dpf::eval_point(k3, static_cast(x)); + rs[x] = dpf::uniform_sample(); + } + EXPECT_TRUE(dpf::verify_dpf3(k1, k2, k3, dpf::prove_dpf3(k1, alpha), + dpf::prove_dpf3(k2, alpha), dpf::prove_dpf3(k3, alpha), s1, s2, s3, + rs)); +} + +TEST(Dpf3, UpdatableInPlaceKeepsAlpha) +{ + using Input = std::uint8_t; + const Input alpha = 9; + auto [k1, k2, k3] = dpf::make_dpf3(alpha, fp61{5}, dpf::updatable{}); + EXPECT_TRUE(k1.updatable && k2.updatable && k3.updatable); + expect_point(k1, k2, k3, alpha, fp61{5}); + + dpf::update_payload(k1, k2, k3, alpha, fp61{8}); + expect_point(k1, k2, k3, alpha, fp61{8}); + + dpf::update_payload(k1, k2, k3, alpha, fp61{0}); + expect_point(k1, k2, k3, alpha, fp61{0}); + + dpf::update_payload(k1, k2, k3, alpha, fp61{100}); + expect_point(k1, k2, k3, alpha, fp61{100}); +} + +TEST(Dpf3, NonUpdatableRejectsUpdate) +{ + using Input = std::uint8_t; + auto [k1, k2, k3] = dpf::make_dpf3(Input{3}, fp61{1}); + EXPECT_FALSE(k1.updatable); + EXPECT_THROW(dpf::update_payload(k1, k2, k3, Input{3}, fp61{2}), std::invalid_argument); +} + +TEST(Dpf3, RemakeFreshTrees) +{ + using Input = std::uint8_t; + const Input alpha = 15; + auto [k1, k2, k3] = dpf::remake_dpf3(alpha, fp61{44}); + expect_point(k1, k2, k3, alpha, fp61{44}); + auto [v1, v2, v3] = dpf::remake_dpf3(alpha, fp61{2}, dpf::verifiable{}); + EXPECT_TRUE(v1.verifiable); + expect_point(v1, v2, v3, alpha, fp61{2}); +} + +TEST(Dpf3, VerifiableUpdatableProofSurvivesUpdate) +{ + using Input = std::uint8_t; + const Input alpha = 33; + auto [k1, k2, k3] = + dpf::make_dpf3(alpha, fp61{6}, dpf::verifiable{}, dpf::updatable{}); + EXPECT_TRUE(dpf::verify_dpf3(dpf::prove_dpf3(k1, alpha), + dpf::prove_dpf3(k2, alpha), dpf::prove_dpf3(k3, alpha))); + dpf::update_payload(k1, k2, k3, alpha, fp61{90}); + expect_point(k1, k2, k3, alpha, fp61{90}); + EXPECT_TRUE(dpf::verify_dpf3(dpf::prove_dpf3(k1, alpha), + dpf::prove_dpf3(k2, alpha), dpf::prove_dpf3(k3, alpha))); +} + +TEST(Dpf3, MultipointFullDomain) +{ + using Input = std::uint8_t; + const std::vector alphas{1, 2, 9, 40}; + const std::vector betas{fp61{7}, fp61{11}, fp61{3}, fp61{4}}; + auto [k1, k2, k3] = dpf::make_multipoint3(alphas, betas); + for (unsigned x = 0; x < 256; ++x) + { + fp61 want{}; + for (std::size_t i = 0; i < alphas.size(); ++i) + if (alphas[i] == static_cast(x)) + want = betas[i]; + const fp61 got = open3( + dpf::eval_multipoint(k1, static_cast(x)), + dpf::eval_multipoint(k2, static_cast(x)), + dpf::eval_multipoint(k3, static_cast(x))); + EXPECT_EQ(got, want) << "x=" << x; + } +} + +TEST(Dpf3, MultipointUpdatableInPlace) +{ + using Input = std::uint8_t; + const std::vector alphas{1, 2, 9, 40}; + const std::vector betas{fp61{7}, fp61{11}, fp61{3}, fp61{4}}; + auto [k1, k2, k3] = dpf::make_multipoint3(alphas, betas, dpf::updatable{}); + EXPECT_TRUE(k1.updatable); + const auto sigma = k1.sigma; + const auto m = k1.bucket_count; + const std::vector betas2{fp61{1}, fp61{2}, fp61{3}, fp61{4}}; + dpf::update_payload(k1, k2, k3, alphas, betas2); + EXPECT_EQ(0, std::memcmp(&k1.sigma, &sigma, sizeof(sigma))); + EXPECT_EQ(k1.bucket_count, m); + for (unsigned x = 0; x < 256; ++x) + { + fp61 want{}; + for (std::size_t i = 0; i < alphas.size(); ++i) + if (alphas[i] == static_cast(x)) + want = betas2[i]; + const fp61 got = open3( + dpf::eval_multipoint(k1, static_cast(x)), + dpf::eval_multipoint(k2, static_cast(x)), + dpf::eval_multipoint(k3, static_cast(x))); + EXPECT_EQ(got, want) << "x=" << x; + } +} + +TEST(Dpf3, MultipointNonUpdatableRejects) +{ + using Input = std::uint8_t; + const std::vector alphas{3, 5}; + const std::vector betas{fp61{1}, fp61{1}}; + auto [k1, k2, k3] = dpf::make_multipoint3(alphas, betas); + EXPECT_THROW(dpf::update_payload(k1, k2, k3, alphas, betas), std::invalid_argument); +} + +TEST(Dpf3, MultipointSeedFlip) +{ + using Input = std::uint8_t; + const std::vector alphas{3, 5, 7}; + const std::vector betas{fp61{1}, fp61{1}, fp61{1}}; + auto [k1, k2, k3] = dpf::make_multipoint3(alphas, betas, dpf::verifiable{}); + ASSERT_FALSE(k1.buckets.empty()); + auto flip = [](auto & plus) { + using arr = + typename std::decay_t::correction_seeds_array; + for (auto & cs : const_cast(plus.dpf_key.correction_seeds())) + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); + }; + for (auto & bucket : k1.buckets) + { + flip(bucket.a); + flip(bucket.b); + } + bool rejected = false; + for (std::size_t i = 0; i < k1.buckets.size(); ++i) + { + auto p1 = dpf::prove_dpf3(k1.buckets[i], Input{0}); + auto p2 = dpf::prove_dpf3(k2.buckets[i], Input{0}); + auto p3 = dpf::prove_dpf3(k3.buckets[i], Input{0}); + if (!dpf::verify_dpf3(p1, p2, p3)) + rejected = true; + } + EXPECT_TRUE(rejected); +} + +TEST(Dpf3, ComparisonFullDomain) +{ + using Input = std::uint8_t; + const Input thresh = 100; + const uint64_t beta = 17; + auto [k1, k2, k3] = dpf::make_dpf3_cmp(thresh, beta); + for (unsigned x = 0; x < 256; ++x) + { + const bool hot = static_cast(x) < thresh; + const auto s1 = dpf::eval_point(k1, static_cast(x)); + const auto s2 = dpf::eval_point(k2, static_cast(x)); + const auto s3 = dpf::eval_point(k3, static_cast(x)); + EXPECT_EQ(open_cmp(s1, s2).raw(), hot ? beta : 0u) << "x=" << x; + EXPECT_EQ(open_cmp(s3, s2).raw(), hot ? beta : 0u) << "x=" << x; + EXPECT_EQ(s1, s3) << "x=" << x; // both hold k0 + if (hot) + EXPECT_NE(s1, beta); + } +} + +TEST(Dpf3, BlockedComparison) +{ + using Input = std::uint8_t; + auto [k1, k2, k3] = dpf::make_dpf3_cmp_blocked<4>(Input{50}, 9u); + EXPECT_EQ(open_cmp(dpf::eval_point(k1, Input{10}), dpf::eval_point(k2, Input{10})) + .raw(), + 9u); + EXPECT_EQ(open_cmp(dpf::eval_point(k1, Input{200}), + dpf::eval_point(k2, Input{200})) + .raw(), + 0u); +} + +TEST(Dpf3, IntervalFullDomain) +{ + using Input = std::uint8_t; + const Input r = 10, p = 20, q = 40; + const uint64_t beta = 5; + auto [k1, k2, k3] = dpf::make_dpf3_ic(r, p, q, beta); + auto two = dpf::make_dpf(r, dpf::ic(p, q, beta)); + for (unsigned x = 0; x < 256; ++x) + { + const auto want = dpf::reconstruct( + dpf::eval_point(dpf::ic, two.first, static_cast(x)), + dpf::eval_point(dpf::ic, two.second, static_cast(x))); + const fp61 got = open_cmp( + dpf::eval_point(k1, static_cast(x)), + dpf::eval_point(k2, static_cast(x))); + EXPECT_EQ(got.raw(), static_cast(want)) << "x=" << x; + } +} + +TEST(Dpf3, ComparisonPayloadUpdateInPlace) +{ + using Input = std::uint8_t; + const Input thresh = 80; + auto [k1, k2, k3] = dpf::make_dpf3_cmp(thresh, 3u); + dpf::update_payload_cmp(k1, k2, k3, 3u, 11u); + for (unsigned x = 0; x < 256; ++x) + { + const bool hot = static_cast(x) < thresh; + const fp61 got = open_cmp( + dpf::eval_point(k1, static_cast(x)), + dpf::eval_point(k2, static_cast(x))); + EXPECT_EQ(got.raw(), hot ? 11u : 0u) << "x=" << x; + } + dpf::update_payload_cmp(k1, k2, k3, 11u, 0u); + for (unsigned x = 0; x < 256; ++x) + { + const fp61 got = open_cmp( + dpf::eval_point(k1, static_cast(x)), + dpf::eval_point(k2, static_cast(x))); + EXPECT_EQ(got.raw(), 0u) << "x=" << x; + } +} + +TEST(Dpf3, ComparisonRemake) +{ + using Input = std::uint8_t; + auto [k1, k2, k3] = dpf::remake_dpf3_cmp(Input{50}, 7u, 0u); + EXPECT_EQ(open_cmp(dpf::eval_point(k1, Input{10}), dpf::eval_point(k2, Input{10})) + .raw(), + 7u); +} + +TEST(Dpf3, DoernerShelatMatchesDealer) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + const Input x0 = 0x13; + const Input x1 = static_cast(alpha ^ x0); + const fp61 beta{77}; + auto [d1, d2, d3] = dpf::make_dpf3(alpha, beta); + auto [s1, s2, s3] = dpf::make_dpf3_doerner_shelat(x0, x1, beta); + expect_point(d1, d2, d3, alpha, beta); + expect_point(s1, s2, s3, alpha, beta); + EXPECT_EQ(dpf::detail::dpf3_impl::open_xor_point(x0, x1), alpha); +} + +TEST(Dpf3, DoernerShelatVerifiable) +{ + using Input = std::uint8_t; + const Input alpha = 19; + const Input x0 = 7; + const Input x1 = static_cast(alpha ^ x0); + auto [k1, k2, k3] = + dpf::make_dpf3_doerner_shelat(x0, x1, fp61{4}, dpf::verifiable{}); + EXPECT_TRUE(k1.verifiable); + expect_point(k1, k2, k3, alpha, fp61{4}); + EXPECT_TRUE(dpf::verify_dpf3(dpf::prove_dpf3(k1, alpha), + dpf::prove_dpf3(k2, alpha), dpf::prove_dpf3(k3, alpha))); +} + +TEST(Dpf3, DoernerShelatUpdatable) +{ + using Input = std::uint8_t; + const Input alpha = 8; + const Input x0 = 1; + const Input x1 = static_cast(alpha ^ x0); + auto [k1, k2, k3] = + dpf::make_dpf3_doerner_shelat(x0, x1, fp61{2}, dpf::updatable{}); + EXPECT_TRUE(k1.updatable); + EXPECT_FALSE(k1.verifiable); + dpf::update_payload(k1, k2, k3, alpha, fp61{55}); + expect_point(k1, k2, k3, alpha, fp61{55}); +} + +TEST(Dpf3, DoernerShelatVerifiableUpdatableTagParity) +{ + using Input = std::uint8_t; + const Input alpha = 14; + const Input x0 = 2; + const Input x1 = static_cast(alpha ^ x0); + auto [k1, k2, k3] = dpf::make_dpf3_doerner_shelat(x0, x1, fp61{3}, + dpf::verifiable{}, dpf::updatable{}); + EXPECT_TRUE(k1.verifiable && k1.updatable); + EXPECT_TRUE(dpf::verify_dpf3(dpf::prove_dpf3(k1, alpha), + dpf::prove_dpf3(k2, alpha), dpf::prove_dpf3(k3, alpha))); + dpf::update_payload(k1, k2, k3, alpha, fp61{11}); + expect_point(k1, k2, k3, alpha, fp61{11}); +} + +TEST(Dpf3, DoernerShelatExtractable) +{ + using Input = std::uint8_t; + const Input alpha = 12; + const Input x0 = 3; + const Input x1 = static_cast(alpha ^ x0); + auto [k1, k2, k3] = + dpf::make_dpf3_doerner_shelat(x0, x1, fp61{1}, dpf::extractable{}); + EXPECT_TRUE(k1.extractable && k2.extractable && k3.extractable); + expect_point(k1, k2, k3, alpha, fp61{1}); + std::vector s1(256), s2(256), s3(256), rs(256); + for (unsigned x = 0; x < 256; ++x) + { + s1[x] = dpf::eval_point(k1, static_cast(x)); + s2[x] = dpf::eval_point(k2, static_cast(x)); + s3[x] = dpf::eval_point(k3, static_cast(x)); + rs[x] = dpf::uniform_sample(); + } + EXPECT_TRUE(dpf::sketch_verify3(k1, k2, k3, s1, s2, s3, rs)); +} + +TEST(Dpf3, RemakeTagParity) +{ + using Input = std::uint8_t; + auto [u1, u2, u3] = dpf::remake_dpf3(Input{1}, fp61{2}, dpf::updatable{}); + EXPECT_TRUE(u1.updatable); + expect_point(u1, u2, u3, Input{1}, fp61{2}); + auto [e1, e2, e3] = + dpf::remake_dpf3(Input{2}, fp61{3}, dpf::verifiable{}, dpf::extractable{}); + EXPECT_TRUE(e1.verifiable && e1.extractable); + expect_point(e1, e2, e3, Input{2}, fp61{3}); +} + +TEST(Dpf3, MultipointVerifiableUpdatable) +{ + using Input = std::uint8_t; + const std::vector alphas{4, 8, 16}; + const std::vector betas{fp61{1}, fp61{2}, fp61{3}}; + auto [k1, k2, k3] = dpf::make_multipoint3(alphas, betas, dpf::verifiable{}, + dpf::updatable{}); + EXPECT_TRUE(k1.verifiable && k1.updatable); + const std::vector betas2{fp61{9}, fp61{8}, fp61{7}}; + dpf::update_payload(k1, k2, k3, alphas, betas2); + for (std::size_t i = 0; i < alphas.size(); ++i) + { + const fp61 got = open3(dpf::eval_multipoint(k1, alphas[i]), + dpf::eval_multipoint(k2, alphas[i]), + dpf::eval_multipoint(k3, alphas[i])); + EXPECT_EQ(got, betas2[i]); + } +} + +TEST(Dpf3, AsSharePartyIndex) +{ + using Input = std::uint8_t; + auto [k1, k2, k3] = dpf::make_dpf3(Input{0}, fp61{1}); + const fp61 y{}; + EXPECT_EQ(dpf::as_share(k1, y).party, 1); + EXPECT_EQ(dpf::as_share(k2, y).party, 2); + EXPECT_EQ(dpf::as_share(k3, y).party, 3); +} + +TEST(Shamir3, InconsistentSharesThrow) +{ + const auto s = dpf::shamir3::share_secret(fp61{42}); + auto bad = s[2]; + bad.value = bad.value + fp61{1}; + EXPECT_THROW(dpf::shamir3::reconstruct(s[0], s[1], bad), std::runtime_error); +} + +TEST(Dpf3, ComparisonPredicatesLeqGtGeq) +{ + using Input = std::uint8_t; + const Input thresh = 100; + const uint64_t beta = 4; + auto check = [&](auto keys, auto pred) { + auto [k1, k2, k3] = keys; + for (unsigned x = 0; x < 256; ++x) + { + const bool hot = pred(static_cast(x)); + const fp61 got = open_cmp(dpf::eval_point(k1, static_cast(x)), + dpf::eval_point(k2, static_cast(x))); + EXPECT_EQ(got.raw(), hot ? beta : 0u) << "x=" << x; + } + }; + check(dpf::make_dpf3_cmp(thresh, dpf::leq(beta)), + [&](Input x) { return x <= thresh; }); + check(dpf::make_dpf3_cmp(thresh, dpf::gt(beta)), + [&](Input x) { return x > thresh; }); + check(dpf::make_dpf3_cmp(thresh, dpf::geq(beta)), + [&](Input x) { return x >= thresh; }); +} + +TEST(Dpf3, ComparisonUpdateFp61NotUint64Wrap) +{ + // Historical bug: `(0 - 11) & ~0ull` is not −11 mod p. Updating 11 → 0 + // must clear the hot lane, not leave a wraparound residue. + using Input = std::uint8_t; + const Input thresh = 60; + auto [k1, k2, k3] = dpf::make_dpf3_cmp(thresh, 11u); + dpf::update_payload_cmp(k1, k2, k3, 11u, 0u); + for (unsigned x = 0; x < 256; ++x) + { + const fp61 got = open_cmp(dpf::eval_point(k1, static_cast(x)), + dpf::eval_point(k2, static_cast(x))); + EXPECT_EQ(got.raw(), 0u) << "x=" << x; + } +} + +TEST(Dpf3, PublicPiIdenticalAfterUpdate) +{ + using Input = std::uint8_t; + const Input alpha = 21; + auto [k1, k2, k3] = dpf::make_dpf3(alpha, fp61{3}, dpf::updatable{}); + EXPECT_EQ(k1.a.offset, k2.a.offset); + EXPECT_EQ(k2.a.offset, k3.a.offset); + EXPECT_EQ(k1.b.offset, k2.b.offset); + EXPECT_EQ(k2.b.offset, k3.b.offset); + dpf::update_payload(k1, k2, k3, alpha, fp61{70}); + EXPECT_EQ(k1.a.offset, k2.a.offset); + EXPECT_EQ(k2.a.offset, k3.a.offset); + EXPECT_EQ(k1.b.offset, k2.b.offset); + EXPECT_EQ(k2.b.offset, k3.b.offset); + expect_point(k1, k2, k3, alpha, fp61{70}); +} + +TEST(Dpf3, ProveRejectsClearedVerifiableFlag) +{ + using Input = std::uint8_t; + const Input alpha = 5; + auto [k1, k2, k3] = dpf::make_dpf3(alpha, fp61{1}, dpf::verifiable{}); + k1.verifiable = false; // outer flag gate (inners remain V) + EXPECT_THROW(dpf::prove_dpf3(k1, alpha), std::invalid_argument); + (void)k2; + (void)k3; +} + +TEST(Dpf3, VerifyExtractableRejectsNonExtractable) +{ + using Input = std::uint8_t; + const Input alpha = 8; + auto [k1, k2, k3] = dpf::make_dpf3(alpha, fp61{2}, dpf::verifiable{}); + std::vector s1(8), s2(8), s3(8), rs(8); + for (unsigned x = 0; x < 8; ++x) + { + s1[x] = dpf::eval_point(k1, static_cast(x)); + s2[x] = dpf::eval_point(k2, static_cast(x)); + s3[x] = dpf::eval_point(k3, static_cast(x)); + rs[x] = fp61{1}; + } + EXPECT_THROW( + dpf::verify_dpf3(k1, k2, k3, dpf::prove_dpf3(k1, alpha), + dpf::prove_dpf3(k2, alpha), dpf::prove_dpf3(k3, alpha), s1, s2, s3, + rs), + std::invalid_argument); +} + +TEST(Dpf3, IntervalBoundaryRelativeToR) +{ + // Interval is relative to public shift `r`; x=r+p and x=r+q−1 are the + // classic edges that mis-scored in the IC example (absolute vs relative). + using Input = std::uint8_t; + const Input r = 10, p = 20, q = 40; + const uint64_t beta = 5; + auto [k1, k2, k3] = dpf::make_dpf3_ic(r, p, q, beta); + auto two = dpf::make_dpf(r, dpf::ic(p, q, beta)); + for (Input x : {Input{29}, Input{30}, Input{35}, Input{49}, Input{50}}) + { + const auto want = dpf::reconstruct( + dpf::eval_point(dpf::ic, two.first, x), + dpf::eval_point(dpf::ic, two.second, x)); + const fp61 got = open_cmp(dpf::eval_point(k1, x), dpf::eval_point(k2, x)); + EXPECT_EQ(got.raw(), static_cast(want)) << "x=" << unsigned(x); + } +} + +TEST(Dpf3, MultipointRemakeFreshSigma) +{ + using Input = std::uint8_t; + const std::vector alphas{2, 4, 8}; + const std::vector betas{fp61{1}, fp61{2}, fp61{3}}; + auto [a1, a2, a3] = dpf::make_multipoint3(alphas, betas, dpf::updatable{}); + const auto sigma0 = a1.sigma; + auto [b1, b2, b3] = dpf::remake_multipoint3(alphas, betas); + EXPECT_NE(0, std::memcmp(&b1.sigma, &sigma0, sizeof(sigma0))); + for (std::size_t i = 0; i < alphas.size(); ++i) + { + EXPECT_EQ(open3(dpf::eval_multipoint(b1, alphas[i]), + dpf::eval_multipoint(b2, alphas[i]), + dpf::eval_multipoint(b3, alphas[i])), + betas[i]); + } + (void)a2; + (void)a3; +} + +TEST(Dpf3, HalfTreeUpdatableUpdate) +{ + using Input = std::uint8_t; + using Interior = dpf::prg::aes128_ccr; + using Exterior = dpf::prg::aes128; + const Input alpha = 55; + auto [k1, k2, k3] = + dpf::make_dpf3(alpha, fp61{8}, dpf::updatable{}); + dpf::update_payload(k1, k2, k3, alpha, fp61{12}); + expect_point(k1, k2, k3, alpha, fp61{12}); +} + +TEST(Dpf3, UpdatePreservesCorrectionSeeds) +{ + using Input = std::uint8_t; + const Input alpha = 17; + auto [k1, k2, k3] = + dpf::make_dpf3(alpha, fp61{4}, dpf::verifiable{}, dpf::updatable{}); + const auto seeds = k1.a.dpf_key.correction_seeds(); + const auto root = k1.a.dpf_key.root(); + dpf::update_payload(k1, k2, k3, alpha, fp61{19}); + EXPECT_EQ(0, std::memcmp(seeds.data(), k1.a.dpf_key.correction_seeds().data(), + sizeof(seeds))); + EXPECT_EQ(0, std::memcmp(&root, &k1.a.dpf_key.root(), sizeof(root))); + expect_point(k1, k2, k3, alpha, fp61{19}); + auto [r1, r2, r3] = + dpf::remake_dpf3(alpha, fp61{19}, dpf::verifiable{}, dpf::updatable{}); + EXPECT_NE(0, std::memcmp(seeds.data(), r1.a.dpf_key.correction_seeds().data(), + sizeof(seeds))); + (void)r2; + (void)r3; +} + +TEST(Dpf3, DoernerShelatVuProofAfterUpdate) +{ + using Input = std::uint8_t; + const Input alpha = 22; + const Input x0 = 6; + const Input x1 = static_cast(alpha ^ x0); + auto [k1, k2, k3] = dpf::make_dpf3_doerner_shelat(x0, x1, fp61{5}, + dpf::verifiable{}, dpf::updatable{}); + EXPECT_TRUE(dpf::verify_dpf3(dpf::prove_dpf3(k1, alpha), + dpf::prove_dpf3(k2, alpha), dpf::prove_dpf3(k3, alpha))); + dpf::update_payload(k1, k2, k3, alpha, fp61{41}); + expect_point(k1, k2, k3, alpha, fp61{41}); + EXPECT_TRUE(dpf::verify_dpf3(dpf::prove_dpf3(k1, alpha), + dpf::prove_dpf3(k2, alpha), dpf::prove_dpf3(k3, alpha))); +} + +TEST(Dpf3, MultipointVuProofAfterUpdate) +{ + using Input = std::uint8_t; + const std::vector alphas{4, 8, 16}; + const std::vector betas{fp61{1}, fp61{2}, fp61{3}}; + auto [k1, k2, k3] = dpf::make_multipoint3(alphas, betas, dpf::verifiable{}, + dpf::updatable{}); + const auto sigma = k1.sigma; + const std::vector betas2{fp61{9}, fp61{8}, fp61{7}}; + dpf::update_payload(k1, k2, k3, alphas, betas2); + EXPECT_EQ(0, std::memcmp(&k1.sigma, &sigma, sizeof(sigma))); + bool any = false; + for (std::size_t i = 0; i < k1.buckets.size(); ++i) + { + any = true; + EXPECT_TRUE(dpf::verify_dpf3(dpf::prove_dpf3(k1.buckets[i], Input{0}), + dpf::prove_dpf3(k2.buckets[i], Input{0}), + dpf::prove_dpf3(k3.buckets[i], Input{0}))); + } + EXPECT_TRUE(any); +} + +TEST(Dpf3, BlockedComparisonFullDomain) +{ + using Input = std::uint8_t; + const Input thresh = 50; + const uint64_t beta = 9; + auto [k1, k2, k3] = dpf::make_dpf3_cmp_blocked<4>(thresh, beta); + for (unsigned x = 0; x < 256; ++x) + { + const bool hot = static_cast(x) < thresh; + const fp61 got = open_cmp(dpf::eval_point(k1, static_cast(x)), + dpf::eval_point(k2, static_cast(x))); + EXPECT_EQ(got.raw(), hot ? beta : 0u) << "x=" << x; + } +} + +TEST(Dpf3, TagsAnyOrderIncludingExtractableUpdatable) +{ + using Input = std::uint8_t; + const Input alpha = 17; + auto [k1, k2, k3] = dpf::make_dpf3(alpha, fp61{4}, + dpf::extractable{}, dpf::updatable{}, dpf::verifiable{}); + EXPECT_TRUE(k1.verifiable && k1.extractable && k1.updatable); + EXPECT_TRUE(k2.extractable && k3.updatable); + expect_point(k1, k2, k3, alpha, fp61{4}); + dpf::update_payload(k1, k2, k3, alpha, fp61{11}); + expect_point(k1, k2, k3, alpha, fp61{11}); +} + +TEST(Dpf3, ComparisonSpecWrappersMatchPlainPredicate) +{ + using Input = std::uint8_t; + const Input thresh = 40; + const uint64_t beta = 3; + auto check = [&](auto keys) { + auto [k1, k2, k3] = keys; + for (unsigned x = 0; x < 256; ++x) + { + const bool hot = static_cast(x) > thresh; + const fp61 got = open_cmp(dpf::eval_point(k1, static_cast(x)), + dpf::eval_point(k2, static_cast(x))); + EXPECT_EQ(got.raw(), hot ? beta : 0u) << "x=" << x; + } + }; + check(dpf::make_dpf3_cmp(thresh, dpf::idcf(dpf::gt(beta)))); + check(dpf::make_dpf3_cmp(thresh, dpf::block_width<4>(dpf::gt(beta)))); +} + diff --git a/test/tests/dwt_lut_test.cpp b/test/tests/dwt_lut_test.cpp new file mode 100644 index 0000000..3e9bb82 --- /dev/null +++ b/test/tests/dwt_lut_test.cpp @@ -0,0 +1,107 @@ +#include + +#include "grotto/dwt_lut.hpp" + +#include +#include +#include + +namespace +{ + +grotto::dwt_lut make(grotto::dwt_family family, const std::vector & samples, + unsigned fractional_bits, unsigned depth) +{ + if (family == grotto::dwt_family::haar) + return grotto::make_haar_dwt_lut(samples, fractional_bits, depth); + return grotto::make_bior53_dwt_lut(samples, fractional_bits, depth); +} + +} // namespace + +TEST(DwtLut, HaarIsQuantizedBlockMean) +{ + const std::vector samples{ + 0.0, 0.5, -1.25, 3.0, 4.0, 0.25, -0.5, 2.0}; + const auto lut = grotto::make_haar_dwt_lut(samples, 8, 1); + ASSERT_EQ(lut.coeff.size(), 4u); + EXPECT_EQ(lut.coeff[0], 64); + EXPECT_EQ(lut.coeff[1], 224); + EXPECT_EQ(lut.coeff[2], 544); + EXPECT_EQ(lut.coeff[3], 192); + EXPECT_EQ(lut(0), 64); + EXPECT_EQ(lut(1), 64); + EXPECT_EQ(lut(7), 192); +} + +TEST(DwtLut, HaarNegativeFloor) +{ + const std::vector samples{-1.1, 0.2, -0.3, -4.0}; + const auto lut = grotto::make_haar_dwt_lut(samples, 10, 1); + ASSERT_EQ(lut.coeff.size(), 2u); + EXPECT_EQ(lut.coeff[0], -461); + EXPECT_EQ(lut.coeff[1], -2202); + EXPECT_EQ(lut(0), -461); + EXPECT_EQ(lut(3), -2202); +} + +TEST(DwtLut, Bior53MatchesSmoothExtension) +{ + const std::vector samples{ + 0.0, 0.5, -1.25, 3.0, 4.0, 0.25, -0.5, 2.0}; + const auto one = make(grotto::dwt_family::bior53, samples, 8, 1); + const std::vector expect1{-513, 144, -288, 2064, -449, 2304}; + EXPECT_EQ(one.coeff, expect1); + + const auto two = make(grotto::dwt_family::bior53, samples, 8, 2); + const std::vector expect2{-3649, -753, 912, 319, 10112}; + EXPECT_EQ(two.coeff, expect2); + const std::int64_t at[8] = {228, 190, 153, 116, 79, 691, 1303, 1915}; + for (std::uint64_t raw = 0; raw < 8; ++raw) + EXPECT_EQ(two(raw), at[raw]) << raw; +} + +TEST(DwtLut, Bior53FloorDivOnNegatives) +{ + const std::vector samples{-1.1, 0.2, -0.3, -4.0}; + const auto lut = grotto::make_bior53_dwt_lut(samples, 10, 1); + const std::vector expect{-7578, -1793, -154, -15770}; + EXPECT_EQ(lut.coeff, expect); + EXPECT_EQ(lut(0), -77); + EXPECT_EQ(lut(1), -3981); + EXPECT_EQ(lut(2), -7885); + EXPECT_EQ(lut(3), -5837); +} + +TEST(DwtLut, SigmoidGridAgreesWithHaarMean) +{ + auto samples = grotto::sample_dwt_signal(6, 4, [](double x) { + return 1.0 / (1.0 + std::exp(-(x - 2.0))); + }); + const auto haar = grotto::make_haar_dwt_lut(samples, 4, 2); + ASSERT_EQ(haar.coeff.size(), 16u); + for (std::uint64_t bin = 0; bin < 16; ++bin) + { + double sum = 0; + for (unsigned k = 0; k < 4; ++k) + sum += samples[bin * 4 + k]; + const auto q = static_cast(std::floor(sum / 4.0 * 16.0)); + EXPECT_EQ(haar.coeff[bin], q) << bin; + EXPECT_EQ(haar(bin * 4), q); + } + const auto bior = grotto::make_bior53_dwt_lut(samples, 4, 2); + EXPECT_EQ(bior(32), 8); + EXPECT_EQ(bior(48), 12); + EXPECT_EQ(haar(32), 8); +} + +TEST(DwtLut, RejectsBadShape) +{ + const std::vector samples{0.0, 1.0, 2.0}; + EXPECT_THROW(grotto::make_haar_dwt_lut(samples, 4, 1), std::invalid_argument); + const std::vector four{0.0, 1.0, 2.0, 3.0}; + EXPECT_THROW(grotto::make_haar_dwt_lut(four, 4, 0), std::invalid_argument); + EXPECT_THROW(grotto::make_bior53_dwt_lut(four, 4, 3), std::invalid_argument); + auto lut = grotto::make_haar_dwt_lut(four, 4, 1); + EXPECT_THROW(lut(4), std::out_of_range); +} diff --git a/test/tests/dyadic_lut_test.cpp b/test/tests/dyadic_lut_test.cpp index 0820943..2000ba8 100644 --- a/test/tests/dyadic_lut_test.cpp +++ b/test/tests/dyadic_lut_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "grotto/dyadic_lut.hpp" @@ -181,8 +182,7 @@ TEST(DyadicLut, MostSignificantBits) EXPECT_EQ(lut(x), bit) << raw << " i=" << i; } } - EXPECT_THROW(grotto::make_msb_lut(grotto::msb_bit_limit), - std::invalid_argument); + EXPECT_THROW(grotto::make_msb_lut(grotto::msb_bit_limit), std::invalid_argument); const auto scaled = grotto::make_msb_lut(0, 4); EXPECT_EQ(scaled(std::int16_t{-1}), 16); EXPECT_EQ(scaled(std::int16_t{1}), 0); diff --git a/test/tests/easy_lut_test.cpp b/test/tests/easy_lut_test.cpp index d3cea1f..b20fbb8 100644 --- a/test/tests/easy_lut_test.cpp +++ b/test/tests/easy_lut_test.cpp @@ -90,6 +90,7 @@ TEST(EasyLut, FewPiecesAtEveryPrecision) EXPECT_EQ((grotto::make_squared_relu_lut(0).parts()), 2u); EXPECT_EQ((grotto::make_leaky_relu_lut(0).parts()), 1u); EXPECT_EQ((grotto::make_leaky_relu_lut(3).parts()), 2u); + EXPECT_EQ((grotto::make_leaky_relu_hundredth_lut().parts()), 2u); for (unsigned fractional_bits : {0u, 2u, 4u}) { @@ -144,6 +145,10 @@ TEST(EasyLut, ExactLinesMatchOnInt16) return raw >= 0 ? raw : round_div(raw, 4); }); } + const auto hundredth = grotto::make_leaky_relu_hundredth_lut(); + expect_all(hundredth, [](std::int64_t raw) { + return raw >= 0 ? raw : round_div(raw, 100); + }); } TEST(EasyLut, ClipIsTheGeneralProgram) diff --git a/test/tests/eval_full_multi_test.cpp b/test/tests/eval_full_multi_test.cpp index c7002e5..e2bbbae 100644 --- a/test/tests/eval_full_multi_test.cpp +++ b/test/tests/eval_full_multi_test.cpp @@ -14,7 +14,13 @@ auto recon(const A & a, const B & b) && dpf::is_secret_share_v>) return dpf::reconstruct(a, b); else - return a - b; + { + using T = std::common_type_t, std::decay_t>; + if constexpr (std::is_integral_v && std::is_unsigned_v) + return static_cast(a - b); + else + return a - b; + } } } // namespace @@ -222,6 +228,13 @@ using Types = testing::Types test_type>, test_type>, test_type>, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, // custom types test_type, diff --git a/test/tests/eval_full_test.cpp b/test/tests/eval_full_test.cpp index 53ec81a..8a1c693 100644 --- a/test/tests/eval_full_test.cpp +++ b/test/tests/eval_full_test.cpp @@ -16,7 +16,13 @@ auto recon(const A & a, const B & b) && dpf::is_secret_share_v>) return dpf::reconstruct(a, b); else - return a - b; + { + using T = std::common_type_t, std::decay_t>; + if constexpr (std::is_integral_v && std::is_unsigned_v) + return static_cast(a - b); + else + return a - b; + } } } // namespace @@ -199,6 +205,13 @@ using Types = testing::Types test_type>, test_type>, test_type>, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, // custom types test_type, diff --git a/test/tests/eval_inner_product_test.cpp b/test/tests/eval_inner_product_test.cpp new file mode 100644 index 0000000..dcb8142 --- /dev/null +++ b/test/tests/eval_inner_product_test.cpp @@ -0,0 +1,695 @@ +#include + +#include +#include +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +using In = std::uint8_t; + +template +auto open(const A & a, const B & b) +{ + if constexpr (dpf::is_secret_share_v) + return dpf::reconstruct(a, b); + else if constexpr (dpf::utils::is_xor_wrapper_v) + return static_cast(a ^ b); + else + return static_cast(a - b); +} + +} // namespace + +TEST(InnerProduct, ScalarIntervalMatchesPoints) +{ + const In alpha = 42; + const std::uint64_t beta = 7; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + const In from = 40, to = 50; + std::vector w(to - from + 1); + std::uint64_t expect = 0; + for (std::size_t i = 0; i < w.size(); ++i) + { + w[i] = i + 1; + const In x = static_cast(from + i); + const auto y = open(*dpf::eval_point(k0, x), *dpf::eval_point(k1, x)); + expect += static_cast(y) * w[i]; + } + EXPECT_EQ(open( + dpf::eval_inner_product(dpf::paired, k0, from, to, w), + dpf::eval_inner_product(dpf::paired, k1, from, to, w)), + expect); + EXPECT_EQ(expect, beta * w[alpha - from]); +} + +TEST(InnerProduct, FullDomainOnlyAlpha) +{ + auto [k0, k1] = dpf::make_dpf(In{7}, std::uint64_t{9}); + std::vector w(256); + for (unsigned i = 0; i < w.size(); ++i) + w[i] = (i * 3u) & 15u; + EXPECT_EQ(open( + dpf::eval_full_inner_product(dpf::paired, k0, w), + dpf::eval_full_inner_product(dpf::paired, k1, w)), + std::uint64_t{9} * w[7]); +} + +TEST(InnerProduct, TwoOutputsSameLeaf) +{ + auto [k0, k1] = dpf::make_dpf(In{9}, std::uint32_t{3}, std::uint32_t{5}); + std::vector> rows; + std::uint64_t expect = 0; + for (In x = 8;; ++x) + { + const std::uint32_t w0 = 1, w1 = x; + rows.push_back({w0, w1}); + const auto y0 = open(*dpf::eval_point<0>(k0, x), *dpf::eval_point<0>(k1, x)); + const auto y1 = open(*dpf::eval_point<1>(k0, x), *dpf::eval_point<1>(k1, x)); + expect += static_cast(y0) * w0 + + static_cast(y1) * w1; + if (x == 10) + break; + } + EXPECT_EQ(open( + dpf::eval_inner_product<0, 1>(dpf::paired, k0, In{8}, In{10}, rows), + dpf::eval_inner_product<0, 1>(dpf::paired, k1, In{8}, In{10}, rows)), + expect); +} + +TEST(InnerProduct, TupleRowMatchesArray) +{ + auto [k0, k1] = dpf::make_dpf(In{4}, std::uint16_t{2}, std::uint16_t{6}); + const std::vector pts{1, 4, 8}; + std::vector> tuples{ + {1u, 1u}, {3u, 5u}, {7u, 9u}}; + std::vector> arrays{{1u, 1u}, {3u, 5u}, {7u, 9u}}; + const auto t0 = dpf::eval_sequence_inner_product<0, 1>(k0, pts.begin(), pts.end(), tuples); + const auto t1 = dpf::eval_sequence_inner_product<0, 1>(k1, pts.begin(), pts.end(), tuples); + const auto a0 = dpf::eval_sequence_inner_product<0, 1>(k0, pts.begin(), pts.end(), arrays); + const auto a1 = dpf::eval_sequence_inner_product<0, 1>(k1, pts.begin(), pts.end(), arrays); + EXPECT_EQ(open(t0, t1), open(a0, a1)); +} + +TEST(InnerProduct, AncestorAndLeaf) +{ + auto [k0, k1] = dpf::make_dpf(In{0x2a}, dpf::at<4>(std::uint8_t{5}), std::uint8_t{9}); + const std::vector pts{0x10, 0x2a, 0x2b, 0x30}; + const std::vector> rows{{1, 0}, {1, 1}, {2, 4}, {8, 1}}; + std::uint64_t expect = 0; + for (std::size_t i = 0; i < pts.size(); ++i) + { + const auto y0 = open(*dpf::eval_point(dpf::out<0>, k0, pts[i]), + *dpf::eval_point(dpf::out<0>, k1, pts[i])); + const auto y1 = open(*dpf::eval_point(dpf::out<1>, k0, pts[i]), + *dpf::eval_point(dpf::out<1>, k1, pts[i])); + expect += static_cast(y0) * rows[i][0] + + static_cast(y1) * rows[i][1]; + if (pts[i] == In{0x2a} || pts[i] == In{0x2b}) + EXPECT_EQ(y0, std::uint8_t{5}); + else + EXPECT_EQ(y0, std::uint8_t{0}); + } + EXPECT_EQ(open( + dpf::eval_sequence_inner_product<0, 1>(k0, pts.begin(), pts.end(), rows), + dpf::eval_sequence_inner_product<0, 1>(k1, pts.begin(), pts.end(), rows)), + expect); + const auto recipe = dpf::make_sequence_recipe(pts.begin(), pts.end()); + EXPECT_EQ(open( + dpf::eval_sequence_inner_product<0, 1>(k0, recipe, pts.begin(), pts.end(), rows), + dpf::eval_sequence_inner_product<0, 1>(k1, recipe, pts.begin(), pts.end(), rows)), + expect); +} + +TEST(InnerProduct, WrapInterval) +{ + auto [k0, k1] = dpf::make_dpf(In{255}, std::uint32_t{4}); + const In from = 250, to = 2; + std::vector w; + std::uint64_t expect = 0; + auto push = [&](In x) { + w.push_back(static_cast(w.size() + 1)); + const auto y = open(*dpf::eval_point(k0, x), *dpf::eval_point(k1, x)); + expect += static_cast(y) * w.back(); + }; + for (unsigned x = from; x < 256; ++x) + push(static_cast(x)); + for (unsigned x = 0; x <= to; ++x) + push(static_cast(x)); + EXPECT_EQ(w.size(), 9u); + EXPECT_EQ(open( + dpf::eval_inner_product(dpf::paired, k0, from, to, w), + dpf::eval_inner_product(dpf::paired, k1, from, to, w)), + expect); + EXPECT_EQ(expect, std::uint64_t{4} * w[5]); // 255 is the 6th point, index 5 +} + +TEST(InnerProduct, XorWeights) +{ + using X = dpf::xor_wrapper; + auto [k0, k1] = dpf::make_dpf(In{3}, X{0x0fu}); + const std::vector pts{1, 3, 4}; + const std::vector w{X{0xffu}, X{0xf0u}, X{0x0fu}}; + // Only x=3 is hot: 0x0f AND 0xf0. + EXPECT_EQ(open( + dpf::eval_sequence_inner_product<0>(k0, pts.begin(), pts.end(), w), + dpf::eval_sequence_inner_product<0>(k1, pts.begin(), pts.end(), w)), + X{0x0fu & 0xf0u}); +} + +TEST(InnerProduct, EmptySequenceIsZero) +{ + auto [k0, k1] = dpf::make_dpf(In{1}, std::uint64_t{3}); + const std::vector pts; + const std::vector w; + EXPECT_EQ(open( + dpf::eval_sequence_inner_product<0>(k0, pts.begin(), pts.end(), w), + dpf::eval_sequence_inner_product<0>(k1, pts.begin(), pts.end(), w)), + std::uint64_t{0}); +} + +TEST(InnerProduct, UnsortedSequenceThrows) +{ + auto [k0, k1] = dpf::make_dpf(In{1}, std::uint64_t{3}); + (void)k1; + const std::vector pts{3, 1}; + const std::vector w{1, 1}; + EXPECT_THROW( + dpf::eval_sequence_inner_product<0>(k0, pts.begin(), pts.end(), w), + std::runtime_error); +} + +TEST(InnerProduct, ColumnsThreeMomentsOneWalk) +{ + const In alpha = 42; + const std::uint64_t beta = 7; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + const std::vector pts{40, 41, 42, 50}; + std::vector r(pts.size()); + std::vector r2(pts.size()); + std::vector ones(pts.size(), 1); + std::uint64_t expect_sum = 0, expect_dot = 0, expect_sq = 0; + for (std::size_t i = 0; i < pts.size(); ++i) + { + r[i] = 3 + i * 5; + r2[i] = r[i] * r[i]; + const auto y = open(*dpf::eval_point(k0, pts[i]), *dpf::eval_point(k1, pts[i])); + expect_sum += static_cast(y); + expect_dot += static_cast(y) * r[i]; + expect_sq += static_cast(y) * r2[i]; + } + const auto streams = std::tie(ones, r, r2); + const auto s0 = dpf::eval_sequence_inner_product<0>( + dpf::columns, k0, pts.begin(), pts.end(), streams); + const auto s1 = dpf::eval_sequence_inner_product<0>( + dpf::columns, k1, pts.begin(), pts.end(), streams); + EXPECT_EQ(open(std::get<0>(s0), std::get<0>(s1)), expect_sum); + EXPECT_EQ(open(std::get<1>(s0), std::get<1>(s1)), expect_dot); + EXPECT_EQ(open(std::get<2>(s0), std::get<2>(s1)), expect_sq); + EXPECT_EQ(expect_sum, beta); + EXPECT_EQ(expect_dot, beta * r[2]); + EXPECT_EQ(expect_sq, beta * r2[2]); +} + +TEST(InnerProduct, ColumnsCallableStreamsAndSideVisit) +{ + auto [k0, k1] = dpf::make_dpf(In{9}, std::uint32_t{4}); + const std::vector pts{1, 9, 12}; + auto ones = [](std::size_t) { return std::uint32_t{1}; }; + auto scale = [](std::size_t i) { return std::uint32_t(i + 2); }; + std::size_t visits = 0; + std::uint32_t seen = 0; + const auto s0 = dpf::eval_sequence_inner_product<0>( + dpf::columns, k0, pts.begin(), pts.end(), std::tie(ones, scale), + dpf::project([](auto share) { return share + share; }), + dpf::also([&](std::size_t, In x, auto share) { + ++visits; + if (x == In{9}) + seen = share.raw(); + })); + const auto s1 = dpf::eval_sequence_inner_product<0>( + dpf::columns, k1, pts.begin(), pts.end(), std::tie(ones, scale), + dpf::project([](auto share) { return share + share; })); + EXPECT_EQ(visits, pts.size()); + const auto hot = *dpf::eval_point(k0, In{9}); + EXPECT_EQ(seen, hot.raw()); + // project doubles the share, so the opened moments are 2 * beta * weight. + EXPECT_EQ(open(std::get<0>(s0), std::get<0>(s1)), std::uint64_t{8}); + EXPECT_EQ(open(std::get<1>(s0), std::get<1>(s1)), std::uint64_t{8} * 3u); +} + +TEST(InnerProduct, ColumnsIntervalMatchesSequence) +{ + auto [k0, k1] = dpf::make_dpf(In{4}, std::uint16_t{6}); + const In from = 2, to = 6; + std::vector w; + for (In x = from;; ++x) + { + w.push_back(static_cast(x)); + if (x == to) + break; + } + const auto a0 = dpf::eval_inner_product<0>(dpf::columns, k0, from, to, std::tie(w)); + const auto a1 = dpf::eval_inner_product<0>(dpf::columns, k1, from, to, std::tie(w)); + std::vector pts; + for (In x = from;; ++x) + { + pts.push_back(x); + if (x == to) + break; + } + const auto b0 = dpf::eval_sequence_inner_product<0>( + dpf::columns, k0, pts.begin(), pts.end(), std::tie(w)); + const auto b1 = dpf::eval_sequence_inner_product<0>( + dpf::columns, k1, pts.begin(), pts.end(), std::tie(w)); + EXPECT_EQ(open(std::get<0>(a0), std::get<0>(a1)), + open(std::get<0>(b0), std::get<0>(b1))); + EXPECT_EQ(open(std::get<0>(a0), std::get<0>(a1)), std::uint16_t{6} * 4); +} + +TEST(InnerProduct, RecipeLengthMismatchThrows) +{ + auto [k0, k1] = dpf::make_dpf(In{1}, std::uint64_t{3}); + (void)k1; + const std::vector pts{1, 2}; + const std::vector shorter{1}; + const std::vector w{1, 1}; + const auto recipe = dpf::make_sequence_recipe(pts.begin(), pts.end()); + EXPECT_THROW( + dpf::eval_sequence_inner_product<0>(k0, recipe, shorter.begin(), shorter.end(), w), + std::invalid_argument); +} + +TEST(InnerProduct, ColumnsUnsortedAndRecipeMismatchThrow) +{ + auto [k0, k1] = dpf::make_dpf(In{1}, std::uint64_t{3}); + (void)k1; + const std::vector unsorted{3, 1}; + const std::vector w{1, 1}; + EXPECT_THROW( + dpf::eval_sequence_inner_product<0>( + dpf::columns, k0, unsorted.begin(), unsorted.end(), std::tie(w)), + std::runtime_error); + + const std::vector pts{1, 2}; + const std::vector shorter{1}; + const auto recipe = dpf::make_sequence_recipe(pts.begin(), pts.end()); + EXPECT_THROW( + dpf::eval_sequence_inner_product<0>( + dpf::columns, k0, recipe, shorter.begin(), shorter.end(), std::tie(w)), + std::invalid_argument); +} + +TEST(InnerProduct, BatchedLeafWalkMatchesPaired) +{ + // Plain `eval_inner_product` (memoized leaf walk) and `dpf::paired` both + // compute sum_x DPF(x)*w[x] when there is one output and `[from, to]` is + // leaf-aligned, so the covering-leaf weight layout matches the clipped + // domain points. + const In alpha = 36; + const std::uint64_t beta = 11; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + const In from = 30, to = 45; // even..odd => full covering leaves + ASSERT_EQ(decltype(k0)::outputs_per_leaf, 2u); + std::vector w(to - from + 1); + for (std::size_t i = 0; i < w.size(); ++i) + w[i] = (i * 7u) + 3u; + + auto m0 = dpf::make_basic_interval_memoizer(k0, from, to); + auto m1 = dpf::make_basic_interval_memoizer(k1, from, to); + const auto leaf0 = dpf::eval_inner_product(k0, from, to, w, m0); + const auto leaf1 = dpf::eval_inner_product(k1, from, to, w, m1); + const auto pair0 = dpf::eval_inner_product(dpf::paired, k0, from, to, w); + const auto pair1 = dpf::eval_inner_product(dpf::paired, k1, from, to, w); + EXPECT_EQ(open(leaf0, leaf1), open(pair0, pair1)); + EXPECT_EQ(open(leaf0, leaf1), beta * w[alpha - from]); +} + +TEST(InnerProduct, ColumnsOneStreamMatchesPaired) +{ + // Transposed (`columns`) with a single weight stream is the same scalar + // product as `paired` on that stream. + auto [k0, k1] = dpf::make_dpf(In{12}, std::uint32_t{5}); + const In from = 8, to = 20; + std::vector w; + for (In x = from;; ++x) + { + w.push_back(static_cast(x + 1)); + if (x == to) + break; + } + const auto p0 = dpf::eval_inner_product(dpf::paired, k0, from, to, w); + const auto p1 = dpf::eval_inner_product(dpf::paired, k1, from, to, w); + const auto c0 = dpf::eval_inner_product<0>(dpf::columns, k0, from, to, std::tie(w)); + const auto c1 = dpf::eval_inner_product<0>(dpf::columns, k1, from, to, std::tie(w)); + EXPECT_EQ(open(p0, p1), open(std::get<0>(c0), std::get<0>(c1))); + EXPECT_EQ(open(p0, p1), std::uint32_t{5} * w[12 - 8]); +} + +TEST(InnerProduct, LengthOneOddAndUnaligned) +{ + auto [k0, k1] = dpf::make_dpf(In{41}, std::uint64_t{9}); + + // Single domain point. + { + const In x = 41; + std::vector w{4}; + EXPECT_EQ(open( + dpf::eval_inner_product(dpf::paired, k0, x, x, w), + dpf::eval_inner_product(dpf::paired, k1, x, x, w)), + std::uint64_t{9} * 4u); + const auto c0 = dpf::eval_inner_product<0>( + dpf::columns, k0, x, x, std::tie(w)); + const auto c1 = dpf::eval_inner_product<0>( + dpf::columns, k1, x, x, std::tie(w)); + EXPECT_EQ(open(std::get<0>(c0), std::get<0>(c1)), std::uint64_t{9} * 4u); + } + + // Odd length, not leaf-aligned (uint64 packs two lanes per leaf). + // `paired` / `columns` weight by clipped domain points; the batched leaf + // walk weights the covering leaves (see file brief / cohort docs). + { + const In from = 39, to = 45; // 7 points; covering leaf also holds 38 + std::vector w(to - from + 1); + std::uint64_t expect = 0; + for (std::size_t i = 0; i < w.size(); ++i) + { + w[i] = i + 2; + const In x = static_cast(from + i); + const auto y = open(*dpf::eval_point(k0, x), *dpf::eval_point(k1, x)); + expect += static_cast(y) * w[i]; + } + EXPECT_EQ(open( + dpf::eval_inner_product(dpf::paired, k0, from, to, w), + dpf::eval_inner_product(dpf::paired, k1, from, to, w)), + expect); + const auto c0 = dpf::eval_inner_product<0>( + dpf::columns, k0, from, to, std::tie(w)); + const auto c1 = dpf::eval_inner_product<0>( + dpf::columns, k1, from, to, std::tie(w)); + EXPECT_EQ(open(std::get<0>(c0), std::get<0>(c1)), expect); + EXPECT_EQ(expect, std::uint64_t{9} * w[41 - 39]); + + // Covering-leaf weights: pad the missing start lane (x=38) with 0 so + // the batched walk agrees with the clipped paired result. + constexpr std::size_t opl = decltype(k0)::outputs_per_leaf; + ASSERT_EQ(opl, 2u); + std::vector cover(w.size() + 1, 0); + for (std::size_t i = 0; i < w.size(); ++i) + cover[i + 1] = w[i]; + auto m0 = dpf::make_basic_interval_memoizer(k0, from, to); + auto m1 = dpf::make_basic_interval_memoizer(k1, from, to); + EXPECT_EQ(open( + dpf::eval_inner_product(k0, from, to, cover, m0), + dpf::eval_inner_product(k1, from, to, cover, m1)), + expect); + } +} + +TEST(InnerProduct, EmptyIntervalWeightsStillZero) +{ + // Empty point list already covered; empty closed interval is impossible, + // but a sequence of length 0 for columns must stay zero. + auto [k0, k1] = dpf::make_dpf(In{1}, std::uint64_t{3}); + const std::vector pts; + const std::vector w; + const auto c0 = dpf::eval_sequence_inner_product<0>( + dpf::columns, k0, pts.begin(), pts.end(), std::tie(w)); + const auto c1 = dpf::eval_sequence_inner_product<0>( + dpf::columns, k1, pts.begin(), pts.end(), std::tie(w)); + EXPECT_EQ(open(std::get<0>(c0), std::get<0>(c1)), std::uint64_t{0}); +} + +TEST(InnerProduct, ColumnsFullAndAlsoThenProject) +{ + auto [k0, k1] = dpf::make_dpf(In{7}, std::uint16_t{4}); + std::vector ones(256, 1); + std::vector r(256); + for (unsigned i = 0; i < 256; ++i) + r[i] = static_cast((i * 3u) & 15u); + + const auto f0 = dpf::eval_full_inner_product<0>( + dpf::columns, k0, std::tie(ones, r)); + const auto f1 = dpf::eval_full_inner_product<0>( + dpf::columns, k1, std::tie(ones, r)); + EXPECT_EQ(open(std::get<0>(f0), std::get<0>(f1)), std::uint16_t{4}); + EXPECT_EQ(open(std::get<1>(f0), std::get<1>(f1)), std::uint16_t{4} * r[7]); + + const std::vector pts{3, 7, 9}; + std::size_t visits = 0; + const auto s0 = dpf::eval_sequence_inner_product<0>( + dpf::columns, k0, pts.begin(), pts.end(), std::tie(ones), + dpf::also([&](std::size_t, In, auto) { ++visits; }), + dpf::project([](auto share) { return share; })); + const auto s1 = dpf::eval_sequence_inner_product<0>( + dpf::columns, k1, pts.begin(), pts.end(), std::tie(ones)); + EXPECT_EQ(visits, pts.size()); + EXPECT_EQ(open(std::get<0>(s0), std::get<0>(s1)), std::uint16_t{4}); +} + +TEST(InnerProduct, PrepareMemoizerThenInnerProduct) +{ + // uint64 packs two lanes per leaf. [10, 31] fills those leaves, so a + // weight per domain point is also a weight per covering lane. + auto [k0, k1] = dpf::make_dpf(In{20}, std::uint64_t{6}); + const In from = 10, to = 31; + ASSERT_EQ(decltype(k0)::outputs_per_leaf, 2u); + ASSERT_EQ(static_cast(to - from + 1) % 2u, 0u); + std::vector w(to - from + 1, 2); + auto cold0 = dpf::eval_inner_product(k0, from, to, w, + dpf::make_basic_interval_memoizer(k0, from, to)); + auto cold1 = dpf::eval_inner_product(k1, from, to, w, + dpf::make_basic_interval_memoizer(k1, from, to)); + auto m0 = dpf::make_basic_interval_memoizer(k0, from, to); + auto m1 = dpf::make_basic_interval_memoizer(k1, from, to); + dpf::eval_prepare_interval(k0, from, to, m0); + dpf::eval_prepare_interval(k1, from, to, m1); + const auto warm0 = dpf::eval_inner_product(k0, from, to, w, m0); + const auto warm1 = dpf::eval_inner_product(k1, from, to, w, m1); + EXPECT_EQ(warm0, cold0); + EXPECT_EQ(warm1, cold1); + EXPECT_EQ(open(warm0, warm1), std::uint64_t{6} * 2u); + // A second pass on the warm memoizer must not rebuild a different share. + EXPECT_EQ(dpf::eval_inner_product(k0, from, to, w, m0), warm0); + EXPECT_EQ(dpf::eval_inner_product(k1, from, to, w, m1), warm1); +} + +TEST(InnerProduct, IntervalMatchesPointReconstruction) +{ + // Long interval: reopen against point-by-point reconstruction for both + // paired and columns (two streams). + const In alpha = 100; + const std::uint64_t beta = 13; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + const In from = 80, to = 140; + const std::size_t n = static_cast(to - from + 1); + std::vector ones(n, 1); + std::vector scale(n); + std::uint64_t expect_sum = 0, expect_dot = 0; + for (std::size_t i = 0; i < n; ++i) + { + scale[i] = i + 1; + const In x = static_cast(from + i); + const auto y = open(*dpf::eval_point(k0, x), *dpf::eval_point(k1, x)); + expect_sum += static_cast(y); + expect_dot += static_cast(y) * scale[i]; + } + EXPECT_EQ(open( + dpf::eval_inner_product(dpf::paired, k0, from, to, scale), + dpf::eval_inner_product(dpf::paired, k1, from, to, scale)), + expect_dot); + const auto c0 = dpf::eval_inner_product<0>( + dpf::columns, k0, from, to, std::tie(ones, scale)); + const auto c1 = dpf::eval_inner_product<0>( + dpf::columns, k1, from, to, std::tie(ones, scale)); + EXPECT_EQ(open(std::get<0>(c0), std::get<0>(c1)), expect_sum); + EXPECT_EQ(open(std::get<1>(c0), std::get<1>(c1)), expect_dot); + EXPECT_EQ(expect_sum, beta); + EXPECT_EQ(expect_dot, beta * scale[alpha - from]); +} + +TEST(InnerProduct, ShortCoveringWeightsThrow) +{ + auto [k0, k1] = dpf::make_dpf(In{20}, std::uint64_t{6}); + (void)k1; + // [10, 30] is 21 points and 22 covering lanes (the leaf of 30 also holds 31). + const In from = 10, to = 30; + std::vector clipped(to - from + 1, 2); + auto m0 = dpf::make_basic_interval_memoizer(k0, from, to); + EXPECT_THROW(dpf::eval_inner_product(k0, from, to, clipped, m0), + std::invalid_argument); + dpf::eval_prepare_interval(k0, from, to, m0); + EXPECT_THROW(dpf::eval_inner_product(k0, from, to, clipped, m0), + std::invalid_argument); + + std::vector cover(clipped.size() + 1, 2); + EXPECT_EQ(open( + dpf::eval_inner_product(k0, from, to, cover, m0), + dpf::eval_inner_product(k1, from, to, cover, + dpf::make_basic_interval_memoizer(k1, from, to))), + std::uint64_t{6} * 2u); +} + +TEST(InnerProduct, OneLaneShortStillThrows) +{ + auto [k0, k1] = dpf::make_dpf(In{4}, std::uint64_t{1}); + (void)k1; + const In from = 0, to = 2; // 3 points, 4 covering lanes + std::vector almost(3, 1); + auto memo = dpf::make_basic_interval_memoizer(k0, from, to); + EXPECT_THROW(dpf::eval_inner_product(k0, from, to, almost, memo), + std::invalid_argument); + almost.push_back(0); + EXPECT_NO_THROW(dpf::eval_inner_product(k0, from, to, almost, memo)); +} + +TEST(InnerProduct, MemoizerSmallerThanIntervalThrows) +{ + auto [k0, k1] = dpf::make_dpf(In{8}, std::uint64_t{3}); + (void)k1; + auto small = dpf::make_basic_interval_memoizer(k0, In{0}, In{1}); + std::vector w(64, 1); + EXPECT_THROW(dpf::eval_inner_product(k0, In{0}, In{30}, w, small), + std::length_error); + EXPECT_THROW(dpf::eval_prepare_interval(k0, In{0}, In{30}, small), + std::length_error); +} + +TEST(InnerProduct, PairedAndColumnsRejectShortWeights) +{ + auto [k0, k1] = dpf::make_dpf(In{5}, std::uint64_t{2}); + (void)k1; + const In from = 1, to = 8; + std::vector short_w(3, 1); + EXPECT_THROW(dpf::eval_inner_product(dpf::paired, k0, from, to, short_w), + std::invalid_argument); + EXPECT_THROW(dpf::eval_inner_product<0>(dpf::columns, k0, from, to, + std::tie(short_w)), std::invalid_argument); + + const std::vector pts{1, 5, 8}; + const std::vector one_row{1}; + EXPECT_THROW(dpf::eval_sequence_inner_product<0>( + k0, pts.begin(), pts.end(), one_row), std::invalid_argument); + const std::vector one{1}; + EXPECT_THROW(dpf::eval_sequence_inner_product<0>( + dpf::columns, k0, pts.begin(), pts.end(), std::tie(one)), + std::invalid_argument); +} + +TEST(InnerProduct, PrepareOnAWrapStillMatchesPoints) +{ + auto [k0, k1] = dpf::make_dpf(In{1}, std::uint32_t{9}); + const In from = 250, to = 4; + std::vector w; + std::uint64_t expect = 0; + for (unsigned x = from; x < 256; ++x) + { + w.push_back(static_cast(w.size() + 1)); + const auto y = open(*dpf::eval_point(k0, static_cast(x)), + *dpf::eval_point(k1, static_cast(x))); + expect += static_cast(y) * w.back(); + } + for (unsigned x = 0; x <= to; ++x) + { + w.push_back(static_cast(w.size() + 1)); + const auto y = open(*dpf::eval_point(k0, static_cast(x)), + *dpf::eval_point(k1, static_cast(x))); + expect += static_cast(y) * w.back(); + } + auto m0 = dpf::make_basic_interval_memoizer(k0, from, to); + auto m1 = dpf::make_basic_interval_memoizer(k1, from, to); + dpf::eval_prepare_interval(k0, from, to, m0); + dpf::eval_prepare_interval(k1, from, to, m1); + EXPECT_EQ(open( + dpf::eval_inner_product(dpf::paired, k0, from, to, w), + dpf::eval_inner_product(dpf::paired, k1, from, to, w)), + expect); + // A wrap is two leaf segments. The memoizer keeps one, so prepare must + // leave the paired product unchanged and must not throw. + EXPECT_EQ(open( + dpf::eval_inner_product(dpf::paired, k0, from, to, w), + dpf::eval_inner_product(dpf::paired, k1, from, to, w)), + expect); + std::vector too_short(w.size() - 1, 1); + EXPECT_THROW( + dpf::eval_inner_product(dpf::paired, k0, from, to, too_short), + std::invalid_argument); + (void)m0; + (void)m1; +} + +TEST(InnerProduct, BatchedWalkMatchesIntervalBuffer) +{ + auto [k0, k1] = dpf::make_dpf(In{20}, std::uint64_t{6}); + const In from = 10, to = 30; + auto [buf0, it0] = dpf::eval_interval(k0, from, to); + auto [buf1, it1] = dpf::eval_interval(k1, from, to); + (void)it0; + (void)it1; + ASSERT_GT(buf0.size(), static_cast(to - from + 1)); + std::vector w(buf0.size()); + for (std::size_t i = 0; i < w.size(); ++i) + w[i] = (i * 3u) + 1u; + std::uint64_t e0 = 0, e1 = 0, opened = 0; + for (std::size_t i = 0; i < w.size(); ++i) + { + e0 += static_cast(buf0[i].value) * w[i]; + e1 += static_cast(buf1[i].value) * w[i]; + opened += static_cast(open(buf0[i], buf1[i])) * w[i]; + } + auto m0 = dpf::make_basic_interval_memoizer(k0, from, to); + auto m1 = dpf::make_basic_interval_memoizer(k1, from, to); + dpf::eval_prepare_interval(k0, from, to, m0); + dpf::eval_prepare_interval(k1, from, to, m1); + const auto ip0 = dpf::eval_inner_product(k0, from, to, w, m0); + const auto ip1 = dpf::eval_inner_product(k1, from, to, w, m1); + EXPECT_EQ(ip0, e0); + EXPECT_EQ(ip1, e1); + EXPECT_EQ(open(ip0, ip1), opened); + std::size_t hot = w.size(); + for (std::size_t i = 0; i < w.size(); ++i) + { + if (open(buf0[i], buf1[i]) != 0) + { + EXPECT_EQ(hot, w.size()); + hot = i; + } + } + ASSERT_LT(hot, w.size()); + EXPECT_EQ(opened, std::uint64_t{6} * w[hot]); +} + +TEST(InnerProduct, FullDomainBatchedRejectsAShortVector) +{ + auto [k0, k1] = dpf::make_dpf(In{3}, std::uint64_t{1}); + (void)k1; + std::vector w(255, 1); + auto memo = dpf::make_basic_full_memoizer(k0); + EXPECT_THROW(dpf::eval_full_inner_product(k0, w, memo), + std::invalid_argument); + w.push_back(1); + EXPECT_EQ(open( + dpf::eval_full_inner_product(k0, w, memo), + dpf::eval_full_inner_product(k1, w, + dpf::make_basic_full_memoizer(k1))), + std::uint64_t{1} * w[3]); +} + +TEST(InnerProduct, TwoOutputRowsRejectAShortList) +{ + auto [k0, k1] = dpf::make_dpf(In{4}, std::uint16_t{2}, std::uint16_t{6}); + (void)k1; + const std::vector pts{1, 4, 8}; + std::vector> rows{{1u, 1u}}; + EXPECT_THROW((dpf::eval_sequence_inner_product<0, 1>( + k0, pts.begin(), pts.end(), rows)), std::invalid_argument); + rows.push_back({3u, 5u}); + rows.push_back({7u, 9u}); + EXPECT_NO_THROW((dpf::eval_sequence_inner_product<0, 1>( + k0, pts.begin(), pts.end(), rows))); +} diff --git a/test/tests/eval_interval_multi_test.cpp b/test/tests/eval_interval_multi_test.cpp index 7c384a5..0b5a467 100644 --- a/test/tests/eval_interval_multi_test.cpp +++ b/test/tests/eval_interval_multi_test.cpp @@ -16,7 +16,13 @@ auto recon(const A & a, const B & b) && dpf::is_secret_share_v>) return dpf::reconstruct(a, b); else - return a - b; + { + using T = std::common_type_t, std::decay_t>; + if constexpr (std::is_integral_v && std::is_unsigned_v) + return static_cast(a - b); + else + return a - b; + } } } // namespace @@ -289,6 +295,13 @@ using Types = testing::Types test_type>, test_type>, test_type>, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, // custom types test_type, diff --git a/test/tests/eval_interval_test.cpp b/test/tests/eval_interval_test.cpp index 8dd7c47..6ab4413 100644 --- a/test/tests/eval_interval_test.cpp +++ b/test/tests/eval_interval_test.cpp @@ -17,7 +17,13 @@ auto recon(const A & a, const B & b) && dpf::is_secret_share_v>) return dpf::reconstruct(a, b); else - return a - b; + { + using T = std::common_type_t, std::decay_t>; + if constexpr (std::is_integral_v && std::is_unsigned_v) + return static_cast(a - b); + else + return a - b; + } } } // namespace @@ -265,6 +271,13 @@ using Types = testing::Types test_type>, test_type>, test_type>, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, // custom types test_type, diff --git a/test/tests/eval_point_multi_test.cpp b/test/tests/eval_point_multi_test.cpp index bfa4cb4..d481000 100644 --- a/test/tests/eval_point_multi_test.cpp +++ b/test/tests/eval_point_multi_test.cpp @@ -14,7 +14,13 @@ auto recon(const A & a, const B & b) && dpf::is_secret_share_v>) return dpf::reconstruct(a, b); else - return a - b; + { + using T = std::common_type_t, std::decay_t>; + if constexpr (std::is_integral_v && std::is_unsigned_v) + return static_cast(a - b); + else + return a - b; + } } } // namespace @@ -128,7 +134,11 @@ TYPED_TEST_P(EvalPointMultiTest, Basic) for (auto [x, y0, y1, y2, y3] : this->params) { - auto [dpf0, dpf1] = dpf::make_dpf(x, y0, y1, y2, y3); + auto _keys = dpf::make_dpf(x, y0, y1, y2, y3); + + auto & dpf0 = std::get<0>(_keys); + + auto & dpf1 = std::get<1>(_keys); this->assert_wrapper(x, y0, y1, y2, y3, [&dpf0](input_type cur) @@ -152,7 +162,11 @@ TYPED_TEST_P(EvalPointMultiTest, BasicPathMemoizer) for (auto [x, y0, y1, y2, y3] : this->params) { - auto [dpf0, dpf1] = dpf::make_dpf(x, y0, y1, y2, y3); + auto _keys = dpf::make_dpf(x, y0, y1, y2, y3); + + auto & dpf0 = std::get<0>(_keys); + + auto & dpf1 = std::get<1>(_keys); this->assert_wrapper(x, y0, y1, y2, y3, [&dpf0, &memo0](input_type cur) @@ -176,7 +190,11 @@ TYPED_TEST_P(EvalPointMultiTest, NonmemoizingPathMemoizer) for (auto [x, y0, y1, y2, y3] : this->params) { - auto [dpf0, dpf1] = dpf::make_dpf(x, y0, y1, y2, y3); + auto _keys = dpf::make_dpf(x, y0, y1, y2, y3); + + auto & dpf0 = std::get<0>(_keys); + + auto & dpf1 = std::get<1>(_keys); this->assert_wrapper(x, y0, y1, y2, y3, [&dpf0, &memo0](input_type cur) @@ -222,6 +240,13 @@ using Types = testing::Types test_type>, test_type>, test_type>, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, // custom types test_type, diff --git a/test/tests/eval_point_test.cpp b/test/tests/eval_point_test.cpp index 1c84032..a40b298 100644 --- a/test/tests/eval_point_test.cpp +++ b/test/tests/eval_point_test.cpp @@ -16,7 +16,13 @@ auto recon(const A & a, const B & b) && dpf::is_secret_share_v>) return dpf::reconstruct(a, b); else - return a - b; + { + using T = std::common_type_t, std::decay_t>; + if constexpr (std::is_integral_v && std::is_unsigned_v) + return static_cast(a - b); + else + return a - b; + } } } // namespace @@ -110,7 +116,11 @@ TYPED_TEST_P(EvalPointTest, Basic) for (auto [x, y] : this->params) { - auto [dpf0, dpf1] = dpf::make_dpf(x, y); + auto _keys = dpf::make_dpf(x, y); + + auto & dpf0 = std::get<0>(_keys); + + auto & dpf1 = std::get<1>(_keys); this->assert_wrapper(x, y, [&dpf0](input_type cur) @@ -131,7 +141,11 @@ TYPED_TEST_P(EvalPointTest, BasicPathMemoizer) for (auto [x, y] : this->params) { - auto [dpf0, dpf1] = dpf::make_dpf(x, y); + auto _keys = dpf::make_dpf(x, y); + + auto & dpf0 = std::get<0>(_keys); + + auto & dpf1 = std::get<1>(_keys); using key0_t = std::decay_t; using key1_t = std::decay_t; auto memo0 = dpf::make_basic_path_memoizer(), @@ -156,7 +170,11 @@ TYPED_TEST_P(EvalPointTest, NonmemoizingPathMemoizer) for (auto [x, y] : this->params) { - auto [dpf0, dpf1] = dpf::make_dpf(x, y); + auto _keys = dpf::make_dpf(x, y); + + auto & dpf0 = std::get<0>(_keys); + + auto & dpf1 = std::get<1>(_keys); using key0_t = std::decay_t; using key1_t = std::decay_t; auto memo0 = dpf::make_nonmemoizing_path_memoizer(), @@ -206,6 +224,13 @@ using Types = testing::Types test_type>, test_type>, test_type>, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, // custom types test_type, diff --git a/test/tests/eval_sequence_multi_test.cpp b/test/tests/eval_sequence_multi_test.cpp index 647e1be..3d7bb64 100644 --- a/test/tests/eval_sequence_multi_test.cpp +++ b/test/tests/eval_sequence_multi_test.cpp @@ -16,7 +16,13 @@ auto recon(const A & a, const B & b) && dpf::is_secret_share_v>) return dpf::reconstruct(a, b); else - return a - b; + { + using T = std::common_type_t, std::decay_t>; + if constexpr (std::is_integral_v && std::is_unsigned_v) + return static_cast(a - b); + else + return a - b; + } } } // namespace @@ -702,6 +708,13 @@ using Types = testing::Types test_type>, test_type>, test_type>, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, // custom types test_type, diff --git a/test/tests/eval_sequence_test.cpp b/test/tests/eval_sequence_test.cpp index af3f62d..fb2d4ce 100644 --- a/test/tests/eval_sequence_test.cpp +++ b/test/tests/eval_sequence_test.cpp @@ -18,7 +18,13 @@ auto recon(const A & a, const B & b) && dpf::is_secret_share_v>) return dpf::reconstruct(a, b); else - return a - b; + { + using T = std::common_type_t, std::decay_t>; + if constexpr (std::is_integral_v && std::is_unsigned_v) + return static_cast(a - b); + else + return a - b; + } } } // namespace @@ -711,6 +717,13 @@ using Types = testing::Types test_type>, test_type>, test_type>, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, + test_type, // custom types test_type, diff --git a/test/tests/eval_until_test.cpp b/test/tests/eval_until_test.cpp new file mode 100644 index 0000000..6bbe5f6 --- /dev/null +++ b/test/tests/eval_until_test.cpp @@ -0,0 +1,138 @@ +#include + +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +auto make_unit16(std::uint16_t alpha) +{ + return dpf::make_dpf(alpha, dpf::idpf_ones<16>()); +} + +} // namespace + +TEST(EvalUntil, SpineMatchesEvalPoint) +{ + const std::uint16_t alpha = 0xBEEF; + auto [k0, k1] = make_unit16(alpha); + + dpf::idpf_eval_ctx ctx0(k0); + dpf::idpf_eval_ctx ctx1(k1); + EXPECT_EQ(ctx0.level(), 0u); + EXPECT_EQ(ctx0.node_count(), 1u); + + // Empty prefixes on a fresh context leave the root in place. + auto empty = dpf::eval_until(ctx0, 0, std::vector{}); + EXPECT_TRUE(empty.empty()); + EXPECT_EQ(ctx0.node_count(), 1u); + + std::uint16_t prefix = 0; + for (std::size_t level = 1; level <= 16; ++level) + { + const auto bit = static_cast( + (alpha >> (16 - level)) & 1u); + prefix = static_cast((prefix << 1) | bit); + auto s0 = dpf::eval_until(ctx0, level, + std::vector{prefix}); + auto s1 = dpf::eval_until(ctx1, level, + std::vector{prefix}); + ASSERT_EQ(s0.size(), 1u); + ASSERT_EQ(s1.size(), 1u); + EXPECT_EQ(ctx0.node_count(), 1u); + EXPECT_LE(ctx0.node_count(), level); + + const auto domain = static_cast( + prefix << (16 - level)); + // Dispatch eval_point through a level switch for the matching out. + std::uint64_t ref = 0; + switch (level) + { +#define LIBDPF_CHECK_LEVEL(L) \ + case L: \ + ref = dpf::reconstruct( \ + *dpf::eval_point(dpf::out, k0, domain), \ + *dpf::eval_point(dpf::out, k1, domain)); \ + break + LIBDPF_CHECK_LEVEL(1); LIBDPF_CHECK_LEVEL(2); LIBDPF_CHECK_LEVEL(3); + LIBDPF_CHECK_LEVEL(4); LIBDPF_CHECK_LEVEL(5); LIBDPF_CHECK_LEVEL(6); + LIBDPF_CHECK_LEVEL(7); LIBDPF_CHECK_LEVEL(8); LIBDPF_CHECK_LEVEL(9); + LIBDPF_CHECK_LEVEL(10); LIBDPF_CHECK_LEVEL(11); LIBDPF_CHECK_LEVEL(12); + LIBDPF_CHECK_LEVEL(13); LIBDPF_CHECK_LEVEL(14); LIBDPF_CHECK_LEVEL(15); + LIBDPF_CHECK_LEVEL(16); +#undef LIBDPF_CHECK_LEVEL + default: + FAIL() << "bad level"; + } + EXPECT_EQ(dpf::reconstruct(s0[0], s1[0]), ref); + EXPECT_EQ(ref, 1u); + } +} + +TEST(EvalUntil, RejectsNonExtendingPrefix) +{ + auto [k0, k1] = make_unit16(0x0001); + (void)k1; + dpf::idpf_eval_ctx ctx(k0); + dpf::eval_until(ctx, 1, std::vector{0}); + EXPECT_THROW( + dpf::eval_until(ctx, 2, std::vector{3}), + std::invalid_argument); +} + +TEST(EvalUntil, BothChildrenStayLinear) +{ + auto [k0, k1] = make_unit16(0xF00D); + dpf::idpf_eval_ctx ctx0(k0); + dpf::idpf_eval_ctx ctx1(k1); + auto s0 = dpf::eval_until(ctx0, 1, std::vector{0, 1}); + auto s1 = dpf::eval_until(ctx1, 1, std::vector{0, 1}); + EXPECT_EQ(ctx0.node_count(), 2u); + EXPECT_EQ(dpf::reconstruct(s0[0], s1[0]), 0u); + EXPECT_EQ(dpf::reconstruct(s0[1], s1[1]), 1u); +} + +// Seam with the older full-prefix walk: at depth 1, eval_until on {0,1} +// opens the same counts as eval_prefixes(out<0,1>). +TEST(EvalUntil, MatchesEvalPrefixesAtDepthOne) +{ + const std::uint16_t alpha = 0x8000; + auto [k0, k1] = make_unit16(alpha); + + dpf::idpf_eval_ctx ctx0(k0); + dpf::idpf_eval_ctx ctx1(k1); + auto u0 = dpf::eval_until(ctx0, 1, std::vector{0, 1}); + auto u1 = dpf::eval_until(ctx1, 1, std::vector{0, 1}); + + auto [b0, it0] = dpf::eval_prefixes(dpf::out<0, 1>, k0); + auto [b1, it1] = dpf::eval_prefixes(dpf::out<0, 1>, k1); + (void)b0; + (void)b1; + auto p0 = std::begin(it0); + auto p1 = std::begin(it1); + EXPECT_EQ(dpf::reconstruct(u0[0], u1[0]), dpf::reconstruct(*p0, *p1)); + ++p0; + ++p1; + EXPECT_EQ(dpf::reconstruct(u0[1], u1[1]), dpf::reconstruct(*p0, *p1)); +} + +TEST(EvalUntil, RetainThenContinue) +{ + auto [k0, k1] = make_unit16(0xC000); + dpf::idpf_eval_ctx ctx0(k0); + dpf::idpf_eval_ctx ctx1(k1); + dpf::eval_until(ctx0, 1, std::vector{0, 1}); + dpf::eval_until(ctx1, 1, std::vector{0, 1}); + ctx0.retain(1); + ctx1.retain(1); + EXPECT_EQ(ctx0.node_count(), 1u); + auto s0 = dpf::eval_until(ctx0, 2, std::vector{2, 3}); + auto s1 = dpf::eval_until(ctx1, 2, std::vector{2, 3}); + // 0xC000 = 1100… so length-2 prefix is 3 (bits 11). + EXPECT_EQ(dpf::reconstruct(s0[0], s1[0]), 0u); + EXPECT_EQ(dpf::reconstruct(s0[1], s1[1]), 1u); +} diff --git a/test/tests/exact_steps_test.cpp b/test/tests/exact_steps_test.cpp new file mode 100644 index 0000000..3a26ad2 --- /dev/null +++ b/test/tests/exact_steps_test.cpp @@ -0,0 +1,164 @@ +#include +#include + +#include "grotto/exact_steps.hpp" + +#include +#include +#include + +namespace +{ + +int ref_bit_width(std::uint16_t bits) +{ + if (bits == 0) + return 0; + return 32 - __builtin_clz(static_cast(bits)); +} + +int ref_countl_one(std::uint16_t bits) +{ + int n = 0; + for (int b = 15; b >= 0; --b) + { + if (((bits >> b) & 1u) == 0) + break; + ++n; + } + return n; +} + +std::uint16_t ref_bit_floor(std::uint16_t bits) +{ + if (bits == 0) + return 0; + return std::uint16_t{1} << (ref_bit_width(bits) - 1); +} + +std::uint32_t ref_bit_ceil(std::uint16_t bits) +{ + if (bits <= 1) + return 1; + if ((bits & (bits - 1u)) == 0) + return bits; + return std::uint32_t{1} << ref_bit_width(bits); +} + +int ref_ceil_log(std::int16_t raw, unsigned k, int group) +{ + const long double x = std::ldexp(static_cast(raw < 0 ? -raw : raw), -static_cast(k)); + return static_cast(std::ceil(std::log2(static_cast(x)) / group - 1e-15)); +} + +int ref_logstar(std::int16_t raw, unsigned k) +{ + long double x = std::ldexp(static_cast(raw), -static_cast(k)); + int n = 0; + while (x > 1.0L) + { + x = std::log2(static_cast(x)); + ++n; + if (n > 8) + break; + } + return n; +} + +int ref_length(std::int16_t raw, unsigned k, int base) +{ + const long double x = std::ldexp(static_cast(raw < 0 ? -raw : raw), -static_cast(k)); + const auto n = static_cast(std::floor(static_cast(x))); + if (n <= 0) + return 1; + int digits = 0; + auto m = n; + while (m > 0) + { + m /= base; + ++digits; + } + return digits; +} + +} // namespace + +TEST(ExactSteps, WordBitsMatchTheUnsignedPattern) +{ + for (int raw = -32768; raw <= 32767; ++raw) + { + const auto bits = static_cast(raw); + const auto value = static_cast(static_cast(raw)); + EXPECT_EQ(grotto::eval_bit_width(value, 0), ref_bit_width(bits)); + EXPECT_EQ(grotto::eval_countl_one(value, 0), ref_countl_one(bits)); + EXPECT_EQ(grotto::eval_has_single_bit(value, 0), + ((bits != 0 && (bits & (bits - 1u)) == 0) ? 1 : 0)); + EXPECT_EQ(grotto::eval_bit_floor(value), ref_bit_floor(bits)); + EXPECT_EQ(grotto::eval_bit_ceil(value), ref_bit_ceil(bits)); + } +} + +TEST(ExactSteps, IntegerLogsAndLogstar) +{ + for (unsigned k : {0u, 4u}) + { + for (int raw = 1; raw <= 32767; raw += (k == 0 ? 17 : 3)) + { + const auto value = static_cast(raw); + EXPECT_EQ(grotto::eval_ilog16(value, k) >> k, ref_ceil_log(static_cast(raw), k, 4)) + << raw << " k=" << k; + EXPECT_EQ(grotto::eval_ilog256(value, k) >> k, ref_ceil_log(static_cast(raw), k, 8)) + << raw; + EXPECT_EQ(grotto::eval_logstar(value, k) >> k, ref_logstar(static_cast(raw), k)) + << raw; + } + } + EXPECT_EQ(grotto::eval_ilog16(0, 0), grotto::ilog_of_zero); + EXPECT_EQ(grotto::eval_logstar(-4, 0), grotto::ilog_of_zero); + EXPECT_EQ(grotto::eval_logstar(1, 0), 0); + EXPECT_EQ(grotto::eval_logstar(2, 0), 1); + EXPECT_EQ(grotto::eval_logstar(4, 0), 2); + EXPECT_EQ(grotto::eval_logstar(16, 0), 3); +} + +TEST(ExactSteps, DecimalFloorCeilAndLengths) +{ + for (unsigned k : {0u, 4u}) + { + for (int raw = -4000; raw <= 4000; raw += 3) + { + const long double x = std::ldexp(static_cast(raw), -static_cast(k)); + const auto floor_raw = static_cast(std::floor(static_cast(x)) * std::ldexp(1.0, static_cast(k))); + const auto ceil_raw = static_cast(std::ceil(static_cast(x)) * std::ldexp(1.0, static_cast(k))); + EXPECT_EQ(grotto::eval_dec_floor(raw, k), floor_raw) << raw; + EXPECT_EQ(grotto::eval_dec_ceil(raw, k), ceil_raw) << raw; + const auto width = static_cast(raw); + EXPECT_EQ(grotto::eval_dec_width(raw, k) >> k, ref_length(width, k, 10)); + EXPECT_EQ(grotto::eval_oct_width(raw, k) >> k, ref_length(width, k, 8)); + EXPECT_EQ(grotto::eval_b64_width(raw, k) >> k, ref_length(width, k, 64)); + const auto digits = std::llabs(static_cast(std::floor(std::fabs(static_cast(x))))); + EXPECT_EQ(grotto::eval_has_single_digit(raw, k) >> k, digits <= 9 ? 1 : 0); + } + } +} + +TEST(ExactSteps, AngleScaleIsTheLinearFactor) +{ + const unsigned k = 16; + const std::int64_t deg = 180ll << k; + const auto rad = grotto::eval_deg2rad(deg, k); + const long double want = 180.0L * 3.14159265358979323846L / 180.0L * std::ldexp(1.0L, k); + EXPECT_LE(std::fabsl(static_cast(rad) - want), 64.0L); + const auto back = grotto::eval_rad2deg(rad, k); + EXPECT_LE(std::llabs(back - deg), 4096); +} + +TEST(ExactSteps, StepLutAgreesWithTheScalarOnInt8) +{ + const auto lut = grotto::make_exact_step_lut(0, [](std::int64_t raw) { + return grotto::eval_bit_width(raw, 0); + }); + for (int raw = -128; raw <= 127; ++raw) + EXPECT_EQ(lut(static_cast(raw)), grotto::eval_bit_width(raw, 0)); + EXPECT_THROW(grotto::make_exact_step_lut(0, [](std::int64_t) { return 0; }), std::invalid_argument); +} diff --git a/test/tests/experiment_test.cpp b/test/tests/experiment_test.cpp new file mode 100644 index 0000000..e162598 --- /dev/null +++ b/test/tests/experiment_test.cpp @@ -0,0 +1,299 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/app_flow.hpp" +#include "dpf/app_plans.hpp" +#include "dpf/beaver.hpp" +#include "dpf/buffered_prg.hpp" +#include "dpf/doerner_shelat.hpp" +#include "dpf/experiment.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" + +namespace +{ + +std::string tmp_dir(const char * tag) +{ + const std::string dir = + std::string("/tmp/libdpf_ex_") + tag + "_" + std::to_string(::getpid()); + (void)::system(("rm -rf " + dir + " && mkdir -p " + dir).c_str()); + return dir; +} + +std::size_t count_lines(const std::string & path) +{ + std::ifstream in(path); + std::size_t n = 0; + std::string line; + while (std::getline(in, line)) + ++n; + return n; +} + +TEST(Experiment, ReplayMatchesMakeDpfRoots) +{ + dpf::experiment::master_seed master{}; + std::uint8_t alpha = 7; + using node_t = dpf::prg::aes128::block_type; + node_t root0a{}, root0b{}, root1a{}, root1b{}; + { + dpf::experiment ex("dpf"); + master = ex.seed(); + auto [k0, k1] = dpf::make_dpf(alpha, std::uint64_t{1}); + root0a = k0.root(); + root1a = k1.root(); + } + { + auto ex = dpf::experiment::replay("dpf", master); + auto [k0, k1] = dpf::make_dpf(alpha, std::uint64_t{1}); + root0b = k0.root(); + root1b = k1.root(); + } + EXPECT_EQ(std::memcmp(&root0a, &root0b, sizeof(root0a)), 0); + EXPECT_EQ(std::memcmp(&root1a, &root1b, sizeof(root1a)), 0); +} + +TEST(Experiment, NestedRaiiRestoresOuterHook) +{ + dpf::experiment outer("outer"); + const auto outer_seed = outer.seed(); + const auto a = dpf::uniform_sample(); + { + dpf::experiment inner("inner"); + EXPECT_NE(inner.seed(), outer_seed); + (void)dpf::uniform_sample(); + } + // Outer stream continues where it left off (inner restored the hook). + const auto b = dpf::uniform_sample(); + auto again = dpf::experiment::replay("outer", outer_seed); + EXPECT_EQ(dpf::uniform_sample(), a); + EXPECT_EQ(dpf::uniform_sample(), b); +} + +TEST(Experiment, NoteSeedFromConstructors) +{ + dpf::experiment ex("ctors"); + EXPECT_TRUE(ex.has_seed_named("master")); + { + dpf::beavers::oracle o(16); + EXPECT_TRUE(ex.has_seed_named("beavers::oracle")); + EXPECT_TRUE(ex.has_seed_named("lane_table")); + (void)o; + } + { + dpf::randomness::buffered_prg prg(8); + EXPECT_TRUE(ex.has_seed_named("buffered_prg")); + (void)prg; + } + { + dpf::prg_pad_rng<> pad; + EXPECT_TRUE(ex.has_seed_named("prg_pad_rng")); + (void)pad; + } + { + dpf::pseudorandom_root_sampler roots; + EXPECT_TRUE(ex.has_seed_named("pseudorandom_root_sampler")); + (void)roots; + } + ex.note_seed("custom", std::uint32_t{0xdeadbeefu}); + EXPECT_TRUE(ex.has_seed_named("custom")); + EXPECT_GE(ex.seed_count(), 6u); +} + +TEST(Experiment, RandomBytesCounterTracksUniformFill) +{ + dpf::reset_random_bytes_count(); + EXPECT_EQ(dpf::random_bytes_count(), 0u); + dpf::experiment ex("bytes"); + // ctor resets after drawing the master. + EXPECT_EQ(dpf::random_bytes_count(), 0u); + (void)dpf::uniform_sample(); + EXPECT_EQ(dpf::random_bytes_count(), 8u); + (void)dpf::uniform_sample(); + EXPECT_EQ(dpf::random_bytes_count(), 12u); +} + +TEST(Experiment, IngestPlanCriticalPathAndEdges) +{ + dpf::experiment ex("plan"); + auto p = dpf::protocol::fss_point_plan(0, 8, 16); + ex.ingest_plan(p); + EXPECT_EQ(ex.interactive_rounds(), 8u); + EXPECT_EQ(ex.dag_depth(), p.waves()); + EXPECT_EQ(ex.plan_bytes_out(), 128u); + EXPECT_EQ(ex.plan_edge_bytes(dpf::protocol::edge_channel::peer), 128u); + EXPECT_EQ(ex.plan_edge_bytes(dpf::protocol::edge_channel::dealer), 0u); + EXPECT_GT(ex.critical_path_length(), 0u); +} + +TEST(Experiment, MeasurePlanProbeAndTiming) +{ + auto plan = dpf::protocol::mailbox_write_fused_plan(0); + auto ex = dpf::app::measure_plan("mailbox", plan); + EXPECT_EQ(ex.interactive_rounds(), 8u); + EXPECT_EQ(ex.rounds().size(), 8u); + std::size_t sum_out = 0, sum_in = 0; + for (const auto & r : ex.rounds()) + { + EXPECT_EQ(r.channel, dpf::protocol::edge_channel::peer); + sum_out += r.bytes_out; + sum_in += r.bytes_in; + } + EXPECT_EQ(sum_out, ex.bytes_out()); + EXPECT_EQ(sum_in, ex.bytes_in()); + EXPECT_EQ(ex.edge_bytes_out(dpf::protocol::edge_channel::peer), + ex.bytes_out()); + EXPECT_GT(ex.wall_ns(), 0u); + EXPECT_GT(ex.prg_evals(), 0u); // walk kernels expand + EXPECT_TRUE(ex.has_seed_named("master")); +} + +TEST(Experiment, MeasureClientServersTwoRounds) +{ + auto plan = dpf::protocol::n_server_pir_plan(0, 2, 64, 8); + const auto slots = plan.slot_bytes_all(); + ASSERT_EQ(slots.size(), 2u); + auto ex = dpf::app::measure_plan("pir2", plan); + EXPECT_EQ(ex.interactive_rounds(), 2u); + ASSERT_EQ(ex.rounds().size(), 2u); + EXPECT_EQ(ex.rounds()[0].bytes_out, slots[0]); + EXPECT_EQ(ex.rounds()[1].bytes_out, slots[1]); + EXPECT_EQ(ex.plan_bytes_out(), slots[0] + slots[1]); +} + +TEST(Experiment, WriteCsvAllFilesAndAppend) +{ + const auto dir = tmp_dir("csv"); + auto plan = dpf::protocol::fss_cmp_plan(0); + auto ex = dpf::app::measure_plan("cmp", plan); + ex.set_run_id(1); + ex.write_csv(dir); + EXPECT_EQ(count_lines(dir + "/summary.csv"), 2u); // header + row + EXPECT_GE(count_lines(dir + "/rounds.csv"), 2u); + EXPECT_GE(count_lines(dir + "/edges.csv"), 2u); + EXPECT_GE(count_lines(dir + "/seeds.csv"), 2u); + EXPECT_GE(count_lines(dir + "/critical_path.csv"), 2u); + + ex.set_run_id(2); + ex.write_csv(dir); + EXPECT_EQ(count_lines(dir + "/summary.csv"), 3u); // append + + std::ifstream seeds(dir + "/seeds.csv"); + std::string line; + bool saw_master = false; + while (std::getline(seeds, line)) + if (line.find("master") != std::string::npos) + saw_master = true; + EXPECT_TRUE(saw_master); + (void)::system(("rm -rf " + dir).c_str()); +} + +TEST(Experiment, RunMeasuredEnvCsv) +{ + const auto dir = tmp_dir("env"); + ASSERT_EQ(::setenv("DPF_EXPERIMENT_DIR", dir.c_str(), 1), 0); + const int rc = dpf::app::run_measured("env_csv", + dpf::protocol::keyword_pir_compose_plan(0, 8), 2); + EXPECT_EQ(rc, 0); + EXPECT_GE(count_lines(dir + "/summary.csv"), 2u); + ASSERT_EQ(::unsetenv("DPF_EXPERIMENT_DIR"), 0); + (void)::system(("rm -rf " + dir).c_str()); +} + +TEST(Experiment, ProbeAbsentDriveStillWorks) +{ + // exercise_plan without experiment must not require clocks/probes. + auto plan = dpf::protocol::range_count_plan(0); + const auto cost = dpf::app::exercise_plan(plan); + EXPECT_EQ(cost.rounds, 8u); + EXPECT_EQ(cost.bytes, 128u); +} + +TEST(Experiment, UninstallRestoresSystemEntropy) +{ + dpf::experiment::master_seed master{}; + { + dpf::experiment ex("tmp"); + master = ex.seed(); + (void)dpf::uniform_sample(); + } + // After destroy, draws are fresh system entropy (not the replay stream). + // Just ensure we can sample without a hook and without throwing. + const auto x = dpf::uniform_sample(); + const auto y = dpf::uniform_sample(); + (void)x; + (void)y; + auto replayed = dpf::experiment::replay("tmp", master); + // Replay still works after a window of system entropy. + (void)dpf::uniform_sample(); +} + +TEST(Experiment, ThreadsDoNotCrossStreams) +{ + constexpr int n = 32; + std::vector a(n), b(n); + dpf::experiment::master_seed sa{}, sb{}; + std::thread t0([&] { + dpf::experiment ex("A", "p0"); + sa = ex.seed(); + for (int i = 0; i < n; ++i) + a[i] = dpf::uniform_sample(); + }); + std::thread t1([&] { + dpf::experiment ex("B", "p1"); + sb = ex.seed(); + for (int i = 0; i < n; ++i) + b[i] = dpf::uniform_sample(); + }); + t0.join(); + t1.join(); + EXPECT_NE(sa, sb); + auto ra = dpf::experiment::replay("A", sa); + for (int i = 0; i < n; ++i) + EXPECT_EQ(dpf::uniform_sample(), a[i]); + auto rb = dpf::experiment::replay("B", sb); + for (int i = 0; i < n; ++i) + EXPECT_EQ(dpf::uniform_sample(), b[i]); +} + +TEST(Experiment, MoveTransfersActiveContext) +{ + dpf::experiment::master_seed master{}; + std::uint64_t first = 0; + { + dpf::experiment ex("move"); + master = ex.seed(); + first = dpf::uniform_sample(); + dpf::experiment moved = std::move(ex); + EXPECT_EQ(moved.seed(), master); + const auto second = dpf::uniform_sample(); + auto again = dpf::experiment::replay("move", master); + EXPECT_EQ(dpf::uniform_sample(), first); + EXPECT_EQ(dpf::uniform_sample(), second); + } +} + +TEST(Experiment, BeginEndTimingWithoutProbe) +{ + dpf::experiment ex("timing"); + ex.begin_timing(); + volatile std::uint64_t sink = 0; + for (int i = 0; i < 1000; ++i) + sink += dpf::uniform_sample(); + (void)sink; + ex.end_timing(); + EXPECT_GT(ex.wall_ns(), 0u); + EXPECT_GE(ex.random_bytes(), 8000u); +} + +} // namespace diff --git a/test/tests/extractable_full_test.cpp b/test/tests/extractable_full_test.cpp new file mode 100644 index 0000000..095b337 --- /dev/null +++ b/test/tests/extractable_full_test.cpp @@ -0,0 +1,62 @@ +#include + +#include +#include + +#include "dpf.hpp" + +// Extractable full-domain expansion must match point eval share-for-share, +// including both lanes of the packed leaf that holds the programmed point. +TEST(ExtractableFull, Fp61SharesMatchPointEval) +{ + constexpr std::uint8_t alpha = 9; + const dpf::fp61 message{42}; + auto [k0, k1] = dpf::make_dpf(alpha, message, dpf::extractable{}); + + auto [buf0, it0] = dpf::eval_full(k0); + auto [buf1, it1] = dpf::eval_full(k1); + auto a0 = std::begin(it0); + auto a1 = std::begin(it1); + + for (unsigned i = 0; i < 256; ++i, ++a0, ++a1) + { + const auto x = static_cast(i); + const auto p0 = (*dpf::eval_point(k0, x)).raw(); + const auto p1 = (*dpf::eval_point(k1, x)).raw(); + EXPECT_EQ((*a0).raw().raw(), p0.raw()) << "party0 at " << i; + EXPECT_EQ((*a1).raw().raw(), p1.raw()) << "party1 at " << i; + } + EXPECT_EQ(a0, std::end(it0)); + EXPECT_EQ(a1, std::end(it1)); + + EXPECT_EQ(dpf::reconstruct(*a0 = *std::begin(it0), *std::begin(it1)), + dpf::fp61{0}); // silence unused if reconstruct needs the type + (void)buf0; + (void)buf1; +} + +TEST(ExtractableFull, Fp61OpenedMailbox) +{ + constexpr std::uint8_t alpha = 9; + const dpf::fp61 message{42}; + auto [k0, k1] = dpf::make_dpf(alpha, message, dpf::extractable{}); + auto [buf0, it0] = dpf::eval_full(k0); + auto [buf1, it1] = dpf::eval_full(k1); + + std::vector y0, y1; + for (auto it = std::begin(it0); it != std::end(it0); ++it) + y0.push_back((*it).raw()); + for (auto it = std::begin(it1); it != std::end(it1); ++it) + y1.push_back((*it).raw()); + + EXPECT_EQ(y0[alpha] - y1[alpha], message); + EXPECT_EQ((y0[0] - y1[0]).raw(), 0u); + EXPECT_EQ((y0[8] - y1[8]).raw(), 0u); + EXPECT_EQ((y0[10] - y1[10]).raw(), 0u); + + std::vector challenge(256); + for (std::size_t i = 0; i < challenge.size(); ++i) + challenge[i] = dpf::fp61{static_cast(i + 1)}; + EXPECT_TRUE(dpf::sketch_verify(dpf::sketch_fold(y0, challenge), + dpf::sketch_fold(y1, challenge))); +} diff --git a/test/tests/field_output_test.cpp b/test/tests/field_output_test.cpp new file mode 100644 index 0000000..3a3cacf --- /dev/null +++ b/test/tests/field_output_test.cpp @@ -0,0 +1,215 @@ +#include +#include + +#include "dpf.hpp" + +#include +#include +#include +#include + +namespace +{ + +template +auto open_at(const Key0 &k0, const Key1 &k1, In x) +{ + const auto y0 = *dpf::eval_point(k0, x); + const auto y1 = *dpf::eval_point(k1, x); + return dpf::reconstruct(y0, y1); +} + +template +void expect_point_payload(In alpha, Out beta) +{ + auto [k0, k1] = dpf::make_dpf(alpha, beta); + const In last = static_cast(16); + for (In x = 0; x < last; ++x) + { + const Out got = open_at(k0, k1, x); + EXPECT_EQ(got, x == alpha ? beta : Out{}) << static_cast(x); + } + const Out on = open_at(k0, k1, alpha); + EXPECT_EQ(on, beta); +} + +} // namespace + +TEST(Field64, ArithmeticMatchesThePrime) +{ + constexpr auto p = dpf::field64::mod; + EXPECT_EQ((dpf::field64{p - 1} + dpf::field64{p - 1}).raw(), p - 2); + EXPECT_EQ((dpf::field64{p - 1} + dpf::field64{1}).raw(), 0u); + EXPECT_EQ((dpf::field64{1} - dpf::field64{2}).raw(), p - 1); + EXPECT_EQ((-dpf::field64{0}).raw(), 0u); + EXPECT_EQ((-dpf::field64{1}).raw(), p - 1); + EXPECT_EQ(dpf::field64{-1}.raw(), p - 1); + EXPECT_EQ((dpf::field64{p - 1} * dpf::field64{p - 1}).raw(), 1u); + EXPECT_EQ((dpf::field64{0x0123456789abcdefull} * dpf::field64{0xfedcba9876543210ull}).raw(), + 0xcfaeafd136c7bbaeull); + EXPECT_EQ((dpf::field64{std::uint64_t{1} << 32} * dpf::field64{std::uint64_t{1} << 32}).raw(), + 0xffffffffull); + const dpf::field64 a{1000}; + const dpf::field64 b{p - 5}; + const dpf::field64 c{17}; + EXPECT_EQ((a + b) * c, a * c + b * c); + EXPECT_TRUE(std::is_trivially_copyable_v); + EXPECT_TRUE(std::is_standard_layout_v); +} + +TEST(Field128, ArithmeticMatchesThePrime) +{ + const dpf::field128 almost{static_cast( + (static_cast(dpf::field128::mod_hi) << 64) + | dpf::field128::mod_lo) - 1}; + EXPECT_EQ(almost + dpf::field128{1}, dpf::field128{0}); + EXPECT_EQ(almost * almost, dpf::field128{1}); + EXPECT_EQ(-almost, dpf::field128{1}); + EXPECT_EQ(dpf::field128{-1}, almost); + EXPECT_EQ(dpf::field128{1} - dpf::field128{2}, almost); + EXPECT_TRUE(std::is_trivially_copyable_v); + EXPECT_TRUE(std::is_standard_layout_v); +} + +TEST(Field128, WideProduct) +{ + const unsigned __int128 a = + (static_cast(0x123456789abcdef0ull) << 64) + | 0x123456789abcdefull; + const unsigned __int128 b = + (static_cast(0xfedcba9876543210ull) << 64) + | 0xfedcba9876543210ull; + const auto got = dpf::field128{a} * dpf::field128{b}; + EXPECT_EQ(got.hi(), 0xb0a8b1cbf73350c9ull); + EXPECT_EQ(got.lo(), 0xf0123456789abe97ull); +} + +TEST(P256, GeneratorAndDoubling) +{ + const auto g = dpf::p256::generator(); + EXPECT_EQ(dpf::p256{1}, g); + EXPECT_EQ(dpf::p256{0}, dpf::p256{}); + EXPECT_TRUE(dpf::p256{}.is_identity()); + EXPECT_EQ(g + dpf::p256{}, g); + EXPECT_EQ(g - g, dpf::p256{}); + EXPECT_EQ(-dpf::p256{1}, dpf::p256{-1}); + const auto two = g + g; + EXPECT_EQ(two, dpf::p256{2}); + EXPECT_EQ(two - g, g); + const unsigned char expect[] = { + 0x03, + 0x7c, 0xf2, 0x7b, 0x18, 0x8d, 0x03, 0x4f, 0x7e, + 0x8a, 0x52, 0x38, 0x03, 0x04, 0xb5, 0x1a, 0xc3, + 0xc0, 0x89, 0x69, 0xe2, 0x77, 0xf2, 0x1b, 0x35, + 0xa6, 0x0b, 0x48, 0xfc, 0x47, 0x66, 0x99, 0x78, + }; + EXPECT_EQ(std::memcmp(two.bytes(), expect, 33), 0); + EXPECT_EQ(dpf::p256::from_compressed(expect), two); + const unsigned char bad[33] = {0x04}; + EXPECT_THROW(dpf::p256::from_compressed(bad), std::invalid_argument); + EXPECT_TRUE(std::is_trivially_copyable_v); + EXPECT_TRUE(std::is_standard_layout_v); +} + +template +void expect_cmp(std::uint8_t alpha, Out beta, Spec spec, bool leq) +{ + auto [k0, k1] = dpf::make_dpf(alpha, spec); + for (int x = 0; x < 24; ++x) + { + const auto q = static_cast(x); + const auto y0 = dpf::eval_point(dpf::cmp, k0, q); + const auto y1 = dpf::eval_point(dpf::cmp, k1, q); + const bool hot = leq ? x <= static_cast(alpha) + : x < static_cast(alpha); + EXPECT_EQ(dpf::reconstruct(y0, y1), hot ? beta : Out{}) << x; + } +} + +TEST(FieldOutput, ComparisonPayload) +{ + const auto f = dpf::field64{5}; + expect_cmp(std::uint8_t{10}, f, dpf::lt(f), false); + expect_cmp(std::uint8_t{10}, f, dpf::leq(f), true); + const auto w = dpf::field128{9}; + expect_cmp(std::uint8_t{10}, w, dpf::lt(w), false); + expect_cmp(std::uint8_t{4}, dpf::p256{1}, dpf::lt(dpf::p256{1}), false); +} + +TEST(FieldOutput, IdcfPrefixUsesTheSameGroup) +{ + const auto beta = dpf::field64{3}; + const std::uint8_t alpha = 0x2a; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::idcf(dpf::lt(beta))); + auto [a0, a1] = dpf::make_dpf(alpha, dpf::lt_at<4>(beta)); + for (int x = 0; x < 32; ++x) + { + const auto q = static_cast(x); + const auto full0 = dpf::eval_point(dpf::cmp, k0, q); + const auto full1 = dpf::eval_point(dpf::cmp, k1, q); + EXPECT_EQ(dpf::reconstruct(full0, full1), + x < static_cast(alpha) ? beta : dpf::field64{}); + const auto p0 = dpf::eval_point<4, dpf::field64>(dpf::cmp_prefix<4>, k0, q); + const auto p1 = dpf::eval_point<4, dpf::field64>(dpf::cmp_prefix<4>, k1, q); + const auto n0 = dpf::eval_point(dpf::cmp, a0, q); + const auto n1 = dpf::eval_point(dpf::cmp, a1, q); + EXPECT_EQ(dpf::reconstruct(p0, p1), dpf::reconstruct(n0, n1)) << x; + } +} + +TEST(FieldOutput, PointPayloadRoundTrip) +{ + expect_point_payload(std::uint8_t{0x2a}, dpf::field64{99}); + expect_point_payload(std::uint8_t{0x11}, dpf::field128{7}); + expect_point_payload(std::uint8_t{0x2a}, dpf::p256{1}); +} + +TEST(FieldOutput, Fp61PayloadNearModulus) +{ + const dpf::fp61 beta{dpf::fp61_mod - 1}; + expect_point_payload(std::uint8_t{0x2a}, beta); + expect_point_payload(std::uint8_t{0x05}, dpf::fp61{dpf::fp61_mod - 7}); +} + +TEST(FieldOutput, Fp61NegativeComparisonDelta) +{ + // δ = −1 ≡ p−1 must survive comparison (not collapse to 0 via a 61-bit mask). + expect_cmp(std::uint8_t{10}, dpf::fp61{dpf::fp61_mod - 1}, + dpf::lt(dpf::fp61{dpf::fp61_mod - 1}), false); + expect_cmp(std::uint8_t{10}, dpf::fp61{dpf::fp61_mod - 1}, + dpf::leq(dpf::fp61{dpf::fp61_mod - 1}), true); +} + +TEST(FieldOutput, P256MalformedCompressedRejected) +{ + unsigned char bad[33] = {0x02}; + bad[32] = 1; // x = 1 is not on P-256 + EXPECT_THROW(dpf::p256::from_compressed(bad), std::invalid_argument); + + dpf::p256 bogus{}; + unsigned char raw[sizeof(dpf::p256)]{}; + std::memcpy(raw, &bogus, sizeof(raw)); + std::memcpy(raw, bad, 33); + std::memcpy(&bogus, raw, sizeof(raw)); + EXPECT_THROW(bogus + dpf::p256{}, std::invalid_argument); + EXPECT_THROW(-bogus, std::invalid_argument); +} + +TEST(FieldOutput, P256ScalarWideComparisonPayload) +{ + const dpf::p256_scalar beta{17}; + expect_cmp(std::uint8_t{10}, beta, dpf::lt(beta), false); + expect_cmp(std::uint8_t{10}, beta, dpf::leq(beta), true); +} + +TEST(FieldOutput, Field128NoncanonicalNegationAndEquality) +{ + dpf::field128 a{}; + const std::uint64_t w[2] = { + dpf::field128::mod_lo, dpf::field128::mod_hi}; + std::memcpy(&a, w, sizeof(w)); + EXPECT_EQ(dpf::field128::canonicalize(a), dpf::field128{}); + EXPECT_EQ(-a, dpf::field128{}); + EXPECT_EQ(a, dpf::field128{}); +} + diff --git a/test/tests/fixedpoint_beaver_test.cpp b/test/tests/fixedpoint_beaver_test.cpp new file mode 100644 index 0000000..a615648 --- /dev/null +++ b/test/tests/fixedpoint_beaver_test.cpp @@ -0,0 +1,310 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "grotto.hpp" + +namespace +{ + +struct bus +{ + std::mutex mu; + std::condition_variable cv; + std::uint64_t word[2]{}; + std::uint64_t deliver[2]{}; + int epoch = 0; + int arrived = 0; + int sent0 = 0; + + std::uint64_t exchange(int me, std::uint64_t mine) + { + std::unique_lock lock(mu); + const int seen = epoch; + word[me] = mine; + if (me == 0) + ++sent0; + if (++arrived == 2) + { + deliver[0] = word[1]; + deliver[1] = word[0]; + arrived = 0; + ++epoch; + cv.notify_all(); + } + else + cv.wait(lock, [&] { return epoch != seen; }); + return deliver[me]; + } +}; + +template +std::pair split_word(T secret) +{ + using U = std::make_unsigned_t; + const U mask = static_cast(~U{0}); + const U bits = static_cast(secret); + const U share = static_cast(dpf::uniform_sample() & mask); + const U other = static_cast(bits - share); + return {static_cast(share), static_cast(other)}; +} + +template +simde_uint128 raw_bits(Fixed value) +{ + std::uint64_t limb[4] = {}; + grotto::detail::store_raw_limbs(value.integral_representation(), limb); + return simde_uint128{limb[0]} | (simde_uint128{limb[1]} << 64); +} + +template +void expect_product(std::pair lhs, std::pair rhs) +{ + using shape = grotto::fixed_mul_beaver_shape; + ASSERT_TRUE(shape::fits); + static const auto prep = grotto::make_fixed_mul_beaver_prep(); + const auto triple = grotto::sample_fixed_mul_beaver_triple(shape::plan::multiply_bits); + bus link; + using result = typename shape::plan::result_type; + result y0{}; + result y1{}; + std::exception_ptr e0; + std::exception_ptr e1; + std::thread t0([&] { + try + { + y0 = grotto::eval_fixed_mul_beaver( + prep, triple, 0, lhs.first, rhs.first, + [&](std::uint64_t mine) { return link.exchange(0, mine); }); + } + catch (...) + { + e0 = std::current_exception(); + } + }); + std::thread t1([&] { + try + { + y1 = grotto::eval_fixed_mul_beaver( + prep, triple, 1, lhs.second, rhs.second, + [&](std::uint64_t mine) { return link.exchange(1, mine); }); + } + catch (...) + { + e1 = std::current_exception(); + } + }); + t0.join(); + t1.join(); + if (e0) + std::rethrow_exception(e0); + if (e1) + std::rethrow_exception(e1); + EXPECT_EQ(link.sent0, static_cast(shape::messages)); + + const auto clear = grotto::fixed_mul( + grotto::make_fixed_from_integral_type( + static_cast(static_cast>(lhs.first) + + static_cast>(lhs.second))), + grotto::make_fixed_from_integral_type( + static_cast(static_cast>(rhs.first) + + static_cast>(rhs.second)))); + const unsigned storage = shape::storage_bits; + const simde_uint128 mask = storage >= 128u + ? ~simde_uint128{0} + : (simde_uint128{1} << storage) - 1; + const auto got = (raw_bits(y0) + raw_bits(y1)) & mask; + const auto want = raw_bits(clear) & mask; + EXPECT_EQ(static_cast(got), static_cast(want)); + EXPECT_EQ(static_cast(got >> 64), + static_cast(want >> 64)); +} + +template +T reconstruct(std::pair shares) +{ + using U = std::make_unsigned_t; + return static_cast(static_cast(shares.first) + static_cast(shares.second)); +} + +} // namespace + +TEST(FixedMulBeaver, EmptyWindowIsZeroAndSilent) +{ + using shape = grotto::fixed_mul_beaver_shape<0, 4, 0, std::int32_t, 0, std::int32_t>; + EXPECT_TRUE(shape::fits); + EXPECT_FALSE(shape::active); + EXPECT_EQ(shape::messages, 0u); + auto prep = grotto::make_fixed_mul_beaver_prep<0, 4, 0, std::int32_t, 0, std::int32_t>(); + grotto::fixed_mul_beaver_triple triple; + int calls = 0; + auto y = grotto::eval_fixed_mul_beaver<0, 4, 0, std::int32_t, 0, std::int32_t>( + prep, triple, 0, 7, 9, [&](std::uint64_t) { + ++calls; + return std::uint64_t{0}; + }); + EXPECT_EQ(calls, 0); + EXPECT_EQ(y.integral_representation(), 0); +} + +TEST(FixedMulBeaver, WideSignedWindowDoesNotFit) +{ + using shape = grotto::fixed_mul_beaver_shape<16, 64, 16, std::int32_t, 16, std::int32_t>; + EXPECT_FALSE(shape::fits); + EXPECT_TRUE(shape::result_lift); + EXPECT_GT(shape::plan::out_bits, 64u); +} + +TEST(FixedMulBeaver, TruncationIsOnlyTheBeaverOpening) +{ + using L = std::uint32_t; + using shape = grotto::fixed_mul_beaver_shape<16, 0, 0, L, 0, L>; + EXPECT_TRUE(shape::fits); + EXPECT_FALSE(shape::lhs_lift); + EXPECT_FALSE(shape::shift_right); + EXPECT_EQ(shape::messages, 2u); + auto prep = grotto::make_fixed_mul_beaver_prep<16, 0, 0, L, 0, L>(); + for (int i = 0; i < 8; ++i) + { + const auto lhs = split_word(i == 0 ? L{7} : dpf::uniform_sample()); + const auto rhs = split_word(i == 0 ? L{9} : dpf::uniform_sample()); + const auto triple = grotto::sample_fixed_mul_beaver_triple(16u); + bus link; + auto y0 = grotto::fixedpoint<0, std::uint16_t>{}; + auto y1 = y0; + std::thread t0([&] { + y0 = grotto::eval_fixed_mul_beaver<16, 0, 0, L, 0, L>( + prep, triple, 0, lhs.first, rhs.first, + [&](std::uint64_t mine) { return link.exchange(0, mine); }); + }); + std::thread t1([&] { + y1 = grotto::eval_fixed_mul_beaver<16, 0, 0, L, 0, L>( + prep, triple, 1, lhs.second, rhs.second, + [&](std::uint64_t mine) { return link.exchange(1, mine); }); + }); + t0.join(); + t1.join(); + EXPECT_EQ(link.sent0, 2); + const auto clear = grotto::fixed_mul<16, 0>( + grotto::make_fixed_from_integral_type<0, L>(reconstruct(lhs)), + grotto::make_fixed_from_integral_type<0, L>(reconstruct(rhs))); + const auto got = static_cast( + static_cast(y0.integral_representation()) + + static_cast(y1.integral_representation())); + EXPECT_EQ(got, clear.integral_representation()); + } +} + +TEST(FixedMulBeaver, NegativeProductFloorsIntoTheWindow) +{ + using Q = std::int32_t; + const auto lhs = split_word(Q{-3}); + const auto rhs = split_word(Q{1}); + expect_product<8, 4, 4, Q, 4, Q>(lhs, rhs); + const auto neg = split_word(Q{-2}); + expect_product<8, 4, 4, Q, 4, Q>(lhs, neg); +} + +TEST(FixedMulBeaver, SignedLiftAndRightShift) +{ + using Q = std::int32_t; + using shape = grotto::fixed_mul_beaver_shape<16, 16, 16, Q, 16, Q>; + EXPECT_TRUE(shape::lhs_lift); + EXPECT_TRUE(shape::shift_right); + EXPECT_FALSE(shape::product_lift); + EXPECT_EQ(shape::plan::multiply_bits, 48u); + EXPECT_EQ(shape::messages, 5u); + auto prep = grotto::make_fixed_mul_beaver_prep<16, 16, 16, Q, 16, Q>(); + const Q samples[][2] = { + {0, 0}, + {1 << 16, 2 << 16}, + {-(3 << 16), 1 << 16}, + {-(3 << 16), -(2 << 16)}, + {std::numeric_limits::max(), -1}, + {std::numeric_limits::min(), 1}, + }; + for (const auto & sample : samples) + { + const auto triple = grotto::sample_fixed_mul_beaver_triple(48u); + const auto lhs = split_word(sample[0]); + const auto rhs = split_word(sample[1]); + bus link; + using result = typename shape::plan::result_type; + result y0{}; + result y1{}; + std::thread t0([&] { + y0 = grotto::eval_fixed_mul_beaver<16, 16, 16, Q, 16, Q>( + prep, triple, 0, lhs.first, rhs.first, + [&](std::uint64_t mine) { return link.exchange(0, mine); }); + }); + std::thread t1([&] { + y1 = grotto::eval_fixed_mul_beaver<16, 16, 16, Q, 16, Q>( + prep, triple, 1, lhs.second, rhs.second, + [&](std::uint64_t mine) { return link.exchange(1, mine); }); + }); + t0.join(); + t1.join(); + EXPECT_EQ(link.sent0, 5); + const auto clear = grotto::fixed_mul<16, 16>( + grotto::make_fixed_from_integral_type<16, Q>(reconstruct(lhs)), + grotto::make_fixed_from_integral_type<16, Q>(reconstruct(rhs))); + const auto got = static_cast(y0.integral_representation()) + + static_cast(y1.integral_representation()); + EXPECT_EQ(got, static_cast(clear.integral_representation())) + << "lhs=" << sample[0] << " rhs=" << sample[1]; + } +} + +TEST(FixedMulBeaver, LeftShiftAndUnsignedLift) +{ + using L = std::uint16_t; + using shape = grotto::fixed_mul_beaver_shape<4, 8, 0, L, 0, L>; + EXPECT_TRUE(shape::shift_left); + EXPECT_TRUE(shape::fits); + const auto lhs = split_word(L{3}); + const auto rhs = split_word(L{5}); + expect_product<4, 8, 0, L, 0, L>(lhs, rhs); +} + +TEST(FixedMulBeaver, NarrowProductIsSignExtendedBeforeTheWindow) +{ + using Q = std::int8_t; + using shape = grotto::fixed_mul_beaver_shape<16, 8, 4, Q, 4, Q>; + EXPECT_TRUE(shape::fits); + EXPECT_TRUE(shape::lhs_lift); + EXPECT_TRUE(shape::product_lift); + EXPECT_TRUE(shape::result_lift); + EXPECT_FALSE(shape::shift_right); + EXPECT_EQ(shape::messages, 6u); + const Q samples[] = {0, 1, -1, -3, 7, -8, 12, std::numeric_limits::max(), + std::numeric_limits::min()}; + for (Q a : samples) + for (Q b : samples) + expect_product<16, 8, 4, Q, 4, Q>(split_word(a), split_word(b)); +} + +TEST(FixedMulBeaver, Int64WindowUsesA96BitProduct) +{ + using Q = std::int64_t; + using shape = grotto::fixed_mul_beaver_shape<32, 32, 32, Q, 32, Q>; + ASSERT_TRUE(shape::fits); + EXPECT_EQ(shape::plan::multiply_bits, 96u); + EXPECT_EQ(shape::plan::modulus_bits, 96u); + EXPECT_TRUE(shape::lhs_lift); + EXPECT_EQ(shape::messages, 8u); + const Q samples[][2] = { + {0, 0}, + {Q{3} << 32, Q{5} << 32}, + {-(Q{3} << 32), Q{1} << 32}, + {-(Q{4} << 32), -(Q{2} << 32)}, + }; + for (const auto & sample : samples) + expect_product<32, 32, 32, Q, 32, Q>(split_word(sample[0]), split_word(sample[1])); +} diff --git a/test/tests/flute_test.cpp b/test/tests/flute_test.cpp new file mode 100644 index 0000000..dfa524a --- /dev/null +++ b/test/tests/flute_test.cpp @@ -0,0 +1,180 @@ +#include + +#include +#include + +#include "dpf/flute.hpp" + +TEST(Flute, EveryTwoBitFunction) +{ + const unsigned delta = 2; + std::uint8_t rows[4]; + for (unsigned fn = 0; fn < 16; ++fn) + { + for (unsigned j = 0; j < 4; ++j) + rows[j] = static_cast((fn >> j) & 1u); + for (unsigned x = 0; x < 4; ++x) + { + std::uint8_t bits[2] = { + static_cast(x & 1u), + static_cast((x >> 1) & 1u), + }; + auto want = dpf::flute::eval_plain(delta, 1, rows, bits); + auto pair = dpf::flute::eval_pair(delta, 1, rows, bits); + auto trio = dpf::flute::eval_trio(delta, 1, rows, bits); + EXPECT_EQ(pair.opened, want); + EXPECT_EQ(trio.opened, want); + EXPECT_EQ(pair.online_bits, 2u); + EXPECT_EQ(trio.online_bits, 3u); + EXPECT_EQ(pair.mask.size(), 2u); + EXPECT_EQ(trio.mask.size(), 3u); + } + } +} + +TEST(Flute, TwoOutputBits) +{ + // LSB of the 3-bit index, and its majority with the other two bits. + const unsigned delta = 3; + const unsigned rows = 8; + std::vector columns(2 * rows); + for (unsigned j = 0; j < rows; ++j) + { + columns[j] = static_cast(j & 1u); + const unsigned ones = (j & 1u) + ((j >> 1) & 1u) + ((j >> 2) & 1u); + columns[rows + j] = static_cast(ones >= 2); + } + for (unsigned x = 0; x < rows; ++x) + { + std::uint8_t bits[3] = { + static_cast(x & 1u), + static_cast((x >> 1) & 1u), + static_cast((x >> 2) & 1u), + }; + auto want = dpf::flute::eval_plain(delta, 2, columns.data(), bits); + auto got = dpf::flute::eval_pair(delta, 2, columns.data(), bits); + EXPECT_EQ(got.opened, want); + EXPECT_EQ(got.online_bits, 4u); + std::uint8_t lam0 = 0; + std::uint8_t lam1 = 0; + lam0 = static_cast(got.mask[0][0] ^ got.mask[0][1]); + lam1 = static_cast(got.mask[1][0] ^ got.mask[1][1]); + (void)lam0; + (void)lam1; + for (unsigned w = 0; w < 2; ++w) + { + const std::uint8_t lam = static_cast( + got.mask[0][w] ^ got.mask[1][w]); + EXPECT_EQ(static_cast(got.masked[w] ^ lam), want[w]); + } + } +} + +namespace +{ + +void expect_lut(unsigned delta, unsigned n_out, const std::vector & columns, + const std::uint8_t * bits) +{ + auto want = dpf::flute::eval_plain(delta, n_out, columns.data(), bits); + auto pair = dpf::flute::eval_pair(delta, n_out, columns.data(), bits); + auto trio = dpf::flute::eval_trio(delta, n_out, columns.data(), bits); + EXPECT_EQ(pair.opened, want); + EXPECT_EQ(trio.opened, want); + EXPECT_EQ(pair.online_bits, static_cast(2 * n_out)); + EXPECT_EQ(trio.online_bits, static_cast(3 * n_out)); + for (unsigned w = 0; w < n_out; ++w) + { + const std::uint8_t two = static_cast( + pair.masked[w] ^ pair.mask[0][w] ^ pair.mask[1][w]); + const std::uint8_t three = static_cast( + trio.masked[w] ^ trio.mask[0][w] ^ trio.mask[1][w] ^ trio.mask[2][w]); + EXPECT_EQ(two, want[w]); + EXPECT_EQ(three, want[w]); + } +} + +std::uint32_t xorshift(std::uint32_t & s) +{ + s ^= s << 13; + s ^= s >> 17; + s ^= s << 5; + return s; +} + +} // namespace + +TEST(Flute, EveryFunctionThroughThreeBits) +{ + for (unsigned delta = 1; delta <= 3; ++delta) + { + const unsigned rows = 1u << delta; + const unsigned nfn = 1u << rows; + std::vector column(rows); + std::vector bits(delta); + for (unsigned fn = 0; fn < nfn; ++fn) + { + for (unsigned j = 0; j < rows; ++j) + column[j] = static_cast((fn >> j) & 1u); + for (unsigned x = 0; x < rows; ++x) + { + for (unsigned i = 0; i < delta; ++i) + bits[i] = static_cast((x >> i) & 1u); + expect_lut(delta, 1, column, bits.data()); + } + } + } +} + +TEST(Flute, FourBitSampleAndEightBitSpecials) +{ + const unsigned delta = 4; + const unsigned rows = 16; + std::uint32_t rng = 0xC0FFEEu; + std::vector columns(2 * rows); + std::vector bits(delta); + for (unsigned sample = 0; sample < 24; ++sample) + { + for (auto & cell : columns) + cell = static_cast(xorshift(rng) & 1u); + for (unsigned x = 0; x < rows; ++x) + { + for (unsigned i = 0; i < delta; ++i) + bits[i] = static_cast((x >> i) & 1u); + expect_lut(delta, 2, columns, bits.data()); + } + } + + const unsigned wide = 8; + const unsigned wrows = 256; + std::vector table(4 * wrows, 0); + for (unsigned j = 0; j < wrows; ++j) + { + unsigned ones = 0; + for (unsigned i = 0; i < wide; ++i) + ones += (j >> i) & 1u; + table[j] = static_cast(ones & 1u); + table[wrows + j] = static_cast(ones == wide); + table[2 * wrows + j] = static_cast((j >> 7) & 1u); + table[3 * wrows + j] = static_cast(j == 0 || j == 255); + } + const unsigned points[] = {0u, 1u, 2u, 17u, 128u, 170u, 254u, 255u}; + std::vector wbits(wide); + for (unsigned x : points) + { + for (unsigned i = 0; i < wide; ++i) + wbits[i] = static_cast((x >> i) & 1u); + expect_lut(wide, 4, table, wbits.data()); + } +} + +TEST(Flute, RejectsABadIndex) +{ + std::uint8_t column[2] = {0, 1}; + std::uint8_t bit = 1; + EXPECT_THROW(dpf::flute::eval_plain(0, 1, column, &bit), std::invalid_argument); + EXPECT_THROW(dpf::flute::eval_pair(9, 1, column, &bit), std::invalid_argument); + bit = 2; + EXPECT_THROW(dpf::flute::eval_trio(1, 1, column, &bit), std::invalid_argument); + EXPECT_THROW(dpf::flute::eval_pair(1, 0, column, &bit), std::invalid_argument); +} diff --git a/test/tests/fp61_test.cpp b/test/tests/fp61_test.cpp index fca0880..3c7de70 100644 --- a/test/tests/fp61_test.cpp +++ b/test/tests/fp61_test.cpp @@ -1,10 +1,14 @@ #include #include +#include #include #include +#include "simde/simde/x86/avx2.h" + #include "dpf/fp61.hpp" +#include "dpf/leaf_arithmetic.hpp" namespace { @@ -55,3 +59,26 @@ TEST(Fp61, StreamPrintsTheReducedValue) os << fp61{fp61_mod + 4}; EXPECT_EQ(os.str(), "4"); } + +TEST(Fp61, FromSeedMersenneFoldsWideWords) +{ + std::uint64_t words[2] = {fp61_mod - 1, 1}; + const auto a = fp61::from_seed(words, sizeof(words)); + // (p-1) + 8·1 (since 2^64 ≡ 8), then reduce — not a 61-bit mask of the lo word. + EXPECT_NE(a.raw(), 0u); + EXPECT_EQ(a.raw(), fp61::reduce((fp61_mod - 1) + 8)); +} + +TEST(Fp61, LeafAddReducesNearModulus) +{ + alignas(16) std::uint64_t left[2] = {fp61_mod - 1, fp61_mod - 2}; + alignas(16) std::uint64_t right[2] = {3, 5}; + alignas(16) std::uint64_t out[2]{}; + simde__m128i a{}, b{}; + std::memcpy(&a, left, sizeof(left)); + std::memcpy(&b, right, sizeof(right)); + const auto sum = dpf::leaf_arithmetic::add_t{}(a, b); + std::memcpy(out, &sum, sizeof(out)); + EXPECT_EQ(out[0], 2u); + EXPECT_EQ(out[1], 3u); +} diff --git a/test/tests/geneval_test.cpp b/test/tests/geneval_test.cpp index e345fa1..2455fd8 100644 --- a/test/tests/geneval_test.cpp +++ b/test/tests/geneval_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "dpf.hpp" @@ -349,6 +350,10 @@ TEST(Geneval, FullDomainUint8) } EXPECT_EQ(recon(g.party0[alpha], g.party1[alpha]), y); EXPECT_EQ(recon(g.party0[0], g.party1[0]), out_t{0}); + EXPECT_TRUE(dpf::verify(g.proof0, g.proof1)); + EXPECT_NE(recon(g.party1[alpha], g.party0[alpha]), y); + g.proof0[0] = simde_mm_xor_si128(g.proof0[0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(g.proof0, g.proof1)); } TEST(Geneval, EmptySequence) @@ -796,10 +801,10 @@ TEST(Geneval, FullMatchesWholeIntervalAndRejectsHugeDomain) EXPECT_EQ(recon(full.party0[255], full.party1[255]), y); EXPECT_EQ(recon(full.party0[0], full.party1[0]), out_t{0}); - EXPECT_THROW((dpf::geneval_full(uint32_t{1}, uint32_t{2}, rng(), - uint32_t{1})), std::length_error); - EXPECT_THROW((dpf::geneval_interval(in_t{5}, in_t{1}, in_t{4}, in_t{3}, - rng(), y)), std::invalid_argument); + EXPECT_THROW(dpf::geneval_full(uint32_t{1}, uint32_t{2}, rng(), + uint32_t{1}), std::length_error); + EXPECT_THROW(dpf::geneval_interval(in_t{5}, in_t{1}, in_t{4}, in_t{3}, + rng(), y), std::invalid_argument); } TEST(Geneval, SequencePermutationKeepsWordsAndDuplicates) @@ -981,8 +986,8 @@ TEST(Geneval, ArithShareOverflowAndWrappingInterval) in_t from = 250; in_t to = 10; - EXPECT_THROW((dpf::geneval_interval(dpf::arith_input, x0, x1, from, to, - rng(), y)), std::invalid_argument); + EXPECT_THROW(dpf::geneval_interval(dpf::arith_input, x0, x1, from, to, + rng(), y), std::invalid_argument); from = 250; to = 255; @@ -1043,8 +1048,8 @@ TEST(Geneval, SignedRegressionsFromTheCornerPass) out_t y = -7; // An inverted signed range must not wrap the long way around. - EXPECT_THROW((dpf::geneval_interval(in_t{2}, in_t{1}, in_t{4}, in_t{-3}, - rng(), y)), std::invalid_argument); + EXPECT_THROW(dpf::geneval_interval(in_t{2}, in_t{1}, in_t{4}, in_t{-3}, + rng(), y), std::invalid_argument); // [INT_MIN, INT_MAX] is numeric order; full is bit-pattern order. // The words are the same trie. Each input's share matches either way. @@ -1402,3 +1407,37 @@ TEST(Geneval, ArithDoernerShelatAndCmpMatchDealer) EXPECT_EQ(opened, ends[i] > secret ? beta : 0u) << int(ends[i]); } } + +TEST(Geneval, ArithCarryLeavesXorShares) +{ + // 250 + 13 = 7 (mod 256). The carry must not collapse the sharing to (7, 0). + auto split_u8 = [](std::uint64_t seed) { + Pad pad; + pad.n = seed; + dpf::detail::local_cw_protocol proto{pad}; + std::uint8_t x0 = 250; + std::uint8_t x1 = 13; + proto.encode_walk_shares(x0, x1, true); + // Seven carries. Each is one bit-Beaver from `sample_beaver2` on + // `xor_wrapper`: `sample_fresh<2>` draws 7 ring elements + // and each element is 8 pad bits. + EXPECT_EQ(pad.n, seed + 7u * 7u * 8u); + EXPECT_EQ(static_cast(x0 ^ x1), 7); + EXPECT_NE(x1, 0); + EXPECT_NE(x0, 7); + }; + split_u8(1); + split_u8(50); + + Pad pad; + dpf::detail::local_cw_protocol proto{pad}; + const std::int8_t secret = -20; + std::int8_t a0 = 100; + std::int8_t a1 = static_cast(secret - a0); + std::int8_t encoded = secret; + dpf::utils::flip_msb_if_signed_integral(encoded); + proto.encode_walk_shares(a0, a1, true); + EXPECT_EQ(static_cast(a0) ^ static_cast(a1), + static_cast(encoded)); + EXPECT_NE(a1, 0); +} diff --git a/test/tests/gf2_adversarial_test.cpp b/test/tests/gf2_adversarial_test.cpp new file mode 100644 index 0000000..31e8106 --- /dev/null +++ b/test/tests/gf2_adversarial_test.cpp @@ -0,0 +1,536 @@ +/// @file gf2_adversarial_test.cpp +/// @brief Adversarial checks for GF(2^k) output types. +/// @details Full domains, lane boundaries, poisoned high bits, independent +/// polynomial inverses, leaf scaling, shares, multi-output keys, +/// comparisons, and proof tampering. + +#include + +#include "dpf.hpp" + +#include +#include +#include +#include + +namespace +{ + +using u128 = unsigned __int128; + +u128 poly_mul(u128 a, u128 b) +{ + unsigned __int128 p = 0; + for (int i = 0; i < 128 && b != 0; ++i) + { + if ((b & 1) != 0) + p ^= a; + a <<= 1; + b >>= 1; + } + return p; +} + +u128 poly_quot_rem(u128 & rem, u128 den, int) +{ + unsigned __int128 q = 0; + int den_bit = -1; + for (int i = 127; i >= 0; --i) + { + if (((den >> i) & 1) != 0) + { + den_bit = i; + break; + } + } + if (den_bit < 0) + return 0; + for (;;) + { + int bit = -1; + for (int i = 127; i >= 0; --i) + { + if (((rem >> i) & 1) != 0) + { + bit = i; + break; + } + } + if (bit < den_bit) + break; + const int sh = bit - den_bit; + q ^= u128{1} << sh; + rem ^= den << sh; + } + return q; +} + +u128 poly_inv(u128 a, u128 mod) +{ + u128 r0 = mod; + u128 r1 = a; + u128 s0 = 0; + u128 s1 = 1; + while (r1 != 0) + { + const u128 q = poly_quot_rem(r0, r1, 0); + const u128 nr = r0; + u128 ns = s0 ^ poly_mul(q, s1); + int mod_bit = -1; + for (int i = 127; i >= 0; --i) + { + if (((mod >> i) & 1) != 0) + { + mod_bit = i; + break; + } + } + while (mod_bit >= 0) + { + int bit = -1; + for (int i = 127; i >= 0; --i) + { + if (((ns >> i) & 1) != 0) + { + bit = i; + break; + } + } + if (bit < mod_bit) + break; + ns ^= mod << (bit - mod_bit); + } + r0 = r1; + s0 = s1; + r1 = nr; + s1 = ns; + } + return r0 == 1 ? s0 : 0; +} + +template +u128 modulus_of() +{ + constexpr unsigned bits = F::bits; + if constexpr (bits == 1) + return 0x3; + else if constexpr (bits == 2) + return 0x7; + else if constexpr (bits == 4) + return 0x13; + else if constexpr (bits == 8) + return 0x11b; + else if constexpr (bits == 16) + return 0x1002d; + else if constexpr (bits == 32) + return 0x190200001ull; + else + return (u128{1} << 64) | (u128{1} << 63) + | (u128{1} << 62) | (u128{1} << 53) | 1; +} + +template +F mask_elem(u128 v) +{ + using word = typename F::integral_type; + if constexpr (F::bits >= sizeof(word) * 8u) + return F{static_cast(v)}; + else + { + const word m = static_cast((word{1} << F::bits) - word{1}); + return F{static_cast(static_cast(v) & m)}; + } +} + +std::uint64_t rng_state = 0x123456789abcdefull; + +std::uint64_t next_rng() +{ + rng_state = rng_state * 6364136223846793005ull + 1ull; + return rng_state; +} + +template +F random_elem() +{ + return mask_elem(next_rng()); +} + +template +F open_at(const Key0 & k0, const Key1 & k1, In x) +{ + const auto y0 = *dpf::eval_point(k0, x); + const auto y1 = *dpf::eval_point(k1, x); + const F fwd = dpf::reconstruct(y0, y1); + const F rev = dpf::reconstruct(y1, y0); + EXPECT_EQ(fwd, rev); + return fwd; +} + +template +void expect_full_domain(F beta) +{ + using In = std::uint8_t; + for (int alpha_i : {0, 1, 31, 32, 127, 128, 254, 255}) + { + const In alpha = static_cast(alpha_i); + auto [k0, k1] = dpf::make_dpf(alpha, beta); + for (int x = 0; x < 256; ++x) + { + const In q = static_cast(x); + const F got = open_at(k0, k1, q); + EXPECT_EQ(got, q == alpha ? beta : F{}) << +q << " alpha " << +alpha; + } + } +} + +template +F open_written(It0 it0, It1 it1) +{ + using V0 = typename std::iterator_traits::value_type; + using V1 = typename std::iterator_traits::value_type; + V0 a = *it0; + V1 b = *it1; + if constexpr (dpf::is_secret_share_v) + return dpf::reconstruct(a, b); + else + { + const auto lane = [](auto v) { + return F{static_cast(static_cast(v))}; + }; + return lane(a) + lane(b); + } +} + +template +void expect_interval_and_sequence(F beta) +{ + using In = std::uint8_t; + const In alpha = 0x2a; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + auto [b0, i0] = dpf::eval_interval(k0, In{0}, In{255}); + auto [b1, i1] = dpf::eval_interval(k1, In{0}, In{255}); + auto p0 = std::begin(i0); + auto p1 = std::begin(i1); + for (int x = 0; x < 256; ++x, ++p0, ++p1) + { + EXPECT_EQ(open_written(p0, p1), + static_cast(x) == alpha ? beta : F{}) << x; + } + + const In pts[] = {0, 1, 41, 42, 43, 127, 128, 255}; + auto [s0, is0] = dpf::eval_sequence(k0, std::begin(pts), std::end(pts)); + auto [s1, is1] = dpf::eval_sequence(k1, std::begin(pts), std::end(pts)); + auto q0 = std::begin(is0); + auto q1 = std::begin(is1); + for (In q : pts) + { + EXPECT_EQ(open_written(q0, q1), + q == alpha ? beta : F{}) << +q; + ++q0; + ++q1; + } +} + +template +void expect_comparison(F beta) +{ + using In = std::uint8_t; + const In alpha = 10; + auto [lt0, lt1] = dpf::make_dpf(alpha, dpf::lt(beta)); + auto [le0, le1] = dpf::make_dpf(alpha, dpf::leq(beta)); + for (int x = 0; x < 256; ++x) + { + const In q = static_cast(x); + const auto a0 = dpf::eval_point(dpf::cmp, lt0, q); + const auto a1 = dpf::eval_point(dpf::cmp, lt1, q); + const auto b0 = dpf::eval_point(dpf::cmp, le0, q); + const auto b1 = dpf::eval_point(dpf::cmp, le1, q); + EXPECT_EQ(dpf::reconstruct(a0, a1), x < 10 ? beta : F{}) << x; + EXPECT_EQ(dpf::reconstruct(b0, b1), x <= 10 ? beta : F{}) << x; + } +} + +template +void expect_scale(Node node, F k) +{ + const auto scaled = dpf::multiply_leaf(node, k); + unsigned char src[sizeof(Node)]; + unsigned char got[sizeof(Node)]; + std::memcpy(src, &node, sizeof(src)); + std::memcpy(got, &scaled, sizeof(got)); + if constexpr (F::bits >= 8) + { + constexpr std::size_t lanes = sizeof(Node) / sizeof(typename F::integral_type); + for (std::size_t i = 0; i < lanes; ++i) + { + typename F::integral_type lane{}; + std::memcpy(&lane, src + i * sizeof(lane), sizeof(lane)); + typename F::integral_type out{}; + std::memcpy(&out, got + i * sizeof(out), sizeof(out)); + EXPECT_EQ(F{out}, F{lane} * k); + } + } + else + { + constexpr unsigned w = F::bits; + constexpr unsigned mask = (1u << w) - 1u; + constexpr unsigned per = 8u / w; + for (std::size_t i = 0; i < sizeof(Node); ++i) + { + unsigned expect = 0; + for (unsigned lane = 0; lane < per; ++lane) + { + const auto a = F{(src[i] >> (lane * w)) & mask}; + expect |= static_cast((a * k).raw()) << (lane * w); + } + EXPECT_EQ(got[i], static_cast(expect)); + } + } +} + +template +void expect_algebra() +{ + const auto mod = modulus_of(); + const F one{1}; + EXPECT_EQ(one + one, F{}); + EXPECT_EQ(-one, one); + EXPECT_EQ(F{-7}, F{7}); + EXPECT_EQ(one * one, one); + EXPECT_EQ(F{} * random_elem(), F{}); + + const unsigned lim = F::bits <= 8 ? (1u << F::bits) : 0u; + if (lim != 0) + { + for (unsigned a = 1; a < lim; ++a) + { + const auto inv = poly_inv(a, mod); + ASSERT_NE(inv, 0u) << a; + EXPECT_EQ(F{static_cast(a)} + * mask_elem(inv), one) << a; + } + for (unsigned a = 0; a < lim; ++a) + { + for (unsigned b = 0; b < lim; ++b) + { + const F prod = F{static_cast(a)} + * F{static_cast(b)}; + if (a != 0 && b != 0) + EXPECT_NE(prod, F{}) << a << " " << b; + } + } + } + else + { + for (int n = 0; n < 48; ++n) + { + const F a = random_elem(); + if (a == F{}) + continue; + const auto inv = poly_inv(a.raw(), mod); + ASSERT_NE(inv, 0u); + EXPECT_EQ(a * mask_elem(inv), one); + } + } + + for (int n = 0; n < 32; ++n) + { + const F a = random_elem(); + const F b = random_elem(); + const F c = random_elem(); + EXPECT_EQ((a + b) * c, a * c + b * c); + EXPECT_EQ((a * b) * c, a * (b * c)); + EXPECT_EQ(a + a, F{}); + } + + unsigned char poison[sizeof(F)]; + std::memset(poison, 0xff, sizeof(poison)); + F poisoned{}; + std::memcpy(&poisoned, poison, sizeof(poisoned)); + EXPECT_EQ(poisoned.raw(), mask_elem(~u128{0}).raw()); + EXPECT_EQ(poisoned + F{}, mask_elem(~u128{0})); + + unsigned char lo[16]{}; + unsigned char hi[16]{}; + lo[0] = 0x15; + hi[0] = 0x15; + if (sizeof(typename F::integral_type) < 16) + hi[sizeof(typename F::integral_type)] = 0x5a; + EXPECT_EQ(F::from_seed(lo, sizeof(lo)), F::from_seed(hi, sizeof(hi))); +} + +template +void expect_leaf_ops() +{ + alignas(32) unsigned char bytes[32]; + for (int i = 0; i < 32; ++i) + bytes[i] = static_cast(0xA5 ^ i); + simde__m128i n128; + simde__m256i n256; + std::memcpy(&n128, bytes, sizeof(n128)); + std::memcpy(&n256, bytes, sizeof(n256)); + const F k = F::bits == 1 ? F{1} : F{2}; + expect_scale(n128, k); + expect_scale(n128, F{}); + expect_scale(n128, F{1}); + expect_scale(n256, k); + + const auto sum = dpf::add_leaf(n128, n128); + unsigned char z[sizeof(n128)]; + std::memcpy(z, &sum, sizeof(z)); + for (unsigned char b : z) + EXPECT_EQ(b, 0); + unsigned char d[sizeof(n128)]; + const auto sub = dpf::subtract_leaf(n128, n128); + std::memcpy(d, &sub, sizeof(d)); + for (unsigned char b : d) + EXPECT_EQ(b, 0); +} + +template +void expect_shares_and_prefix(F beta) +{ + const auto add = dpf::make_additive_shares(beta); + EXPECT_EQ(dpf::reconstruct(add.first, add.second), beta); + EXPECT_EQ(dpf::reconstruct(add.second, add.first), beta); + const auto sub = dpf::make_subtractive_shares(beta); + EXPECT_EQ(dpf::reconstruct(sub.first, sub.second), beta); + EXPECT_EQ(dpf::reconstruct(sub.second, sub.first), beta); + + auto drawn = dpf::additively_share(beta); + EXPECT_EQ(dpf::reconstruct(drawn.first, drawn.second), beta); +} + +template +void expect_verifiable(F beta) +{ + using In = std::uint8_t; + const In alpha = 0x11; + auto [k0, k1] = dpf::make_dpf(alpha, beta, dpf::verifiable{}); + for (int x = 0; x < 256; ++x) + { + const In q = static_cast(x); + dpf::proof_token a{}; + dpf::proof_token b{}; + const auto y0 = *dpf::eval_point(k0, q, dpf::prove(a)); + const auto y1 = *dpf::eval_point(k1, q, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)) << +q; + EXPECT_EQ(dpf::reconstruct(y0, y1), q == alpha ? beta : F{}); + } + auto & leaves = const_cast &>(k0.leaves()); + auto * raw = reinterpret_cast(&std::get<0>(leaves).get()); + raw[0] = static_cast(raw[0] ^ 0x1u); + dpf::proof_token tampered{}; + dpf::proof_token honest{}; + (void)*dpf::eval_point(k0, alpha, dpf::prove(tampered)); + (void)*dpf::eval_point(k1, alpha, dpf::prove(honest)); + EXPECT_FALSE(dpf::verify(tampered, honest)); +} + +template +void run_all(F beta) +{ + expect_algebra(); + expect_full_domain(F{}); + expect_full_domain(F{1}); + expect_full_domain(beta); + expect_interval_and_sequence(beta); + expect_comparison(beta); + expect_leaf_ops(); + expect_shares_and_prefix(beta); +} + +} // namespace + +TEST(Gf2Adversarial, AlgebraDomainAndLeaves) +{ + run_all(dpf::gf2{1}); + run_all(dpf::gf22{3}); + run_all(dpf::gf24{0xa}); + run_all(dpf::gf28{0x1b}); + run_all(dpf::gf216{0x2d}); + run_all(dpf::gf232{0x90200001u}); + run_all(dpf::gf264{0x11}); +} + +TEST(Gf2Adversarial, ProofsRejectAFlippedLeaf) +{ + expect_verifiable(dpf::gf2{1}); + expect_verifiable(dpf::gf24{0xf}); + expect_verifiable(dpf::gf28{0xff}); + expect_verifiable(dpf::gf264{~std::uint64_t{0}}); +} + +TEST(Gf2Adversarial, PrefixLongerThanTheLane) +{ + using In = std::uint8_t; + const In alpha = 0x2a; + auto [k0, k1] = dpf::make_dpf(alpha, + dpf::at<8>(dpf::gf28{0x1b}), dpf::gf28{0x5a}); + const auto p0 = *dpf::eval_point<0>(k0, alpha); + const auto p1 = *dpf::eval_point<0>(k1, alpha); + const auto l0 = *dpf::eval_point<1>(k0, alpha); + const auto l1 = *dpf::eval_point<1>(k1, alpha); + EXPECT_EQ(dpf::reconstruct(p0, p1), dpf::gf28{0x1b}); + EXPECT_EQ(dpf::reconstruct(l0, l1), dpf::gf28{0x5a}); + const auto off0 = *dpf::eval_point<1>(k0, In{0}); + const auto off1 = *dpf::eval_point<1>(k1, In{0}); + EXPECT_EQ(dpf::reconstruct(off0, off1), dpf::gf28{}); +} + +TEST(Gf2Adversarial, MultiOutputDoesNotBleed) +{ + using In = std::uint8_t; + const In alpha = 0x2a; + const dpf::gf28 lane{0x1b}; + const std::uint8_t wide = 9; + auto [k0, k1] = dpf::make_dpf(alpha, lane, wide); + for (int x = 0; x < 64; ++x) + { + const In q = static_cast(x); + const auto a0 = *dpf::eval_point<0>(k0, q); + const auto a1 = *dpf::eval_point<0>(k1, q); + const auto b0 = *dpf::eval_point<1>(k0, q); + const auto b1 = *dpf::eval_point<1>(k1, q); + EXPECT_EQ(dpf::reconstruct(a0, a1), q == alpha ? lane : dpf::gf28{}); + EXPECT_EQ(dpf::reconstruct(b0, b1), q == alpha ? wide : std::uint8_t{0}); + } +} + +TEST(Gf2Adversarial, NakedLeafMasksHighBits) +{ + const auto leaf = dpf::make_naked_leaf(std::uint8_t{3}, dpf::gf24{0xF5}); + EXPECT_EQ((dpf::extract_leaf(leaf, std::uint8_t{3})), + dpf::gf24{0x5}); + EXPECT_EQ((dpf::extract_leaf(leaf, std::uint8_t{2})), + dpf::gf24{}); + EXPECT_EQ((dpf::extract_leaf(leaf, std::uint8_t{4})), + dpf::gf24{}); + EXPECT_EQ((dpf::extract_leaf(leaf, std::uint8_t{31})), + dpf::gf24{}); +} + +TEST(Gf2Adversarial, UnassignedWildcardThrows) +{ + auto [w0, w1] = dpf::make_dpf(std::uint8_t{3}, dpf::wildcard_value{}); + EXPECT_THROW((void)*dpf::eval_point(w0, std::uint8_t{3}), std::runtime_error); + EXPECT_THROW((void)*dpf::eval_point(w1, std::uint8_t{3}), std::runtime_error); + auto [p0, p1] = dpf::make_dpf(std::uint8_t{1}, dpf::wildcard_value{}); + EXPECT_THROW((void)*dpf::eval_point(p0, std::uint8_t{1}), std::runtime_error); + (void)p1; +} + +TEST(Gf2Adversarial, FromSeedDropsBytesPastTheWord) +{ + unsigned char narrow[16]{}; + unsigned char wide[16]; + std::memset(wide, 0xa5, sizeof(wide)); + narrow[0] = 0x15; + wide[0] = 0x15; + EXPECT_EQ(dpf::gf24::from_seed(narrow, 16), dpf::gf24{0x5}); + EXPECT_EQ(dpf::gf24::from_seed(wide, 16), dpf::gf24{0x5}); + narrow[0] = 0xab; + wide[0] = 0xab; + EXPECT_EQ(dpf::gf28::from_seed(narrow, 1), dpf::gf28::from_seed(wide, 16)); +} diff --git a/test/tests/gf2_test.cpp b/test/tests/gf2_test.cpp new file mode 100644 index 0000000..2fe8e25 --- /dev/null +++ b/test/tests/gf2_test.cpp @@ -0,0 +1,306 @@ +#include + +#include "dpf.hpp" + +#include +#include +#include +#include +#include +#include + +namespace +{ + +template +F pow_elem(F base, unsigned long long exp) +{ + F r{1}; + while (exp != 0) + { + if ((exp & 1ull) != 0) + r = r * base; + exp >>= 1; + if (exp != 0) + base = base * base; + } + return r; +} + +template +void expect_field_laws() +{ + constexpr unsigned bits = F::bits; + EXPECT_EQ(F{0} + F{1}, F{1}); + EXPECT_EQ(F{1} + F{1}, F{0}); + EXPECT_EQ(-F{1}, F{1}); + EXPECT_EQ(F{-1}, F{1}); + EXPECT_EQ(F{1} * F{1}, F{1}); + EXPECT_EQ(F{0} * F{5}, F{0}); + EXPECT_TRUE(std::is_trivially_copyable_v); + EXPECT_TRUE(std::is_standard_layout_v); + EXPECT_TRUE(dpf::utils::has_characteristic_two_v); + EXPECT_EQ(dpf::utils::bitlength_of_v, bits); + EXPECT_EQ(dpf::utils::make_default_v, F{1}); + + if constexpr (bits > 1) + { + const F x{2}; + F xpow{1}; + for (unsigned i = 0; i < bits; ++i) + xpow = xpow * x; + if constexpr (bits == 2 || bits == 4) + EXPECT_EQ(xpow, F{0x3}); + else if constexpr (bits == 8) + EXPECT_EQ(xpow, F{0x1b}); + else if constexpr (bits == 16) + EXPECT_EQ(xpow, F{0x2d}); + else if constexpr (bits == 32) + EXPECT_EQ(xpow.raw(), 0x90200001u); + else + { + const auto tail = static_cast( + (typename F::integral_type{1} << 63) + | (typename F::integral_type{1} << 62) + | (typename F::integral_type{1} << 53) + | typename F::integral_type{1}); + EXPECT_EQ(xpow.raw(), tail); + } + } + + const F a{0x13}; + const F b{0x2a}; + const F c{0x7}; + EXPECT_EQ((a + b) * c, a * c + b * c); + EXPECT_EQ((a * b) * c, a * (b * c)); + if constexpr (bits <= 32) + { + if (a != F{0}) + EXPECT_EQ(a * pow_elem(a, (1ull << bits) - 2ull), F{1}); + } + + if constexpr (bits <= 8) + { + const unsigned lim = 1u << bits; + for (unsigned i = 1; i < lim; ++i) + EXPECT_EQ(F{i} * pow_elem(F{i}, (1ull << bits) - 2ull), F{1}) << i; + } +} + +template +auto open_at(const Key0 & k0, const Key1 & k1, In x) +{ + const auto y0 = *dpf::eval_point(k0, x); + const auto y1 = *dpf::eval_point(k1, x); + return dpf::reconstruct(y0, y1); +} + +template +void expect_point_payload(In alpha, Out beta) +{ + auto [k0, k1] = dpf::make_dpf(alpha, beta); + for (int x = 0; x < 32; ++x) + { + const In q = static_cast(x); + const Out got = open_at(k0, k1, q); + EXPECT_EQ(got, q == alpha ? beta : Out{}) << static_cast(x); + } + EXPECT_EQ(open_at(k0, k1, alpha), beta); +} + +template +void expect_cmp(std::uint8_t alpha, Out beta, Spec spec, bool leq) +{ + auto [k0, k1] = dpf::make_dpf(alpha, spec); + for (int x = 0; x < 24; ++x) + { + const auto q = static_cast(x); + const auto y0 = dpf::eval_point(dpf::cmp, k0, q); + const auto y1 = dpf::eval_point(dpf::cmp, k1, q); + const bool hot = leq ? x <= static_cast(alpha) + : x < static_cast(alpha); + EXPECT_EQ(dpf::reconstruct(y0, y1), hot ? beta : Out{}) << x; + } +} + +} // namespace + +TEST(Gf2, FieldLaws) +{ + expect_field_laws(); + expect_field_laws(); + expect_field_laws(); + expect_field_laws(); + expect_field_laws(); + expect_field_laws(); + expect_field_laws(); +} + +TEST(Gf2, SubByteAdditionIsXor) +{ + EXPECT_EQ(dpf::gf22{3} + dpf::gf22{1}, dpf::gf22{2}); + EXPECT_EQ(dpf::gf24{0xf} + dpf::gf24{1}, dpf::gf24{0xe}); + EXPECT_EQ(dpf::gf24{2} * dpf::gf24{2}, dpf::gf24{4}); + EXPECT_EQ(dpf::gf22{2} * dpf::gf22{2}, dpf::gf22{3}); +} + +TEST(Gf2, LeafScaleIsPerLane) +{ + alignas(16) unsigned char bytes[16]; + for (int i = 0; i < 16; ++i) + bytes[i] = 0xe4; + simde__m128i node; + std::memcpy(&node, bytes, sizeof(node)); + const auto scaled = dpf::multiply_leaf(node, dpf::gf24{2}); + unsigned char out[16]; + std::memcpy(out, &scaled, sizeof(out)); + const auto lo = static_cast((dpf::gf24{0x4} * dpf::gf24{2}).raw()); + const auto hi = static_cast((dpf::gf24{0xe} * dpf::gf24{2}).raw()); + const auto expect = static_cast(lo | (hi << 4)); + for (unsigned char b : out) + EXPECT_EQ(b, expect); + + const auto summed = dpf::add_leaf(node, node); + unsigned char z[16]; + std::memcpy(z, &summed, sizeof(z)); + for (unsigned char b : z) + EXPECT_EQ(b, 0); +} + +TEST(Gf2, ShufbScalarVectorMatchesFieldMul) +{ + alignas(32) unsigned char bytes[33]; + for (int i = 0; i < 33; ++i) + bytes[i] = static_cast(i * 17 + 3); + const unsigned scalars[] = {0u, 1u, 2u, 0x1bu, 0x80u, 0xffu, 0x2du, 0x8000u, 0xffffu}; + + for (unsigned s : scalars) + { + if (s > 0xffu) + continue; + simde__m128i n128; + simde__m256i n256; + std::memcpy(&n128, bytes, 16); + std::memcpy(&n256, bytes, 32); + const auto a128 = dpf::multiply_leaf(n128, dpf::gf28{s}); + const auto a256 = dpf::multiply_leaf(n256, dpf::gf28{s}); + unsigned char o128[16]; + unsigned char o256[32]; + std::memcpy(o128, &a128, 16); + std::memcpy(o256, &a256, 32); + for (int i = 0; i < 16; ++i) + EXPECT_EQ(o128[i], (dpf::gf28{bytes[i]} * dpf::gf28{s}).raw()) << s << " " << i; + for (int i = 0; i < 32; ++i) + EXPECT_EQ(o256[i], (dpf::gf28{bytes[i]} * dpf::gf28{s}).raw()) << s << " " << i; + + unsigned char tail[33]; + std::memcpy(tail, bytes, 33); + dpf::gf2_detail::scale_gf28(tail, bytes, 33, static_cast(s)); + for (int i = 0; i < 33; ++i) + EXPECT_EQ(tail[i], (dpf::gf28{bytes[i]} * dpf::gf28{s}).raw()) << "tail " << i; + } + + alignas(32) unsigned char lanes[32]; + for (int i = 0; i < 16; ++i) + { + const auto lane = static_cast(i * 19 + 1); + lanes[2 * i] = static_cast(lane); + lanes[2 * i + 1] = static_cast(lane >> 8); + } + for (unsigned s : scalars) + { + simde__m256i node; + std::memcpy(&node, lanes, 32); + const auto scaled = dpf::multiply_leaf(node, dpf::gf216{s}); + unsigned char got[32]; + std::memcpy(got, &scaled, 32); + for (int i = 0; i < 16; ++i) + { + const auto lane = static_cast(lanes[2 * i] | (lanes[2 * i + 1] << 8)); + const auto prod = (dpf::gf216{lane} * dpf::gf216{s}).raw(); + EXPECT_EQ(got[2 * i], static_cast(prod)) << s << " " << i; + EXPECT_EQ(got[2 * i + 1], static_cast(prod >> 8)) << s << " " << i; + } + } +} + +TEST(Gf2, PointPayload) +{ + expect_point_payload(std::uint8_t{0x2a}, dpf::gf2{1}); + expect_point_payload(std::uint8_t{0x11}, dpf::gf22{3}); + expect_point_payload(std::uint8_t{0x05}, dpf::gf24{0xa}); + expect_point_payload(std::uint8_t{0x2a}, dpf::gf28{0x1b}); + expect_point_payload(std::uint8_t{0x07}, dpf::gf216{0x2d}); + expect_point_payload(std::uint8_t{0x13}, dpf::gf232{0x90200001u}); + expect_point_payload(std::uint8_t{0x04}, dpf::gf264{0x11}); +} + +TEST(Gf2, ComparisonPayload) +{ + expect_cmp(std::uint8_t{10}, dpf::gf24{0x7}, dpf::lt(dpf::gf24{0x7}), false); + expect_cmp(std::uint8_t{10}, dpf::gf28{0x1b}, dpf::leq(dpf::gf28{0x1b}), true); + expect_cmp(std::uint8_t{4}, dpf::gf264{0x53}, dpf::lt(dpf::gf264{0x53}), false); +} + +template +void expect_inv_exhaustive() +{ + EXPECT_THROW(dpf::detail::shamir_field::inv(F{0}), std::invalid_argument); + const unsigned long long n = 1ull << F::bits; + for (unsigned long long i = 1; i < n; ++i) + { + const F a{static_cast(i)}; + const F b = dpf::detail::shamir_field::inv(a); + EXPECT_EQ(a * b, F{1}) << i; + } +} + +template +void expect_shamir23(F secret, F slope) +{ + const auto shares = dpf::shamir::deal(secret, std::array{{slope}}); + EXPECT_EQ((dpf::shamir::reconstruct(std::get<0>(shares), std::get<1>(shares))), secret); + EXPECT_EQ((dpf::shamir::reconstruct(std::get<1>(shares), std::get<2>(shares))), secret); + EXPECT_EQ((dpf::shamir::reconstruct(std::get<2>(shares), std::get<0>(shares))), secret); + EXPECT_EQ((dpf::shamir::reconstruct( + std::get<0>(shares), std::get<1>(shares), std::get<2>(shares))), secret); +} + +TEST(Gf2, InverseAndShamir) +{ + expect_inv_exhaustive(); + expect_inv_exhaustive(); + expect_inv_exhaustive(); + expect_inv_exhaustive(); + + const dpf::gf216 wide[] = {dpf::gf216{1}, dpf::gf216{2}, dpf::gf216{0x2d}, + dpf::gf216{0xffff}}; + for (auto a : wide) + EXPECT_EQ(a * dpf::detail::shamir_field::inv(a), dpf::gf216{1}); + const dpf::gf232 mid[] = {dpf::gf232{1}, dpf::gf232{2}, dpf::gf232{0x190200001u}}; + for (auto a : mid) + EXPECT_EQ(a * dpf::detail::shamir_field::inv(a), dpf::gf232{1}); + const dpf::gf264 big[] = {dpf::gf264{1}, dpf::gf264{2}, dpf::gf264{~std::uint64_t{0}}}; + for (auto a : big) + EXPECT_EQ(a * dpf::detail::shamir_field::inv(a), dpf::gf264{1}); + + expect_shamir23(dpf::gf22{1}, dpf::gf22{2}); + expect_shamir23(dpf::gf28{0x1b}, dpf::gf28{0x5a}); + expect_shamir23(dpf::gf264{0x11}, dpf::gf264{0x53}); + + const auto shares = dpf::shamir::deal( + dpf::gf28{0x1b}, std::array{{dpf::gf28{2}, dpf::gf28{9}}}); + EXPECT_EQ((dpf::shamir::reconstruct( + std::get<0>(shares), std::get<2>(shares), std::get<4>(shares))), + dpf::gf28{0x1b}); + + // Point 2 is 0 in GF(2), so that party would hold the secret. + const auto leaked = dpf::shamir::deal( + dpf::gf2{1}, std::array{{dpf::gf2{1}}}); + EXPECT_EQ(std::get<1>(leaked).raw(), dpf::gf2{1}.raw()); + EXPECT_THROW((dpf::shamir::reconstruct(std::get<0>(leaked), std::get<1>(leaked))), + std::invalid_argument); + + const auto one = dpf::shamir::deal(dpf::gf2{1}, std::array{}); + EXPECT_EQ(dpf::shamir::reconstruct(std::get<0>(one)), dpf::gf2{1}); +} diff --git a/test/tests/growing_idpf_test.cpp b/test/tests/growing_idpf_test.cpp new file mode 100644 index 0000000..85485e5 --- /dev/null +++ b/test/tests/growing_idpf_test.cpp @@ -0,0 +1,487 @@ +#include + +#include +#include +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +using block_t = dpf::prg::aes128::block_type; +constexpr std::size_t kBits = 8; + +static block_t g_roots[2]; +static int g_ri = 0; +block_t take_root() +{ + return g_roots[g_ri++]; +} + +void reset_roots(block_t r0, block_t r1) +{ + g_roots[0] = r0; + g_roots[1] = r1; + g_ri = 0; +} + +std::uint8_t sibling_at(std::uint8_t alpha, std::size_t level) +{ + return static_cast(alpha ^ (1u << (kBits - 1 - level))); +} + +template +auto grow_rest(Keys keys, std::uint8_t alpha, + const std::array & betas) +{ + if constexpr (I >= N) + return keys; + else + { + auto next = dpf::extend(keys.first, keys.second, alpha, + dpf::at(betas[I])); + return grow_rest(std::move(next), alpha, betas); + } +} + +template +auto grow_incrementally(std::uint8_t alpha, + const std::array & betas, block_t r0, block_t r1) +{ + reset_roots(r0, r1); + auto keys = dpf::make_dpf(alpha, + dpf::root_sampler_t{take_root}, + dpf::at<1>(betas[0])); + return grow_rest<1, N>(std::move(keys), alpha, betas); +} + +} // namespace + +TEST(GrowingIdpf, PrefixesOpenToOwnPayload) +{ + const std::uint8_t alpha = 0xB2; + const std::array betas = { + 0x11ull, 0x2222ull, 0x333333ull, 0x44444444ull, + 0x5555555555ull, 0x666666666666ull, 0x77777777777777ull, + 0x8888888888888888ull}; + + block_t r0 = dpf::uniform_sample(); + block_t r1 = dpf::uniform_sample(); + auto [k0, k1] = grow_incrementally(alpha, betas, r0, r1); + + using KT = std::decay_t; + EXPECT_EQ(KT::depth, kBits - 1); + EXPECT_EQ(KT::num_outputs, kBits); + + auto open = [&](auto out_ic, std::uint8_t x) { + return dpf::reconstruct( + *dpf::eval_point(out_ic, k0, x), + *dpf::eval_point(out_ic, k1, x)); + }; + + [&](std::index_sequence) { + (([&] { + EXPECT_EQ(open(dpf::out, alpha), betas[L]) << "prefix " << L; + EXPECT_EQ(open(dpf::out, sibling_at(alpha, L)), 0ull) + << "sibling at prefix " << L; + }()), ...); + }(std::make_index_sequence{}); +} + +TEST(GrowingIdpf, ExtendMatchesFullySpecified) +{ + const std::uint8_t alpha = 0x6D; + const std::array betas = { + 1001, 2002, 3003, 4004, 5005, 6006, 7007, 8008}; + + block_t r0 = dpf::uniform_sample(); + block_t r1 = dpf::uniform_sample(); + + auto [k0, k1] = grow_incrementally(alpha, betas, r0, r1); + + reset_roots(r0, r1); + auto [ref0, ref1] = dpf::make_dpf(alpha, + dpf::root_sampler_t{take_root}, + dpf::at<1>(betas[0]), dpf::at<2>(betas[1]), dpf::at<3>(betas[2]), + dpf::at<4>(betas[3]), dpf::at<5>(betas[4]), dpf::at<6>(betas[5]), + dpf::at<7>(betas[6]), dpf::at<8>(betas[7])); + + using KT = std::decay_t; + static_assert(std::is_same_v>); + EXPECT_EQ(std::memcmp(k0.correction_words().data(), + ref0.correction_words().data(), + sizeof(typename KT::correction_words_array)), 0); + EXPECT_EQ(std::memcmp(k0.correction_advice().data(), + ref0.correction_advice().data(), + sizeof(typename KT::correction_advice_array)), 0); + EXPECT_EQ(std::memcmp(&k0.root(), &ref0.root(), sizeof(block_t)), 0); + EXPECT_EQ(std::memcmp(&k1.root(), &ref1.root(), sizeof(block_t)), 0); + + [&](std::index_sequence) { + (([&] { + EXPECT_EQ(std::memcmp(&k0.template leaf(), + &ref0.template leaf(), sizeof(k0.template leaf())), 0) + << "leaf0 " << L; + EXPECT_EQ(std::memcmp(&k1.template leaf(), + &ref1.template leaf(), sizeof(k1.template leaf())), 0) + << "leaf1 " << L; + EXPECT_EQ(dpf::reconstruct( + *dpf::eval_point(dpf::out, k0, alpha), + *dpf::eval_point(dpf::out, k1, alpha)), + betas[L]) + << "open " << L; + }()), ...); + }(std::make_index_sequence{}); +} + +TEST(GrowingIdpf, AddOutputWildcardOnExistingLevel) +{ + const std::uint8_t alpha = 0xA5; + block_t r0 = dpf::uniform_sample(); + block_t r1 = dpf::uniform_sample(); + reset_roots(r0, r1); + auto [k0, k1] = dpf::make_dpf(alpha, + dpf::root_sampler_t{take_root}, + dpf::at<2>(std::uint64_t{42})); + // at<2>(u64) → level 1. at<3>(u32) → level 1 (lg_opl=2), new group. + auto [a0, a1] = dpf::add_output(k0, k1, alpha, + dpf::at<3>(dpf::wildcard_value{})); + using AT = std::decay_t; + EXPECT_EQ(AT::depth, 1u); + EXPECT_EQ(AT::num_outputs, 2u); + EXPECT_TRUE(AT::wildcard_bits[1]); + + auto o0 = dpf::eval_point(dpf::out<0>, a0, alpha); + auto o1 = dpf::eval_point(dpf::out<0>, a1, alpha); + EXPECT_EQ(dpf::reconstruct(*o0, *o1), 42ull); +} + +TEST(GrowingIdpf, DeepestPrefixMatchesClassicDpf) +{ + const std::uint8_t alpha = 0xC3; + const std::array betas = { + 1, 2, 4, 8, 16, 32, 64, 128}; + block_t r0 = dpf::uniform_sample(); + block_t r1 = dpf::uniform_sample(); + auto [k0, k1] = grow_incrementally(alpha, betas, r0, r1); + + auto recon = [&](std::uint8_t x) { + return dpf::reconstruct( + *dpf::eval_point(dpf::out, k0, x), + *dpf::eval_point(dpf::out, k1, x)); + }; + + auto [c0, c1] = dpf::make_dpf(alpha, betas.back()); + for (std::uint32_t x = 0; x < 256; ++x) + { + const auto want = dpf::reconstruct( + *dpf::eval_point(c0, static_cast(x)), + *dpf::eval_point(c1, static_cast(x))); + EXPECT_EQ(recon(static_cast(x)), + static_cast(want)) + << "x=" << x; + } +} + +TEST(GrowingIdpf, ChaChaPrgOpensThePrefix) +{ + using prg = dpf::prg::chacha20; + using block = prg::block_type; + static block roots[2]; + static int ri = 0; + auto take = +[]() -> block { return roots[ri++]; }; + const std::uint8_t alpha = 0x3C; + const std::uint64_t beta = 0x1234; + roots[0] = dpf::uniform_sample(); + roots[1] = dpf::uniform_sample(); + ri = 0; + auto [k0, k1] = dpf::make_dpf(alpha, + dpf::root_sampler_t{take}, dpf::at<1>(beta)); + const auto opened = dpf::reconstruct( + *dpf::eval_point(dpf::out<0>, k0, alpha), + *dpf::eval_point(dpf::out<0>, k1, alpha)); + EXPECT_EQ(opened, beta); +} + +namespace +{ + +struct GrowPad +{ + simde__m128i block() { return dpf::uniform_sample(); } + std::uint8_t bit() + { + return static_cast( + dpf::uniform_sample() & 1u); + } +}; + +} // namespace + +TEST(GrowingIdpf, MemoizerExtendMatchesRewalk) +{ + const std::uint8_t alpha = 0xB2; + block_t r0 = dpf::uniform_sample(); + block_t r1 = dpf::uniform_sample(); + reset_roots(r0, r1); + auto [k0, k1] = dpf::make_dpf(alpha, + dpf::root_sampler_t{take_root}, + dpf::at<1>(std::uint64_t{7})); + + auto [d0, d1] = dpf::extend(k0, k1, alpha, dpf::at<2>(std::uint64_t{9})); + + auto m0 = dpf::make_basic_path_memoizer(k0); + auto m1 = dpf::make_basic_path_memoizer(k1); + (void)dpf::eval_point(dpf::out<0>, k0, alpha, m0); + (void)dpf::eval_point(dpf::out<0>, k1, alpha, m1); + auto [m_k0, m_k1] = + dpf::extend(k0, k1, m0, m1, alpha, dpf::at<2>(std::uint64_t{9})); + + EXPECT_EQ(0, std::memcmp(d0.correction_words().data(), + m_k0.correction_words().data(), + sizeof(d0.correction_words()))); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf::out<0>, m_k0, alpha), + *dpf::eval_point(dpf::out<0>, m_k1, alpha)), + 7ull); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf::out<1>, m_k0, alpha), + *dpf::eval_point(dpf::out<1>, m_k1, alpha)), + 9ull); + (void)d1; +} + +TEST(GrowingIdpf, ExtendDsMatchesDealer) +{ + const std::uint8_t alpha = 0xB2; + block_t r0 = dpf::uniform_sample(); + block_t r1 = dpf::uniform_sample(); + reset_roots(r0, r1); + auto [k0, k1] = dpf::make_dpf(alpha, + dpf::root_sampler_t{take_root}, + dpf::at<1>(std::uint64_t{7})); + auto [d0, d1] = dpf::extend(k0, k1, alpha, dpf::at<2>(std::uint64_t{9})); + + auto m0 = dpf::make_basic_path_memoizer(k0); + auto m1 = dpf::make_basic_path_memoizer(k1); + (void)dpf::eval_point(dpf::out<0>, k0, alpha, m0); + (void)dpf::eval_point(dpf::out<0>, k1, alpha, m1); + GrowPad pads{}; + dpf::local_cw_protocol proto{pads}; + auto [s0, s1] = dpf::extend_ds(k0, k1, m0, m1, alpha, std::uint8_t{0}, proto, + dpf::at<2>(std::uint64_t{9})); + + EXPECT_EQ(0, std::memcmp(d0.correction_words().data(), + s0.correction_words().data(), + sizeof(d0.correction_words()))); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf::out<1>, s0, alpha), + *dpf::eval_point(dpf::out<1>, s1, alpha)), + 9ull); + (void)d1; +} + +TEST(GrowingIdpf, AddOutputDsWildcard) +{ + const std::uint8_t alpha = 0xA5; + block_t r0 = dpf::uniform_sample(); + block_t r1 = dpf::uniform_sample(); + reset_roots(r0, r1); + auto [k0, k1] = dpf::make_dpf(alpha, + dpf::root_sampler_t{take_root}, + dpf::at<2>(std::uint64_t{42})); + auto m0 = dpf::make_basic_path_memoizer(k0); + auto m1 = dpf::make_basic_path_memoizer(k1); + (void)dpf::eval_point(dpf::out<0>, k0, alpha, m0); + (void)dpf::eval_point(dpf::out<0>, k1, alpha, m1); + GrowPad pads{}; + dpf::local_cw_protocol proto{pads}; + auto [a0, a1] = dpf::add_output_ds(k0, k1, m0, m1, alpha, std::uint8_t{0}, + proto, dpf::at<3>(dpf::wildcard_value{})); + EXPECT_EQ(std::decay_t::num_outputs, 2u); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf::out<0>, a0, alpha), + *dpf::eval_point(dpf::out<0>, a1, alpha)), + 42ull); +} + +TEST(GrowingIdpf, ShallowMemoizerThrows) +{ + const std::uint8_t alpha = 0x10; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::at<2>(std::uint64_t{1})); + using bare = dpf::unwrap_party_key_t>; + auto m0 = dpf::make_basic_path_memoizer(k0); + auto m1 = dpf::make_basic_path_memoizer(k1); + const bare & b0 = k0; + const bare & b1 = k1; + dpf::detail::ensure_level(b0, alpha, m0, 0); + dpf::detail::ensure_level(b1, alpha, m1, 0); + EXPECT_THROW( + (void)dpf::extend(k0, k1, m0, m1, alpha, dpf::at<3>(std::uint64_t{2})), + std::invalid_argument); +} + +TEST(GrowingIdpfDeath, MismatchedKeyPairThrows) +{ + const std::uint8_t alpha = 0x55; + // depth >= 1 so correction-word memcmp runs + auto [k0, _] = dpf::make_dpf(alpha, dpf::at<2>(std::uint64_t{1})); + auto [__, k1] = dpf::make_dpf(alpha, dpf::at<2>(std::uint64_t{1})); + EXPECT_THROW( + (void)dpf::extend(k0, k1, alpha, dpf::at<3>(std::uint64_t{2})), + std::invalid_argument); +} + +TEST(GrowingIdpfDeath, WrongPathBitThrows) +{ + const std::uint8_t alpha = 0x80; // MSB = 1 + auto [k0, k1] = dpf::make_dpf(alpha, dpf::at<1>(std::uint64_t{1})); + // depth 0; programmed bit is 1; flip it + EXPECT_THROW( + (void)dpf::extend(k0, k1, /*bit=*/false, alpha, + dpf::at<2>(std::uint64_t{2})), + std::invalid_argument); +} + +TEST(GrowingIdpfDeath, SpecNotOnNewDepthThrows) +{ + const std::uint8_t alpha = 0x11; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::at<1>(std::uint64_t{1})); + // Deepens by one via at<2>, but also plants at<1> on the old level. + EXPECT_THROW( + (void)dpf::extend(k0, k1, alpha, dpf::at<2>(std::uint64_t{9}), + dpf::at<1>(std::uint64_t{8})), + std::invalid_argument); +} + +TEST(GrowingIdpf, ExtendSaturatesEightBitDomain) +{ + const std::uint8_t alpha = 0x01; + const std::array betas = {1, 2, 3, 4, 5, 6, 7, 8}; + block_t r0 = dpf::uniform_sample(); + block_t r1 = dpf::uniform_sample(); + auto [k0, k1] = grow_incrementally(alpha, betas, r0, r1); + using KT = std::decay_t; + EXPECT_EQ(KT::depth, 7u); + EXPECT_EQ(KT::depth + 1, dpf::utils::bitlength_of_v); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf::out<7>, k0, alpha), + *dpf::eval_point(dpf::out<7>, k1, alpha)), + 8ull); +} + +TEST(GrowingIdpfDeath, MemoizerOnSiblingCorruptsNewSlot) +{ + const std::uint8_t alpha = 0xB2; + const std::uint8_t sibling = static_cast(alpha ^ 0x80); + // depth 1 so the frontier is past the root + auto [k0, k1] = dpf::make_dpf(alpha, dpf::at<2>(std::uint64_t{7})); + auto [good0, good1] = + dpf::extend(k0, k1, alpha, dpf::at<3>(std::uint64_t{9})); + + auto m0 = dpf::make_basic_path_memoizer(k0); + auto m1 = dpf::make_basic_path_memoizer(k1); + (void)dpf::eval_point(dpf::out<0>, k0, sibling, m0); + (void)dpf::eval_point(dpf::out<0>, k1, sibling, m1); + auto [bad0, bad1] = + dpf::extend(k0, k1, m0, m1, alpha, dpf::at<3>(std::uint64_t{9})); + + EXPECT_NE(0, std::memcmp(good0.correction_words().data(), + bad0.correction_words().data(), + sizeof(good0.correction_words()))); + const auto got = dpf::reconstruct(*dpf::eval_point(dpf::out<1>, bad0, alpha), + *dpf::eval_point(dpf::out<1>, bad1, alpha)); + EXPECT_NE(got, 9ull); + (void)good1; +} + +TEST(GrowingIdpfDeath, DsWrongSharesDisagreeWithDealer) +{ + const std::uint8_t alpha = 0xB2; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::at<2>(std::uint64_t{7})); + auto [good0, good1] = + dpf::extend(k0, k1, alpha, dpf::at<3>(std::uint64_t{9})); + + auto m0 = dpf::make_basic_path_memoizer(k0); + auto m1 = dpf::make_basic_path_memoizer(k1); + (void)dpf::eval_point(dpf::out<0>, k0, alpha, m0); + (void)dpf::eval_point(dpf::out<0>, k1, alpha, m1); + GrowPad pads{}; + dpf::local_cw_protocol proto{pads}; + // Flip the bit used at the extend level (depth 1 → second MSB). + const std::uint8_t wrong = static_cast(alpha ^ 0x40); + auto [bad0, bad1] = dpf::extend_ds(k0, k1, m0, m1, wrong, std::uint8_t{0}, + proto, dpf::at<3>(std::uint64_t{9})); + + EXPECT_NE(0, std::memcmp(good0.correction_words().data(), + bad0.correction_words().data(), + sizeof(good0.correction_words()))); + (void)good1; + (void)bad1; +} + +TEST(GrowingIdpf, ExhaustiveDomainAfterMemoGrow) +{ + const std::uint8_t alpha = 0x5A; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::at<1>(std::uint64_t{3})); + auto m0 = dpf::make_basic_path_memoizer(k0); + auto m1 = dpf::make_basic_path_memoizer(k1); + (void)dpf::eval_point(dpf::out<0>, k0, alpha, m0); + (void)dpf::eval_point(dpf::out<0>, k1, alpha, m1); + auto [g0, g1] = + dpf::extend(k0, k1, m0, m1, alpha, dpf::at<2>(std::uint64_t{11})); + auto [d0, d1] = + dpf::extend(k0, k1, alpha, dpf::at<2>(std::uint64_t{11})); + + for (unsigned x = 0; x < 256; ++x) + { + const auto xa = static_cast(x); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf::out<0>, g0, xa), + *dpf::eval_point(dpf::out<0>, g1, xa)), + dpf::reconstruct(*dpf::eval_point(dpf::out<0>, d0, xa), + *dpf::eval_point(dpf::out<0>, d1, xa))) + << "out0 x=" << x; + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf::out<1>, g0, xa), + *dpf::eval_point(dpf::out<1>, g1, xa)), + dpf::reconstruct(*dpf::eval_point(dpf::out<1>, d0, xa), + *dpf::eval_point(dpf::out<1>, d1, xa))) + << "out1 x=" << x; + } +} + +TEST(GrowingIdpf, DsAndDealerAgreeFullDomain) +{ + const std::uint8_t alpha = 0x3C; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::at<1>(std::uint64_t{4})); + auto [d0, d1] = + dpf::extend(k0, k1, alpha, dpf::at<2>(std::uint64_t{8})); + auto m0 = dpf::make_basic_path_memoizer(k0); + auto m1 = dpf::make_basic_path_memoizer(k1); + (void)dpf::eval_point(dpf::out<0>, k0, alpha, m0); + (void)dpf::eval_point(dpf::out<0>, k1, alpha, m1); + GrowPad pads{}; + dpf::local_cw_protocol proto{pads}; + auto [s0, s1] = dpf::extend_ds(k0, k1, m0, m1, alpha, std::uint8_t{0}, proto, + dpf::at<2>(std::uint64_t{8})); + + EXPECT_EQ(0, std::memcmp(d0.correction_words().data(), + s0.correction_words().data(), + sizeof(d0.correction_words()))); + EXPECT_EQ(0, std::memcmp(d0.correction_advice().data(), + s0.correction_advice().data(), + sizeof(d0.correction_advice()))); + for (unsigned x = 0; x < 256; ++x) + { + const auto xa = static_cast(x); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf::out<1>, s0, xa), + *dpf::eval_point(dpf::out<1>, s1, xa)), + dpf::reconstruct(*dpf::eval_point(dpf::out<1>, d0, xa), + *dpf::eval_point(dpf::out<1>, d1, xa))) + << "x=" << x; + } +} + +TEST(GrowingIdpf, EmptyAddOutputThrows) +{ + const std::uint8_t alpha = 0x01; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::at<1>(std::uint64_t{1})); + EXPECT_THROW((void)dpf::add_output(k0, k1, alpha), std::invalid_argument); +} diff --git a/test/tests/half_tree_test.cpp b/test/tests/half_tree_test.cpp index 37d35d1..f39420f 100644 --- a/test/tests/half_tree_test.cpp +++ b/test/tests/half_tree_test.cpp @@ -320,3 +320,36 @@ TEST(HalfTree, IncrementalPlacementSmoke) EXPECT_EQ(got, q == alpha ? uint8_t{7} : uint8_t{0}) << i; } } + +TEST(HalfTree, VerifiableFullDomainDetectsSeedTamper) +{ + using in_t = std::uint8_t; + using out_t = std::uint16_t; + const in_t alpha = 0; + const out_t beta = 0x1111; + auto [k0, k1] = dpf::make_dpf(alpha, beta, dpf::verifiable{}); + EXPECT_TRUE(std::decay_t::tree::is_half_tree); + for (int i = 0; i < 256; ++i) + { + const in_t q = static_cast(i); + dpf::proof_token a{}, b{}; + const out_t got = recon(*dpf::eval_point(k0, q, dpf::prove(a)), + *dpf::eval_point(k1, q, dpf::prove(b))); + EXPECT_EQ(got, q == alpha ? beta : out_t{}) << i; + EXPECT_TRUE(dpf::verify(a, b)) << i; + } + for (auto & cs : const_cast::correction_seeds_array &>( + k0.correction_seeds())) + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); + int rejected = 0; + for (int i = 0; i < 256; ++i) + { + const in_t q = static_cast(i); + dpf::proof_token a{}, b{}; + (void)*dpf::eval_point(k0, q, dpf::prove(a)); + (void)*dpf::eval_point(k1, q, dpf::prove(b)); + if (!dpf::verify(a, b)) + ++rejected; + } + EXPECT_GT(rejected, 0); +} diff --git a/test/tests/helpers/eval_common_data.hpp b/test/tests/helpers/eval_common_data.hpp index 8f0d9b8..9cc4807 100644 --- a/test/tests/helpers/eval_common_data.hpp +++ b/test/tests/helpers/eval_common_data.hpp @@ -45,6 +45,13 @@ static std::tuple param_type>, param_type>, param_type>, + param_type, + param_type, + param_type, + param_type, + param_type, + param_type, + param_type, // custom types param_type, @@ -555,6 +562,62 @@ static std::tuple std::make_tuple(uint16_t(0xFFFF), dpf::xor_wrapper(uint64_t(0xAAAAAAAAAAAAAAAA))), std::make_tuple(uint16_t(0xFFFF), dpf::xor_wrapper(uint64_t(0xFFFFFFFFFFFFFFFF))) }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf2{1}), + std::make_tuple(uint16_t(0x5555), dpf::gf2{1}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf2{1}), + std::make_tuple(uint16_t(0x8000), dpf::gf2{1}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf2{1}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf2{1}) + }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf22{1}), + std::make_tuple(uint16_t(0x5555), dpf::gf22{2}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf22{3}), + std::make_tuple(uint16_t(0x8000), dpf::gf22{1}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf22{2}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf22{3}) + }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf24{1}), + std::make_tuple(uint16_t(0x5555), dpf::gf24{0x6}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf24{0xa}), + std::make_tuple(uint16_t(0x8000), dpf::gf24{0xf}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf24{0x2}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf24{0xd}) + }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf28{1}), + std::make_tuple(uint16_t(0x5555), dpf::gf28{0x1b}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf28{0x80}), + std::make_tuple(uint16_t(0x8000), dpf::gf28{0xff}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf28{0x02}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf28{0x5a}) + }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf216{1}), + std::make_tuple(uint16_t(0x5555), dpf::gf216{0x2d}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf216{0x8000}), + std::make_tuple(uint16_t(0x8000), dpf::gf216{0xffff}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf216{0x0002}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf216{0x1234}) + }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf232{1}), + std::make_tuple(uint16_t(0x5555), dpf::gf232{0x90200001u}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf232{0x80000000u}), + std::make_tuple(uint16_t(0x8000), dpf::gf232{0xffffffffu}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf232{0x00000002u}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf232{0x13579bdfu}) + }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf264{1}), + std::make_tuple(uint16_t(0x5555), dpf::gf264{0x11}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf264{0x8000000000000000ull}), + std::make_tuple(uint16_t(0x8000), dpf::gf264{~std::uint64_t{0}}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf264{0x2}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf264{0x123456789abcdefull}) + }, { std::make_tuple(custom_input_type(0x0000), uint64_t(0x0000000000000001)), std::make_tuple(custom_input_type(0x0000), uint64_t(0x5555555555555555)), diff --git a/test/tests/helpers/eval_common_multi_data.hpp b/test/tests/helpers/eval_common_multi_data.hpp index abf5e53..9fc0b4a 100644 --- a/test/tests/helpers/eval_common_multi_data.hpp +++ b/test/tests/helpers/eval_common_multi_data.hpp @@ -59,6 +59,13 @@ static std::tuple param_type>, param_type>, param_type>, + param_type, + param_type, + param_type, + param_type, + param_type, + param_type, + param_type, // custom types param_type, @@ -591,6 +598,188 @@ static std::tuple dpf::xor_wrapper(uint64_t(0xAAAAAAAAAAAAAAAA)), dpf::xor_wrapper(uint64_t(0xFFFFFFFFFFFFFFFF))) }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf2{1}, + dpf::gf2{1}, + dpf::gf2{1}, + dpf::gf2{1}), + std::make_tuple(uint16_t(0x5555), dpf::gf2{1}, + dpf::gf2{1}, + dpf::gf2{1}, + dpf::gf2{1}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf2{1}, + dpf::gf2{1}, + dpf::gf2{1}, + dpf::gf2{1}), + std::make_tuple(uint16_t(0x8000), dpf::gf2{1}, + dpf::gf2{1}, + dpf::gf2{1}, + dpf::gf2{1}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf2{1}, + dpf::gf2{1}, + dpf::gf2{1}, + dpf::gf2{1}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf2{1}, + dpf::gf2{1}, + dpf::gf2{1}, + dpf::gf2{1}), + }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf22{1}, + dpf::gf22{2}, + dpf::gf22{3}, + dpf::gf22{1}), + std::make_tuple(uint16_t(0x5555), dpf::gf22{2}, + dpf::gf22{3}, + dpf::gf22{1}, + dpf::gf22{2}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf22{3}, + dpf::gf22{1}, + dpf::gf22{2}, + dpf::gf22{3}), + std::make_tuple(uint16_t(0x8000), dpf::gf22{1}, + dpf::gf22{2}, + dpf::gf22{3}, + dpf::gf22{1}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf22{2}, + dpf::gf22{3}, + dpf::gf22{1}, + dpf::gf22{2}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf22{3}, + dpf::gf22{1}, + dpf::gf22{2}, + dpf::gf22{3}), + }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf24{1}, + dpf::gf24{0x6}, + dpf::gf24{0xa}, + dpf::gf24{0xf}), + std::make_tuple(uint16_t(0x5555), dpf::gf24{0x6}, + dpf::gf24{0xa}, + dpf::gf24{0xf}, + dpf::gf24{0x2}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf24{0xa}, + dpf::gf24{0xf}, + dpf::gf24{0x2}, + dpf::gf24{0xd}), + std::make_tuple(uint16_t(0x8000), dpf::gf24{0xf}, + dpf::gf24{0x2}, + dpf::gf24{0xd}, + dpf::gf24{1}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf24{0x2}, + dpf::gf24{0xd}, + dpf::gf24{1}, + dpf::gf24{0x6}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf24{0xd}, + dpf::gf24{1}, + dpf::gf24{0x6}, + dpf::gf24{0xa}), + }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf28{1}, + dpf::gf28{0x1b}, + dpf::gf28{0x80}, + dpf::gf28{0xff}), + std::make_tuple(uint16_t(0x5555), dpf::gf28{0x1b}, + dpf::gf28{0x80}, + dpf::gf28{0xff}, + dpf::gf28{0x02}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf28{0x80}, + dpf::gf28{0xff}, + dpf::gf28{0x02}, + dpf::gf28{0x5a}), + std::make_tuple(uint16_t(0x8000), dpf::gf28{0xff}, + dpf::gf28{0x02}, + dpf::gf28{0x5a}, + dpf::gf28{1}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf28{0x02}, + dpf::gf28{0x5a}, + dpf::gf28{1}, + dpf::gf28{0x1b}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf28{0x5a}, + dpf::gf28{1}, + dpf::gf28{0x1b}, + dpf::gf28{0x80}), + }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf216{1}, + dpf::gf216{0x2d}, + dpf::gf216{0x8000}, + dpf::gf216{0xffff}), + std::make_tuple(uint16_t(0x5555), dpf::gf216{0x2d}, + dpf::gf216{0x8000}, + dpf::gf216{0xffff}, + dpf::gf216{0x0002}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf216{0x8000}, + dpf::gf216{0xffff}, + dpf::gf216{0x0002}, + dpf::gf216{0x1234}), + std::make_tuple(uint16_t(0x8000), dpf::gf216{0xffff}, + dpf::gf216{0x0002}, + dpf::gf216{0x1234}, + dpf::gf216{1}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf216{0x0002}, + dpf::gf216{0x1234}, + dpf::gf216{1}, + dpf::gf216{0x2d}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf216{0x1234}, + dpf::gf216{1}, + dpf::gf216{0x2d}, + dpf::gf216{0x8000}), + }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf232{1}, + dpf::gf232{0x90200001u}, + dpf::gf232{0x80000000u}, + dpf::gf232{0xffffffffu}), + std::make_tuple(uint16_t(0x5555), dpf::gf232{0x90200001u}, + dpf::gf232{0x80000000u}, + dpf::gf232{0xffffffffu}, + dpf::gf232{0x00000002u}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf232{0x80000000u}, + dpf::gf232{0xffffffffu}, + dpf::gf232{0x00000002u}, + dpf::gf232{0x13579bdfu}), + std::make_tuple(uint16_t(0x8000), dpf::gf232{0xffffffffu}, + dpf::gf232{0x00000002u}, + dpf::gf232{0x13579bdfu}, + dpf::gf232{1}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf232{0x00000002u}, + dpf::gf232{0x13579bdfu}, + dpf::gf232{1}, + dpf::gf232{0x90200001u}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf232{0x13579bdfu}, + dpf::gf232{1}, + dpf::gf232{0x90200001u}, + dpf::gf232{0x80000000u}), + }, + { + std::make_tuple(uint16_t(0x0000), dpf::gf264{1}, + dpf::gf264{0x11}, + dpf::gf264{0x8000000000000000ull}, + dpf::gf264{~std::uint64_t{0}}), + std::make_tuple(uint16_t(0x5555), dpf::gf264{0x11}, + dpf::gf264{0x8000000000000000ull}, + dpf::gf264{~std::uint64_t{0}}, + dpf::gf264{0x2}), + std::make_tuple(uint16_t(0x7FFF), dpf::gf264{0x8000000000000000ull}, + dpf::gf264{~std::uint64_t{0}}, + dpf::gf264{0x2}, + dpf::gf264{0x123456789abcdefull}), + std::make_tuple(uint16_t(0x8000), dpf::gf264{~std::uint64_t{0}}, + dpf::gf264{0x2}, + dpf::gf264{0x123456789abcdefull}, + dpf::gf264{1}), + std::make_tuple(uint16_t(0xAAAA), dpf::gf264{0x2}, + dpf::gf264{0x123456789abcdefull}, + dpf::gf264{1}, + dpf::gf264{0x11}), + std::make_tuple(uint16_t(0xFFFF), dpf::gf264{0x123456789abcdefull}, + dpf::gf264{1}, + dpf::gf264{0x11}, + dpf::gf264{0x8000000000000000ull}), + }, { std::make_tuple(custom_input_type(0x0000), uint64_t(0x0000000000000001), uint64_t(0x5555555555555555), diff --git a/test/tests/ic_test.cpp b/test/tests/ic_test.cpp index f3ae988..590786d 100644 --- a/test/tests/ic_test.cpp +++ b/test/tests/ic_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "dpf.hpp" @@ -113,8 +114,8 @@ TEST(Ic, MemoizerAgrees) { const uint8_t r = 40, p = 7, q = 90; auto keys = dpf::make_dpf(r, dpf::ic(p, q, uint32_t{11}, uint32_t{2})); - dpf::basic_path_memoizer memo0; - dpf::basic_path_memoizer memo1; + dpf::basic_path_memoizer memo0; + dpf::basic_path_memoizer memo1; for (int x = 0; x < 256; ++x) { const auto a = dpf::eval_point(dpf::ic, keys.first, static_cast(x), memo0); @@ -131,7 +132,7 @@ TEST(Ic, IntervalAndSequenceBuffers) auto keys = dpf::make_dpf(r, dpf::ic(p, q, uint16_t{9})); auto buf0 = dpf::make_output_buffer(dpf::ic, keys.first, uint8_t{3}, uint8_t{18}); auto buf1 = dpf::make_output_buffer(dpf::ic, keys.second, uint8_t{3}, uint8_t{18}); - dpf::basic_path_memoizer memo; + dpf::basic_path_memoizer memo; dpf::eval_interval(dpf::ic, keys.first, uint8_t{3}, uint8_t{18}, buf0, memo); dpf::eval_interval(dpf::ic, keys.second, uint8_t{3}, uint8_t{18}, buf1); for (std::size_t i = 0; i < buf0.size(); ++i) @@ -226,6 +227,7 @@ TEST(Ic, Geneval) rngs, dpf::ic(p, q, beta)); ASSERT_EQ(opened.party0.size(), 7u); ASSERT_EQ(opened.live_levels, 8u); + EXPECT_TRUE(dpf::verify(opened.proof0, opened.proof1)); const uint8_t r = static_cast(r0 ^ r1); for (std::size_t i = 0; i < 7; ++i) { @@ -239,8 +241,7 @@ TEST(Ic, Geneval) TEST(Ic, RejectsWrappedBounds) { - EXPECT_THROW(dpf::make_dpf(uint8_t{1}, dpf::ic(uint8_t{9}, uint8_t{2}, uint32_t{1})), - std::invalid_argument); + EXPECT_THROW(dpf::make_dpf(uint8_t{1}, dpf::ic(uint8_t{9}, uint8_t{2}, uint32_t{1})), std::invalid_argument); } TEST(Ic, BitPayload) @@ -334,14 +335,14 @@ TEST(Ic, AdditiveGeneval) std::begin(none), std::begin(none), ic_rng(), dpf::ic(p, q, beta)); EXPECT_TRUE(empty.party0.empty()); EXPECT_EQ(empty.live_levels, 0u); + // Empty-range tokens stay zero and must not verify as a matching pair. + EXPECT_FALSE(dpf::verify(empty.proof0, empty.proof1)); } TEST(Ic, IntervalRejectsDescendingEndpoints) { auto keys = dpf::make_dpf(uint8_t{4}, dpf::ic(uint8_t{1}, uint8_t{6}, uint32_t{1})); auto buf = dpf::make_output_buffer(dpf::ic, keys.first, 1); - EXPECT_THROW(dpf::eval_interval(dpf::ic, keys.first, uint8_t{9}, uint8_t{2}, buf), - std::invalid_argument); - EXPECT_THROW(dpf::make_output_buffer(dpf::ic, keys.first, uint8_t{9}, uint8_t{2}), - std::invalid_argument); + EXPECT_THROW(dpf::eval_interval(dpf::ic, keys.first, uint8_t{9}, uint8_t{2}, buf), std::invalid_argument); + EXPECT_THROW(dpf::make_output_buffer(dpf::ic, keys.first, uint8_t{9}, uint8_t{2}), std::invalid_argument); } diff --git a/test/tests/idpf_agg_test.cpp b/test/tests/idpf_agg_test.cpp new file mode 100644 index 0000000..1ad0144 --- /dev/null +++ b/test/tests/idpf_agg_test.cpp @@ -0,0 +1,90 @@ +#include + +#include +#include +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +using key0_t = decltype(dpf::make_dpf(std::uint16_t{0}, + dpf::idpf_ones<16>()).first); +using key1_t = decltype(dpf::make_dpf(std::uint16_t{0}, + dpf::idpf_ones<16>()).second); + +void split_keys(const std::vector & values, + std::vector & k0, std::vector & k1) +{ + k0.clear(); + k1.clear(); + for (auto v : values) + { + auto [a, b] = dpf::make_dpf(v, dpf::idpf_ones<16>()); + k0.push_back(std::move(a)); + k1.push_back(std::move(b)); + } +} + +} // namespace + +TEST(IdpfAgg, MaxAndKthAgainstPlaintext) +{ + const std::vector values{3, 100, 7, 100, 42}; + std::vector k0; + std::vector k1; + split_keys(values, k0, k1); + + EXPECT_EQ(dpf::idpf_agg_max(k0, k1), 100u); + EXPECT_EQ(dpf::idpf_agg_kth(k0, k1, 1), 100u); + EXPECT_EQ(dpf::idpf_agg_kth(k0, k1, values.size()), 3u); + + auto sorted = values; + std::sort(sorted.begin(), sorted.end(), std::greater<>{}); + EXPECT_EQ(dpf::idpf_agg_kth(k0, k1, 3), sorted[2]); +} + +TEST(IdpfAgg, AllEqual) +{ + const std::vector values{0x00AA, 0x00AA, 0x00AA}; + std::vector k0; + std::vector k1; + split_keys(values, k0, k1); + EXPECT_EQ(dpf::idpf_agg_max(k0, k1), 0x00AAu); + EXPECT_EQ(dpf::idpf_agg_kth(k0, k1, 1), 0x00AAu); + EXPECT_EQ(dpf::idpf_agg_kth(k0, k1, 3), 0x00AAu); +} + +TEST(IdpfAgg, KEqualsOneAndN) +{ + const std::vector values{1, 2, 3, 4}; + std::vector k0; + std::vector k1; + split_keys(values, k0, k1); + EXPECT_EQ(dpf::idpf_agg_kth(k0, k1, 1), 4u); + EXPECT_EQ(dpf::idpf_agg_kth(k0, k1, 4), 1u); +} + +TEST(IdpfAgg, Duplicates) +{ + const std::vector values{9, 9, 1, 9, 5}; + std::vector k0; + std::vector k1; + split_keys(values, k0, k1); + EXPECT_EQ(dpf::idpf_agg_max(k0, k1), 9u); + EXPECT_EQ(dpf::idpf_agg_kth(k0, k1, 2), 9u); + EXPECT_EQ(dpf::idpf_agg_kth(k0, k1, 4), 5u); +} + +// Seam: max equals kth(k=1); both agree with a plaintext sort. +TEST(IdpfAgg, MaxEqualsKthOne) +{ + const std::vector values{4, 90, 4, 15}; + std::vector k0; + std::vector k1; + split_keys(values, k0, k1); + EXPECT_EQ(dpf::idpf_agg_max(k0, k1), dpf::idpf_agg_kth(k0, k1, 1)); +} diff --git a/test/tests/iknp_party_test.cpp b/test/tests/iknp_party_test.cpp new file mode 100644 index 0000000..71c7775 --- /dev/null +++ b/test/tests/iknp_party_test.cpp @@ -0,0 +1,497 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/iknp.hpp" +#include "dpf/prg_aes_ccr.hpp" +#include "flow_util.hpp" +#include "iknp_deal.hpp" + +namespace +{ + +using dpf::net::role; +using dpf::net::trio; + +template +void run_pair(Fn0 && fn0, Fn1 && fn1) +{ + const auto dir = std::filesystem::temp_directory_path() + / ("libdpf_iknp_" + std::to_string(::getpid())); + std::filesystem::create_directories(dir); + std::exception_ptr ep0; + std::exception_ptr ep1; + std::thread t0([&] { + try + { + auto net = trio::connect_pair(role::p0, dir.string()); + fn0(net); + } + catch (...) + { + ep0 = std::current_exception(); + } + }); + std::thread t1([&] { + try + { + auto net = trio::connect_pair(role::p1, dir.string()); + fn1(net); + } + catch (...) + { + ep1 = std::current_exception(); + } + }); + t0.join(); + t1.join(); + std::filesystem::remove_all(dir); + if (ep0) + std::rethrow_exception(ep0); + if (ep1) + std::rethrow_exception(ep1); +} + +simde__m128i xor_block(simde__m128i a, simde__m128i b) +{ + return simde_mm_xor_si128(a, b); +} + +TEST(iknp, pads_match_dealer_relations) +{ + constexpr std::size_t nblock = 4; + constexpr std::size_t nbit = 5; + constexpr std::size_t nb2a = 3; + constexpr std::size_t ncw = 2; + dpf::iknp::material m0, m1; + run_pair( + [&](trio & net) { + m0 = dpf::iknp::sample(net.to(role::p1), 0, nblock, nbit, nb2a, ncw); + }, + [&](trio & net) { + m1 = dpf::iknp::sample(net.to(role::p0), 1, nblock, nbit, nb2a, ncw); + }); + ASSERT_EQ(m0.blocks.size(), nblock); + ASSERT_EQ(m1.blocks.size(), nblock); + for (std::size_t i = 0; i < nblock; ++i) + { + const auto a = static_cast(m0.blocks[i].a ^ m1.blocks[i].a); + const auto b = xor_block(m0.blocks[i].b, m1.blocks[i].b); + const auto c = xor_block(m0.blocks[i].c, m1.blocks[i].c); + const auto expect = (a & 1u) ? b : simde_mm_setzero_si128(); + EXPECT_EQ(std::memcmp(&c, &expect, sizeof(c)), 0); + } + for (std::size_t i = 0; i < nbit; ++i) + { + const auto a = static_cast(m0.bits[i].a ^ m1.bits[i].a); + const auto b = static_cast(m0.bits[i].b ^ m1.bits[i].b); + const auto c = static_cast(m0.bits[i].c ^ m1.bits[i].c); + EXPECT_EQ(c, static_cast((a & b) & 1u)); + } + for (std::size_t i = 0; i < nb2a; ++i) + { + const auto bit = static_cast(m0.b2a[i].r ^ m1.b2a[i].r); + EXPECT_EQ(m0.b2a[i].add + m1.b2a[i].add, bit); + } + // gamma0 ⊕ gamma1 = (bit1·rand0) ⊕ (bit0·rand1) (XOR shares; neither + // party learns the peer pad bit). + for (std::size_t i = 0; i < ncw; ++i) + { + const auto prod = xor_block( + (m1.cws[i].bit & 1u) ? m0.cws[i].rand : simde_mm_setzero_si128(), + (m0.cws[i].bit & 1u) ? m1.cws[i].rand : simde_mm_setzero_si128()); + const auto got = xor_block(m0.cws[i].gamma, m1.cws[i].gamma); + EXPECT_EQ(std::memcmp(&got, &prod, sizeof(prod)), 0); + } +} + +template +void expect_point(Point alpha, Point x0, Point x1, std::uint64_t beta, bool additive) +{ + using namespace dpf::party; + run_pair( + [&](trio & net) { + dist_with_point_key_iknp( + net, role::p0, x0, x1, beta, + [&](const auto & key) { + const auto y = util::share_bits(*dpf::eval_point(key, alpha)); + const auto open = util::open_subtractive(net, role::p0, y); + EXPECT_EQ(open, beta); + const Point other = static_cast( + static_cast(alpha) ^ 1u); + const auto z = util::share_bits(*dpf::eval_point(key, other)); + const auto oz = util::open_subtractive(net, role::p0, z); + EXPECT_EQ(oz, 0u); + }, + [](const auto &) {}, false, additive); + EXPECT_TRUE(net.dealer_inbox_done()); + }, + [&](trio & net) { + dist_with_point_key_iknp( + net, role::p1, x0, x1, beta, + [](const auto &) {}, + [&](const auto & key) { + const auto y = util::share_bits(*dpf::eval_point(key, alpha)); + (void)util::open_subtractive(net, role::p1, y); + const Point other = static_cast( + static_cast(alpha) ^ 1u); + const auto z = util::share_bits(*dpf::eval_point(key, other)); + (void)util::open_subtractive(net, role::p1, z); + }, false, additive); + EXPECT_TRUE(net.dealer_inbox_done()); + }); +} + +TEST(iknp, point_reveal) +{ + const std::uint8_t alpha = 0x2a; + expect_point(alpha, 0x10, static_cast(alpha ^ 0x10), + 7, false); +} + +TEST(iknp, point_additive) +{ + const std::uint8_t alpha = 0x2a; + const std::uint8_t x0 = 0x10; + const std::uint8_t x1 = static_cast(alpha - x0); + expect_point(alpha, x0, x1, 11, true); +} + +TEST(iknp, half_tree_reveal) +{ + using namespace dpf::party; + using Ht = dpf::prg::aes128_ccr; + const std::uint8_t alpha = 7; + const std::uint8_t x0 = 0x25; + const std::uint8_t x1 = static_cast(alpha ^ x0); + const std::uint64_t beta = 9; + run_pair( + [&](trio & net) { + dist_with_point_key_iknp(net, role::p0, x0, x1, beta, + [&](const auto & key) { + const auto open = util::open_subtractive(net, role::p0, + util::share_bits(*dpf::eval_point(key, alpha))); + EXPECT_EQ(open, beta); + }, + [](const auto &) {}); + EXPECT_TRUE(net.dealer_inbox_done()); + }, + [&](trio & net) { + dist_with_point_key_iknp(net, role::p1, x0, x1, beta, + [](const auto &) {}, + [&](const auto & key) { + (void)util::open_subtractive(net, role::p1, + util::share_bits(*dpf::eval_point(key, alpha))); + }); + EXPECT_TRUE(net.dealer_inbox_done()); + }); +} + +TEST(iknp, comparison_reveal_and_oblivious) +{ + using namespace dpf::party; + const std::uint8_t alpha = 0x40; + const std::uint8_t x0 = 0x14; + const std::uint8_t x1 = static_cast(alpha ^ x0); + const std::uint64_t beta = 9; + auto check = [&](bool reveal) { + run_pair( + [&](trio & net) { + auto on = [&](const auto & key) { + const auto mask = key.cmp().mask; + const auto below = util::open_additive(net, role::p0, + util::share_bits(dpf::eval_point(dpf::cmp, key, + static_cast(alpha - 1)))) & mask; + const auto at = util::open_additive(net, role::p0, + util::share_bits(dpf::eval_point(dpf::cmp, key, alpha))) + & mask; + EXPECT_EQ(below, beta); + EXPECT_EQ(at, 0u); + }; + if (reveal) + dist_with_cmp_key_iknp( + net, role::p0, x0, x1, dpf::lt(beta), on, [](const auto &) {}); + else + dist_with_cmp_key_iknp(net, role::p0, x0, x1, dpf::lt(beta), + on, [](const auto &) {}); + EXPECT_TRUE(net.dealer_inbox_done()); + }, + [&](trio & net) { + auto on = [&](const auto & key) { + const auto mask = key.cmp().mask; + (void)(util::open_additive(net, role::p1, + util::share_bits(dpf::eval_point(dpf::cmp, key, + static_cast(alpha - 1)))) & mask); + (void)(util::open_additive(net, role::p1, + util::share_bits(dpf::eval_point(dpf::cmp, key, alpha))) + & mask); + }; + if (reveal) + dist_with_cmp_key_iknp( + net, role::p1, x0, x1, dpf::lt(beta), [](const auto &) {}, on); + else + dist_with_cmp_key_iknp(net, role::p1, x0, x1, dpf::lt(beta), + [](const auto &) {}, on); + EXPECT_TRUE(net.dealer_inbox_done()); + }); + }; + check(true); + check(false); +} + +TEST(iknp, interval_shared_and_reveal) +{ + using namespace dpf::party; + const std::uint8_t r = 40, p = 7, q = 90; + const std::uint8_t r0 = 0x13; + const std::uint8_t r1 = static_cast(r ^ r0); + const std::uint32_t if_true = 11, if_false = 2; + auto check = [&](bool reveal) { + run_pair( + [&](trio & net) { + auto on = [&](const auto & key) { + const auto gmask = key.group_mask; + const auto nmask = key.input_mask; + for (unsigned x : {0u, 7u, 40u, 90u, 200u}) + { + const auto mine = util::share_bits( + dpf::eval_point(dpf::ic, key, static_cast(x))); + const auto peer = net.exchange_with(role::p1, mine); + const auto w = (x - static_cast(r)) & nmask; + const bool inside = w >= p && w <= q; + const auto want = (inside ? if_true : if_false) & gmask; + EXPECT_EQ((mine + peer) & gmask, want); + } + }; + if (reveal) + dist_with_ic_key_iknp( + net, role::p0, r0, r1, dpf::ic(p, q, if_true, if_false), + on, [](const auto &) {}); + else + dist_with_ic_key_iknp(net, role::p0, r0, r1, + dpf::ic(p, q, if_true, if_false), on, [](const auto &) {}); + EXPECT_TRUE(net.dealer_inbox_done()); + }, + [&](trio & net) { + auto on = [&](const auto & key) { + for (unsigned x : {0u, 7u, 40u, 90u, 200u}) + { + const auto mine = util::share_bits( + dpf::eval_point(dpf::ic, key, static_cast(x))); + (void)net.exchange_with(role::p0, mine); + } + }; + if (reveal) + dist_with_ic_key_iknp( + net, role::p1, r0, r1, dpf::ic(p, q, if_true, if_false), + [](const auto &) {}, on); + else + dist_with_ic_key_iknp(net, role::p1, r0, r1, + dpf::ic(p, q, if_true, if_false), [](const auto &) {}, on); + EXPECT_TRUE(net.dealer_inbox_done()); + }); + }; + check(false); + check(true); +} + +template +void assign_wildcard(Key & key, Share my_share, trio & net, role self) +{ + const role peer = self == role::p0 ? role::p1 : role::p0; + auto & wrap = std::get<0>(key.leaf_nodes); + if (wrap.is_ready()) + wrap.begin_update(); + auto blinded = wrap.compute_and_get_blinded_output_share(my_share); + auto peer_blinded = net.exchange_with(peer, blinded); + auto leaf = wrap.compute_and_get_leaf_share(peer_blinded); + auto peer_leaf = net.exchange_with(peer, leaf); + wrap.reconstruct_correction_word(peer_leaf); +} + +TEST(iknp, wildcard_assign) +{ + using namespace dpf::party::util; + const std::uint8_t alpha = 0xAA; + const std::uint8_t x0 = 0x31; + const std::uint8_t x1 = static_cast(alpha ^ x0); + const std::uint32_t y = 0xAAAAAAAAu; + const std::uint32_t y0 = 0x12345678u; + const std::uint32_t y1 = y - y0; + using out_t = dpf::wildcard_value; + run_pair( + [&](trio & net) { + dpf::party::dist_with_point_key_iknp(net, role::p0, x0, x1, out_t{}, + [&](auto key) { + assign_wildcard(key, y0, net, role::p0); + const auto on = open_subtractive(net, role::p0, + share_bits(*dpf::eval_point(key, alpha))); + const auto off = open_subtractive(net, role::p0, + share_bits(*dpf::eval_point(key, + static_cast(alpha ^ 1u)))); + EXPECT_EQ(on, y); + EXPECT_EQ(off, 0u); + }, + [](auto) {}); + EXPECT_TRUE(net.dealer_inbox_done()); + }, + [&](trio & net) { + dpf::party::dist_with_point_key_iknp(net, role::p1, x0, x1, out_t{}, + [](auto) {}, + [&](auto key) { + assign_wildcard(key, y1, net, role::p1); + (void)open_subtractive(net, role::p1, + share_bits(*dpf::eval_point(key, alpha))); + (void)open_subtractive(net, role::p1, + share_bits(*dpf::eval_point(key, + static_cast(alpha ^ 1u)))); + }); + EXPECT_TRUE(net.dealer_inbox_done()); + }); +} + +TEST(iknp, extractable_sketch) +{ + const std::uint8_t alpha = 0x2a; + const std::uint8_t x0 = 0x10; + const std::uint8_t x1 = static_cast(alpha ^ x0); + const dpf::fp61 beta{7}; + run_pair( + [&](trio & net) { + dpf::party::dist_with_extractable_point_key_iknp( + net, role::p0, x0, x1, beta, + [&](const auto & key) { + const std::array rs{dpf::fp61{3}}; + dpf::sketch_share local{}; + auto sk = dpf::sketch(local, rs); + (void)*dpf::eval_point(key, alpha, sk); + auto theirs = net.exchange_with(role::p1, local, + dpf::net::msg::sketch_share); + EXPECT_TRUE(dpf::sketch_verify(local, theirs)); + }, + [](const auto &) {}); + EXPECT_TRUE(net.dealer_inbox_done()); + }, + [&](trio & net) { + dpf::party::dist_with_extractable_point_key_iknp( + net, role::p1, x0, x1, beta, + [](const auto &) {}, + [&](const auto & key) { + const std::array rs{dpf::fp61{3}}; + dpf::sketch_share local{}; + auto sk = dpf::sketch(local, rs); + (void)*dpf::eval_point(key, alpha, sk); + auto theirs = net.exchange_with(role::p0, local, + dpf::net::msg::sketch_share); + EXPECT_TRUE(dpf::sketch_verify(theirs, local)); + }); + EXPECT_TRUE(net.dealer_inbox_done()); + }); +} + +TEST(iknp, oblivious_point_hash) +{ + using namespace dpf::party; + // Default (non-reveal) point keygen hashes the shared prefix, so this + // exercises the per-level AND tape as well as the correction words. + const std::uint8_t alpha = 0x2a; + const std::uint8_t x0 = 0x10; + const std::uint8_t x1 = static_cast(alpha ^ x0); + const std::uint64_t beta = 4; + run_pair( + [&](trio & net) { + dist_with_point_key_iknp(net, role::p0, x0, x1, beta, + [&](const auto & key) { + const auto on = util::open_subtractive(net, role::p0, + util::share_bits(*dpf::eval_point(key, alpha))); + const auto off = util::open_subtractive(net, role::p0, + util::share_bits(*dpf::eval_point(key, + static_cast(alpha ^ 1u)))); + EXPECT_EQ(on, beta); + EXPECT_EQ(off, 0u); + }, + [](const auto &) {}); + EXPECT_TRUE(net.dealer_inbox_done()); + }, + [&](trio & net) { + dist_with_point_key_iknp(net, role::p1, x0, x1, beta, + [](const auto &) {}, + [&](const auto & key) { + (void)util::open_subtractive(net, role::p1, + util::share_bits(*dpf::eval_point(key, alpha))); + (void)util::open_subtractive(net, role::p1, + util::share_bits(*dpf::eval_point(key, + static_cast(alpha ^ 1u)))); + }); + EXPECT_TRUE(net.dealer_inbox_done()); + }); +} + +TEST(iknp, transfer_labels_follows_choice_and_reuses_base) +{ + constexpr std::size_t n = 7; + std::vector m0(n), m1(n); + std::vector choices(n); + for (std::size_t i = 0; i < n; ++i) + { + m0[i] = dpf::uniform_sample(); + m1[i] = dpf::uniform_sample(); + choices[i] = static_cast(i & 1u); + } + std::vector again0(2), again1(2); + again0[0] = dpf::uniform_sample(); + again0[1] = dpf::uniform_sample(); + again1[0] = dpf::uniform_sample(); + again1[1] = dpf::uniform_sample(); + const std::uint8_t again_choice[2] = {1, 0}; + + std::vector got, got2; + run_pair( + [&](trio & net) { + dpf::iknp::detail::role_state st; + std::vector unused; + dpf::iknp::transfer_labels(net.to(role::p1), 0, true, st, m0, m1, + {}, unused); + EXPECT_TRUE(unused.empty()); + std::vector empty_out; + dpf::iknp::transfer_labels(net.to(role::p1), 0, true, st, {}, {}, + {}, empty_out); + dpf::iknp::transfer_labels(net.to(role::p1), 0, true, st, again0, + again1, {}, unused); + }, + [&](trio & net) { + dpf::iknp::detail::role_state st; + dpf::iknp::transfer_labels(net.to(role::p0), 1, false, st, {}, {}, + choices, got); + std::vector none; + std::vector empty_out; + dpf::iknp::transfer_labels(net.to(role::p0), 1, false, st, {}, {}, + none, empty_out); + EXPECT_TRUE(empty_out.empty()); + dpf::iknp::transfer_labels(net.to(role::p0), 1, false, st, {}, {}, + std::vector(again_choice, again_choice + 2), got2); + }); + + ASSERT_EQ(got.size(), n); + for (std::size_t i = 0; i < n; ++i) + { + const auto & expect = choices[i] ? m1[i] : m0[i]; + EXPECT_EQ(std::memcmp(&got[i], &expect, sizeof(expect)), 0) << i; + } + ASSERT_EQ(got2.size(), 2u); + EXPECT_EQ(std::memcmp(&got2[0], &again1[0], sizeof(again1[0])), 0); + EXPECT_EQ(std::memcmp(&got2[1], &again0[1], sizeof(again0[1])), 0); +} + +} // namespace diff --git a/test/tests/incremental_test.cpp b/test/tests/incremental_test.cpp index e5662db..43d6e51 100644 --- a/test/tests/incremental_test.cpp +++ b/test/tests/incremental_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "dpf.hpp" #include "grotto/fixedpoint.hpp" @@ -1895,3 +1896,315 @@ TEST_F(IncrementalDpfTest, SequenceRecipeAtPrefixSlot) } } +// --------------------------------------------------------------------------- +// Regressions for bugs found under ASan/UBSan: +// * eq(..., if_false) must absorb on every eval surface, not only point +// * path memoizer resume past a full-width cmp depth must not shift by nbits +// --------------------------------------------------------------------------- + +TEST_F(IncrementalDpfTest, EqIfFalseAbsorbsOnEveryEvalSurface) +{ + const uint8_t alpha = 5; + const uint8_t yt = 7; + const uint8_t yf = 3; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::eq(yt, yf)); + using KT = std::decay_t; + EXPECT_TRUE(KT::is_multilevel); + EXPECT_EQ(std::get<0>(k0.public_addends), yf); + constexpr auto opl = KT::template outputs_per_leaf_of<0>; + + auto expect_at = [&](uint8_t q) { + return (q == alpha) ? yt : yf; + }; + + for (unsigned q = 0; q < 8u; ++q) + { + EXPECT_EQ(recon(*dpf::eval_point(k0, uint8_t(q)), + *dpf::eval_point(k1, uint8_t(q))), + expect_at(uint8_t(q))) + << "point q=" << q; + } + + auto [f0, itf0] = dpf::eval_full(k0); + auto [f1, itf1] = dpf::eval_full(k1); + (void)itf0; + (void)itf1; + for (unsigned q = 0; q < 8u; ++q) + { + EXPECT_EQ(recon(f0[q], f1[q]), expect_at(uint8_t(q))) + << "full q=" << q; + } + + // Leaf-aligned interval so buffer index == lane. + constexpr uint8_t from = 0; + constexpr uint8_t to = 15; // one full packing leaf when opl==16 + auto [iv0, ii0] = dpf::eval_interval(dpf::out<0>, k0, from, to); + auto [iv1, ii1] = dpf::eval_interval(dpf::out<0>, k1, from, to); + (void)ii0; + (void)ii1; + ASSERT_EQ(iv0.size(), static_cast(to - from + 1)); + for (unsigned q = from; q <= to; ++q) + { + const uint8_t want = (q < 8u) ? expect_at(uint8_t(q)) : yf; + EXPECT_EQ(recon(iv0[q - from], iv1[q - from]), want) + << "interval q=" << q; + } + + std::array pts{{7, 0, 5, 2, 1, 6, 3, 4}}; + auto s0 = dpf::make_output_buffer_for(k0, pts.size()); + auto s1 = dpf::make_output_buffer_for(k1, pts.size()); + dpf::eval_sequence(dpf::out<0>, k0, pts.begin(), pts.end(), s0); + dpf::eval_sequence(dpf::out<0>, k1, pts.begin(), pts.end(), s1); + for (std::size_t i = 0; i < pts.size(); ++i) + { + auto e0 = dpf::eval_point(dpf::out<0>, k0, pts[i]); + auto e1 = dpf::eval_point(dpf::out<0>, k1, pts[i]); + EXPECT_EQ(recon(s0[i * opl + e0.offset], s1[i * opl + e1.offset]), + expect_at(pts[i])) + << "sequence i=" << i; + } + + std::array sorted{{0, 1, 2, 3, 4, 5, 6, 7}}; + auto b0 = dpf::eval_sequence_breadth_first(dpf::out<0>, k0, sorted.begin(), + sorted.end()); + auto b1 = dpf::eval_sequence_breadth_first(dpf::out<0>, k1, sorted.begin(), + sorted.end()); + for (std::size_t i = 0; i < sorted.size(); ++i) + { + EXPECT_EQ(recon(b0[i], b1[i]), expect_at(sorted[i])) + << "breadth i=" << i; + } + + // Weights must cover every packing lane the interval exterior materialises. + std::vector w(iv0.size(), 1); + uint64_t expect_ip = 0; + for (std::size_t i = 0; i < iv0.size(); ++i) + expect_ip += static_cast(recon(iv0[i], iv1[i])) * w[i]; + const auto ip0 = dpf::eval_inner_product(dpf::out<0>, k0, from, to, w); + const auto ip1 = dpf::eval_inner_product(dpf::out<0>, k1, from, to, w); + EXPECT_EQ(static_cast(recon(ip0, ip1)), + static_cast(expect_ip)); +} + +TEST_F(IncrementalDpfTest, EqAtIfFalseWithPackedIntervalAndXor) +{ + const uint32_t alpha = 0x00c0ffeeu; + auto [k0, k1] = dpf::make_dpf(alpha, + dpf::eq_at<16>(uint16_t{99}, uint16_t{7}), + dpf::eq(dpf::xor_wrapper{0x00ff00ffu}, + dpf::xor_wrapper{0x00001111u})); + using KT = std::decay_t; + constexpr auto opl = KT::template outputs_per_leaf_of<0>; + + const uint16_t lane = static_cast(alpha >> 16); + // Align to a packing leaf so buffer index math is exact. + const uint16_t from = static_cast(lane & ~(opl - 1u)); + const uint16_t to = static_cast(from + opl - 1u); + auto [buf0, iit0] = dpf::eval_interval(dpf::out<0, 16>, k0, from, to); + auto [buf1, iit1] = dpf::eval_interval(dpf::out<0, 16>, k1, from, to); + (void)iit0; + (void)iit1; + for (uint16_t q = from; q <= to; ++q) + { + const std::size_t idx = static_cast(q - from); + const uint16_t want = (q == lane) ? uint16_t{99} : uint16_t{7}; + EXPECT_EQ(recon(buf0[idx], buf1[idx]), want) << "eq_at lane=" << q; + const uint32_t full = static_cast(q) << 16; + EXPECT_EQ(recon(*dpf::eval_point(dpf::out<0, 16>, k0, full), + *dpf::eval_point(dpf::out<0, 16>, k1, full)), + want); + } + + // Spot-check the full-width xor_wrapper eq (avoid 2^32 full-domain walk). + const auto on = dpf::xor_wrapper{0x00ff00ffu}; + const auto off = dpf::xor_wrapper{0x00001111u}; + EXPECT_EQ(recon(*dpf::eval_point(dpf::out<1>, k0, alpha), + *dpf::eval_point(dpf::out<1>, k1, alpha)), + on); + EXPECT_EQ(recon(*dpf::eval_point(dpf::out<1>, k0, alpha ^ 1u), + *dpf::eval_point(dpf::out<1>, k1, alpha ^ 1u)), + off); + EXPECT_EQ(recon(*dpf::eval_point(dpf::out<1>, k0, 0u), + *dpf::eval_point(dpf::out<1>, k1, 0u)), + off); + // Leaf-aligned interval around α for the xor slot. + using KT1 = std::decay_t; + constexpr auto opl1 = KT1::template outputs_per_leaf_of<1>; + const uint32_t xfrom = alpha & ~(opl1 - 1u); + const uint32_t xto = xfrom + static_cast(opl1 - 1u); + auto [xf0, xi0] = dpf::eval_interval(dpf::out<1>, k0, xfrom, xto); + auto [xf1, xi1] = dpf::eval_interval(dpf::out<1>, k1, xfrom, xto); + (void)xi0; + (void)xi1; + for (uint32_t q = xfrom; q <= xto; ++q) + { + const auto want = (q == alpha) ? on : off; + EXPECT_EQ(recon(xf0[q - xfrom], xf1[q - xfrom]), want) << "xor q=" << q; + } +} + +TEST_F(IncrementalDpfTest, EqIfFalseDealerMatchesDoernerShelatSurfaces) +{ + const uint8_t alpha = 0x2au; + const uint8_t x0s = 0x11u; + const uint8_t x1s = static_cast(alpha ^ x0s); + auto dealer = dpf::make_dpf(alpha, dpf::eq(uint8_t{9}, uint8_t{4})); + auto ds = dpf::make_dpf_doerner_shelat(x0s, x1s, + dpf::eq(uint8_t{9}, uint8_t{4})); + + for (unsigned q = 0; q < 256u; q += 17u) + { + const uint8_t qq = static_cast(q); + EXPECT_EQ(recon(*dpf::eval_point(dealer.first, qq), + *dpf::eval_point(dealer.second, qq)), + recon(*dpf::eval_point(ds.first, qq), + *dpf::eval_point(ds.second, qq))); + } + auto [fa0, ia0] = dpf::eval_full(dealer.first); + auto [fa1, ia1] = dpf::eval_full(dealer.second); + auto [fb0, ib0] = dpf::eval_full(ds.first); + auto [fb1, ib1] = dpf::eval_full(ds.second); + (void)ia0; + (void)ia1; + (void)ib0; + (void)ib1; + for (unsigned q = 0; q < 256u; q += 17u) + EXPECT_EQ(recon(fa0[q], fa1[q]), recon(fb0[q], fb1[q])); +} + +TEST_F(IncrementalDpfTest, PathMemoizerResumePastFullWidthCmpDepth) +{ + const uint32_t alpha = 0x00abcdefu; + auto [k0, k1] = dpf::make_dpf(alpha, uint32_t{7}, dpf::lt(uint64_t{3})); + auto path0 = dpf::make_basic_path_memoizer(k0); + auto path1 = dpf::make_basic_path_memoizer(k1); + + const uint64_t mask = k0.cmp().mask; + EXPECT_EQ(dpf::reconstruct(dpf::eval_point(dpf::cmp, k0, alpha, path0), + dpf::eval_point(dpf::cmp, k1, alpha, path1)) + & mask, + 0u); + EXPECT_EQ(dpf::reconstruct( + dpf::eval_point(dpf::cmp, k0, alpha - 1u, path0), + dpf::eval_point(dpf::cmp, k1, alpha - 1u, path1)) + & mask, + 3u); + + EXPECT_EQ(recon(*dpf::eval_point(k0, alpha, path0), + *dpf::eval_point(k1, alpha, path1)), + 7u); + EXPECT_EQ(recon(*dpf::eval_point(k0, alpha ^ 1u, path0), + *dpf::eval_point(k1, alpha ^ 1u, path1)), + 0u); + + auto p0 = dpf::make_basic_path_memoizer(k0); + auto p1 = dpf::make_basic_path_memoizer(k1); + EXPECT_EQ(recon(*dpf::eval_point(k0, alpha, p0), + *dpf::eval_point(k1, alpha, p1)), + 7u); + EXPECT_EQ(dpf::reconstruct(dpf::eval_point(dpf::cmp, k0, alpha, p0), + dpf::eval_point(dpf::cmp, k1, alpha, p1)) + & mask, + 0u); + EXPECT_EQ(recon(*dpf::eval_point(k0, alpha ^ 2u, p0), + *dpf::eval_point(k1, alpha ^ 2u, p1)), + 0u); +} + +TEST_F(IncrementalDpfTest, PathMemoizerResumeCmpOnlyFullWidth) +{ + const uint32_t alpha = 0x80000001u; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::geq(uint64_t{5}, uint64_t{1})); + auto path0 = dpf::make_basic_path_memoizer(k0); + auto path1 = dpf::make_basic_path_memoizer(k1); + const uint64_t mask = k0.cmp().mask; + auto rq = [&](uint32_t q) { + return dpf::reconstruct(dpf::eval_point(dpf::cmp, k0, q, path0), + dpf::eval_point(dpf::cmp, k1, q, path1)) + & mask; + }; + EXPECT_EQ(rq(alpha), 5u); + EXPECT_EQ(rq(alpha), 5u); + EXPECT_EQ(rq(alpha - 1u), 1u); + EXPECT_EQ(rq(alpha + 1u), 5u); +} + +TEST_F(IncrementalDpfTest, EqMixedWithBlockedCmpSharesMemoizer) +{ + const uint8_t alpha = 0x5au; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::eq(uint8_t{11}, uint8_t{2}), + dpf::block_width<3>(dpf::lt(uint64_t{9}, uint64_t{1}))); + auto path0 = dpf::make_basic_path_memoizer(k0); + auto path1 = dpf::make_basic_path_memoizer(k1); + + EXPECT_EQ(recon(*dpf::eval_point(k0, alpha, path0), + *dpf::eval_point(k1, alpha, path1)), + 11u); + const uint64_t mask = k0.cmp().mask; + EXPECT_EQ(dpf::reconstruct( + dpf::eval_point(dpf::cmp, k0, uint8_t(alpha - 1), path0), + dpf::eval_point(dpf::cmp, k1, uint8_t(alpha - 1), path1)) + & mask, + 9u); + EXPECT_EQ(dpf::reconstruct(dpf::eval_point(dpf::cmp, k0, alpha, path0), + dpf::eval_point(dpf::cmp, k1, alpha, path1)) + & mask, + 1u); + + auto [f0, i0] = dpf::eval_full(k0); + auto [f1, i1] = dpf::eval_full(k1); + (void)i0; + (void)i1; + EXPECT_EQ(recon(f0[alpha], f1[alpha]), 11u); + EXPECT_EQ(recon(f0[uint8_t(alpha ^ 1)], f1[uint8_t(alpha ^ 1)]), 2u); +} + +TEST_F(IncrementalDpfTest, IntervalMemoizerReuseAcrossEqAndShallowAt) +{ + const uint32_t alpha = 0x00a1b2c3u; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::eq(uint32_t{8}, uint32_t{1}), + dpf::at<8>(uint8_t{42})); + using KT = std::decay_t; + constexpr auto opl0 = KT::template outputs_per_leaf_of<0>; + + const uint32_t efrom = alpha & ~(opl0 - 1u); + const uint32_t eto = efrom + static_cast(opl0 - 1u); + auto [f0, fi0] = dpf::eval_interval(dpf::out<0>, k0, efrom, eto); + auto [f1, fi1] = dpf::eval_interval(dpf::out<0>, k1, efrom, eto); + (void)fi0; + (void)fi1; + for (uint32_t q = efrom; q <= eto; ++q) + { + const uint32_t want = (q == alpha) ? 8u : 1u; + EXPECT_EQ(recon(f0[q - efrom], f1[q - efrom]), want) << "eq q=" << q; + } + + const uint8_t top = static_cast(alpha >> 24); + auto [ait0, ai0] = dpf::eval_interval(dpf::out<1, 8>, k0, uint8_t{0}, + uint8_t{255}); + auto [ait1, ai1] = dpf::eval_interval(dpf::out<1, 8>, k1, uint8_t{0}, + uint8_t{255}); + (void)ai0; + (void)ai1; + EXPECT_EQ(recon(ait0[top], ait1[top]), 42u); + EXPECT_EQ(recon(ait0[uint8_t(top ^ 1)], ait1[uint8_t(top ^ 1)]), 0u); + + // Re-walk a different eq window after the shallow interval. + const uint32_t from = alpha - 3u; + const uint32_t to = alpha + 3u; + const uint32_t afrom = from & ~(opl0 - 1u); + const uint32_t ato = (to + opl0 - 1u) & ~(opl0 - 1u); + const uint32_t ato_inclusive = ato + static_cast(opl0 - 1u); + auto [eit0, ee0] = dpf::eval_interval(dpf::out<0>, k0, afrom, + ato_inclusive); + auto [eit1, ee1] = dpf::eval_interval(dpf::out<0>, k1, afrom, + ato_inclusive); + (void)ee0; + (void)ee1; + for (uint32_t q = from; q <= to; ++q) + { + const uint32_t want = (q == alpha) ? 8u : 1u; + EXPECT_EQ(recon(eit0[q - afrom], eit1[q - afrom]), want) << "q=" << q; + } +} + diff --git a/test/tests/interleave_leaves_test.cpp b/test/tests/interleave_leaves_test.cpp new file mode 100644 index 0000000..dd10e9f --- /dev/null +++ b/test/tests/interleave_leaves_test.cpp @@ -0,0 +1,311 @@ +#include + +#include "dpf.hpp" + +#include +#include +#include +#include +#include + +namespace +{ + +template +using storage = dpf::leaf_storage_t; + +template +constexpr unsigned lane_bits() +{ + if constexpr (dpf::utils::is_packed_subbyte_v) + return static_cast(dpf::utils::packed_lane_bits_v); + else + return static_cast(sizeof(LaneT) * 8u); +} + +template +constexpr std::uint64_t lane_mask() +{ + if constexpr (dpf::utils::is_packed_subbyte_v) + return (std::uint64_t{1} << dpf::utils::packed_lane_bits_v) - 1u; + else if constexpr (sizeof(LaneT) >= 8) + return ~std::uint64_t{0}; + else + return (std::uint64_t{1} << (sizeof(LaneT) * 8u)) - 1u; +} + +template +std::uint64_t get_lane(const storage * buf, std::size_t i) +{ + if constexpr (dpf::utils::is_packed_subbyte_v) + { + constexpr unsigned w = dpf::utils::packed_lane_bits_v; + const std::size_t bit = i * w; + const std::size_t word = bit / 64u; + const unsigned shift = static_cast(bit % 64u); + std::uint64_t v = buf[word] >> shift; + if (shift + w > 64u) + v |= buf[word + 1u] << (64u - shift); + return v & lane_mask(); + } + else if constexpr (std::is_class_v) + { + return static_cast( + static_cast(buf[i])) & lane_mask(); + } + else + { + return static_cast(buf[i]) & lane_mask(); + } +} + +template +void set_lane(storage * buf, std::size_t i, std::uint64_t val) +{ + val &= lane_mask(); + if constexpr (dpf::utils::is_packed_subbyte_v) + { + constexpr unsigned w = dpf::utils::packed_lane_bits_v; + const std::size_t bit = i * w; + const std::size_t word = bit / 64u; + const unsigned shift = static_cast(bit % 64u); + const std::uint64_t mask = lane_mask(); + buf[word] = (buf[word] & ~(mask << shift)) | (val << shift); + if (shift + w > 64u) + { + const unsigned lo = 64u - shift; + buf[word + 1u] = (buf[word + 1u] & ~(mask >> lo)) | (val >> lo); + } + } + else + { + buf[i] = static_cast>(val); + } +} + +template +std::vector> make_key(std::size_t nleaves, std::size_t key_id) +{ + std::vector> v(dpf::leaf_storage_words(nleaves), + storage{0}); + for (std::size_t i = 0; i < nleaves; ++i) + { + // Distinct pattern per (key, leaf); fits every width's mask. + const std::uint64_t val + = (key_id * 131u + i * 17u + 3u) & lane_mask(); + set_lane(v.data(), i, val); + } + return v; +} + +template +void check_roundtrip(std::size_t nkeys, std::size_t nleaves) +{ + std::vector>> owned; + owned.reserve(nkeys); + std::vector *> in_ptrs; + std::vector *> out_ptrs; + in_ptrs.reserve(nkeys); + out_ptrs.reserve(nkeys); + for (std::size_t k = 0; k < nkeys; ++k) + { + owned.push_back(make_key(nleaves, k)); + in_ptrs.push_back(owned.back().data()); + } + + std::vector> interleaved( + dpf::leaf_storage_words(nkeys * nleaves), storage{0}); + dpf::interleave_leaves(interleaved.data(), in_ptrs.data(), nkeys, + nleaves); + + for (std::size_t i = 0; i < nleaves; ++i) + { + for (std::size_t k = 0; k < nkeys; ++k) + { + const std::size_t g = dpf::cohort_index(i, k, nkeys); + EXPECT_EQ(get_lane(interleaved.data(), g), + get_lane(owned[k].data(), i)) + << "LaneT bits=" << lane_bits() << " nkeys=" << nkeys + << " nleaves=" << nleaves << " i=" << i << " k=" << k; + } + } + + std::vector>> round; + round.reserve(nkeys); + for (std::size_t k = 0; k < nkeys; ++k) + { + round.emplace_back(dpf::leaf_storage_words(nleaves), + storage{0}); + out_ptrs.push_back(round.back().data()); + } + dpf::deinterleave_leaves(out_ptrs.data(), interleaved.data(), nkeys, + nleaves); + + for (std::size_t k = 0; k < nkeys; ++k) + { + for (std::size_t i = 0; i < nleaves; ++i) + { + EXPECT_EQ(get_lane(round[k].data(), i), + get_lane(owned[k].data(), i)) + << "deinterleave bits=" << lane_bits() + << " nkeys=" << nkeys << " i=" << i << " k=" << k; + } + } +} + +} // namespace + +template +class InterleaveLeavesTest : public ::testing::Test +{ +}; + +using InterleaveTypes = ::testing::Types< + std::uint64_t, + std::uint32_t, + std::uint16_t, + std::uint8_t, + dpf::nyble, + dpf::twobit, + dpf::bit, + dpf::gf2, + dpf::gf22, + dpf::gf24, + dpf::gf28, + dpf::gf216, + dpf::gf232, + dpf::gf264>; + +TYPED_TEST_SUITE(InterleaveLeavesTest, InterleaveTypes); + +TYPED_TEST(InterleaveLeavesTest, KeyCountsAndOddLength) +{ + // Length not a multiple of pack width (8 for bits-in-byte, 32 for + // 2-bit-in-u64, 16 for 4-bit-in-u64, etc.): 13 is odd for all of those. + constexpr std::size_t nleaves = 13; + for (std::size_t nkeys : {std::size_t{1}, std::size_t{3}, std::size_t{5}, + std::size_t{16}}) + check_roundtrip(nkeys, nleaves); +} + +TYPED_TEST(InterleaveLeavesTest, LongerNotMultipleOfWord) +{ + // 70 leaves: not a multiple of 64 (bit word) or 32 (twobit word). + check_roundtrip(5, 70); + check_roundtrip(8, 70); +} + +TEST(InterleaveLeaves, BitPackingIsKeyMajorWithinLeaf) +{ + // Three keys, five 1-bit leaves. Logical order of bits in the output + // stream is (i0,k0),(i0,k1),(i0,k2),(i1,k0),... — not a byte index of + // i*m+k into a uint8_t array. + constexpr std::size_t nkeys = 3; + constexpr std::size_t nleaves = 5; + std::array k0{0}, k1{0}, k2{0}; + // key0: 1 0 1 1 0 + // key1: 0 1 1 0 1 + // key2: 1 1 0 0 1 + k0[0] = 0b01101ull; + k1[0] = 0b10110ull; + k2[0] = 0b10011ull; + const std::uint64_t * keys[3] = {k0.data(), k1.data(), k2.data()}; + std::uint64_t out = 0; + dpf::interleave_leaves(&out, keys, nkeys, nleaves); + + // Expected 15 bits, low-first: for i=0..4, bits of keys 0,1,2 + // i0: 1,0,1 | i1: 0,1,1 | i2: 1,1,0 | i3: 1,0,0 | i4: 0,1,1 + // bit0..14 = 1,0,1,0,1,1,1,1,0,1,0,0,0,1,1 + const std::uint64_t expect = 0b110001011110101ull; + EXPECT_EQ(out & ((1ull << 15) - 1ull), expect); +} + +TEST(InterleaveLeaves, InnerProductModintFromBits) +{ + // Same three keys as above. Leaf integers (key 0 in the low bit): + // i0 = 0b101 = 5, i1 = 0b110 = 6, i2 = 0b011 = 3, i3 = 0b001 = 1, i4 = 0b110 = 6. + constexpr std::size_t nkeys = 3; + constexpr std::size_t nleaves = 5; + std::array k0{0b01101ull}, k1{0b10110ull}, k2{0b10011ull}; + const std::uint64_t * keys[3] = {k0.data(), k1.data(), k2.data()}; + std::uint64_t bits = 0; + dpf::interleave_leaves(&bits, keys, nkeys, nleaves); + + const std::uint64_t w[5] = {1, 2, 3, 4, 5}; + const auto got = dpf::interleaved_bits_inner_product<3>(&bits, nleaves, nkeys, w); + // 5*1 + 6*2 + 3*3 + 1*4 + 6*5 = 5+12+9+4+30 = 60 ≡ 60-7*8 = 4 (mod 8) + EXPECT_EQ(static_cast(static_cast::integral_type>(got)), 4u); + + std::array, 5> mw{1, 2, 3, 4, 5}; + const auto got_m = dpf::interleaved_bits_inner_product<3>(&bits, nleaves, nkeys, mw); + EXPECT_EQ(static_cast(static_cast::integral_type>(got_m)), 4u); +} + +TEST(InterleaveLeaves, InnerProductModint128) +{ + constexpr std::size_t nkeys = 128; + constexpr std::size_t nleaves = 3; + std::vector key_bits(nkeys * 2, 0); + std::vector ptrs(nkeys); + for (std::size_t k = 0; k < nkeys; ++k) + { + // Leaf 0: bit k set. Leaf 1: only key 0. Leaf 2: zero. + if (k == 0) + key_bits[k * 2] = 0b011ull; + else + key_bits[k * 2] = 0b001ull; + ptrs[k] = key_bits.data() + k * 2; + } + std::vector bits(dpf::leaf_storage_words(nkeys * nleaves)); + dpf::interleave_leaves(bits.data(), ptrs.data(), nkeys, nleaves); + + const std::uint64_t w[3] = {1, 3, 9}; + const auto got = dpf::interleaved_bits_inner_product<128>( + bits.data(), nleaves, nkeys, w); + using limb = dpf::modint<128>::integral_type; + const limb all = ~limb{0}; + const limb expect = all * limb{1} + limb{1} * limb{3}; + EXPECT_EQ(static_cast(got), expect); +} + +TEST(InterleaveLeaves, InnerProductLowBitsOfWideGroup) +{ + // Eight 1-bit keys, read as modint<4>: only keys 0..3. + constexpr std::size_t nkeys = 8; + constexpr std::size_t nleaves = 2; + std::array raw{}; + const std::uint64_t * ptrs[8]; + for (std::size_t k = 0; k < nkeys; ++k) + { + raw[k] = (k < 4) ? 0b11ull : 0b01ull; // both leaves set for low keys + ptrs[k] = &raw[k]; + } + std::uint64_t bits[4]{}; + dpf::interleave_leaves(bits, ptrs, nkeys, nleaves); + const std::uint64_t w[2] = {1, 1}; + const auto got = dpf::interleaved_bits_inner_product<4>(bits, nleaves, nkeys, w); + // Each leaf's low 4 bits are 0b1111 = 15. 15+15 = 30 ≡ 14 (mod 16). + EXPECT_EQ(static_cast(static_cast::integral_type>(got)), 14u); +} + +TYPED_TEST(InterleaveLeavesTest, EmptyAndSingleLeaf) +{ + check_roundtrip(0, 0); + check_roundtrip(3, 0); + check_roundtrip(0, 5); + check_roundtrip(1, 1); + check_roundtrip(4, 1); +} + +TEST(InterleaveLeaves, InnerProductEmptyIsZero) +{ + const std::uint64_t w[1] = {9}; + EXPECT_EQ(static_cast(static_cast::integral_type>( + dpf::interleaved_bits_inner_product<3>( + static_cast(nullptr), 0, 3, w))), + 0u); + std::uint64_t bits = 0; + EXPECT_EQ(static_cast(static_cast::integral_type>( + dpf::interleaved_bits_inner_product<3>(&bits, 5, 0, w))), + 0u); +} diff --git a/test/tests/it_dpf3_test.cpp b/test/tests/it_dpf3_test.cpp new file mode 100644 index 0000000..2c1619a --- /dev/null +++ b/test/tests/it_dpf3_test.cpp @@ -0,0 +1,68 @@ +#include + +#include +#include +#include + +#include "dpf.hpp" + +TEST(ItDpf3, OnPointAndOffPoint) +{ + constexpr std::uint8_t alpha = 42; + constexpr std::uint64_t beta = 7; + auto [k0, k1, k2] = dpf::make_it_dpf3(alpha, beta); + + EXPECT_FALSE((std::is_same_v(dpf::make_dpf3(alpha, dpf::fp61{1})))>)); + + const auto on = dpf::eval_it_dpf3(k0, alpha) + dpf::eval_it_dpf3(k1, alpha) + + dpf::eval_it_dpf3(k2, alpha); + EXPECT_EQ(on, beta); + + const auto off = dpf::eval_it_dpf3(k0, std::uint8_t{41}) + + dpf::eval_it_dpf3(k1, std::uint8_t{41}) + + dpf::eval_it_dpf3(k2, std::uint8_t{41}); + EXPECT_EQ(off, 0u); +} + +TEST(ItDpf3, InnerProductIsTableEntry) +{ + constexpr std::uint8_t index = 17; + std::vector table(256); + for (std::size_t i = 0; i < table.size(); ++i) + table[i] = i * i + 3; + + auto [k0, k1, k2] = dpf::make_it_dpf3(index, 1); + const auto s0 = dpf::eval_it_dpf3_inner_product(k0, table); + const auto s1 = dpf::eval_it_dpf3_inner_product(k1, table); + const auto s2 = dpf::eval_it_dpf3_inner_product(k2, table); + EXPECT_EQ(s0 + s1 + s2, table[index]); +} + +// Seam: same PIR shape as make_dpf3 + shamir reconstruct, different key type +// and three-way sum instead of any-two Lagrange. +TEST(ItDpf3, PirDotDistinctFromShamirDpf3) +{ + constexpr std::uint8_t index = 42; + std::vector table(256); + for (std::size_t i = 0; i < table.size(); ++i) + table[i] = i + 1; + + auto [i0, i1, i2] = dpf::make_it_dpf3(index, 1); + const auto it_opened = + dpf::eval_it_dpf3_inner_product(i0, table) + + dpf::eval_it_dpf3_inner_product(i1, table) + + dpf::eval_it_dpf3_inner_product(i2, table); + EXPECT_EQ(it_opened, table[index]); + + std::vector ftable(256); + for (std::size_t i = 0; i < ftable.size(); ++i) + ftable[i] = dpf::fp61{static_cast(i + 1)}; + auto [d1, d2, d3] = dpf::make_dpf3(index, dpf::fp61{1}); + const auto s1 = dpf::eval_full_inner_product(d1, ftable); + const auto s2 = dpf::eval_full_inner_product(d2, ftable); + const auto opened = dpf::shamir3::reconstruct( + dpf::as_share(d1, s1), dpf::as_share(d2, s2)); + EXPECT_EQ(opened.raw(), table[index]); + EXPECT_FALSE((std::is_same_v)); +} diff --git a/test/tests/keyword2_test.cpp b/test/tests/keyword2_test.cpp index 1636839..da88b1a 100644 --- a/test/tests/keyword2_test.cpp +++ b/test/tests/keyword2_test.cpp @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/test/tests/lane_blast_test.cpp b/test/tests/lane_blast_test.cpp index c73b5d9..60b546f 100644 --- a/test/tests/lane_blast_test.cpp +++ b/test/tests/lane_blast_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "dpf.hpp" @@ -164,8 +165,8 @@ void expect_interval(In alpha, Lane y, In from, In to) EXPECT_EQ(p1, std::end(b.second)); } -template -void expect_live_words(const Key & key, const auto & g) +template +void expect_live_words(const Key & key, const GenevalResult & g) { ASSERT_LE(g.live_levels, g.correction_words.size()); for (std::size_t i = 0; i < g.live_levels; ++i) @@ -326,8 +327,7 @@ TEST(LaneBlast, Uint8TwobitEveryInputAndEveryShape) EXPECT_EQ(f0, std::end(fi0)); const in_t unsorted[] = {255, 40, 0}; - EXPECT_THROW(dpf::make_sequence_recipe(k0, std::begin(unsorted), std::end(unsorted)), - std::runtime_error); + EXPECT_THROW(dpf::make_sequence_recipe(k0, std::begin(unsorted), std::end(unsorted)), std::runtime_error); const in_t seq[] = {0, 40, 40, 41, 104, 255}; auto recipe = dpf::make_sequence_recipe(k0, std::begin(seq), std::end(seq)); auto s0 = dpf::eval_sequence(k0, recipe); diff --git a/test/tests/leaf_later_test.cpp b/test/tests/leaf_later_test.cpp new file mode 100644 index 0000000..88b3f8a --- /dev/null +++ b/test/tests/leaf_later_test.cpp @@ -0,0 +1,149 @@ +#include + +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +// Full-block payload ⇒ outputs_per_leaf = 1, so a single public F matches the +// leaf correction word share-for-share. +using input_t = std::uint8_t; +using output_t = simde_uint128; +constexpr std::size_t n = 256; + +output_t leaf_cw_as_output(const dpf::utils::dpf_type_t & key) +{ + using exterior = typename std::decay_t::exterior_node; + return dpf::extract_leaf(key.template leaf<0>(), 0); +} + +// party_key wrappers from make_dpf +template +output_t leaf_cw_as_output(const Key & key) +{ + using exterior = typename Key::exterior_node; + return dpf::extract_leaf(key.template leaf<0>(), 0); +} + +output_t make_payload(std::uint64_t lo) +{ + return output_t{lo}; +} + +} // namespace + +TEST(LeafLater, MatchesCorrectedImmediately) +{ + const input_t alpha = 42; + const output_t beta = make_payload(7); + + auto [k0, k1] = dpf::make_dpf(alpha, beta); + // Public leaf CW (same on both keys); applying it recovers the immediate path. + const output_t F = leaf_cw_as_output(k0); + EXPECT_EQ(F, leaf_cw_as_output(k1)); + + auto full0 = dpf::eval_full(k0); + auto full1 = dpf::eval_full(k1); + + std::vector buf0(n), buf1(n); + std::vector c0(n), c1(n); + dpf::eval_full(buf0, c0, k0, dpf::leaf_later{}); + dpf::eval_full(buf1, c1, k1, dpf::leaf_later{}); + dpf::apply_leaf_correction(buf0, c0, F); + dpf::apply_leaf_correction(buf1, c1, F); + + auto it0 = std::begin(full0.second); + auto it1 = std::begin(full1.second); + for (std::size_t i = 0; i < n; ++i, ++it0, ++it1) + { + const auto imm0 = dpf::detail_walk::group_value(*it0); + const auto imm1 = dpf::detail_walk::group_value(*it1); + EXPECT_EQ(buf0[i], imm0) << "party0 @" << i; + EXPECT_EQ(buf1[i], imm1) << "party1 @" << i; + EXPECT_EQ(buf0[i] - buf1[i], imm0 - imm1) << i; + const auto got = buf0[i] - buf1[i]; + if (i == alpha) + EXPECT_EQ(got, beta); + else + EXPECT_EQ(got, output_t{0}); + } +} + +TEST(LeafLater, ApplyAfterRotateMatchesCorrectThenRotate) +{ + const input_t alpha = 10; + const output_t beta = make_payload(99); + const std::size_t s = 32; + + auto [k0, k1] = dpf::make_dpf(alpha, beta); + const output_t F = leaf_cw_as_output(k0); + + auto full0 = dpf::eval_full(k0); + auto full1 = dpf::eval_full(k1); + std::vector early0(n), early1(n); + { + auto a = std::begin(full0.second); + auto b = std::begin(full1.second); + for (std::size_t i = 0; i < n; ++i, ++a, ++b) + { + early0[i] = dpf::detail_walk::group_value(*a); + early1[i] = dpf::detail_walk::group_value(*b); + } + } + early0 = dpf::cyclic_shift(early0, s); + early1 = dpf::cyclic_shift(early1, s); + + std::vector late0(n), late1(n); + std::vector c0(n), c1(n); + dpf::eval_full(late0, c0, k0, dpf::leaf_later{}); + dpf::eval_full(late1, c1, k1, dpf::leaf_later{}); + dpf::cyclic_shift_pair(late0, c0, s); + dpf::cyclic_shift_pair(late1, c1, s); + dpf::apply_leaf_correction(late0, c0, F); + dpf::apply_leaf_correction(late1, c1, F); + + for (std::size_t i = 0; i < n; ++i) + { + EXPECT_EQ(late0[i], early0[i]) << i; + EXPECT_EQ(late1[i], early1[i]) << i; + } +} + +TEST(LeafLater, DuoramShapedUpdate) +{ + // Unit at r, rotate by i*−r, then apply a public F built from the leaf CW + // of a key keyed at the online message (same as correcting immediately for + // that message). Neighbours stay unchanged. + const input_t r = 10; + const input_t i_star = 42; + const std::size_t shift = static_cast(i_star - r); + const output_t message = make_payload(7); + + auto [k0, k1] = dpf::make_dpf(r, message); + const output_t F = leaf_cw_as_output(k0); + + std::vector mem0(n), mem1(n); + mem0[i_star] = make_payload(100); + + std::vector v0(n), v1(n); + std::vector t0(n), t1(n); + dpf::eval_full_add_into(v0, t0, k0, dpf::leaf_later{}, dpf::rotate{shift}); + dpf::eval_full_add_into(v1, t1, k1, dpf::leaf_later{}, dpf::rotate{shift}); + dpf::apply_leaf_correction(v0, t0, F); + dpf::apply_leaf_correction(v1, t1, F); + + for (std::size_t i = 0; i < n; ++i) + { + mem0[i] = mem0[i] + v0[i]; + mem1[i] = mem1[i] + v1[i]; + } + + EXPECT_EQ(mem0[i_star] - mem1[i_star], make_payload(100) + message); + EXPECT_EQ(mem0[r] - mem1[r], output_t{0}); + EXPECT_EQ(mem0[0] - mem1[0], output_t{0}); +} diff --git a/test/tests/log_test.cpp b/test/tests/log_test.cpp new file mode 100644 index 0000000..ebf4e02 --- /dev/null +++ b/test/tests/log_test.cpp @@ -0,0 +1,744 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dpf/app_flow.hpp" +#include "dpf/experiment.hpp" +#include "dpf/launch.hpp" +#include "dpf/log.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/prg_chacha.hpp" +#include "dpf/prg_count.hpp" +#include "dpf/run_config.hpp" +#include "dpf/run_log.hpp" +#include "dpf/yao.hpp" + +namespace +{ + +std::string temp_path(const char * tag) +{ + return "/tmp/libdpf_log_test_" + std::to_string(::getpid()) + "_" + tag + ".log"; +} + +std::vector read_lines(const std::string & path) +{ + std::ifstream in(path); + std::vector out; + std::string line; + while (std::getline(in, line)) + out.push_back(line); + return out; +} + +bool has(const std::string & line, const std::string & needle) +{ + return line.find(needle) != std::string::npos; +} + +std::vector with_event(const std::vector & lines, + const std::string & ev) +{ + std::vector out; + for (const auto & l : lines) + if (has(l, " ev=" + ev + " ") || (l.size() >= ev.size() + 4 + && l.compare(l.size() - ev.size() - 4, std::string::npos, " ev=" + ev) == 0)) + out.push_back(l); + return out; +} + +/// Route the log to a fresh file for one test; silence it afterwards. +struct file_log +{ + std::string path; + explicit file_log(const char * tag, dpf::log::level l = dpf::log::level::debug, + dpf::log::seed_policy seeds = dpf::log::seed_policy::full) + : path(temp_path(tag)) + { + std::remove(path.c_str()); + dpf::log::settings s; + s.threshold = l; + s.sinks = "file:" + path; + s.seeds = seeds; + dpf::log::configure(s); + } + ~file_log() + { + dpf::log::settings s; + s.sinks = "none"; + dpf::log::configure(s); + std::remove(path.c_str()); + } + std::vector lines() const { return read_lines(path); } +}; + +} // namespace + +// Runs first: nothing has configured the log yet in this process. +TEST(Log, SilentUntilConfigured) +{ + EXPECT_FALSE(dpf::log::enabled(dpf::log::level::error)); + EXPECT_FALSE(dpf::log::enabled(dpf::log::level::info)); + int evaluated = 0; + DPF_LOG(error, "never").kv("x", ++evaluated); + EXPECT_EQ(evaluated, 0); +} + +TEST(Log, LevelAndSeedPolicyNames) +{ + using dpf::log::level; + EXPECT_EQ(dpf::log::parse_level("silent"), level::silent); + EXPECT_EQ(dpf::log::parse_level("warn"), level::warning); + EXPECT_EQ(dpf::log::parse_level("3"), level::info); + EXPECT_EQ(dpf::log::parse_level("absurd"), level::trace); + EXPECT_THROW(dpf::log::parse_level("loud"), std::invalid_argument); + EXPECT_EQ(dpf::log::parse_seed_policy("hash"), dpf::log::seed_policy::hash); + EXPECT_EQ(dpf::log::parse_seed_policy("off"), dpf::log::seed_policy::off); + EXPECT_THROW(dpf::log::parse_seed_policy("maybe"), std::invalid_argument); + dpf::log::settings bad; + bad.sinks = "stderr,carrier-pigeon"; + EXPECT_THROW(dpf::log::configure(bad), std::invalid_argument); + EXPECT_FALSE(dpf::log::enabled(dpf::log::level::error)); +} + +TEST(Log, RecordFormatAndThreshold) +{ + std::string path; + { + file_log log("format", dpf::log::level::info); + path = log.path; + DPF_LOG(info, "demo").kv("plain", "abc").kv("spaced", "a b") + .kv("quote", "say \"hi\"").kv("eq", "k=v").kv("n", std::size_t{42}) + .kv("neg", -3).kv("flag", true).kv("empty", "").hex("h", "\x01\xff", 2); + DPF_LOG(debug, "hidden").kv("x", 1); + DPF_LOG(warning, "shown").kv("x", 2); + const auto lines = log.lines(); + ASSERT_EQ(lines.size(), 2u); + const auto & l = lines[0]; + EXPECT_EQ(l.rfind("ts=", 0), 0u); + EXPECT_TRUE(has(l, "Z lvl=info inv=" + dpf::log::invocation_id() + " pid=")); + EXPECT_EQ(dpf::log::invocation_id().size(), 16u); + EXPECT_TRUE(has(l, " ev=demo plain=abc spaced=\"a b\" quote=\"say \\\"hi\\\"\" " + "eq=\"k=v\" n=42 neg=-3 flag=1 empty=\"\" h=01ff")); + EXPECT_TRUE(has(lines[1], "lvl=warning")); + EXPECT_TRUE(has(lines[1], "ev=shown x=2")); + } + EXPECT_FALSE(dpf::log::enabled(dpf::log::level::error)); +} + +TEST(Log, RoleScopeTagsAndRestores) +{ + file_log log("role"); + DPF_LOG(info, "outside"); + { + const dpf::log::role_scope a("p1"); + DPF_LOG(info, "inside"); + { + const dpf::log::role_scope b("dealer"); + DPF_LOG(info, "nested"); + } + DPF_LOG(info, "back"); + } + const auto lines = log.lines(); + ASSERT_EQ(lines.size(), 4u); + EXPECT_FALSE(has(lines[0], " role=")); + EXPECT_TRUE(has(lines[1], " role=p1 ev=inside")); + EXPECT_TRUE(has(lines[2], " role=dealer ev=nested")); + EXPECT_TRUE(has(lines[3], " role=p1 ev=back")); +} + +TEST(Log, SeedPolicies) +{ + const std::uint8_t seed[4] = {0xde, 0xad, 0xbe, 0xef}; + { + file_log log("seed_full", dpf::log::level::info, dpf::log::seed_policy::full); + DPF_LOG(info, "s").seed("value", seed, sizeof(seed)); + EXPECT_TRUE(has(log.lines().at(0), "value=deadbeef")); + } + { + file_log log("seed_hash", dpf::log::level::info, dpf::log::seed_policy::hash); + DPF_LOG(info, "s").seed("value", seed, sizeof(seed)); + const auto l = log.lines().at(0); + EXPECT_TRUE(has(l, "value=sha256:")); + EXPECT_FALSE(has(l, "deadbeef")); + const auto pos = l.find("sha256:") + 7; + EXPECT_EQ(l.substr(pos).size(), 16u); + } + { + file_log log("seed_off", dpf::log::level::info, dpf::log::seed_policy::off); + DPF_LOG(info, "s").seed("value", seed, sizeof(seed)); + EXPECT_TRUE(has(log.lines().at(0), "value=withheld")); + } + const auto abc = dpf::log::detail::sha256("", + reinterpret_cast("abc"), 3); + std::string hex; + dpf::log::detail::append_hex(hex, abc.data(), abc.size()); + EXPECT_EQ(hex, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); +} + +TEST(Log, ConcurrentRecordsStayWholeLines) +{ + file_log log("threads", dpf::log::level::info); + constexpr int threads = 8; + constexpr int each = 400; + std::vector ts; + for (int t = 0; t < threads; ++t) + ts.emplace_back([t] { + const dpf::log::role_scope role("p" + std::to_string(t)); + for (int i = 0; i < each; ++i) + DPF_LOG(info, "tick").kv("thread", t).kv("i", i) + .kv("pad", std::string(64, static_cast('a' + t))); + }); + for (auto & t : ts) + t.join(); + const auto lines = log.lines(); + ASSERT_EQ(lines.size(), static_cast(threads * each)); + std::map per; + for (const auto & l : lines) + { + ASSERT_EQ(l.rfind("ts=", 0), 0u) << l; + const auto p = l.find(" thread="); + ASSERT_NE(p, std::string::npos) << l; + const int t = std::stoi(l.substr(p + 8)); + EXPECT_TRUE(has(l, " role=p" + std::to_string(t) + " ")) << l; + EXPECT_TRUE(has(l, "pad=" + std::string(64, static_cast('a' + t)))) << l; + ++per[t]; + } + for (int t = 0; t < threads; ++t) + EXPECT_EQ(per[t], each); +} + +TEST(Log, RunConfigKeysAndDescribe) +{ + dpf::app::run_config cfg; + cfg.set("log_level", "debug"); + cfg.set("log", "file:/tmp/x.log,stderr"); + cfg.set("log_seeds", "hash"); + cfg.set("cpu2", "3"); + EXPECT_EQ(cfg.log_level, dpf::log::level::debug); + EXPECT_EQ(cfg.log_sinks, "file:/tmp/x.log,stderr"); + EXPECT_EQ(cfg.log_seeds, dpf::log::seed_policy::hash); + EXPECT_EQ(cfg.cpu[2], 3); + EXPECT_THROW(cfg.set("log_level", "chatty"), std::invalid_argument); + EXPECT_THROW(cfg.set("cpu0", "3abc"), std::invalid_argument); + std::map kv; + for (const auto & p : cfg.describe()) + kv[p.first] = p.second; + for (const char * k : {"log_level", "log", "log_seeds", "cpu2", "compact", + "keepalive_idle", "connect_ms", "accept_ms", "join_ms", "handshake_ms"}) + EXPECT_EQ(kv.count(k), 1u) << k; + EXPECT_EQ(kv["log_level"], "debug"); + EXPECT_EQ(kv["cpu2"], "3"); + + ::setenv("DPF_LOG_LEVEL", "warning", 1); + ::setenv("DPF_LOG_SEEDS", "off", 1); + const auto env = dpf::app::run_config::from_env(); + ::unsetenv("DPF_LOG_LEVEL"); + ::unsetenv("DPF_LOG_SEEDS"); + EXPECT_EQ(env.log_level, dpf::log::level::warning); + EXPECT_EQ(env.log_seeds, dpf::log::seed_policy::off); +} + +TEST(Log, BannerRecordsProvenance) +{ + const std::string path = temp_path("banner"); + std::remove(path.c_str()); + ::setenv("DPF_TEST_MARKER", "banner-check", 1); + ::setenv("DPF_TEST_SEED", "0123456789abcdef", 1); + dpf::app::run_config cfg; + cfg.log_sinks = "file:" + path; + cfg.log_seeds = dpf::log::seed_policy::hash; + dpf::app::start_logging(cfg); + const auto lines = read_lines(path); + ::unsetenv("DPF_TEST_MARKER"); + ::unsetenv("DPF_TEST_SEED"); + for (const char * ev : {"start", "build", "host", "argv", "env", "log", "config"}) + EXPECT_FALSE(with_event(lines, ev).empty()) << ev; + const auto build = with_event(lines, "build").at(0); + EXPECT_TRUE(has(build, " rev=")) << build; + EXPECT_TRUE(has(build, " entropy=")) << build; + EXPECT_TRUE(has(with_event(lines, "start").at(0), " utc=")) << lines[0]; + bool marker = false; + bool seed_hidden = false; + for (const auto & l : with_event(lines, "env")) + { + marker = marker || has(l, "name=DPF_TEST_MARKER value=banner-check"); + seed_hidden = seed_hidden + || (has(l, "name=DPF_TEST_SEED value=sha256:") && !has(l, "0123456789abcdef")); + } + EXPECT_TRUE(marker); + EXPECT_TRUE(seed_hidden); + const auto config = with_event(lines, "config").at(0); + EXPECT_TRUE(has(config, " transport=async")) << config; + EXPECT_TRUE(has(config, " log_seeds=hash")) << config; + dpf::log::settings off; + off.sinks = "none"; + dpf::log::configure(off); + std::remove(path.c_str()); +} + +TEST(Log, LinkUpNamesEndpointsAndAuthentication) +{ + for (const char * encryption : {"off", "on"}) + { + file_log log("links", dpf::log::level::info); + dpf::protocol::composer c0(0); + dpf::protocol::composer c1(1); + auto x0 = c0.input(dpf::protocol::domain::a, 8); + auto x1 = c1.input(dpf::protocol::domain::a, 8); + auto o0 = c0.exchange(x0); + (void)c1.exchange(x1); + auto p0 = c0.schedule(); + auto p1 = c1.schedule(); + dpf::app::party_values v0(p0.nodes().size()), v1(p1.nodes().size()); + const std::uint64_t a = 11, b = 31; + v0[x0.id].assign(8, 0); + v1[x1.id].assign(8, 0); + std::memcpy(v0[x0.id].data(), &a, 8); + std::memcpy(v1[x1.id].data(), &b, 8); + dpf::app::run_config cfg; + cfg.kind = dpf::net::transport::mux; + cfg.set("encryption", encryption); + const bool tls = std::strcmp(encryption, "on") == 0; + const auto r = dpf::run_two_party(p0, p1, v0, v1, {}, cfg); + std::uint64_t open = 0; + std::memcpy(&open, v0[o0.id].data(), 8); + EXPECT_EQ(open, 42u) << encryption; + ASSERT_EQ(r.party_wall_ns.size(), 2u); + const auto lines = log.lines(); + const auto ups = with_event(lines, "link.up"); + ASSERT_EQ(ups.size(), 2u) << encryption; + bool saw_accept = false, saw_connect = false; + for (const auto & l : ups) + { + EXPECT_TRUE(has(l, " transport=mux")) << l; + EXPECT_TRUE(has(l, " local=127.0.0.1:")) << l; + EXPECT_TRUE(has(l, " remote=127.0.0.1:")) << l; + if (tls) + { + EXPECT_TRUE(has(l, " encryption=TLSv1.3/")) << l; + EXPECT_TRUE(has(l, " peer_key=")) << l; + EXPECT_TRUE(has(l, " auth=")) << l; + } + else + EXPECT_TRUE(has(l, " auth=none encryption=none")) << l; + EXPECT_TRUE(has(l, " sndbuf=")) << l; + EXPECT_TRUE(has(l, " rtt_us=")) << l; + saw_accept = saw_accept || (has(l, " role=p0 ") && has(l, " how=accept peer=p1")); + saw_connect = saw_connect || (has(l, " role=p1 ") && has(l, " how=connect peer=p0")); + } + EXPECT_TRUE(saw_accept) << encryption; + EXPECT_TRUE(saw_connect) << encryption; + EXPECT_FALSE(with_event(lines, "listen").empty()); + EXPECT_EQ(with_event(lines, "plan").size(), 2u); + const auto done = with_event(lines, "party.done"); + ASSERT_EQ(done.size(), 2u); + for (const auto & l : done) + { + EXPECT_TRUE(has(l, " wall_ns=")) << l; + EXPECT_TRUE(has(l, " wire_out=")) << l; + } + EXPECT_EQ(with_event(lines, "parties.done").size(), 1u); + EXPECT_TRUE(with_event(lines, "link.plaintext").empty()); + } +} + +TEST(Log, NodeArgumentsNameTheBadField) +{ + const char * bad_party[] = {"node", "--party=zero", "--peers=a:1,b:2"}; + try + { + (void)dpf::app::parse_node_args(3, const_cast(bad_party), + dpf::app::run_config{}); + FAIL() << "expected a parse error"; + } + catch (const std::invalid_argument & e) + { + EXPECT_TRUE(has(e.what(), "--party needs a number")) << e.what(); + } + const char * bad_port[] = {"node", "--party=0", "--peers=a:1,b:70000"}; + EXPECT_THROW((void)dpf::app::parse_node_args(3, const_cast(bad_port), + dpf::app::run_config{}), + std::invalid_argument); + const char * memory[] = {"node", "--party=1", "--peers=a:1,b:2", "--transport=async"}; + const auto a = dpf::app::parse_node_args(4, const_cast(memory), + dpf::app::run_config{}); + EXPECT_EQ(a.cfg.kind, dpf::net::transport::mux); + EXPECT_EQ(a.replaced_transport, "async"); +} + +TEST(SymCount, PurposeAndPrimitiveCells) +{ + using dpf::prg::primitive; + using dpf::prg::purpose; + dpf::prg::reset_eval_count(); + auto seed = simde_mm_set_epi64x(3, 4); + auto blk = dpf::prg::aes128::eval(seed, 0); + blk = dpf::prg::aes128::eval(blk, 1); + { + const dpf::prg::purpose_scope h(purpose::hash); + (void)dpf::prg::aes128::eval01(blk); + { + const dpf::prg::purpose_scope inner(purpose::harness); + (void)dpf::prg::aes128::eval(blk, 7); + } + (void)dpf::prg::aes128::eval(blk, 8); + } + (void)dpf::prg::chacha<20>::eval(seed, 0); + EXPECT_EQ(dpf::prg::count(purpose::expand, primitive::aes128), 2u); + EXPECT_EQ(dpf::prg::count(purpose::hash, primitive::aes128), 3u); + EXPECT_EQ(dpf::prg::count(purpose::harness, primitive::aes128), 1u); + EXPECT_EQ(dpf::prg::count(purpose::expand, primitive::chacha), 1u); + EXPECT_EQ(dpf::prg::eval_count(), 6u); + const auto snap = dpf::prg::snapshot(); + std::uint64_t all = 0; + for (auto n : snap) + all += n; + EXPECT_EQ(all, 7u); + dpf::prg::reset_eval_count(); + EXPECT_EQ(dpf::prg::eval_count(), 0u); +} + +TEST(SymCount, GarblingHashesCountAsHash) +{ + using dpf::prg::primitive; + using dpf::prg::purpose; + dpf::prg::reset_eval_count(); + const auto x = simde_mm_set_epi64x(9, 10); + (void)dpf::yao::detail::cr_hash(x, 5); + EXPECT_EQ(dpf::prg::count(purpose::hash, primitive::aes128), 1u); + EXPECT_EQ(dpf::prg::count(purpose::expand, primitive::aes128), 0u); + dpf::prg::reset_eval_count(); +} + +TEST(SymCount, ExperimentSeedStreamIsNotProtocolWork) +{ + using dpf::prg::primitive; + using dpf::prg::purpose; + dpf::experiment ex("stream"); + ex.begin_timing(); + std::array buf{}; + dpf::uniform_fill(buf); + ex.end_timing(); + EXPECT_EQ(ex.random_bytes(), 1600u); + EXPECT_EQ(ex.prg_evals(), 0u); + const auto & sym = ex.sym_counts(); + EXPECT_EQ(sym[static_cast(purpose::harness) * dpf::prg::primitive_count + + static_cast(primitive::aes128)], + 100u); +} + +TEST(Experiment, SeedSourceIsLoggedAndWritten) +{ + const std::string dir = "/tmp/libdpf_log_test_csv_" + std::to_string(::getpid()); + (void)::system(("rm -rf '" + dir + "'").c_str()); + file_log log("seed_source", dpf::log::level::info); + dpf::experiment::master_seed master{}; + { + dpf::experiment ex("fresh_one"); + master = ex.seed(); + EXPECT_FALSE(ex.seed_provided()); + ex.begin_timing(); + (void)dpf::prg::aes128::eval(simde_mm_set_epi64x(1, 2), 0); + ex.end_timing(); + ex.write_csv(dir); + } + { + auto again = dpf::experiment::replay("fresh_one", master); + EXPECT_TRUE(again.seed_provided()); + again.set_run_id(1); + again.write_csv(dir); + } + const auto seeds = with_event(log.lines(), "seed"); + ASSERT_EQ(seeds.size(), 2u); + std::string hex; + dpf::log::detail::append_hex(hex, master.data(), master.size()); + EXPECT_TRUE(has(seeds[0], " source=fresh")) << seeds[0]; + EXPECT_TRUE(has(seeds[0], " value=" + hex)) << seeds[0]; + EXPECT_TRUE(has(seeds[1], " source=provided")) << seeds[1]; + EXPECT_TRUE(has(seeds[1], " value=" + hex)) << seeds[1]; + const auto runs = read_lines(dir + "/runs.csv"); + ASSERT_EQ(runs.size(), 3u); + EXPECT_EQ(runs[0], "name,party,run_id,invocation,seed_source,written_utc"); + EXPECT_TRUE(has(runs[1], "fresh_one,p0,0," + dpf::log::invocation_id() + ",fresh,")); + EXPECT_TRUE(has(runs[2], "fresh_one,p0,1," + dpf::log::invocation_id() + ",provided,")); + const auto sym = read_lines(dir + "/sym.csv"); + ASSERT_GE(sym.size(), 2u); + EXPECT_EQ(sym[0], "name,party,run_id,purpose,primitive,blocks,invocation"); + EXPECT_EQ(sym[1], "fresh_one,p0,0,expand,aes128,1," + dpf::log::invocation_id()); + (void)::system(("rm -rf '" + dir + "'").c_str()); +} + +namespace +{ + +constexpr std::uint32_t k_draw = 94201; + +struct chain +{ + dpf::protocol::plan plan; + dpf::protocol::node x; + dpf::protocol::node out; +}; + +chain make_chain(std::size_t party, int steps) +{ + dpf::protocol::composer c(party); + chain ch; + ch.x = c.input(dpf::protocol::domain::a, 8); + auto cur = ch.x; + for (int i = 0; i < steps; ++i) + cur = c.compute(k_draw, {c.exchange(cur)}, dpf::protocol::domain::a, 8); + ch.out = cur; + ch.plan = c.schedule(); + return ch; +} + +struct draw_log +{ + std::mutex mu; + std::vector values; + std::size_t hooked = 0; +}; + +/// Adds 1 to its input, draws one word, and runs `aes` AES blocks. +dpf::protocol::kernel_fn draw_kernel(draw_log & log, int aes) +{ + return [&log, aes](std::uint32_t, const std::vector &, + const std::vector & inputs, + dpf::protocol::block_span output, std::size_t lanes) { + const bool hooked = dpf::detail::uniform_bytes_hook != nullptr; + const auto r = dpf::uniform_sample(); + { + std::lock_guard lock(log.mu); + log.values.push_back(r); + log.hooked += hooked ? 1 : 0; + } + auto blk = simde_mm_set_epi64x(1, 2); + for (int i = 0; i < aes; ++i) + blk = dpf::prg::aes128::eval(blk, static_cast(i)); + asm volatile("" : "+x"(blk)); + for (std::size_t l = 0; l < lanes; ++l) + { + std::uint64_t v = 0; + std::memcpy(&v, inputs[0].at(l), 8); + ++v; + std::memcpy(output.at(l), &v, 8); + } + }; +} + +struct chain_run +{ + std::vector plans; + std::vector inputs; +}; + +chain_run two_party_chain(int steps) +{ + chain_run r; + for (std::size_t p = 0; p < 2; ++p) + { + auto ch = make_chain(p, steps); + dpf::app::party_values v(ch.plan.nodes().size()); + v[ch.x.id].assign(8, 0); + const std::uint64_t in = p == 0 ? 5 : 6; + std::memcpy(v[ch.x.id].data(), &in, 8); + r.plans.push_back(ch.plan); + r.inputs.push_back(v); + } + return r; +} + +std::vector sorted_draws(draw_log & log) +{ + std::lock_guard lock(log.mu); + auto v = log.values; + log.values.clear(); + log.hooked = 0; + std::sort(v.begin(), v.end()); + return v; +} + +void expect_replay(dpf::net::transport kind, std::size_t pool, std::size_t trials) +{ + const auto run = two_party_chain(3); + draw_log log; + std::map k{{k_draw, draw_kernel(log, 0)}}; + dpf::app::run_config cfg; + cfg.kind = kind; + cfg.compute_threads = pool; + cfg.trials = trials; + dpf::experiment first("replay"); + (void)dpf::app::exercise_parties(run.plans, run.inputs, k, &first, cfg); + const std::size_t hooked = log.hooked; + const auto a = sorted_draws(log); + auto again = dpf::experiment::replay("replay", first.seed()); + (void)dpf::app::exercise_parties(run.plans, run.inputs, k, &again, cfg); + const auto b = sorted_draws(log); + ASSERT_EQ(a.size(), 6u * trials) << dpf::net::transport_name(kind) << " pool " << pool; + EXPECT_EQ(hooked, a.size()) << dpf::net::transport_name(kind) << " pool " << pool; + EXPECT_EQ(a, b) << dpf::net::transport_name(kind) << " pool " << pool; + EXPECT_TRUE(first.has_seed_named("p0/master")); + EXPECT_TRUE(first.has_seed_named("p1/master")); +} + +} // namespace + +TEST(Replay, RecordedMasterReplaysEveryParty) +{ + expect_replay(dpf::net::transport::async_memory, 0, 1); + expect_replay(dpf::net::transport::memory_sink, 0, 1); + expect_replay(dpf::net::transport::mux, 0, 3); +} + +TEST(Replay, ComputePoolKernelsDrawFromTheirPartysStream) +{ + expect_replay(dpf::net::transport::async_memory, 2, 1); +} + +TEST(Replay, PartyStreamsDifferAndDependOnlyOnTheMaster) +{ + const dpf::experiment::master_seed m{}; + auto a = dpf::experiment::replay("x", m); + const auto p0 = a.derive_party(0).seed(); + const auto p1 = a.derive_party(1).seed(); + auto b = dpf::experiment::replay("other name", m); + EXPECT_NE(p0, p1); + EXPECT_EQ(b.derive_party(1).seed(), p1); + EXPECT_EQ(b.derive_party(1).seed_origin(), dpf::experiment::origin::derived); +} + +TEST(Counting, ComputePoolWorkIsChargedToItsParty) +{ + const auto run = two_party_chain(3); + draw_log log; + std::map k{{k_draw, draw_kernel(log, 20000)}}; + for (std::size_t pool : {std::size_t{0}, std::size_t{2}}) + { + dpf::app::run_config cfg; + cfg.kind = dpf::net::transport::async_memory; + cfg.compute_threads = pool; + dpf::experiment ex("pool"); + (void)dpf::app::exercise_parties(run.plans, run.inputs, k, &ex, cfg); + EXPECT_EQ(ex.prg_evals(), 3u * 20000u) << "pool " << pool; + EXPECT_EQ(ex.random_bytes(), 3u * 8u) << "pool " << pool; + EXPECT_GT(ex.cpu_ns(), ex.wall_ns() / 4) << "pool " << pool; + (void)sorted_draws(log); + } +} + +TEST(Bytes, ReceivedBytesMatchSentOnASymmetricChain) +{ + const auto run = two_party_chain(3); + draw_log log; + std::map k{{k_draw, draw_kernel(log, 0)}}; + dpf::app::run_config cfg; + cfg.kind = dpf::net::transport::mux; + dpf::experiment ex("bytes"); + (void)dpf::app::exercise_parties(run.plans, run.inputs, k, &ex, cfg); + EXPECT_EQ(ex.bytes_out(), ex.plan_bytes_out()); + EXPECT_EQ(ex.bytes_in(), ex.bytes_out()); + EXPECT_EQ(ex.edge_bytes_in(dpf::protocol::edge_channel::peer), + ex.edge_bytes_out(dpf::protocol::edge_channel::peer)); + ASSERT_EQ(ex.rounds().size(), 3u); + for (const auto & r : ex.rounds()) + EXPECT_EQ(r.bytes_in, 8u) << "round " << r.round; +} + +TEST(Trials, EveryPartyIsTimedAndMediansReachSummary) +{ + const auto run = two_party_chain(2); + draw_log log; + std::map k{{k_draw, draw_kernel(log, 0)}}; + dpf::app::run_config cfg; + cfg.kind = dpf::net::transport::async_memory; + cfg.warmup = 1; + cfg.trials = 3; + dpf::experiment ex("trials"); + (void)dpf::app::exercise_parties(run.plans, run.inputs, k, &ex, cfg); + EXPECT_EQ(ex.trials().size(), 3u); + EXPECT_GE(ex.slowest_median_ns(), ex.median_trial_ns()); + const std::string dir = "/tmp/libdpf_log_test_trials_" + std::to_string(::getpid()); + (void)::system(("rm -rf '" + dir + "'").c_str()); + ex.write_csv(dir); + const auto trials = read_lines(dir + "/trials.csv"); + ASSERT_EQ(trials.size(), 1u + 3u * 2u); + EXPECT_EQ(trials[0], "name,party,run_id,trial,wall_ns,invocation"); + EXPECT_EQ(trials[1].rfind("trials,p0,0,0,", 0), 0u) << trials[1]; + EXPECT_EQ(trials[2].rfind("trials,p1,0,0,", 0), 0u) << trials[2]; + const auto summary = read_lines(dir + "/summary.csv"); + ASSERT_EQ(summary.size(), 2u); + EXPECT_TRUE(has(summary[0], ",median_ns,slowest_median_ns,trials,invocation")); + EXPECT_TRUE(has(summary[1], "," + std::to_string(ex.median_trial_ns()) + "," + + std::to_string(ex.slowest_median_ns()) + ",3," + dpf::log::invocation_id())); + (void)::system(("rm -rf '" + dir + "'").c_str()); +} + +TEST(Csv, ChangedHeaderMovesTheOldFileAside) +{ + const std::string dir = "/tmp/libdpf_log_test_rotate_" + std::to_string(::getpid()); + (void)::system(("rm -rf '" + dir + "' && mkdir -p '" + dir + "'").c_str()); + { + std::ofstream old(dir + "/summary.csv"); + old << "name,party,run_id,wall_ns\nold,p0,0,1\n"; + } + file_log log("rotate", dpf::log::level::warning); + dpf::experiment ex("rotate"); + ex.write_csv(dir); + const auto now = read_lines(dir + "/summary.csv"); + ASSERT_EQ(now.size(), 2u); + EXPECT_TRUE(has(now[0], ",invocation")); + std::size_t moved = 0; + for (const auto & e : std::filesystem::directory_iterator(dir)) + if (e.path().filename().string().rfind("summary.before-", 0) == 0) + { + ++moved; + EXPECT_EQ(read_lines(e.path().string()).at(1), "old,p0,0,1"); + } + EXPECT_EQ(moved, 1u); + EXPECT_EQ(with_event(log.lines(), "csv.moved").size(), 1u); + (void)::system(("rm -rf '" + dir + "'").c_str()); +} + +TEST(Gate, AllPartiesStartTogetherAndAFailureReleasesTheRest) +{ + { + dpf::app::detail::start_gate gate(3); + std::atomic through{0}; + std::vector ts; + for (int i = 0; i < 3; ++i) + ts.emplace_back([&] { through += gate.arrive_and_wait() ? 1 : 0; }); + for (auto & t : ts) + t.join(); + EXPECT_EQ(through.load(), 3); + } + { + dpf::app::detail::start_gate gate(3); + std::atomic through{0}; + std::vector ts; + for (int i = 0; i < 2; ++i) + ts.emplace_back([&] { through += gate.arrive_and_wait() ? 1 : 0; }); + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + gate.fail(); + for (auto & t : ts) + t.join(); + EXPECT_EQ(through.load(), 0); + } +} diff --git a/test/tests/lut_union_test.cpp b/test/tests/lut_union_test.cpp new file mode 100644 index 0000000..a08884e --- /dev/null +++ b/test/tests/lut_union_test.cpp @@ -0,0 +1,472 @@ +#include + +#include "dpf/compose.hpp" +#include "dpf/verifiable.hpp" +#include "grotto/lut_union.hpp" + +#include "simde/simde/x86/sse2.h" + +#include +#include +#include +#include +#include + +namespace +{ + +using grotto::offset_horner_group_add; +using grotto::offset_horner_group_sub; + +grotto::piecewise_lut lut_a() +{ + grotto::piecewise_lut lut; + lut.knots = {0, 10, 50}; + lut.coeff = {{1, 0}, {0, 2}, {7, 1}}; + return lut; +} + +grotto::piecewise_lut lut_b() +{ + grotto::piecewise_lut lut; + lut.knots = {0, 4, 12, 80}; + lut.coeff = {{3, 0, 0}, {1, 0, 1}, {9, 2, 0}, {4, 1, 0}}; + return lut; +} + +grotto::piecewise_lut lut_c() +{ + grotto::piecewise_lut lut; + lut.knots = {0, 7, 90}; + lut.coeff = {{8, 1, 0}, {2, 0, 3}, {1, 1, 1}}; + return lut; +} + +std::vector open_union(const grotto::offset_poly_keys & mat, + const grotto::lut_union_plan & plan) +{ + const auto s0 = grotto::lut_union_eval<0>(mat, plan); + const auto s1 = grotto::lut_union_eval<1>(mat, plan); + EXPECT_EQ(s0.size(), s1.size()); + std::vector out(s0.size()); + for (std::size_t i = 0; i < s0.size(); ++i) + out[i] = s0[i] + s1[i]; + return out; +} + +template +void expect_partition(const grotto::lut_union_plan & plan) +{ + if (plan.knots.empty()) + { + ADD_FAILURE() << "empty union"; + return; + } + for (const auto & func : plan.funcs) + { + std::vector seen(plan.knots.size(), 0); + for (const auto & span : func) + { + auto mark = [&](std::size_t j) { + if (j >= seen.size()) + { + ADD_FAILURE() << "span index " << j; + return; + } + seen[j] += 1; + }; + if (span.begin <= span.end) + { + for (std::size_t j = span.begin; j < span.end; ++j) + mark(j); + } + else + { + for (std::size_t j = span.begin; j < plan.knots.size(); ++j) + mark(j); + for (std::size_t j = 0; j < span.end; ++j) + mark(j); + } + } + for (int bit : seen) + EXPECT_EQ(bit, 1); + } +} + +} // namespace + +TEST(LutUnion, WideDomainMapsTheWrapAcrossTheFront) +{ + grotto::piecewise_lut a; + a.knots = {10, 30}; + a.coeff = {{1}, {2}}; + grotto::piecewise_lut b; + b.knots = {0, 20}; + b.coeff = {{3}, {4}}; + const auto plan = grotto::make_lut_union_plan( + std::vector>{a, b}, uint64_t{0}); + + ASSERT_EQ(plan.knots, (std::vector{0, 10, 20, 30})); + EXPECT_EQ(plan.comparisons, 1u); + EXPECT_EQ(plan.prefix_walks, 1u); + EXPECT_EQ(plan.depth, 64u); + EXPECT_EQ(plan.geneval_rounds(), plan.depth); + EXPECT_EQ(plan.degree, 0u); + + ASSERT_EQ(plan.funcs[0].size(), 2u); + EXPECT_EQ(plan.funcs[0][0].begin, 1u); + EXPECT_EQ(plan.funcs[0][0].end, 3u); + EXPECT_EQ(plan.funcs[0][1].begin, 3u); + EXPECT_EQ(plan.funcs[0][1].end, 1u); + + ASSERT_EQ(plan.funcs[1].size(), 2u); + EXPECT_EQ(plan.funcs[1][0].begin, 0u); + EXPECT_EQ(plan.funcs[1][0].end, 2u); + EXPECT_EQ(plan.funcs[1][1].begin, 2u); + EXPECT_EQ(plan.funcs[1][1].end, 0u); + expect_partition(plan); +} + +TEST(LutUnion, OneWalkMatchesEachLutOnItsOwnKnots) +{ + const auto a = lut_a(); + const auto b = lut_b(); + const uint8_t center = 12; + const auto plan = grotto::make_lut_union_plan({a, b}, uint8_t{3}); + EXPECT_GT(plan.endpoints(), a.knots.size()); + EXPECT_EQ(plan.degree, 2u); + EXPECT_EQ(plan.lanes, 3u); + EXPECT_EQ(plan.depth, 8u); + EXPECT_EQ(plan.comparisons, 1u); + EXPECT_EQ(plan.prefix_walks, 1u); + + const auto mat = grotto::make_offset_poly_keys(center, plan.degree); + for (int eta = 0; eta < 256; eta += 17) + { + const auto e = static_cast(eta); + const auto here = grotto::make_lut_union_plan({a, b}, e); + const auto got = open_union(mat, here); + ASSERT_EQ(got.size(), 2u); + EXPECT_EQ(got[0], grotto::offset_poly_clear(center, a.knots, a.coeff, e)) + << eta; + EXPECT_EQ(got[1], grotto::offset_poly_clear(center, b.knots, b.coeff, e)) + << eta; + } +} + +TEST(LutUnion, GenevalPlanIsOneComparisonHoweverManyLuts) +{ + const uint8_t eta = 3; + const auto few = grotto::make_lut_union_plan({lut_a(), lut_b()}, eta); + const auto many = grotto::make_lut_union_plan({lut_a(), lut_b(), lut_c()}, eta); + EXPECT_GT(many.endpoints(), few.endpoints()); + EXPECT_EQ(few.geneval_rounds(), many.geneval_rounds()); + EXPECT_EQ(few.funcs.size(), 2u); + EXPECT_EQ(many.funcs.size(), 3u); + + dpf::protocol::composer c0(0); + grotto::schedule_lut_union(c0, few); + dpf::protocol::composer c1(0); + grotto::schedule_lut_union(c1, many); + const auto p0 = c0.default_plan(); + const auto p1 = c1.default_plan(); + EXPECT_EQ(p0.rounds(), few.depth); + EXPECT_EQ(p1.rounds(), many.depth); + EXPECT_EQ(p0.rounds(), p1.rounds()); + EXPECT_EQ(p0.slot_bytes(0), grotto::lut_union_slot_bytes(few.lanes)); + EXPECT_EQ(p1.slot_bytes(0), grotto::lut_union_slot_bytes(many.lanes)); +} + +TEST(LutUnion, GenevalXorAndAdditiveSharesMatchTheClearLuts) +{ + const uint8_t center = 12; + const uint8_t eta = 3; + const auto a = lut_a(); + const auto b = lut_b(); + const auto plan = grotto::make_lut_union_plan({a, b}, eta); + const uint8_t share = 0x3c; + const uint8_t other = static_cast(center ^ share); + + const auto xor_got = grotto::geneval_lut_union(share, other, plan); + EXPECT_EQ(xor_got.eta, eta); + ASSERT_EQ(xor_got.value0.size(), 2u); + EXPECT_EQ(xor_got.value0[0] + xor_got.value1[0], + grotto::offset_poly_clear(center, a.knots, a.coeff, eta)); + EXPECT_EQ(xor_got.value0[1] + xor_got.value1[1], + grotto::offset_poly_clear(center, b.knots, b.coeff, eta)); + + const uint8_t c0 = 5; + const uint8_t c1 = offset_horner_group_sub(center, c0); + const auto add_got = grotto::geneval_lut_union(dpf::arith_input, c0, c1, plan); + EXPECT_EQ(add_got.value0[0] + add_got.value1[0], xor_got.value0[0] + xor_got.value1[0]); + EXPECT_EQ(add_got.value0[1] + add_got.value1[1], xor_got.value0[1] + xor_got.value1[1]); +} + +TEST(LutUnion, EasyAndConstantLutsShareTheUnion) +{ + const auto relu = grotto::piecewise_from_easy(grotto::make_relu_lut()); + const auto clip = grotto::piecewise_from_easy( + grotto::make_clip_lut(0, -2, 3)); + grotto::constant_lut sign; + sign.bounds = {std::numeric_limits::min(), 0}; + sign.values = {-1, 1}; + const auto step = grotto::piecewise_from_constant(sign); + + const int8_t center = -20; + const int8_t eta = 15; + const auto plan = grotto::make_lut_union_plan( + std::vector>{relu, clip, step}, eta); + EXPECT_EQ(plan.comparisons, 1u); + EXPECT_EQ(plan.prefix_walks, 1u); + EXPECT_GT(plan.endpoints(), relu.knots.size()); + + const auto mat = grotto::make_offset_poly_keys(center, plan.degree); + const auto s0 = grotto::lut_union_eval<0>(mat, plan); + const auto s1 = grotto::lut_union_eval<1>(mat, plan); + const int8_t wrapped = offset_horner_group_add(center, eta); + const uint64_t opened[3] = {s0[0] + s1[0], s0[1] + s1[1], s0[2] + s1[2]}; + EXPECT_EQ(opened[0], static_cast(grotto::make_relu_lut()(wrapped))); + EXPECT_EQ(opened[1], static_cast(grotto::make_clip_lut(0, -2, 3)(wrapped))); + EXPECT_EQ(opened[2], static_cast(sign(wrapped))); + EXPECT_EQ(opened[0], grotto::offset_poly_clear(center, relu.knots, relu.coeff, eta)); +} + +TEST(LutUnion, RejectsARoundingDenominatorAndANarrowKey) +{ + EXPECT_THROW(grotto::piecewise_from_easy(grotto::make_leaky_relu_lut(1)), + std::invalid_argument); + EXPECT_THROW(grotto::make_lut_union_plan( + std::vector>{}, uint8_t{0}), + std::invalid_argument); + + const auto plan = grotto::make_lut_union_plan({lut_b()}, uint8_t{1}); + const auto narrow = grotto::make_offset_poly_keys(4, 0); + EXPECT_THROW(grotto::lut_union_eval<0>(narrow, plan), std::invalid_argument); + + grotto::piecewise_lut unsorted; + unsorted.knots = {0, 5, 3}; + unsorted.coeff = {{1}, {1}, {1}}; + EXPECT_THROW(grotto::make_lut_union_plan({unsorted}, uint8_t{0}), std::invalid_argument); + + grotto::piecewise_lut ragged; + ragged.knots = {0, 1}; + ragged.coeff = {{1}, {1, 2}}; + EXPECT_THROW(grotto::make_lut_union_plan({ragged}, uint8_t{0}), std::invalid_argument); + + grotto::piecewise_lut empty_row; + empty_row.knots = {0}; + empty_row.coeff = {{}}; + EXPECT_THROW(grotto::make_lut_union_plan({empty_row}, uint8_t{0}), std::invalid_argument); + + grotto::piecewise_lut too_wide; + too_wide.knots = {0}; + too_wide.coeff = {std::vector(grotto::offset_poly_max_degree + 2, 1)}; + EXPECT_THROW(grotto::make_lut_union_plan({too_wide}, uint8_t{0}), std::invalid_argument); + + grotto::easy_lut broken; + broken.bounds = {0}; + broken.c0 = {0}; + EXPECT_THROW(grotto::piecewise_from_easy(broken), std::invalid_argument); + + grotto::constant_lut bare; + bare.bounds = {std::numeric_limits::min()}; + EXPECT_THROW(grotto::piecewise_from_constant(bare), std::invalid_argument); + + dpf::protocol::composer composer(0); + EXPECT_THROW(grotto::schedule_lut_union(composer, grotto::lut_union_plan{}), + std::invalid_argument); +} + +TEST(LutUnion, CoarsePieceCoversSeveralUnionKnots) +{ + const auto plan = grotto::make_lut_union_plan({lut_a(), lut_b()}, uint8_t{0}); + expect_partition(plan); + ASSERT_EQ(plan.knots, (std::vector{0, 4, 10, 12, 50, 80})); + const auto & first = plan.funcs[0][0]; + EXPECT_EQ(first.end - first.begin, 2u); + EXPECT_EQ(first.kappa, 0); + EXPECT_EQ(first.coeff, (std::vector{1, 0})); + + const uint8_t center = 200; + const uint8_t eta = 100; + const auto carried = grotto::make_lut_union_plan({lut_a(), lut_b()}, eta); + expect_partition(carried); + EXPECT_NE(std::find(carried.knots.begin(), carried.knots.end(), uint8_t{156}), + carried.knots.end()); + const auto mat = grotto::make_offset_poly_keys(center, carried.degree); + const auto got = open_union(mat, carried); + EXPECT_EQ(got[0], grotto::offset_poly_clear(center, lut_a().knots, lut_a().coeff, eta)); + EXPECT_EQ(got[1], grotto::offset_poly_clear(center, lut_b().knots, lut_b().coeff, eta)); +} + +TEST(LutUnion, EveryEtaMatchesASeparatePolynomialEval) +{ + const auto a = lut_a(); + const auto b = lut_b(); + const uint8_t center = 12; + const auto probe = grotto::make_lut_union_plan({a, b}, uint8_t{0}); + const auto mat = grotto::make_offset_poly_keys(center, probe.degree); + const auto wide = grotto::make_offset_poly_keys(center, probe.degree + 2); + const auto alone_a = grotto::make_offset_poly_keys(center, 1); + const auto alone_b = grotto::make_offset_poly_keys(center, 2); + for (int eta = 0; eta < 256; ++eta) + { + const auto e = static_cast(eta); + const auto plan = grotto::make_lut_union_plan({a, b}, e); + expect_partition(plan); + const auto got = open_union(mat, plan); + const auto again = open_union(mat, plan); + EXPECT_EQ(got, again); + EXPECT_EQ(got, open_union(wide, plan)); + const uint64_t a_alone = grotto::offset_poly_eval<0>(alone_a, a.knots, a.coeff, e) + + grotto::offset_poly_eval<1>(alone_a, a.knots, a.coeff, e); + const uint64_t b_alone = grotto::offset_poly_eval<0>(alone_b, b.knots, b.coeff, e) + + grotto::offset_poly_eval<1>(alone_b, b.knots, b.coeff, e); + EXPECT_EQ(got[0], a_alone) << eta; + EXPECT_EQ(got[1], b_alone) << eta; + } +} + +TEST(LutUnion, OnePieceLutCoversTheWholeUnion) +{ + grotto::piecewise_lut whole; + whole.knots = {0}; + whole.coeff = {{5, 1}}; + const auto plan = grotto::make_lut_union_plan({whole, lut_a()}, uint8_t{0}); + expect_partition(plan); + ASSERT_EQ(plan.funcs[0].size(), 1u); + EXPECT_EQ(plan.funcs[0][0].begin, 0u); + EXPECT_EQ(plan.funcs[0][0].end, plan.knots.size()); + + // A nonzero eta inserts the carry cut, so the one public knot becomes two + // refined pieces. They still partition the union. + const uint8_t eta = 9; + const auto split = grotto::make_lut_union_plan({whole, lut_a()}, eta); + expect_partition(split); + EXPECT_GT(split.funcs[0].size(), 1u); + const uint8_t center = 40; + const auto mat = grotto::make_offset_poly_keys(center, split.degree); + const auto got = open_union(mat, split); + EXPECT_EQ(got[0], grotto::offset_poly_clear(center, whole.knots, whole.coeff, eta)); + EXPECT_EQ(got[1], grotto::offset_poly_clear(center, lut_a().knots, lut_a().coeff, eta)); +} + +TEST(LutUnion, IdenticalKnotsStayASingleCopy) +{ + const auto a = lut_a(); + const auto plan = grotto::make_lut_union_plan({a, a}, uint8_t{0}); + EXPECT_EQ(plan.knots, a.knots); + EXPECT_EQ(plan.funcs.size(), 2u); + EXPECT_EQ(plan.prefix_walks, 1u); + expect_partition(plan); +} + +TEST(LutUnion, VerifiableTokensCoverEveryLane) +{ + const auto a = lut_a(); + const auto b = lut_b(); + const uint8_t center = 12; + const uint8_t eta = 5; + const auto plan = grotto::make_lut_union_plan({a, b}, eta); + const auto mat = grotto::make_offset_poly_keys(center, plan.degree, dpf::verifiable{}); + std::vector tok0(plan.lanes), tok1(plan.lanes); + const auto s0 = grotto::lut_union_eval<0>(mat, plan, tok0.data()); + const auto s1 = grotto::lut_union_eval<1>(mat, plan, tok1.data()); + EXPECT_EQ(s0[0] + s1[0], grotto::offset_poly_clear(center, a.knots, a.coeff, eta)); + EXPECT_EQ(s0[1] + s1[1], grotto::offset_poly_clear(center, b.knots, b.coeff, eta)); + for (std::size_t m = 0; m < plan.lanes; ++m) + EXPECT_TRUE(dpf::verify(tok0[m], tok1[m])) << m; + tok0[0][0] = simde_mm_xor_si128(tok0[0][0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(tok0[0], tok1[0])); + EXPECT_TRUE(dpf::verify(tok0[1], tok1[1])); +} + +TEST(LutUnion, ScheduleOnAnExistingSeedStaysOneWalk) +{ + const auto few = grotto::make_lut_union_plan({lut_a()}, uint8_t{1}); + const auto many = grotto::make_lut_union_plan({lut_a(), lut_b(), lut_c()}, uint8_t{1}); + EXPECT_EQ(few.lanes, 2u); + EXPECT_EQ(grotto::lut_union_slot_bytes(1), 16u); + EXPECT_EQ(grotto::lut_union_slot_bytes(few.lanes), 16u); + EXPECT_EQ(grotto::lut_union_slot_bytes(many.lanes), 24u); + + dpf::protocol::composer composer(0); + auto seed = composer.input(dpf::protocol::domain::fss, 16); + grotto::schedule_lut_union(composer, seed, many); + const auto scheduled = composer.default_plan(); + ASSERT_EQ(scheduled.rounds(), many.depth); + for (std::uint16_t round = 0; round < scheduled.rounds(); ++round) + EXPECT_EQ(scheduled.slot_bytes(round), grotto::lut_union_slot_bytes(many.lanes)); +} + +TEST(LutUnion, SignedDomainAndRealTables) +{ + const auto relu = grotto::piecewise_from_easy(grotto::make_relu_lut()); + const auto abs_lut = grotto::piecewise_from_easy(grotto::make_abs_lut()); + const auto square = grotto::piecewise_from_easy(grotto::make_squared_relu_lut(0)); + for (const auto & row : relu.coeff) + EXPECT_EQ(row.size(), 2u); + for (const auto & row : abs_lut.coeff) + EXPECT_EQ(row.size(), 2u); + for (const auto & row : square.coeff) + EXPECT_EQ(row.size(), 3u); + + const int8_t center = -20; + const auto probe = grotto::make_lut_union_plan( + std::vector>{relu, abs_lut, square}, int8_t{0}); + EXPECT_EQ(probe.degree, 2u); + EXPECT_EQ(probe.depth, 8u); + const auto mat = grotto::make_offset_poly_keys(center, probe.degree); + const auto relu_f = grotto::make_relu_lut(); + const auto abs_f = grotto::make_abs_lut(); + const auto sq_f = grotto::make_squared_relu_lut(0); + for (int eta = -128; eta < 128; eta += 7) + { + const auto e = static_cast(eta); + const auto plan = grotto::make_lut_union_plan( + std::vector>{relu, abs_lut, square}, e); + expect_partition(plan); + const auto s0 = grotto::lut_union_eval<0>(mat, plan); + const auto s1 = grotto::lut_union_eval<1>(mat, plan); + const int8_t wrapped = offset_horner_group_add(center, e); + EXPECT_EQ(s0[0] + s1[0], static_cast(relu_f(wrapped))) << eta; + EXPECT_EQ(s0[1] + s1[1], static_cast(abs_f(wrapped))) << eta; + EXPECT_EQ(s0[2] + s1[2], static_cast(sq_f(wrapped))) << eta; + } + + const int8_t share = 3; + const int8_t other = static_cast(center ^ share); + const auto plan = grotto::make_lut_union_plan( + std::vector>{relu, abs_lut, square}, int8_t{-3}); + const auto got = grotto::geneval_lut_union(share, other, plan); + const int8_t wrapped = offset_horner_group_add(center, int8_t{-3}); + EXPECT_EQ(got.value0[0] + got.value1[0], static_cast(relu_f(wrapped))); + EXPECT_EQ(got.value0[1] + got.value1[1], static_cast(abs_f(wrapped))); + EXPECT_EQ(got.value0[2] + got.value1[2], static_cast(sq_f(wrapped))); +} + +TEST(LutUnion, SixteenBitDomainKeepsOneComparison) +{ + grotto::piecewise_lut left; + left.knots = {0, 1000}; + left.coeff = {{3, 1}, {8, 0}}; + grotto::piecewise_lut right; + right.knots = {0, 400, 2000}; + right.coeff = {{1, 0, 2}, {9, 1, 0}, {4, 0, 1}}; + const uint16_t center = 50; + const uint16_t eta = 40000; + const auto plan = grotto::make_lut_union_plan({left, right}, eta); + EXPECT_EQ(plan.depth, 16u); + EXPECT_EQ(plan.geneval_rounds(), 16u); + EXPECT_EQ(plan.comparisons, 1u); + expect_partition(plan); + const auto mat = grotto::make_offset_poly_keys(center, plan.degree); + const auto s0 = grotto::lut_union_eval<0>(mat, plan); + const auto s1 = grotto::lut_union_eval<1>(mat, plan); + EXPECT_EQ(s0[0] + s1[0], grotto::offset_poly_clear(center, left.knots, left.coeff, eta)); + EXPECT_EQ(s0[1] + s1[1], grotto::offset_poly_clear(center, right.knots, right.coeff, eta)); + + dpf::protocol::composer composer(0); + grotto::schedule_lut_union(composer, plan); + EXPECT_EQ(composer.default_plan().rounds(), 16u); +} diff --git a/test/tests/multipoint_test.cpp b/test/tests/multipoint_test.cpp index 5f5bed8..b91db13 100644 --- a/test/tests/multipoint_test.cpp +++ b/test/tests/multipoint_test.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -36,7 +37,7 @@ TEST(Multipoint, PlainPointsAndZeros) EXPECT_FALSE(decltype(k0)::is_verifiable); EXPECT_TRUE(decltype(k0)::is_multipoint); EXPECT_EQ(k0.bucket_count, k1.bucket_count); - EXPECT_EQ(k0.bucket_domain, k1.bucket_domain); + EXPECT_TRUE(k0.bucket_domain == k1.bucket_domain); EXPECT_GT(k0.bucket_count, alphas.size()); expect_points(k0, k1, alphas, betas); @@ -93,8 +94,14 @@ TEST(Multipoint, TamperedBucketRejects) const std::vector betas{1, 1, 1, 1}; auto [k0, k1] = dpf::make_multipoint(alphas, betas, dpf::verifiable{}); - auto & cs = const_cast(k0.buckets[0].correction_seeds()[0]); - cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); + // A single level-0 seed is invisible when that party's root control bit is 0. + ASSERT_FALSE(k0.buckets.empty()); + for (auto & bucket : k0.buckets) + { + using arr = typename std::decay_t::correction_seeds_array; + for (auto & cs : const_cast(bucket.correction_seeds())) + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); + } dpf::proof_token a0{}, a1{}; dpf::audit_multipoint(k0, dpf::prove(a0)); @@ -152,29 +159,92 @@ TEST(Multipoint, RejectsAnEmptyListAndALengthMismatch) { const std::vector alphas{1, 2}; const std::vector betas{1}; - EXPECT_THROW( - { + EXPECT_THROW({ auto keys = dpf::make_multipoint(alphas, betas); (void)keys; - }, - std::invalid_argument); - EXPECT_THROW( - { + }, std::invalid_argument); + EXPECT_THROW({ auto keys = dpf::make_multipoint( std::vector{}, std::vector{}); (void)keys; - }, - std::invalid_argument); + }, std::invalid_argument); +} + +TEST(Multipoint, FullDomainProofsRejectABucketWordFlip) +{ + using Input = std::uint8_t; + const std::vector alphas{1, 9, 40}; + const std::vector betas{7, 11, 3}; + auto [k0, k1] = dpf::make_multipoint(alphas, betas, dpf::verifiable{}); + int mismatches = 0; + for (int x = 0; x < 256; ++x) + { + const Input q = static_cast(x); + dpf::proof_token a{}, b{}; + const auto y = dpf::reconstruct( + dpf::eval_multipoint(k0, q, dpf::prove(a)), + dpf::eval_multipoint(k1, q, dpf::prove(b))); + std::uint64_t want = 0; + for (std::size_t i = 0; i < alphas.size(); ++i) + if (alphas[i] == q) + want = betas[i]; + EXPECT_EQ(y, want) << int(q); + EXPECT_TRUE(dpf::verify(a, b)) << int(q); + } + for (auto & word : const_cast::correction_words_array &>( + k0.buckets[0].correction_words())) + word = simde_mm_xor_si128(word, simde_mm_set1_epi8(0x3c)); + for (auto & cs : const_cast::correction_seeds_array &>( + k0.buckets[0].correction_seeds())) + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); + for (int x = 0; x < 256; ++x) + { + const Input q = static_cast(x); + const auto y = dpf::reconstruct(dpf::eval_multipoint(k0, q), + dpf::eval_multipoint(k1, q)); + std::uint64_t want = 0; + for (std::size_t i = 0; i < alphas.size(); ++i) + if (alphas[i] == q) + want = betas[i]; + if (y != want) + ++mismatches; + } + EXPECT_GT(mismatches, 0); + dpf::proof_token a0{}, a1{}; + dpf::audit_multipoint(k0, dpf::prove(a0)); + dpf::audit_multipoint(k1, dpf::prove(a1)); + EXPECT_FALSE(dpf::verify(a0, a1)); +} + +TEST(Multipoint, WideDomain) +{ + using Input = std::uint64_t; + const std::vector alphas{ + 0x100000001ull, + 0x8000000000000001ull, + 42ull, + 0xfffffffffffffffeull}; + const std::vector betas{9, 8, 7, 6}; + auto [k0, k1] = dpf::make_multipoint(alphas, betas); + expect_points(k0, k1, alphas, betas); + EXPECT_EQ(dpf::reconstruct(dpf::eval_multipoint(k0, Input{1}), + dpf::eval_multipoint(k1, Input{1})), + 0u); + + auto [v0, v1] = dpf::make_multipoint(alphas, betas, dpf::verifiable{}); + dpf::proof_token p0{}, p1{}; + const auto y0 = dpf::eval_multipoint(v0, alphas[1], dpf::prove(p0)); + const auto y1 = dpf::eval_multipoint(v1, alphas[1], dpf::prove(p1)); + EXPECT_EQ(dpf::reconstruct(y0, y1), betas[1]); + EXPECT_TRUE(dpf::verify(p0, p1)); } TEST(Multipoint, RejectsDuplicates) { const std::vector alphas{1, 2, 1, 4}; const std::vector betas{1, 2, 3, 4}; - EXPECT_THROW( - { + EXPECT_THROW({ auto keys = dpf::make_multipoint(alphas, betas); (void)keys; - }, - std::invalid_argument); + }, std::invalid_argument); } diff --git a/test/tests/net_control_test.cpp b/test/tests/net_control_test.cpp new file mode 100644 index 0000000..e79dfa6 --- /dev/null +++ b/test/tests/net_control_test.cpp @@ -0,0 +1,1092 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "dpf/app_flow.hpp" +#include "dpf/compose.hpp" +#include "dpf/compose_async.hpp" +#include "dpf/launch.hpp" +#include "dpf/net/async_round_sink.hpp" +#include "dpf/net/async_sctp_stream_array.hpp" +#include "dpf/net/async_stream_array.hpp" +#include "dpf/net/connect.hpp" +#include "dpf/net/party_session.hpp" +#include "dpf/net/policy.hpp" +#include "dpf/net/round_lane.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/net/sync_stream_array.hpp" +#include "dpf/online_session.hpp" +#include "dpf/party_run.hpp" +#include "dpf/party_runner.hpp" +#include "dpf/run_config.hpp" + +namespace +{ + +using dpf::protocol::domain; +using clock_type = std::chrono::steady_clock; + +void put(std::vector> & values, dpf::protocol::node n, + std::uint64_t v) +{ + if (values.size() <= n.id) + values.resize(n.id + 1); + values[n.id].assign(8, 0); + std::memcpy(values[n.id].data(), &v, 8); +} + +std::uint64_t get(const std::vector> & values, + dpf::protocol::node n, std::size_t lane = 0) +{ + std::uint64_t v = 0; + std::memcpy(&v, values[n.id].data() + 8 * lane, 8); + return v; +} + +/// Pump `io` until `n` of the counted completions arrive or 5 s pass. +void pump(asio::io_context & io, std::atomic & left) +{ + const auto deadline = clock_type::now() + std::chrono::seconds(5); + while (left.load() > 0 && clock_type::now() < deadline) + { + if (io.stopped()) + io.restart(); + io.run_one_for(std::chrono::milliseconds(10)); + } +} + +void step(asio::io_context & io) +{ + if (io.stopped()) + io.restart(); + io.run_one_for(std::chrono::milliseconds(5)); +} + +unsigned short free_port() +{ + asio::io_context io; + asio::ip::tcp::acceptor a(io); + dpf::net::open_listener(a, 0); + return a.local_endpoint().port(); +} + +/// Two parties: x0 + x1 opened, then `k` dependent steps (+1 and reopen). +struct chain +{ + dpf::protocol::plan plan; + dpf::protocol::node x; + dpf::protocol::node out; +}; + +constexpr std::uint32_t k_inc = 94001; + +chain make_chain(std::size_t party, int steps) +{ + dpf::protocol::composer c(party); + chain ch; + ch.x = c.input(domain::a, 8); + auto cur = ch.x; + for (int i = 0; i < steps; ++i) + { + auto e = c.exchange(cur); + cur = c.compute(k_inc, {e}, domain::a, 8); + } + ch.out = cur; + ch.plan = c.schedule(); + return ch; +} + +dpf::protocol::kernel_fn inc_kernel(std::chrono::milliseconds sleep = {}) +{ + return [sleep](std::uint32_t, const std::vector &, + const std::vector & inputs, + dpf::protocol::block_span output, std::size_t lanes) { + if (sleep.count() > 0) + std::this_thread::sleep_for(sleep); + for (std::size_t l = 0; l < lanes; ++l) + { + std::uint64_t v = 0; + std::memcpy(&v, inputs[0].at(l), 8); + v += 1; + std::memcpy(output.at(l), &v, 8); + } + }; +} + +/// Expected result of `make_chain` from inputs a, b. +std::uint64_t chain_value(std::uint64_t a, std::uint64_t b, int steps) +{ + // Each step opens (both parties hold the prior value) and adds 1. + std::uint64_t v = a + b + 1; + for (int i = 1; i < steps; ++i) + v = 2 * v + 1; + return v; +} + +} // namespace + +// --------------------------------------------------------------------------- +// Explicit configuration +// --------------------------------------------------------------------------- + +TEST(RunConfig, EnvAndArgsShareKeys) +{ + ::setenv("DPF_LANES", "4", 1); + ::setenv("DPF_WIRE_WINDOW", "65536", 1); + auto cfg = dpf::app::run_config::from_env(); + ::unsetenv("DPF_LANES"); + ::unsetenv("DPF_WIRE_WINDOW"); + EXPECT_EQ(cfg.n_lanes, 4u); + EXPECT_EQ(cfg.policy.window_bytes, 65536u); + const char * argv[] = {"x", "--transport=parallel", "--framing=always", + "--instances=3", "--sndbuf=262144", "--trials=5", "positional"}; + const auto rest = cfg.apply_args(7, const_cast(argv)); + ASSERT_EQ(rest.size(), 1u); + EXPECT_EQ(rest[0], "positional"); + EXPECT_EQ(cfg.kind, dpf::net::transport::parallel); + EXPECT_EQ(cfg.framing, dpf::net::framing_mode::always); + EXPECT_EQ(cfg.instances, 3u); + EXPECT_EQ(cfg.policy.socket.send_buffer, 262144); + EXPECT_EQ(cfg.trials, 5u); + EXPECT_NE(cfg.summary().find("transport=parallel"), std::string::npos); + EXPECT_THROW(cfg.set("lanse", "3"), std::invalid_argument); + EXPECT_THROW(cfg.set("lanes", "three"), std::invalid_argument); + EXPECT_THROW(cfg.set("transport", "udp"), std::invalid_argument); + EXPECT_THROW(cfg.set("chunk", std::to_string(std::size_t{64} << 20)), + std::invalid_argument); +} + +TEST(RoundLane, FramingModesAndLimits) +{ + dpf::net::round_lane_map a(4, 3, dpf::net::framing_mode::always); + EXPECT_TRUE(a.framed); + EXPECT_EQ(a.lane(2), 2u); + dpf::net::round_lane_map b(2, 6); + EXPECT_TRUE(b.framed); + EXPECT_EQ(b.lane(5), 1u); + EXPECT_THROW(dpf::net::round_lane_map(2, 6, dpf::net::framing_mode::never), + std::invalid_argument); + EXPECT_THROW(dpf::net::round_lane_map(1, 70000), std::invalid_argument); + EXPECT_EQ(dpf::net::lane_count_for_rounds(20), 8u); + EXPECT_EQ(dpf::net::lane_count_for_rounds(20, dpf::net::lanes_one_per_round), + 20u); + EXPECT_EQ(dpf::net::lane_count_for_rounds(3, 8), 3u); +} + +// --------------------------------------------------------------------------- +// Sink hello and framing +// --------------------------------------------------------------------------- + +namespace +{ + +std::string sink_mismatch(std::vector s0, std::vector s1, + std::size_t c0, std::size_t c1, dpf::net::framing_mode f0, + dpf::net::framing_mode f1) +{ + asio::io_context io; + auto ends = dpf::net::make_async_memory_stream_pair(io, 4); + dpf::net::sink_options o0, o1; + o0.framing = f0; + o1.framing = f1; + dpf::net::async_round_sink a(ends.first, s0, c0, o0); + dpf::net::async_round_sink b(ends.second, s1, c1, o1); + const auto deadline = clock_type::now() + std::chrono::seconds(2); + while (clock_type::now() < deadline) + { + try + { + (void)a.peer_ready(0, 0); + (void)b.peer_ready(0, 0); + } + catch (const std::exception & e) + { + return e.what(); + } + step(io); + } + return {}; +} + +} // namespace + +TEST(Sink, HelloNamesTheDisagreement) +{ + using fm = dpf::net::framing_mode; + auto rounds = sink_mismatch({8, 8}, {8}, 1, 1, fm::automatic, fm::automatic); + EXPECT_NE(rounds.find("rounds"), std::string::npos) << rounds; + auto widths = sink_mismatch({8, 8}, {8, 16}, 1, 1, fm::automatic, fm::automatic); + EXPECT_NE(widths.find("slot widths"), std::string::npos) << widths; + auto inst = sink_mismatch({8}, {8}, 2, 1, fm::automatic, fm::automatic); + EXPECT_NE(inst.find("instances 1 vs 2"), std::string::npos) << inst; + auto frame = sink_mismatch({8}, {8}, 1, 1, fm::always, fm::automatic); + EXPECT_NE(frame.find("framing"), std::string::npos) << frame; +} + +TEST(Sink, FramedPartialPrefixReadyPerInstance) +{ + asio::io_context io; + auto ends = dpf::net::make_async_memory_stream_pair(io, 1); + dpf::net::sink_options so; + so.framing = dpf::net::framing_mode::always; + dpf::net::async_round_sink a(ends.first, {8}, 4, so); + dpf::net::async_round_sink b(ends.second, {8}, 4, so); + std::uint8_t slot[8] = {1}; + a.submit(0, 0, slot, 8); + a.submit(0, 1, slot, 8); + a.flush_round(0); + const auto deadline = clock_type::now() + std::chrono::seconds(2); + while (!b.peer_ready(0, 1) && clock_type::now() < deadline) + step(io); + EXPECT_TRUE(b.peer_ready(0, 0)); + EXPECT_TRUE(b.peer_ready(0, 1)); + EXPECT_FALSE(b.peer_ready(0, 2)); + a.submit(0, 2, slot, 8); + a.submit(0, 3, slot, 8); + a.flush_round(0); + while (!b.peer_ready(0, 3) && clock_type::now() < deadline) + step(io); + EXPECT_TRUE(b.peer_ready(0, 3)); + EXPECT_TRUE(a.framed()); +} + +TEST(Sink, PeerFailureSurfacesImmediately) +{ + asio::io_context io; + auto ends = dpf::net::make_async_memory_stream_pair(io, 2); + dpf::net::async_round_sink a(ends.first, {8, 8}, 1); + { + dpf::net::async_round_sink b(ends.second, {8, 8}, 1); + for (int i = 0; i < 50; ++i) + io.poll(); + } + ends.second.close(); + const auto t0 = clock_type::now(); + bool threw = false; + try + { + for (int i = 0; i < 1000 && !threw; ++i) + { + (void)a.peer_ready(0, 0); + a.wait_io_for(std::chrono::milliseconds(5)); + } + } + catch (const std::system_error &) + { + threw = true; + } + EXPECT_TRUE(threw); + EXPECT_LT(clock_type::now() - t0, std::chrono::seconds(2)); +} + +// --------------------------------------------------------------------------- +// Drive-loop budgets +// --------------------------------------------------------------------------- + +TEST(Drive, HealthyPlanLongerThanWaitTimeout) +{ + const int steps = 6; + auto c0 = make_chain(0, steps); + auto c1 = make_chain(1, steps); + std::map k{ + {k_inc, inc_kernel(std::chrono::milliseconds(25))}}; + std::vector> v0(c0.plan.nodes().size()), + v1(c1.plan.nodes().size()); + put(v0, c0.x, 1); + put(v1, c1.x, 2); + dpf::protocol::drive_options opt; + opt.wait_timeout = std::chrono::milliseconds(100); + const auto t0 = clock_type::now(); + dpf::protocol::drive_both_on_async_streams(c0.plan, c1.plan, v0, v1, k, 1, opt); + EXPECT_GT(clock_type::now() - t0, std::chrono::milliseconds(120)); + EXPECT_EQ(get(v0, c0.out), chain_value(1, 2, steps)); +} + +TEST(Drive, EdgeAndRoundBudgetsNameTheWait) +{ + auto c0 = make_chain(0, 2); + asio::io_context io0, io1; + auto ends = dpf::net::make_async_dual_memory_stream_pair(io0, io1, 2); + std::vector> v0(c0.plan.nodes().size()); + put(v0, c0.x, 1); + std::map k{{k_inc, inc_kernel()}}; + + dpf::protocol::drive_options edge; + edge.wait_timeout = std::chrono::seconds(20); + edge.edge_timeout[dpf::net::edge_peer] = std::chrono::milliseconds(40); + auto t0 = clock_type::now(); + try + { + dpf::protocol::drive_plan_on_async_streams(c0.plan, ends.first, v0, k, 0, 1, + edge); + FAIL() << "one-sided drive should time out"; + } + catch (const std::runtime_error & e) + { + const std::string what = e.what(); + EXPECT_NE(what.find("peer"), std::string::npos) << what; + EXPECT_NE(what.find("budget 40"), std::string::npos) << what; + } + EXPECT_LT(clock_type::now() - t0, std::chrono::seconds(5)); + + auto ends2 = dpf::net::make_async_dual_memory_stream_pair(io0, io1, 2); + std::vector> v1(c0.plan.nodes().size()); + put(v1, c0.x, 1); + dpf::protocol::drive_options round; + round.wait_timeout = std::chrono::seconds(20); + round.round_timeout[0] = std::chrono::milliseconds(30); + t0 = clock_type::now(); + EXPECT_THROW(dpf::protocol::drive_plan_on_async_streams(c0.plan, ends2.first, + v1, k, 0, 1, round), + std::runtime_error); + EXPECT_LT(clock_type::now() - t0, std::chrono::seconds(5)); +} + +// --------------------------------------------------------------------------- +// Backends: windows, stats, scheduling, graceful close +// --------------------------------------------------------------------------- + +TEST(Memory, WindowSetterAndGracefulClose) +{ + asio::io_context io; + auto ends = dpf::net::make_async_memory_stream_pair(io, 1); + ends.first.set_window_bytes(100); + EXPECT_EQ(ends.first.window_bytes(), 100u); + std::vector a(300, 1), b(300, 2); + std::atomic left{2}; + ends.first.async_write(0, a.data(), a.size(), [&](auto) { --left; }); + ends.first.async_write(0, b.data(), b.size(), [&](auto) { --left; }); + EXPECT_EQ(ends.first.buffered_bytes(), 600u); + ends.first.close(); + std::vector got(600); + std::atomic rd{1}; + std::error_code rec; + ends.second.async_read(0, got.data(), got.size(), [&](const std::error_code & ec) { + rec = ec; + --rd; + }); + pump(io, rd); + EXPECT_FALSE(rec); + EXPECT_EQ(got[0], 1); + EXPECT_EQ(got[599], 2); + const auto st = ends.first.stats(); + EXPECT_EQ(st.payload_out, 600u); + EXPECT_TRUE(st.closed); +} + +namespace +{ + +/// Localhost mux pair, both ends on `io`. +struct mux_pair +{ + std::unique_ptr a; + std::unique_ptr b; +}; + +mux_pair make_mux_pair(asio::io_context & io, std::size_t lanes, + const dpf::net::wire_policy & pol = {}) +{ + asio::ip::tcp::acceptor acc(io); + dpf::net::open_listener(acc, 0); + asio::ip::tcp::socket s0(io), s1(io); + std::thread t([&] { + dpf::net::connect_until(s1, "127.0.0.1", acc.local_endpoint().port(), + std::chrono::seconds(5)); + }); + dpf::net::accept_until(acc, s0, std::chrono::seconds(5)); + t.join(); + mux_pair out; + out.a = std::make_unique(io, std::move(s0), + 0, 1, lanes, pol); + out.b = std::make_unique(io, std::move(s1), + 1, 0, lanes, pol); + return out; +} + +} // namespace + +TEST(Mux, StatsCountHeaders) +{ + asio::io_context io; + auto m = make_mux_pair(io, 2); + std::vector out(100, 7), in(100); + std::atomic left{2}; + m.a->async_write(0, out.data(), out.size(), [&](auto) { --left; }); + m.b->async_read(0, in.data(), in.size(), [&](auto) { --left; }); + pump(io, left); + const auto s = m.a->stats(); + EXPECT_EQ(s.payload_out, 100u); + EXPECT_EQ(s.bytes_out, 110u); + EXPECT_EQ(s.frames_out, 1u); + EXPECT_EQ(in, out); +} + +TEST(Mux, SmallWriteIsNotQueuedBehindLargeWrite) +{ + asio::io_context io; + dpf::net::wire_policy pol; + pol.chunk_bytes = 16 << 10; + pol.window_bytes = 0; + auto m = make_mux_pair(io, 2, pol); + std::vector big(8u << 20, 1), small(8, 2); + std::vector big_in(big.size()), small_in(8); + std::atomic left{2}; + std::atomic order{0}; + int big_at = 0, small_at = 0; + m.a->async_write(0, big.data(), big.size(), [](auto) {}); + m.a->async_write(1, small.data(), small.size(), [](auto) {}); + m.b->async_read(0, big_in.data(), big_in.size(), [&](auto) { + big_at = ++order; + --left; + }); + m.b->async_read(1, small_in.data(), small_in.size(), [&](auto) { + small_at = ++order; + --left; + }); + pump(io, left); + EXPECT_EQ(small_at, 1); + EXPECT_EQ(big_at, 2); + EXPECT_EQ(small_in, small); + EXPECT_EQ(big_in, big); + EXPECT_GT(m.a->stats().frames_out, 100u); +} + +TEST(Mux, DestroyAfterWriteStillDelivers) +{ + asio::io_context io; + auto m = make_mux_pair(io, 1); + std::vector out(4u << 20, 9), in(out.size()); + m.a->async_write(0, out.data(), out.size(), [](auto) {}); + m.a.reset(); + std::atomic left{1}; + std::error_code rec; + m.b->async_read(0, in.data(), in.size(), [&](const std::error_code & ec) { + rec = ec; + --left; + }); + pump(io, left); + EXPECT_FALSE(rec); + EXPECT_EQ(in, out); +} + +TEST(Parallel, PerLaneWindows) +{ + asio::io_context io; + std::atomic port{0}; + std::vector a, b; + std::thread t([&] { a = dpf::net::accept_parallel_tcp(io, port, 2); }); + while (port.load() == 0) + std::this_thread::yield(); + b = dpf::net::connect_parallel_tcp(io, "127.0.0.1", port, 2); + t.join(); + dpf::net::wire_policy pol; + pol.window_bytes = 1000; + dpf::net::async_parallel_stream_array pa(io, std::move(a), pol); + dpf::net::async_parallel_stream_array pb(io, std::move(b), pol); + EXPECT_EQ(pa.lane_window_bytes(0), 1000u); + EXPECT_EQ(pa.window_bytes(), 2000u); + pa.set_window_bytes(500); + EXPECT_EQ(pa.lane_window_bytes(1), 500u); + std::vector out(64, 3), in(64); + std::atomic left{2}; + pa.async_write(1, out.data(), out.size(), [&](auto) { --left; }); + pb.async_read(1, in.data(), in.size(), [&](auto) { --left; }); + pump(io, left); + EXPECT_EQ(in, out); + EXPECT_EQ(pa.stats().bytes_out, 68u); +} + +// --------------------------------------------------------------------------- +// Synchronous mux: same wire as async mux, no flush deadlock +// --------------------------------------------------------------------------- + +TEST(SyncMux, InteroperatesWithAsyncMux) +{ + // Blocking sync faces need one side to read first so the peer's write can + // complete (the old fd mux pumped both directions while blocked). + std::atomic port{0}; + std::vector from_sync(3000, 5), from_async(5000, 6); + std::vector got_sync(from_async.size()), got_async(from_sync.size()); + std::exception_ptr err; + std::mutex err_mu; + auto note = [&](std::exception_ptr e) { + std::lock_guard lock(err_mu); + if (!err) + err = std::move(e); + }; + std::thread sync_side([&] { + try + { + dpf::run::tcp_pair_mux(1, "127.0.0.1", port, 2, + [&](unsigned, dpf::net::mux_stream_array & mux) { + mux.read(0, got_sync.data(), got_sync.size()); + mux.write(1, from_sync.data(), from_sync.size()); + mux.flush(1); + }); + } + catch (...) + { + note(std::current_exception()); + } + }); + try + { + dpf::run::tcp_pair_mux(0, "127.0.0.1", port, 2, + [&](unsigned, dpf::net::mux_stream_array & mux) { + mux.write(0, from_async.data(), from_async.size()); + mux.flush(0); + mux.read(1, got_async.data(), got_async.size()); + }); + } + catch (...) + { + note(std::current_exception()); + } + sync_side.join(); + if (err) + std::rethrow_exception(err); + EXPECT_EQ(got_async, from_sync); + EXPECT_EQ(got_sync, from_async); +} + +TEST(SyncMux, LargeCrossFlushDoesNotDeadlock) +{ + std::atomic port{0}; + std::vector big(4u << 20); + for (std::size_t i = 0; i < big.size(); ++i) + big[i] = static_cast(i); + std::atomic ok{0}; + auto side = [&](unsigned party) { + dpf::run::tcp_pair_mux(party, "127.0.0.1", port, 1, + [&](unsigned, dpf::net::mux_stream_array & mux) { + mux.write(0, big.data(), big.size()); + mux.flush(0); + std::vector in(big.size()); + mux.read(0, in.data(), in.size()); + if (in == big) + ++ok; + }); + }; + std::thread t0([&] { side(0); }); + std::thread t1([&] { side(1); }); + t0.join(); + t1.join(); + EXPECT_EQ(ok.load(), 2); +} + +// --------------------------------------------------------------------------- +// Sessions: static tables, deadlines, per-edge transport, reconnect +// --------------------------------------------------------------------------- + +TEST(Session, ConnectHasADeadline) +{ + asio::io_context io; + asio::ip::tcp::socket s(io); + const auto port = free_port(); + const auto t0 = clock_type::now(); + EXPECT_THROW(dpf::net::connect_until(s, "127.0.0.1", port, + std::chrono::milliseconds(200)), + std::system_error); + EXPECT_LT(clock_type::now() - t0, std::chrono::seconds(2)); +} + +TEST(Session, StaticTableAnyStartOrder) +{ + const std::vector table = { + {"127.0.0.1", free_port()}, {"127.0.0.1", free_port()}}; + std::atomic ok{0}; + auto run = [&](unsigned me, std::chrono::milliseconds delay) { + std::this_thread::sleep_for(delay); + asio::io_context io; + dpf::net::party_session s(io, me, 2, std::size_t{1}); + s.join(table); + std::uint64_t mine = me + 10, got = 0; + std::atomic left{2}; + s.peer(1 - me).async_write(0, &mine, 8, [&](auto) { --left; }); + s.peer(1 - me).async_read(0, &got, 8, [&](auto) { --left; }); + pump(io, left); + if (got == 11u - me) + ++ok; + }; + std::thread late([&] { run(0, std::chrono::milliseconds(300)); }); + std::thread early([&] { run(1, std::chrono::milliseconds(0)); }); + late.join(); + early.join(); + EXPECT_EQ(ok.load(), 2); +} + +TEST(Session, TransportMismatchIsNamed) +{ + auto ports = dpf::net::make_mesh_ports(2); + std::string e0, e1; + auto run = [&](unsigned me, dpf::net::transport t, std::string & err) { + try + { + asio::io_context io; + dpf::net::session_options so; + so.n_lanes = 2; + so.limits.accept = std::chrono::milliseconds(2000); + dpf::net::party_session s(io, me, 2, so); + s.set_edge_transport(1 - me, t); + s.join("127.0.0.1", ports); + } + catch (const std::exception & e) + { + err = e.what(); + } + }; + std::thread t0([&] { run(0, dpf::net::transport::mux, e0); }); + std::thread t1([&] { run(1, dpf::net::transport::parallel, e1); }); + t0.join(); + t1.join(); + const std::string both = e0 + " | " + e1; + EXPECT_NE(both.find("transport"), std::string::npos) << both; +} + +TEST(Session, ParallelAndSctpEdges) +{ + std::vector kinds = {dpf::net::transport::parallel}; + if (dpf::net::sctp_available()) + kinds.push_back(dpf::net::transport::sctp); + for (auto kind : kinds) + { + auto ports = dpf::net::make_mesh_ports(2); + std::atomic ok{0}; + std::string err; + std::mutex mu; + auto run = [&](unsigned me) { + try + { + asio::io_context io; + dpf::net::session_options so; + so.n_lanes = 3; + so.kind = kind; + // SCTP links cannot be encrypted. + so.security.encrypt = kind != dpf::net::transport::sctp; + dpf::net::party_session s(io, me, 2, so); + s.join("127.0.0.1", ports); + std::vector out(1000, static_cast(me + 1)); + std::vector in(1000); + std::atomic left{2}; + s.peer(1 - me).async_write(2, out.data(), out.size(), [&](auto) { --left; }); + s.peer(1 - me).async_read(2, in.data(), in.size(), [&](auto) { --left; }); + pump(io, left); + if (in[0] == static_cast(2 - me) + && s.edge_stats(1 - me).payload_out == 1000u) + ++ok; + } + catch (const std::exception & e) + { + std::lock_guard lock(mu); + err = e.what(); + } + }; + std::thread t0([&] { run(0); }); + std::thread t1([&] { run(1); }); + t0.join(); + t1.join(); + EXPECT_EQ(ok.load(), 2) << dpf::net::transport_name(kind) << ": " << err; + } +} + +TEST(Session, ReconnectResumesMidPlan) +{ + const int steps = 5; + auto c0 = make_chain(0, steps); + auto c1 = make_chain(1, steps); + auto ports = dpf::net::make_mesh_ports(2); + std::uint64_t result[2] = {0, 0}; + std::uint64_t resumes[2] = {0, 0}; + std::string err; + std::mutex mu; + auto run = [&](unsigned me, const chain & ch) { + try + { + asio::io_context io; + dpf::net::party_session s(io, me, 2, std::size_t{steps}); + s.join("127.0.0.1", ports); + int calls = 0; + std::map k{ + {k_inc, + [&, base = inc_kernel()](std::uint32_t op, + const std::vector & ns, + const std::vector & in, + dpf::protocol::block_span out, std::size_t lanes) { + if (me == 0 && ++calls == 2) + s.peer(1).close(); + base(op, ns, in, out, lanes); + }}}; + dpf::net::sink_options so; + so.reconnect = s.reconnector(1 - me); + dpf::net::async_round_sink sink(s.peer(1 - me), ch.plan.slot_bytes_all(), + 1, so); + std::vector> v(ch.plan.nodes().size()); + put(v, ch.x, me + 1); + dpf::protocol::drive_via_schedule(ch.plan, sink, v, k, me); + result[me] = get(v, ch.out); + resumes[me] = sink.stats().resumes; + } + catch (const std::exception & e) + { + std::lock_guard lock(mu); + err += std::string(e.what()) + "; "; + } + }; + std::thread t0([&] { run(0, c0); }); + std::thread t1([&] { run(1, c1); }); + t0.join(); + t1.join(); + ASSERT_TRUE(err.empty()) << err; + EXPECT_EQ(result[0], chain_value(1, 2, steps)); + EXPECT_EQ(result[1], chain_value(1, 2, steps)); + EXPECT_EQ(resumes[0], 1u); + EXPECT_EQ(resumes[1], 1u); +} + +TEST(Session, DealerLinkHasItsOwnEpoch) +{ + asio::io_context dio, pio; + std::atomic port{0}; + std::string err; + std::mutex mu; + std::thread dealer([&] { + try + { + dpf::net::dealer_session d(dio, 1); + port.store(d.listen()); + d.accept_parties(); + std::uint64_t v = 5; + std::atomic left{1}; + d.party(0).async_write(0, &v, 8, [&](auto) { --left; }); + pump(dio, left); + d.reconnect(0); + v = 6; + left = 1; + d.party(0).async_write(0, &v, 8, [&](auto) { --left; }); + pump(dio, left); + } + catch (const std::exception & e) + { + std::lock_guard lock(mu); + err += e.what(); + } + }); + while (port.load() == 0) + std::this_thread::yield(); + dpf::net::party_session p(pio, 0, 2, std::size_t{1}); + p.connect_dealer("127.0.0.1", port.load()); + std::uint64_t got = 0; + std::atomic left{1}; + p.dealer().async_read(0, &got, 8, [&](auto) { --left; }); + pump(pio, left); + EXPECT_EQ(got, 5u); + p.reconnect_dealer(); + left = 1; + p.dealer().async_read(0, &got, 8, [&](auto) { --left; }); + pump(pio, left); + dealer.join(); + EXPECT_TRUE(err.empty()) << err; + EXPECT_EQ(got, 6u); +} + +// --------------------------------------------------------------------------- +// N-party runner and harness +// --------------------------------------------------------------------------- + +TEST(Runner, TwoPartyOnEveryTransport) +{ + std::vector kinds = {dpf::net::transport::async_memory, + dpf::net::transport::local, dpf::net::transport::mux, + dpf::net::transport::parallel}; + if (dpf::net::sctp_available()) + kinds.push_back(dpf::net::transport::sctp); + const int steps = 4; + for (auto kind : kinds) + { + auto c0 = make_chain(0, steps); + auto c1 = make_chain(1, steps); + dpf::app::party_values v0(c0.plan.nodes().size()), v1(c1.plan.nodes().size()); + put(v0, c0.x, 3); + put(v1, c1.x, 4); + dpf::app::run_config cfg; + cfg.kind = kind; + cfg.n_lanes = 2; + cfg.security.encrypt = kind != dpf::net::transport::sctp; + std::map k{{k_inc, inc_kernel()}}; + const auto r = dpf::run_two_party(c0.plan, c1.plan, v0, v1, k, cfg); + EXPECT_EQ(get(v0, c0.out), chain_value(3, 4, steps)) + << dpf::net::transport_name(kind); + EXPECT_EQ(get(v1, c1.out), chain_value(3, 4, steps)) + << dpf::net::transport_name(kind); + EXPECT_GT(r.wire[0].payload_out, 0u) << dpf::net::transport_name(kind); + if (kind == dpf::net::transport::async_memory || kind == dpf::net::transport::sctp) + EXPECT_EQ(r.wire[0].bytes_out, r.wire[0].payload_out); + else + EXPECT_GT(r.wire[0].bytes_out, r.wire[0].payload_out) + << dpf::net::transport_name(kind); + } +} + +TEST(Runner, InstancesAndComputePool) +{ + const int steps = 3; + auto c0 = make_chain(0, steps); + auto c1 = make_chain(1, steps); + dpf::app::party_values v0(c0.plan.nodes().size()), v1(c1.plan.nodes().size()); + v0[c0.x.id].assign(8 * 4, 0); + v1[c1.x.id].assign(8 * 4, 0); + for (std::size_t l = 0; l < 4; ++l) + { + std::uint64_t a = l, b = 10; + std::memcpy(v0[c0.x.id].data() + 8 * l, &a, 8); + std::memcpy(v1[c1.x.id].data() + 8 * l, &b, 8); + } + dpf::app::run_config cfg; + cfg.instances = 4; + cfg.compute_threads = 2; + cfg.framing = dpf::net::framing_mode::always; + std::map k{{k_inc, inc_kernel()}}; + (void)dpf::run_two_party(c0.plan, c1.plan, v0, v1, k, cfg); + for (std::size_t l = 0; l < 4; ++l) + EXPECT_EQ(get(v0, c0.out, l), chain_value(l, 10, steps)); +} + +TEST(Runner, StarOnEveryTransport) +{ + std::vector kinds = {dpf::net::transport::async_memory, + dpf::net::transport::local, dpf::net::transport::mux, + dpf::net::transport::parallel}; + if (dpf::net::sctp_available()) + kinds.push_back(dpf::net::transport::sctp); + // pirsona_bitmore_fetch(L) is a star over 2^L servers. + constexpr std::size_t L = 2; + constexpr std::size_t n = std::size_t{1} << L; + constexpr std::size_t query = 16 * L; + for (auto kind : kinds) + { + auto seeds = std::make_shared>>(n); + auto answers = std::make_shared>>(n); + for (std::size_t i = 0; i < n; ++i) + { + (*seeds)[i].assign(query, static_cast(i + 1)); + (*answers)[i].assign(8, static_cast(0x40 + i)); + } + auto client = dpf::protocol::pirsona_bitmore_fetch(L, 16, 8, seeds, answers); + dpf::app::run_config cfg; + cfg.kind = kind; + cfg.n_lanes = 1; + cfg.wait_timeout = std::chrono::seconds(10); + cfg.security.encrypt = kind != dpf::net::transport::sctp; + EXPECT_NO_THROW(dpf::session::drive_async_star(n, {query, 8u}, + std::move(client), + [&](std::size_t i) { + return dpf::protocol::star_server_reply_rounds(query, 8, (*answers)[i]); + }, + cfg)) + << dpf::net::transport_name(kind); + } +} + +TEST(Runner, ShortInputIsRejectedNotZeroed) +{ + auto c0 = make_chain(0, 1); + auto c1 = make_chain(1, 1); + dpf::app::party_values v0(c0.plan.nodes().size()), v1(c1.plan.nodes().size()); + put(v0, c0.x, 1); + put(v1, c1.x, 2); + dpf::app::run_config cfg; + cfg.instances = 4; + std::map k{{k_inc, inc_kernel()}}; + try + { + (void)dpf::run_two_party(c0.plan, c1.plan, v0, v1, k, cfg); + FAIL() << "8-byte input for 4 instances should be rejected"; + } + catch (const std::exception & e) + { + EXPECT_NE(std::string(e.what()).find("input node"), std::string::npos) + << e.what(); + } +} + +TEST(Runner, ThreePartyDealerRingAndPeer) +{ + struct built + { + dpf::protocol::plan plan; + dpf::protocol::node y, ring, pad, mask, x, open; + }; + auto make = [](std::size_t party) { + dpf::protocol::composer c(party); + built b; + b.y = c.input(domain::y, 8); + b.ring = c.rss_from_y(b.y); + b.pad = c.input(domain::a, 8); + b.mask = c.dealer_deliver(b.pad); + b.x = c.input(domain::a, 8); + b.open = c.exchange(b.x); + b.plan = c.schedule(); + return b; + }; + for (auto kind : {dpf::net::transport::async_memory, dpf::net::transport::mux}) + { + built b[3] = {make(0), make(1), make(2)}; + std::vector values(3); + for (int i = 0; i < 3; ++i) + { + values[i].resize(b[i].plan.nodes().size()); + put(values[i], b[i].y, 100 + i); + put(values[i], b[i].pad, i == 2 ? 77 : 0); + put(values[i], b[i].x, i == 0 ? 20 : 22); + } + dpf::app::run_config cfg; + cfg.kind = kind; + (void)dpf::app::run_parties({b[0].plan, b[1].plan, b[2].plan}, values, {}, + cfg); + for (int i = 0; i < 3; ++i) + { + std::uint64_t own = 0, next = 0; + std::memcpy(&own, values[i][b[i].ring.id].data(), 8); + std::memcpy(&next, values[i][b[i].ring.id].data() + 8, 8); + EXPECT_EQ(own, 100u + i) << dpf::net::transport_name(kind); + EXPECT_EQ(next, 100u + (i + 1) % 3) << dpf::net::transport_name(kind); + } + for (int i = 0; i < 2; ++i) + { + EXPECT_EQ(get(values[i], b[i].mask), 77u); + EXPECT_EQ(get(values[i], b[i].open), 42u); + } + } +} + +TEST(Runner, SeparateProcessesFromAStaticTable) +{ + const std::vector peers = { + "127.0.0.1:" + std::to_string(free_port()), + "127.0.0.1:" + std::to_string(free_port())}; + const std::string list = peers[0] + "," + peers[1]; + const int steps = 3; + pid_t kids[2]; + for (int me = 0; me < 2; ++me) + { + const pid_t pid = ::fork(); + ASSERT_GE(pid, 0); + if (pid == 0) + { + int code = 1; + try + { + const std::string party = "--party=" + std::to_string(me); + const std::string pl = "--peers=" + list; + const char * argv[] = {"node", party.c_str(), pl.c_str(), + "--transport=mux", "--lanes=2"}; + const auto args = dpf::app::parse_node_args(5, + const_cast(argv), dpf::app::run_config{}); + auto ch = make_chain(static_cast(me), steps); + dpf::app::party_values v(ch.plan.nodes().size()); + put(v, ch.x, me == 0 ? 5 : 6); + std::map k{ + {k_inc, inc_kernel()}}; + (void)dpf::app::run_node(args, ch.plan, v, k); + code = get(v, ch.out) == chain_value(5, 6, steps) ? 0 : 2; + } + catch (const std::exception & e) + { + std::fprintf(stderr, "party %d: %s\n", me, e.what()); + code = 3; + } + ::_exit(code); + } + kids[me] = pid; + } + for (int me = 0; me < 2; ++me) + { + int status = 0; + ASSERT_EQ(::waitpid(kids[me], &status, 0), kids[me]); + ASSERT_TRUE(WIFEXITED(status)); + EXPECT_EQ(WEXITSTATUS(status), 0) << "party " << me; + } +} + +TEST(Harness, TrialsConfigAndWireRecorded) +{ + auto c0 = make_chain(0, 2); + auto c1 = make_chain(1, 2); + std::vector inputs(2); + inputs[0].resize(c0.plan.nodes().size()); + inputs[1].resize(c1.plan.nodes().size()); + put(inputs[0], c0.x, 1); + put(inputs[1], c1.x, 2); + std::map k{{k_inc, inc_kernel()}}; + dpf::app::run_config cfg; + cfg.kind = dpf::net::transport::mux; + cfg.warmup = 1; + cfg.trials = 3; + dpf::experiment ex("chain", "p0"); + const auto cost = + dpf::app::exercise_parties({c0.plan, c1.plan}, inputs, k, &ex, cfg); + EXPECT_EQ(ex.trials().size(), 3u); + EXPECT_GT(cost.wall_ns, 0u); + EXPECT_GT(cost.wire_out, cost.bytes); + EXPECT_EQ(ex.wire().bytes_out, cost.wire_out); + bool has_transport = false; + for (const auto & kv : ex.config()) + has_transport = has_transport || (kv.first == "transport" && kv.second == "mux"); + EXPECT_TRUE(has_transport); + const std::string dir = "/tmp/libdpf_net_control_" + std::to_string(::getpid()); + ex.write_csv(dir); + for (const char * f : {"/config.csv", "/trials.csv", "/wire.csv"}) + { + std::ifstream in(dir + f); + EXPECT_TRUE(static_cast(in)) << f; + } + (void)::system(("rm -rf '" + dir + "'").c_str()); +} + +TEST(Prep, ShippedOverADealerSession) +{ + dpf::prep::demand d; + d.ring_triples = 2; + dpf::app::run_config cfg; + cfg.kind = dpf::net::transport::mux; + auto shipped = dpf::session::ship_prep(d, cfg); + std::uint8_t a0[8], b0[8], c0[8], a1[8], b1[8], c1[8]; + shipped.party0.take_ring(a0, b0, c0); + shipped.party1.take_ring(a1, b1, c1); + std::uint64_t ta[2], tb[2], tc[2]; + std::memcpy(&ta[0], a0, 8); + std::memcpy(&tb[0], b0, 8); + std::memcpy(&tc[0], c0, 8); + std::memcpy(&ta[1], a1, 8); + std::memcpy(&tb[1], b1, 8); + std::memcpy(&tc[1], c1, 8); + EXPECT_EQ((ta[0] + ta[1]) * (tb[0] + tb[1]), tc[0] + tc[1]); +} + +TEST(Sink, WindowGatesPipelining) +{ + asio::io_context io0, io1; + auto ends = dpf::net::make_async_dual_memory_stream_pair(io0, io1, 1, 64); + dpf::net::sink_options so; + so.drain_timeout = std::chrono::milliseconds(300); + dpf::net::async_round_sink a(ends.first, {256}, 1, so); + std::vector slot(256, 1); + a.submit(0, 0, slot.data(), slot.size()); + EXPECT_THROW(a.flush_round(0), std::runtime_error); + EXPECT_FALSE(a.can_send_ahead()); +} diff --git a/test/tests/nmod_test.cpp b/test/tests/nmod_test.cpp index 8db93bc..52eb526 100644 --- a/test/tests/nmod_test.cpp +++ b/test/tests/nmod_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "grotto/nmod.hpp" @@ -164,8 +165,7 @@ TEST(Nmod, RejectsAZeroReciprocalAndAHugeQuotient) EXPECT_THROW(grotto::nmod(1, 0, 0, 0, 4), std::invalid_argument); EXPECT_THROW(grotto::nmod(1, 0, 1, 0, 64), std::invalid_argument); EXPECT_THROW(grotto::nmod_pow2(1, 0, 128, 4), std::overflow_error); - EXPECT_THROW(grotto::nmod(INT64_MAX, 0, u128{1} << 80, 0, 4), - std::overflow_error); + EXPECT_THROW(grotto::nmod(INT64_MAX, 0, u128{1} << 80, 0, 4), std::overflow_error); } TEST(Nmod, ScalePastTheProductWindow) diff --git a/test/tests/offset_horner_test.cpp b/test/tests/offset_horner_test.cpp index 09712df..5ad087f 100644 --- a/test/tests/offset_horner_test.cpp +++ b/test/tests/offset_horner_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "dpf.hpp" #include "grotto/offset_horner.hpp" @@ -445,23 +446,17 @@ TEST(OffsetHorner, WrapSharesHideThePayload) } } -TEST(OffsetHorner, PowerKeysAreIndependentComparisons) +TEST(OffsetHorner, PowersShareOneSeedSpine) { constexpr std::size_t D = 3; const uint16_t center = 1000; auto mat = grotto::make_offset_horner_keys(center); - const auto & k0 = std::get<0>(mat.keys[0]); - const auto & k1 = std::get<0>(mat.keys[1]); + const auto & k0 = std::get<0>(mat.keys); + const auto & k1 = std::get<1>(mat.keys); EXPECT_NE(std::memcmp(&k0.root(), &k1.root(), sizeof(k0.root())), 0); - bool cw_differs = false; const std::size_t depth = std::remove_reference_t::depth; - for (std::size_t level = 0; level < depth; ++level) - { - if (k0.value_cw(level) != k1.value_cw(level)) - cw_differs = true; - } - EXPECT_TRUE(cw_differs); - EXPECT_EQ(mat.keys.size(), D + 1); + EXPECT_GT(depth, 0u); + EXPECT_EQ(k0.value_cw(0), k1.value_cw(0)); } TEST(OffsetHorner, DegreeZeroMatchesSignRespectingDot) @@ -744,7 +739,6 @@ TEST(OffsetHorner, GenevalXorSharesMatchTheDealerPoint) EXPECT_EQ(grotto::geneval_offset_horner_center(center, uint8_t{0}), center); const auto got = grotto::geneval_offset_horner(share, other, eta, knots, coeff); - EXPECT_EQ(got.center, center); EXPECT_EQ(got.eta, eta); EXPECT_EQ(got.value0 + got.value1, gold(center, eta, knots, coeff)); EXPECT_EQ(got.value0 + got.value1, 30u); @@ -769,7 +763,6 @@ TEST(OffsetHorner, GenevalFromAdditiveSharesOfXAndR) const uint8_t eta = offset_horner_group_sub(x, r); const uint8_t center = offset_horner_group_add(r, r); EXPECT_EQ(got.eta, eta); - EXPECT_EQ(got.center, center); EXPECT_EQ(got.value0 + got.value1, gold(center, eta, knots, coeff)); EXPECT_EQ(got.value0 + got.value1, 88u); const uint8_t wrapped = offset_horner_group_add(center, eta); @@ -796,7 +789,6 @@ TEST(OffsetHorner, GenevalSignedSharesUseGenevalConvention) const int8_t eta = -3; EXPECT_EQ(grotto::geneval_offset_horner_center(share, other), center); const auto got = grotto::geneval_offset_horner(share, other, eta, knots, coeff); - EXPECT_EQ(got.center, center); EXPECT_EQ(got.value0 + got.value1, gold(center, eta, knots, coeff)); const int8_t x = 40; @@ -809,7 +801,6 @@ TEST(OffsetHorner, GenevalSignedSharesUseGenevalConvention) knots, coeff); const int8_t expect_center = offset_horner_group_add(r, r); const int8_t expect_eta = offset_horner_group_sub(x, r); - EXPECT_EQ(from_mask.center, expect_center); EXPECT_EQ(from_mask.eta, expect_eta); EXPECT_EQ(from_mask.value0 + from_mask.value1, gold(expect_center, expect_eta, knots, coeff)); @@ -891,7 +882,6 @@ void expect_geneval(T center, T eta, const std::vector & knots, const T other = static_cast(center ^ share); const auto g = grotto::geneval_offset_horner(share, other, eta, knots, coeff); const uint64_t want = gold(center, eta, knots, coeff); - EXPECT_EQ(g.center, center) << where; EXPECT_EQ(g.value0 + g.value1, want) << where; uint64_t summed = 0; for (std::size_t k = 0; k <= Degree; ++k) @@ -1244,14 +1234,17 @@ template bool addition_leaves_domain(T center, T eta) { constexpr unsigned bits = dpf::utils::bitlength_of_v; - if (bits > 62) + if constexpr (bits > 62) return false; - const int64_t sum = math_of(center) + math_of(eta); - const int64_t mod = int64_t{1} << bits; - if constexpr (std::is_signed_v) - return sum >= (mod >> 1) || sum < -(mod >> 1); else - return sum >= mod; + { + const int64_t sum = math_of(center) + math_of(eta); + const int64_t mod = int64_t{1} << bits; + if constexpr (std::is_signed_v) + return sum >= (mod >> 1) || sum < -(mod >> 1); + else + return sum >= mod; + } } template @@ -1399,10 +1392,10 @@ void exercise_big_domain() const T r1 = offset_horner_group_sub(r, r0); const auto got = grotto::geneval_offset_horner(x0, x1, r0, r1, knots, coeff); const T sum = offset_horner_group_add(x, r); - EXPECT_EQ(got.center, offset_horner_group_add(r, r)); + const T expect_center = offset_horner_group_add(r, r); EXPECT_EQ(got.eta, offset_horner_group_sub(x, r)); - EXPECT_EQ(offset_horner_group_add(got.center, got.eta), sum); - EXPECT_EQ(got.value0 + got.value1, gold(got.center, got.eta, knots, coeff)); + EXPECT_EQ(offset_horner_group_add(expect_center, got.eta), sum); + EXPECT_EQ(got.value0 + got.value1, gold(expect_center, got.eta, knots, coeff)); if (::testing::Test::HasFailure()) return; } diff --git a/test/tests/offset_jet_test.cpp b/test/tests/offset_jet_test.cpp new file mode 100644 index 0000000..d36d6e6 --- /dev/null +++ b/test/tests/offset_jet_test.cpp @@ -0,0 +1,192 @@ +#include +#include + +#include "grotto/offset_jet.hpp" + +#include "dpf/verifiable.hpp" + +#include +#include +#include + +namespace +{ + +uint64_t binom_ref(std::int64_t n, unsigned k) +{ + if (k == 0) + return 1; + if (n >= 0) + { + unsigned __int128 acc = 1; + for (unsigned i = 1; i <= k; ++i) + acc = acc * static_cast(n - static_cast(k - i)) / i; + return static_cast(acc); + } + const uint64_t mag = binom_ref(-n + static_cast(k) - 1, k); + return (k & 1u) ? static_cast(0) - mag : mag; +} + +} // namespace + +TEST(OffsetJet, BinomMatchesReference) +{ + for (uint64_t n = 0; n < 40; ++n) + for (unsigned k = 0; k <= 16; ++k) + EXPECT_EQ(grotto::offset_jet_binom(n, k), binom_ref(static_cast(n), k)) + << "n=" << n << " k=" << k; + + for (std::int64_t n = -20; n < 0; ++n) + for (unsigned k = 0; k <= 10; ++k) + EXPECT_EQ(grotto::offset_jet_binom(n, k), binom_ref(n, k)) + << "n=" << n << " k=" << k; + + // Chu–Vandermonde sanity for a large center and a public kappa. + const uint64_t c = (uint64_t{1} << 40) + 17; + const std::int64_t kappa = -3; + for (unsigned k = 0; k <= 8; ++k) + { + uint64_t lhs = grotto::offset_jet_binom( + static_cast(c) + kappa, k); + uint64_t rhs = 0; + for (unsigned j = 0; j <= k; ++j) + rhs += grotto::offset_jet_binom(c, j) + * grotto::offset_jet_binom(kappa, k - j); + EXPECT_EQ(lhs, rhs) << "k=" << k; + } +} + +TEST(OffsetJet, PublicCoefficientsMatchTheWrappedPoint) +{ + const std::size_t degree = 3; + const uint8_t center = 9; + const auto mat = grotto::make_offset_jet_keys(center, degree); + // f(x) = 2 + 3 C(x,1) + C(x,3) + const std::vector coeff{2, 3, 0, 1}; + const std::vector knots{0}; + for (int eta = 0; eta < 256; eta += 19) + { + const auto e = static_cast(eta); + const uint64_t s0 = grotto::offset_jet_eval<0>(mat, knots, coeff, e); + const uint64_t s1 = grotto::offset_jet_eval<1>(mat, knots, coeff, e); + const uint64_t clear = grotto::offset_jet_clear(center, knots, coeff, e); + EXPECT_EQ(s0 + s1, clear); + const uint8_t wrapped = static_cast(center + e); + uint64_t expect = 0; + for (std::size_t k = 0; k <= degree; ++k) + expect += coeff[k] * grotto::offset_jet_binom(static_cast(wrapped), + static_cast(k)); + EXPECT_EQ(clear, expect); + } +} + +TEST(OffsetJet, CarrySplitStillEvaluates) +{ + const uint8_t center = 200; + const uint8_t eta = 100; + const auto mat = grotto::make_offset_jet_keys(center, 1); + const std::vector coeff{5, 1}; + const std::vector knots{0}; + const uint64_t got = grotto::offset_jet_eval<0>(mat, knots, coeff, eta) + + grotto::offset_jet_eval<1>(mat, knots, coeff, eta); + // wrapped = 200+100 = 44; f = 5 + C(44,1) = 5+44 + EXPECT_EQ(got, uint64_t{5} + 44); +} + +TEST(OffsetJet, DifferenceAndPrefixFromOneJet) +{ + const std::size_t degree = 3; + const uint8_t center = 12; + const uint8_t eta = 3; + // Need degree+1 for prefix of a degree-2 polynomial; use degree 3 key. + const auto mat = grotto::make_offset_jet_keys(center, degree); + const std::vector poly{4, 2, 1}; // 4 + 2 C(x,1) + C(x,2) + std::vector coeff = poly; + coeff.push_back(0); // pad to degree 3 + const std::vector knots{0}; + + const auto j0 = grotto::offset_jet_shares<0>(mat, knots, eta); + const auto j1 = grotto::offset_jet_shares<1>(mat, knots, eta); + std::vector jet(degree + 1); + for (std::size_t k = 0; k <= degree; ++k) + jet[k] = j0[k] + j1[k]; + + const uint8_t x = static_cast(center + eta); + const uint64_t value = grotto::offset_jet_dot(coeff, jet); + uint64_t expect_v = 0; + for (std::size_t k = 0; k < poly.size(); ++k) + expect_v += poly[k] * grotto::offset_jet_binom(static_cast(x), + static_cast(k)); + EXPECT_EQ(value, expect_v); + + const auto dcoeff = grotto::offset_jet_difference_coeff(coeff); + const uint64_t diff = grotto::offset_jet_dot(dcoeff, jet); + const uint64_t fx1 = expect_v + - poly[0] * 0 // recompute f(x+1) - f(x) + + 0; + uint64_t expect_fx1 = 0; + for (std::size_t k = 0; k < poly.size(); ++k) + expect_fx1 += poly[k] * grotto::offset_jet_binom( + static_cast(static_cast(x + 1)), + static_cast(k)); + EXPECT_EQ(diff, static_cast(expect_fx1 - expect_v)); + (void)fx1; + + // Prefix needs degree+1: key degree 3, poly degree <= 2. + const auto pcoeff = grotto::offset_jet_prefix_coeff(poly); + ASSERT_EQ(pcoeff.size(), degree + 1u); + const uint64_t prefix = grotto::offset_jet_dot(pcoeff, jet); + uint64_t expect_p = 0; + for (uint8_t i = 0; i < x; ++i) + { + for (std::size_t k = 0; k < poly.size(); ++k) + expect_p += poly[k] * grotto::offset_jet_binom(static_cast(i), + static_cast(k)); + } + EXPECT_EQ(prefix, expect_p); +} + +TEST(OffsetJet, VerifiableProofs) +{ + const std::size_t degree = 2; + const auto mat = grotto::make_offset_jet_keys(2, degree, dpf::verifiable{}); + const std::vector coeff{1, 0, 3}; + const std::vector knots{0}; + const uint8_t eta = 5; + std::vector a(degree + 1), b(degree + 1); + const uint64_t s0 = grotto::offset_jet_eval<0>(mat, knots, coeff, eta, a.data()); + const uint64_t s1 = grotto::offset_jet_eval<1>(mat, knots, coeff, eta, b.data()); + EXPECT_EQ(s0 + s1, grotto::offset_jet_clear(2, knots, coeff, eta)); + for (std::size_t m = 0; m <= degree; ++m) + EXPECT_TRUE(dpf::verify(a[m], b[m])); +} + +TEST(OffsetJet, RejectsOversizeDegree) +{ + EXPECT_THROW(grotto::make_offset_jet_keys(1, grotto::offset_jet_max_degree + 1), std::invalid_argument); +} + +TEST(OffsetJet, NegativeCenterDegreeTwoPlus) +{ + const std::size_t degree = 3; + const int8_t center = -7; + const auto mat = grotto::make_offset_jet_keys(center, degree); + // f(x) = 1 + C(x,1) + 3 C(x,2) + C(x,3) + const std::vector coeff{1, 1, 3, 1}; + const std::vector knots{static_cast(-128)}; + for (int eta = -20; eta <= 20; eta += 5) + { + const auto e = static_cast(eta); + const uint64_t s0 = grotto::offset_jet_eval<0>(mat, knots, coeff, e); + const uint64_t s1 = grotto::offset_jet_eval<1>(mat, knots, coeff, e); + const uint64_t clear = grotto::offset_jet_clear(center, knots, coeff, e); + EXPECT_EQ(s0 + s1, clear) << "eta=" << eta; + + const int8_t wrapped = grotto::offset_horner_group_add(center, e); + uint64_t expect = 0; + for (std::size_t k = 0; k <= degree; ++k) + expect += coeff[k] * grotto::offset_jet_binom( + static_cast(wrapped), static_cast(k)); + EXPECT_EQ(clear, expect) << "eta=" << eta; + } +} diff --git a/test/tests/offset_poly_test.cpp b/test/tests/offset_poly_test.cpp new file mode 100644 index 0000000..86b3870 --- /dev/null +++ b/test/tests/offset_poly_test.cpp @@ -0,0 +1,158 @@ +#include +#include + +#include "grotto/offset_poly.hpp" + +#include "dpf/verifiable.hpp" + +#include +#include +#include + +namespace +{ + +uint64_t wrapped_pow(uint8_t center, uint8_t eta, std::size_t degree) +{ + const uint64_t point = static_cast(static_cast(center + eta)); + uint64_t acc = 0; + uint64_t pow = 1; + std::vector coeff(degree + 1, 0); + coeff[0] = 3; + coeff[degree] = 1; + for (uint64_t c : coeff) + { + acc += c * pow; + pow *= point; + } + return acc; +} + +} // namespace + +TEST(OffsetPoly, PublicCoefficientsMatchTheWrappedPolynomial) +{ + const std::size_t degree = 4; + const auto mat = grotto::make_offset_poly_keys(2, degree); + std::vector coeff(degree + 1, 0); + coeff[0] = 3; + coeff[degree] = 1; + const std::vector knots{0}; + for (int eta = 0; eta < 256; eta += 17) + { + const auto e = static_cast(eta); + const uint64_t s0 = grotto::offset_poly_eval<0>(mat, knots, {coeff}, e); + const uint64_t s1 = grotto::offset_poly_eval<1>(mat, knots, {coeff}, e); + const uint64_t clear = grotto::offset_poly_clear(2, knots, {coeff}, e); + EXPECT_EQ(s0 + s1, clear); + EXPECT_EQ(clear, wrapped_pow(2, e, degree)); + } +} + +TEST(OffsetPoly, CarrySplitStillEvaluatesTheWrappedPoint) +{ + const auto mat = grotto::make_offset_poly_keys(200, 1); + const std::vector coeff{5, 1}; + const std::vector knots{0}; + const uint8_t eta = 100; + const uint64_t got = grotto::offset_poly_eval<0>(mat, knots, {coeff}, eta) + + grotto::offset_poly_eval<1>(mat, knots, {coeff}, eta); + EXPECT_EQ(got, uint64_t{5} + 44); +} + +TEST(OffsetPoly, SharedCoefficientsUseOneBeaverDot) +{ + const std::size_t degree = 2; + const uint8_t center = 9; + const uint8_t eta = 4; + const auto mat = grotto::make_offset_poly_keys(center, degree); + const std::vector coeff{4, 0, 2}; + const std::vector knots{0}; + const std::vector share0{1, 7, 9}; + std::vector share1(degree + 1); + for (std::size_t i = 0; i < coeff.size(); ++i) + share1[i] = coeff[i] - share0[i]; + + const auto kappas = grotto::offset_poly_kappas(knots, degree, eta); + const auto p0 = grotto::offset_poly_power_shares<0>(mat, knots, eta); + const auto p1 = grotto::offset_poly_power_shares<1>(mat, knots, eta); + ASSERT_EQ(p0.size(), kappas.size()); + + std::vector q0, q1, y0, y1; + for (std::size_t piece = 0; piece < kappas.size(); ++piece) + { + const auto a0 = grotto::offset_poly_shift_share(share0, kappas[piece]); + const auto a1 = grotto::offset_poly_shift_share(share1, kappas[piece]); + for (std::size_t m = 0; m <= degree; ++m) + { + q0.push_back(a0[m]); + q1.push_back(a1[m]); + y0.push_back(p0[piece][m]); + y1.push_back(p1[piece][m]); + } + } + auto triple = dpf::beavers::sample_dot(q0.size()); + std::vector opened_d(q0.size()), opened_e(y0.size()); + for (std::size_t i = 0; i < q0.size(); ++i) + { + // Open only masked differences q-a and power-b (F_Poly). + opened_d[i] = (q0[i] - triple.x[i].p0) + (q1[i] - triple.x[i].p1); + opened_e[i] = (y0[i] - triple.y[i].p0) + (y1[i] - triple.y[i].p1); + } + const uint64_t v0 = grotto::offset_poly_beaver_share(0, q0, y0, opened_d, opened_e, triple); + const uint64_t v1 = grotto::offset_poly_beaver_share(1, q1, y1, opened_d, opened_e, triple); + const uint64_t clear = grotto::offset_poly_clear(center, knots, {coeff}, eta); + EXPECT_EQ(v0 + v1, clear); + const uint64_t point = static_cast(center + eta); + EXPECT_EQ(clear, 4 + 2 * point * point); +} + +TEST(OffsetPoly, VerifiableTokensRejectATamperedProof) +{ + const std::size_t degree = 2; + const auto mat = grotto::make_offset_poly_keys(2, degree, dpf::verifiable{}); + const std::vector coeff{1, 0, 3}; + const std::vector knots{0}; + const uint8_t eta = 5; + std::vector a(degree + 1), b(degree + 1); + const uint64_t s0 = grotto::offset_poly_eval<0>(mat, knots, {coeff}, eta, a.data()); + const uint64_t s1 = grotto::offset_poly_eval<1>(mat, knots, {coeff}, eta, b.data()); + EXPECT_EQ(s0 + s1, grotto::offset_poly_clear(2, knots, {coeff}, eta)); + for (std::size_t m = 0; m <= degree; ++m) + EXPECT_TRUE(dpf::verify(a[m], b[m])) << m; + a[0][0] = simde_mm_xor_si128(a[0][0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(a[0], b[0])); + EXPECT_TRUE(dpf::verify(a[1], b[1])); +} + +TEST(OffsetPoly, HornerAndPolyAgreeOnTheSameKnots) +{ + constexpr std::size_t D = 3; + const uint8_t center = 17; + const uint8_t eta = 9; + const std::vector knots{0, 40, 100}; + std::vector> horner_coeff{ + {2, 0, 1, 0}, + {0, 3, 0, 1}, + {5, 1, 0, 0}, + }; + std::vector> poly_coeff(horner_coeff.size()); + for (std::size_t i = 0; i < horner_coeff.size(); ++i) + poly_coeff[i].assign(horner_coeff[i].begin(), horner_coeff[i].end()); + + auto hmat = grotto::make_offset_horner_keys(center); + auto pmat = grotto::make_offset_poly_keys(center, D); + const uint64_t h = grotto::offset_horner_eval<0, D>(hmat, knots, horner_coeff, eta) + + grotto::offset_horner_eval<1, D>(hmat, knots, horner_coeff, eta); + const uint64_t p = grotto::offset_poly_eval<0>(pmat, knots, poly_coeff, eta) + + grotto::offset_poly_eval<1>(pmat, knots, poly_coeff, eta); + EXPECT_EQ(h, p); + EXPECT_EQ(h, grotto::offset_horner_clear(center, knots, horner_coeff, eta)); + EXPECT_EQ(p, grotto::offset_poly_clear(center, knots, poly_coeff, eta)); +} + +TEST(OffsetPoly, RejectsADegreePastTheCap) +{ + EXPECT_THROW(grotto::make_offset_poly_keys(1, grotto::offset_poly_max_degree + 1), std::invalid_argument); + EXPECT_THROW(grotto::make_offset_poly_keys(1, grotto::offset_poly_max_degree + 1, dpf::verifiable{}), std::invalid_argument); +} diff --git a/test/tests/offset_repr_test.cpp b/test/tests/offset_repr_test.cpp new file mode 100644 index 0000000..331300c --- /dev/null +++ b/test/tests/offset_repr_test.cpp @@ -0,0 +1,172 @@ +#include +#include + +#include "grotto/offset_repr.hpp" + +#include "dpf/verifiable.hpp" + +#include +#include +#include + +namespace +{ + +uint64_t fib_ref(uint64_t n) +{ + if (n == 0) + return 0; + uint64_t a = 0, b = 1; + for (uint64_t i = 1; i < n; ++i) + { + const uint64_t c = a + b; + a = b; + b = c; + } + return b; +} + +std::vector matvec2( + const std::vector> & M, + const std::vector & v) +{ + return {M[0][0] * v[0] + M[0][1] * v[1], M[1][0] * v[0] + M[1][1] * v[1]}; +} + +} // namespace + +TEST(OffsetRepr, FibonacciStateMatchesReference) +{ + for (uint64_t n = 0; n < 90; ++n) + { + const auto S = grotto::offset_repr_fibonacci_state(n); + ASSERT_EQ(S.size(), 2u); + EXPECT_EQ(S[1], fib_ref(n)) << "F_" << n; + EXPECT_EQ(S[0], fib_ref(n + 1)) << "F_" << (n + 1); + } +} + +TEST(OffsetRepr, MatrixPowAdvancesFibonacci) +{ + const auto M = grotto::offset_repr_fibonacci_matrix(); + const auto S0 = grotto::offset_repr_fibonacci_state(0); + for (std::int64_t k = 0; k < 40; ++k) + { + const auto Mk = grotto::offset_repr_matrix_pow(M, k); + const auto advanced = matvec2(Mk, S0); + const auto expect = grotto::offset_repr_fibonacci_state(static_cast(k)); + EXPECT_EQ(advanced, expect) << "k=" << k; + } + // Negative: M^{-k} S_k = S_0. + for (std::int64_t k = 1; k < 20; ++k) + { + const auto Sk = grotto::offset_repr_fibonacci_state(static_cast(k)); + const auto Minv = grotto::offset_repr_matrix_pow(M, -k); + const auto back = matvec2(Minv, Sk); + EXPECT_EQ(back, S0) << "back from k=" << k; + } +} + +TEST(OffsetRepr, GeometricIsScalarPow) +{ + const uint64_t lambda = 3; + const auto M = grotto::offset_repr_geometric_matrix(lambda); + uint64_t expect = 1; + for (std::int64_t e = 0; e < 20; ++e) + { + const auto P = grotto::offset_repr_matrix_pow(M, e); + EXPECT_EQ(P[0][0], expect); + expect *= lambda; + } + const auto Minv = grotto::offset_repr_matrix_pow(M, -1); + EXPECT_EQ(Minv[0][0] * lambda, uint64_t{1}); +} + +TEST(OffsetRepr, Crc32JumpMatchesNaive) +{ + constexpr std::uint32_t poly = 0xEDB88320u; + auto step1 = [](std::uint32_t s) { + return (s >> 1) ^ (poly & (0u - (s & 1u))); + }; + for (std::uint32_t seed : {0u, 1u, 0xFFFFFFFFu, 0x12345678u}) + { + for (unsigned steps = 0; steps < 200; ++steps) + { + std::uint32_t naive = seed; + for (unsigned i = 0; i < steps; ++i) + naive = step1(naive); + EXPECT_EQ(grotto::offset_repr_crc32_jump(seed, steps), naive) + << "seed=" << seed << " steps=" << steps; + } + } + // Doubling path for large jumps. + const std::uint32_t seed = 0xA5A5A5A5u; + std::uint32_t naive = seed; + for (unsigned i = 0; i < 1000; ++i) + naive = step1(naive); + EXPECT_EQ(grotto::offset_repr_crc32_jump(seed, 1000), naive); +} + +TEST(OffsetRepr, KeyedFibonacciMatchesClear) +{ + const uint8_t center = 10; + const auto state = grotto::offset_repr_fibonacci_state(center); + const auto M = grotto::offset_repr_fibonacci_matrix(); + const auto mat = grotto::make_offset_repr_keys(center, state); + const std::vector knots{0}; + for (int eta = 0; eta < 256; eta += 17) + { + const auto e = static_cast(eta); + const auto s0 = grotto::offset_repr_eval<0>(mat, M, knots, e); + const auto s1 = grotto::offset_repr_eval<1>(mat, M, knots, e); + const auto clear = grotto::offset_repr_clear(center, state, M, knots, e); + ASSERT_EQ(s0.size(), 2u); + ASSERT_EQ(s1.size(), 2u); + ASSERT_EQ(clear.size(), 2u); + EXPECT_EQ(s0[0] + s1[0], clear[0]); + EXPECT_EQ(s0[1] + s1[1], clear[1]); + const uint8_t wrapped = static_cast(center + e); + const auto expect = grotto::offset_repr_fibonacci_state(wrapped); + EXPECT_EQ(clear, expect) << "eta=" << eta; + } +} + +TEST(OffsetRepr, CarrySplitStillAdvances) +{ + const uint8_t center = 200; + const uint8_t eta = 100; // wraps: 44 + const auto state = grotto::offset_repr_fibonacci_state(center); + const auto M = grotto::offset_repr_fibonacci_matrix(); + const auto mat = grotto::make_offset_repr_keys(center, state); + const std::vector knots{0}; + const auto got0 = grotto::offset_repr_eval<0>(mat, M, knots, eta); + const auto got1 = grotto::offset_repr_eval<1>(mat, M, knots, eta); + const auto expect = grotto::offset_repr_fibonacci_state(44); + EXPECT_EQ(got0[0] + got1[0], expect[0]); + EXPECT_EQ(got0[1] + got1[1], expect[1]); +} + +TEST(OffsetRepr, VerifiableProofs) +{ + const uint8_t center = 7; + const auto state = grotto::offset_repr_fibonacci_state(center); + const auto M = grotto::offset_repr_fibonacci_matrix(); + const auto mat = grotto::make_offset_repr_keys(center, state, dpf::verifiable{}); + const std::vector knots{0}; + const uint8_t eta = 5; + std::vector a(2), b(2); + const auto s0 = grotto::offset_repr_eval<0>(mat, M, knots, eta, a.data()); + const auto s1 = grotto::offset_repr_eval<1>(mat, M, knots, eta, b.data()); + const auto clear = grotto::offset_repr_clear(center, state, M, knots, eta); + EXPECT_EQ(s0[0] + s1[0], clear[0]); + EXPECT_EQ(s0[1] + s1[1], clear[1]); + EXPECT_TRUE(dpf::verify(a[0], b[0])); + EXPECT_TRUE(dpf::verify(a[1], b[1])); +} + +TEST(OffsetRepr, RejectsBadDim) +{ + EXPECT_THROW(grotto::make_offset_repr_keys(1, {}), std::invalid_argument); + EXPECT_THROW(grotto::make_offset_repr_keys(1, + std::vector(grotto::offset_repr_max_dim + 1, 0)), std::invalid_argument); +} diff --git a/test/tests/offset_twist_test.cpp b/test/tests/offset_twist_test.cpp new file mode 100644 index 0000000..6121d3f --- /dev/null +++ b/test/tests/offset_twist_test.cpp @@ -0,0 +1,153 @@ +#include +#include + +#include "grotto/offset_twist.hpp" + +#include "dpf/verifiable.hpp" + +#include +#include +#include + +namespace +{ + +uint64_t pow_u64(uint64_t base, uint64_t exp) +{ + uint64_t acc = 1; + while (exp != 0) + { + if (exp & 1u) + acc *= base; + base *= base; + exp >>= 1; + } + return acc; +} + +uint64_t twisted_poly(uint64_t x, uint64_t lambda, const std::vector & coeff) +{ + uint64_t acc = 0; + uint64_t pow = 1; + for (uint64_t c : coeff) + { + acc += c * pow; + pow *= x; + } + return acc * pow_u64(lambda, x); +} + +uint64_t twisted_half(uint64_t x, const std::vector & coeff) +{ + uint64_t acc = 0; + uint64_t pow = 1; + for (uint64_t c : coeff) + { + acc += c * pow; + pow *= x; + } + if (x >= 64) + return 0; + return acc >> static_cast(x); +} + +} // namespace + +TEST(OffsetTwist, OddLambdaMatchesClear) +{ + const uint8_t center = 9; + const uint64_t lambda = 3; + const std::size_t degree = 2; + const auto mat = grotto::make_offset_twist_keys(center, degree, lambda); + // f(x) = (2 + 5x + x^2) * 3^x + const std::vector coeff{2, 5, 1}; + const std::vector knots{0}; + for (int eta = 0; eta < 256; eta += 19) + { + const auto e = static_cast(eta); + const uint64_t s0 = grotto::offset_twist_eval<0>(mat, knots, coeff, e); + const uint64_t s1 = grotto::offset_twist_eval<1>(mat, knots, coeff, e); + const uint64_t clear = grotto::offset_twist_clear( + center, lambda, knots, coeff, e); + EXPECT_EQ(s0 + s1, clear) << "eta=" << eta; + const uint8_t wrapped = static_cast(center + e); + EXPECT_EQ(clear, twisted_poly(wrapped, lambda, coeff)) << "eta=" << eta; + } +} + +TEST(OffsetTwist, CarrySplitStillTwists) +{ + const uint8_t center = 200; + const uint8_t eta = 100; // wraps to 44 + const uint64_t lambda = 5; + const auto mat = grotto::make_offset_twist_keys(center, 1, lambda); + const std::vector coeff{1, 2}; // (1 + 2x) 5^x + const std::vector knots{0}; + const uint64_t got = grotto::offset_twist_eval<0>(mat, knots, coeff, eta) + + grotto::offset_twist_eval<1>(mat, knots, coeff, eta); + EXPECT_EQ(got, twisted_poly(44, lambda, coeff)); +} + +TEST(OffsetTwist, HalfShiftsOnShares) +{ + const uint8_t center = 4; + const std::size_t degree = 2; + const auto mat = grotto::make_offset_twist_keys(center, degree, grotto::twist_half); + // Dyadic path returns shares of the shifted value; untwisted sum stays shared. + const std::vector coeff{7, 3, 1}; + const std::vector knots{0}; + for (int eta = 0; eta < 40; eta += 3) + { + const auto e = static_cast(eta); + const uint64_t s0 = grotto::offset_twist_eval<0>(mat, knots, coeff, e); + const uint64_t s1 = grotto::offset_twist_eval<1>(mat, knots, coeff, e); + const uint8_t wrapped = static_cast(center + e); + const uint64_t clear = grotto::offset_twist_clear( + center, grotto::twist_half, knots, coeff, e); + EXPECT_EQ(s0 + s1, clear) << "eta=" << eta; + EXPECT_EQ(clear, twisted_half(wrapped, coeff)) << "eta=" << eta; + } +} + +TEST(OffsetTwist, ArithmeticoGeometricClosedForm) +{ + const uint64_t lambda = 3; + for (uint64_t n = 1; n < 30; ++n) + { + uint64_t naive = 0; + for (uint64_t k = 1; k <= n; ++k) + naive += k * pow_u64(lambda, k); + EXPECT_EQ(grotto::offset_twist_arithmetico_geometric(n, lambda), naive) + << "n=" << n; + } +} + +TEST(OffsetTwist, VerifiableProofs) +{ + const uint8_t center = 6; + const uint64_t lambda = 7; + const std::size_t degree = 2; + const auto mat = grotto::make_offset_twist_keys( + center, degree, lambda, dpf::verifiable{}); + const std::vector coeff{1, 0, 4}; + const std::vector knots{0}; + const uint8_t eta = 3; + std::vector a(degree + 1), b(degree + 1); + const uint64_t s0 = grotto::offset_twist_eval<0>(mat, knots, coeff, eta, a.data()); + const uint64_t s1 = grotto::offset_twist_eval<1>(mat, knots, coeff, eta, b.data()); + EXPECT_EQ(s0 + s1, + grotto::offset_twist_clear(center, lambda, knots, coeff, eta)); + for (std::size_t m = 0; m <= degree; ++m) + EXPECT_TRUE(dpf::verify(a[m], b[m])); +} + +TEST(OffsetTwist, RejectsEvenLambda) +{ + EXPECT_THROW(grotto::make_offset_twist_keys(1, 1, uint64_t{2}), std::invalid_argument); +} + +TEST(OffsetTwist, RejectsOversizeDegree) +{ + EXPECT_THROW(grotto::make_offset_twist_keys( + 1, grotto::offset_twist_max_degree + 1, uint64_t{3}), std::invalid_argument); +} diff --git a/test/tests/opt_in_malicious_test.cpp b/test/tests/opt_in_malicious_test.cpp new file mode 100644 index 0000000..85bdfb1 --- /dev/null +++ b/test/tests/opt_in_malicious_test.cpp @@ -0,0 +1,316 @@ +/// @file opt_in_malicious_test.cpp +/// @brief Opt-in verifiable / extractable / MAC checks stay off by default. +#include +#include + +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/beaver.hpp" +#include "grotto/carry.hpp" + +namespace +{ + +using Input = std::uint8_t; +using u64 = std::uint64_t; + +struct Counter +{ + int draws = 0; + u64 operator()() + { + ++draws; + return 0x9e3779b97f4a7c15ull * static_cast(draws); + } +}; + +} // namespace + +TEST(OptInProfile, SemiHonestKeyHasNoProofOrSketch) +{ + auto [k0, k1] = dpf::make_dpf_profile(Input{0x2a}, u64{7}); + EXPECT_FALSE(decltype(k0)::is_verifiable); + EXPECT_FALSE(decltype(k0)::is_extractable); + EXPECT_FALSE(decltype(k1)::is_verifiable); + EXPECT_FALSE(decltype(k1)::is_extractable); + + auto plain = dpf::make_dpf(Input{0x2a}, u64{7}); + EXPECT_FALSE(decltype(plain.first)::is_verifiable); + EXPECT_FALSE(decltype(plain.first)::is_extractable); +} + +TEST(OptInProfile, CheckedKeyOptsIn) +{ + auto [k0, k1] = dpf::make_dpf_profile(Input{0x2a}, dpf::fp61{7}); + EXPECT_TRUE(decltype(k0)::is_verifiable); + EXPECT_TRUE(decltype(k0)::is_extractable); +} + +TEST(OptInProfile, FlagsAreIndependentOfTheOutputMacBit) +{ + using ver_only = dpf::auth_profile; + using ext_only = dpf::auth_profile; + using mac_only = dpf::auth_profile; + static_assert(dpf::checked::output_mac); + static_assert(!dpf::semi_honest::output_mac); + static_assert(std::tuple_size_v())> == 2); + static_assert(std::tuple_size_v())> == 0); + static_assert(std::tuple_size_v())> == 1); + + auto ver = dpf::make_dpf_profile(Input{1}, u64{4}); + EXPECT_TRUE(decltype(ver.first)::is_verifiable); + EXPECT_FALSE(decltype(ver.first)::is_extractable); + auto ext = dpf::make_dpf_profile(Input{1}, dpf::fp61{4}); + EXPECT_FALSE(decltype(ext.first)::is_verifiable); + EXPECT_TRUE(decltype(ext.first)::is_extractable); + auto mac = dpf::make_dpf_profile(Input{1}, u64{4}); + EXPECT_FALSE(decltype(mac.first)::is_verifiable); + EXPECT_FALSE(decltype(mac.first)::is_extractable); +} + +TEST(OptInProfile, CheckedUint8DomainProofSketchAndSeedFlip) +{ + const Input alpha = 0x2a; + const dpf::fp61 beta{9}; + auto [k0, k1] = dpf::make_dpf_profile(alpha, beta); + std::array s0{}, s1{}, r{}; + for (int x = 0; x < 256; ++x) + { + const Input q = static_cast(x); + dpf::proof_token a{}, b{}; + const auto y0 = *dpf::eval_point(k0, q, dpf::prove(a)); + const auto y1 = *dpf::eval_point(k1, q, dpf::prove(b)); + s0[static_cast(x)] = y0.raw(); + s1[static_cast(x)] = y1.raw(); + EXPECT_TRUE(dpf::verify(a, b)) << x; + EXPECT_EQ(dpf::reconstruct(y0, y1), x == alpha ? beta : dpf::fp61{0}); + r[static_cast(x)] = dpf::fp61{static_cast(3 + x)}; + } + EXPECT_TRUE(dpf::sketch_verify(dpf::sketch_fold(s0, r), dpf::sketch_fold(s1, r))); + auto forged = s0; + forged[0] = forged[0] + beta; + EXPECT_FALSE(dpf::sketch_verify(dpf::sketch_fold(forged, r), dpf::sketch_fold(s1, r))); + + auto bad = k0; + using arr = typename decltype(k0)::correction_seeds_array; + for (auto & cs : const_cast(bad.correction_seeds())) + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); + int failed = 0; + for (int x = 0; x < 256; ++x) + { + dpf::proof_token a{}, b{}; + (void)*dpf::eval_point(bad, static_cast(x), dpf::prove(a)); + (void)*dpf::eval_point(k1, static_cast(x), dpf::prove(b)); + if (!dpf::verify(a, b)) + ++failed; + } + EXPECT_GT(failed, 0); +} + +TEST(OptInMac, DefaultSessionHasNoTagVectors) +{ + dpf::beavers::session s; + auto x = s.input(); + auto y = s.input(); + auto z = s(x * y); + Counter rng; + s.sample(rng); + auto tape = s.export_party(0); + EXPECT_FALSE(tape.has_mac); + EXPECT_TRUE(tape.lambda_tag.empty()); + EXPECT_TRUE(tape.dot_cross_tag.empty()); + (void)z; +} + +TEST(OptInMac, HonestHornerOpeningsVerify) +{ + auto key = dpf::sample_mac_key(); + dpf::beavers::session s; + s.set_mac_key(key); + auto x = s.input(); + auto z = s.horner(x, {u64{1}, u64{2}, u64{3}}); + Counter rng; + s.sample(rng); + s.bind(x, u64{5}, rng); + s.evaluate(); + EXPECT_EQ(s.open(z), 1u + 2u * 5u + 3u * 25u); + EXPECT_TRUE(s.verify_delta(x)); + EXPECT_TRUE(s.verify_all()); +} + +TEST(OptInMac, FlippedTagRejects) +{ + auto key = dpf::sample_mac_key(); + dpf::beavers::session s; + s.set_mac_key(key); + auto x = s.input(); + auto y = s.input(); + auto z = s(x * y); + Counter rng; + s.sample(rng); + s.bind(x, u64{3}, rng); + s.bind(y, u64{5}, rng); + s.evaluate(); + EXPECT_EQ(s.open(z), 15u); + auto a = s.delta_auth(x); + dpf::beavers::auth_opening o0{a.value.p0, a.tag.p0}; + dpf::beavers::auth_opening o1{a.value.p1, a.tag.p1}; + EXPECT_TRUE(dpf::beavers::verify_auth_opening(o0, o1, key)); + o0.tag ^= 1ull; + EXPECT_FALSE(dpf::beavers::verify_auth_opening(o0, o1, key)); +} + +TEST(OptInExtractable, NoteSketchNoOpOnPlainKey) +{ + using key_t = decltype(dpf::make_dpf(Input{1}, u64{1}).first); + dpf::sketch_share sk{}; + const std::array ys{9}; + const std::array rs{dpf::fp61{2}}; + dpf::note_sketch(sk, ys, rs); + EXPECT_EQ(sk.z1, dpf::fp61{0}); + EXPECT_EQ(sk.z2, dpf::fp61{0}); + EXPECT_EQ(sk.z3, dpf::fp61{0}); +} + +TEST(OptInExtractable, HonestSketchAcceptsTamperRejects) +{ + const Input alpha = 0x11; + const dpf::fp61 beta{42}; + auto [k0, k1] = dpf::make_dpf(alpha, beta, dpf::extractable{}); + EXPECT_TRUE(decltype(k0)::is_extractable); + EXPECT_FALSE(decltype(k0)::is_verifiable); + + std::array pts{0x10, 0x11, 0x12, 0x13}; + std::array r{ + dpf::fp61{3}, dpf::fp61{5}, dpf::fp61{7}, dpf::fp61{11}}; + std::array s0{}, s1{}; + for (std::size_t i = 0; i < pts.size(); ++i) + { + s0[i] = (*dpf::eval_point(k0, pts[i])).raw(); + s1[i] = (*dpf::eval_point(k1, pts[i])).raw(); + } + dpf::sketch_share sk0{}, sk1{}; + dpf::note_sketch(sk0, s0, r); + dpf::note_sketch(sk1, s1, r); + EXPECT_TRUE(dpf::sketch_verify(sk0, sk1)); + s0[0] = s0[0] + beta; + dpf::note_sketch(sk0, s0, r); + EXPECT_FALSE(dpf::sketch_verify(sk0, sk1)); +} + +TEST(OptInMemoProve, HonestIdempotentAndTamper) +{ + const Input alpha = 0x2a; + auto [k0, k1] = dpf::make_dpf(alpha, + dpf::block_width<4>(dpf::lt(u64{1})), dpf::verifiable{}); + using KT0 = decltype(k0); + using KT1 = decltype(k1); + const Input from = 0x20; + const Input to = 0x2f; + const auto nbits = static_cast(k0.cmp().nbits); + using integral = typename KT0::integral_type; + const auto a = static_cast(from); + const auto b = static_cast(to); + const auto excl = dpf::detail::incr::cmp_exclusive_end(b); + const auto count = dpf::detail::incr::cmp_inclusive_count(a, b); + constexpr std::size_t stop = + KT0::cmp_depth == 0 ? KT0::depth : KT0::cmp_depth; + const std::size_t levels = KT0::cmp_h; + + dpf::detail::incr::cmp_full_interval_memo memo0{count}; + dpf::detail::incr::cmp_full_interval_memo memo1{count}; + dpf::detail::incr::eval_cmp_interval_impl_interior(k0, a, excl, nbits, memo0, + levels, nullptr); + dpf::detail::incr::eval_cmp_interval_impl_interior(k1, a, excl, nbits, memo1, + levels, nullptr); + + const integral lane = static_cast(alpha); + dpf::proof_token pi0{}, pi1{}; + dpf::detail::vdpf::init_proof(pi0, k0); + dpf::detail::vdpf::init_proof(pi1, k1); + dpf::basic_path_memoizer path0{}; + dpf::basic_path_memoizer path1{}; + dpf::detail::blocked::eval_share_memo(k0, lane, a, excl, memo0, &pi0, + &path0); + dpf::detail::blocked::eval_share_memo(k1, lane, a, excl, memo1, &pi1, + &path1); + EXPECT_TRUE(dpf::verify(pi0, pi1)); + + const auto snap0 = pi0; + dpf::detail::blocked::eval_share_memo(k0, lane, a, excl, memo0, &pi0, + &path0); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(pi0, snap0)); + + // CW tamper on party 0. + auto k0_bad = k0; + for (auto & cs : const_cast( + k0_bad.correction_seeds())) + { + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(0x5a)); + } + dpf::detail::incr::cmp_full_interval_memo memo_bad{count}; + dpf::detail::incr::eval_cmp_interval_impl_interior(k0_bad, a, excl, nbits, + memo_bad, levels, nullptr); + dpf::proof_token q0{}, q1{}; + dpf::detail::vdpf::init_proof(q0, k0_bad); + dpf::detail::vdpf::init_proof(q1, k1); + dpf::basic_path_memoizer pb0{}; + dpf::basic_path_memoizer pb1{}; + dpf::detail::blocked::eval_share_memo(k0_bad, lane, a, excl, memo_bad, + &q0, &pb0); + dpf::detail::blocked::eval_share_memo(k1, lane, a, excl, memo1, &q1, + &pb1); + EXPECT_FALSE(dpf::verify(q0, q1)); +} + +TEST(OptInMemoProve, BfsIntervalProveUnchanged) +{ + const Input alpha = 0x2a; + auto [k0, k1] = dpf::make_dpf(alpha, + dpf::block_width<4>(dpf::lt(u64{1})), dpf::verifiable{}); + const Input from = 0x00; + const Input to = 0x3f; + dpf::proof_token a{}, b{}; + dpf::prove_cmp_interval(k0, from, to, dpf::prove(a)); + dpf::prove_cmp_interval(k1, from, to, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); + + // Re-proving the same interval yields the same BFS transcript. + dpf::proof_token a2{}, b2{}; + dpf::prove_cmp_interval(k0, from, to, dpf::prove(a2)); + dpf::prove_cmp_interval(k1, from, to, dpf::prove(b2)); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(a, a2)); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(b, b2)); + + // Interval eval with prove still verifies (memo walk does not fold again). + auto buf0 = dpf::eval_interval(dpf::cmp, k0, from, to, dpf::prove(a2)); + auto buf1 = dpf::eval_interval(dpf::cmp, k1, from, to, dpf::prove(b2)); + EXPECT_TRUE(dpf::verify(a2, b2)); + EXPECT_EQ(buf0.size(), buf1.size()); +} + +TEST(OptInCarry, VerifiableAndMacRoundTrip) +{ + grotto::carry_auth auth{}; + auth.verifiable = true; + auth.output_mac = true; + auto keys = grotto::make_carry_in_keys(8, 3, auth); + ASSERT_TRUE(keys.has_mac); + ASSERT_TRUE(keys.low_lt_v.has_value()); + const std::uint64_t opened = 0x3cu; + dpf::proof_token t0[4]{}, t1[4]{}; + const auto n0 = grotto::prove_carry_keys(keys, 0, opened, t0, 4); + const auto n1 = grotto::prove_carry_keys(keys, 1, opened, t1, 4); + EXPECT_EQ(n0, n1); + EXPECT_TRUE(dpf::verify_batch( + std::vector(t0, t0 + n0), + std::vector(t1, t1 + n1))); + const auto y0 = grotto::eval_carry_in(keys, 0, opened); + const auto y1 = grotto::eval_carry_in(keys, 1, opened); + auto [m0, m1] = grotto::mac_carry_result(keys, y0.value, y1.value); + EXPECT_TRUE(dpf::mac_verify(m0, m1, keys.mac, t0[0], t1[0])); +} diff --git a/test/tests/path_sketch_test.cpp b/test/tests/path_sketch_test.cpp new file mode 100644 index 0000000..9e143b7 --- /dev/null +++ b/test/tests/path_sketch_test.cpp @@ -0,0 +1,94 @@ +#include + +#include +#include + +#include "dpf.hpp" + +namespace +{ + +std::vector random_challenges(std::size_t n) +{ + std::vector rs(n); + for (auto & r : rs) + r = dpf::uniform_sample(); + return rs; +} + +} // namespace + +TEST(PathSketch, HonestIdpfAccepts) +{ + using Input = std::uint8_t; + const Input alpha = 0xA0; // prefix 1010_0000 → length-3 prefix 101 + auto [k0, k1] = dpf::make_dpf(alpha, + dpf::idpf(std::uint64_t{5}, std::uint64_t{5}, std::uint64_t{5})); + + const auto rs = random_challenges(dpf::path_sketch_challenge_count(3)); + EXPECT_TRUE((dpf::verify_idpf_path<3>(k0, k1, rs))); +} + +TEST(PathSketch, HonestUnitWeightAccepts) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0b10100101}, + dpf::idpf(std::uint64_t{1}, std::uint64_t{1}, std::uint64_t{1}, + std::uint64_t{1})); + const auto rs = random_challenges(dpf::path_sketch_challenge_count(4)); + EXPECT_TRUE((dpf::verify_idpf_path<4>(k0, k1, rs))); +} + +TEST(PathSketch, LevelSketchRejectsTwoHot) +{ + // Manufacture a two-hot vector and feed sketch_fold directly. + std::vector y0 = {dpf::fp61{3}, dpf::fp61{0}, dpf::fp61{0}, + dpf::fp61{0}}; + std::vector y1 = {dpf::fp61{0}, dpf::fp61{0}, dpf::fp61{2}, + dpf::fp61{0}}; + // Opened values: 3, 0, -2, 0 — two nonzeros. + std::vector r = {dpf::fp61{9}, dpf::fp61{4}, dpf::fp61{7}, + dpf::fp61{2}}; + const auto s0 = dpf::sketch_fold(y0, r); + const auto s1 = dpf::sketch_fold(y1, r); + EXPECT_FALSE(dpf::sketch_verify(s0, s1)); +} + +TEST(PathSketch, ParentGapRejectsBrokenRelation) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0xA0}, + dpf::idpf(std::uint64_t{5}, std::uint64_t{5}, std::uint64_t{5})); + + auto gamma = random_challenges(2); + // Honest parent gap opens to 0. + const auto g0 = dpf::sketch_path_parent(dpf::out<0, 1>, dpf::out<1, 2>, + k0, gamma.data(), gamma.size()); + const auto g1 = dpf::sketch_path_parent(dpf::out<0, 1>, dpf::out<1, 2>, + k1, gamma.data(), gamma.size()); + EXPECT_TRUE(dpf::sketch_path_verify_parent(g0, g1)); + + // Bias party 0's gap — must reject. + EXPECT_FALSE(dpf::sketch_path_verify_parent(g0 + dpf::fp61{1}, g1)); +} + +TEST(PathSketch, ChallengeCountFormula) +{ + // Depth 1: only level sketch at N=1 → 2 challenges. + EXPECT_EQ(dpf::path_sketch_challenge_count(1), 2u); + // Depth 2: level1 (2) + parent(2) + level2 (4) = 8. + EXPECT_EQ(dpf::path_sketch_challenge_count(2), 8u); + // Depth 3: 8 + parent@2 (4) + level3 (8) = 20. + EXPECT_EQ(dpf::path_sketch_challenge_count(3), 20u); +} + +TEST(PathSketch, MasticClientsVerify) +{ + auto [a0, a1] = dpf::make_dpf(std::uint8_t{0xA0}, + dpf::idpf(std::uint64_t{5}, std::uint64_t{5}, std::uint64_t{5})); + auto [b0, b1] = dpf::make_dpf(std::uint8_t{0xB0}, + dpf::idpf(std::uint64_t{3}, std::uint64_t{3}, std::uint64_t{3})); + const auto rs = random_challenges(dpf::path_sketch_challenge_count(3)); + EXPECT_TRUE((dpf::verify_idpf_path<3>(a0, a1, rs))); + EXPECT_TRUE((dpf::verify_idpf_path<3>(b0, b1, rs))); +} diff --git a/test/tests/pprf_test.cpp b/test/tests/pprf_test.cpp new file mode 100644 index 0000000..e7e3777 --- /dev/null +++ b/test/tests/pprf_test.cpp @@ -0,0 +1,331 @@ +#include + +#include +#include +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +template +bool eq_block(const Block & a, const Block & b) +{ + return std::memcmp(&a, &b, sizeof(Block)) == 0; +} + +template +void check_pprf_spread(InputT alpha) +{ + auto master = dpf::make_pprf_master(); + auto punctured = dpf::puncture(master, alpha, /*program_alpha=*/true); + + const auto master_at_alpha = dpf::pprf_eval(master, alpha); + EXPECT_TRUE(eq_block(master_at_alpha, *punctured.programmed)); + EXPECT_TRUE(eq_block(dpf::pprf_eval(punctured, alpha), master_at_alpha)); + + std::vector points = { + InputT{0}, + InputT{1}, + static_cast(alpha + 1), + static_cast(alpha ^ InputT{1}), + }; + if constexpr (dpf::utils::bitlength_of_v > 8) + { + points.push_back(static_cast( + InputT{1} << (dpf::utils::bitlength_of_v / 2))); + points.push_back(static_cast(alpha ^ (InputT{1} << 7))); + } + + for (InputT x : points) + { + if (x == alpha) + continue; + EXPECT_TRUE(eq_block(dpf::pprf_eval(master, x), + dpf::pprf_eval(punctured, x))); + } + + auto bare = dpf::puncture(master, alpha, /*program_alpha=*/false); + EXPECT_FALSE(bare.programmed.has_value()); + EXPECT_THROW((void)dpf::pprf_eval(bare, alpha), std::invalid_argument); + for (InputT x : points) + { + if (x == alpha) + continue; + EXPECT_TRUE(eq_block(dpf::pprf_eval(master, x), + dpf::pprf_eval(bare, x))); + } + + EXPECT_EQ(punctured.siblings.size(), dpf::utils::bitlength_of_v); +} + +bool node_has_seed(const dpf::pprf_copath & copath, + const dpf::prg::aes128::block_type & seed) +{ + for (const auto & node : copath.nodes) + { + if (eq_block(node.seed, seed)) + return true; + } + return false; +} + +} // namespace + +TEST(Pprf, PathBitHelpersAreConstexpr) +{ + using input_t = std::uint8_t; + static_assert(dpf::detail::pprf_impl::path_bit(0b1010'0000u, 0)); + static_assert(!dpf::detail::pprf_impl::path_bit(0b0010'0000u, 0)); + static_assert(dpf::detail::pprf_impl::path_prefix(0b1010'1100u, 4) + == input_t{0b1010u}); + static_assert(dpf::detail::pprf_impl::prefix_matches( + 0b1010'1100u, 4, input_t{0b1010u})); + static_assert(!dpf::detail::pprf_impl::prefix_matches( + 0b1010'1100u, 4, input_t{0b1011u})); + SUCCEED(); +} + +TEST(Pprf, Uint32) +{ + check_pprf_spread(0x00c0ffeeu); +} + +TEST(Pprf, Uint128) +{ + using input_t = simde_uint128; + const input_t alpha = (input_t{1} << 120) | input_t{0xdeadbeefull}; + check_pprf_spread(alpha); +} + +TEST(PprfCopath, OneHiddenAgreesWithOnePoint) +{ + using input_t = std::uint8_t; + constexpr std::size_t n = dpf::utils::bitlength_of_v; + auto master = dpf::make_pprf_master(); + const input_t alpha = 0x2au; + + auto one = dpf::puncture(master, alpha, /*program_alpha=*/true); + const input_t hidden[] = {alpha}; + auto copath = dpf::puncture(master, std::begin(hidden), std::end(hidden), + /*program_hidden=*/true); + + ASSERT_EQ(copath.nodes.size(), n); + ASSERT_EQ(copath.programmed.size(), 1u); + EXPECT_TRUE(eq_block(copath.programmed[0], *one.programmed)); + + for (std::size_t i = 0; i < n; ++i) + { + EXPECT_EQ(copath.nodes[i].level, i + 1); + EXPECT_TRUE(eq_block(copath.nodes[i].seed, one.siblings[i])); + EXPECT_EQ(copath.nodes[i].prefix, + dpf::detail::pprf_impl::path_prefix( + static_cast( + alpha ^ static_cast(input_t{1} << (n - 1 - i))), + i + 1)); + } + + for (unsigned x = 0; x < 256; ++x) + { + const auto xi = static_cast(x); + EXPECT_TRUE(eq_block(dpf::pprf_eval(copath, xi), dpf::pprf_eval(one, xi))); + if (xi != alpha) + EXPECT_TRUE( + eq_block(dpf::pprf_eval(copath, xi), dpf::pprf_eval(master, xi))); + } + + auto bare = dpf::puncture(master, std::begin(hidden), std::end(hidden), + /*program_hidden=*/false); + EXPECT_TRUE(bare.programmed.empty()); + EXPECT_THROW((void)dpf::pprf_eval(bare, alpha), std::invalid_argument); + for (unsigned x = 0; x < 256; ++x) + { + const auto xi = static_cast(x); + if (xi == alpha) + continue; + EXPECT_TRUE( + eq_block(dpf::pprf_eval(bare, xi), dpf::pprf_eval(master, xi))); + } +} + +TEST(PprfCopath, AdjacentAndSeparatedSets) +{ + using input_t = std::uint8_t; + constexpr std::size_t n = dpf::utils::bitlength_of_v; + auto master = dpf::make_pprf_master(); + + const input_t adjacent[] = {2, 3}; + auto adj = dpf::puncture(master, std::begin(adjacent), std::end(adjacent)); + // Share a 7-bit prefix: one sibling per shared level, none at the leaves. + EXPECT_EQ(adj.nodes.size(), n - 1); + EXPECT_LE(adj.nodes.size(), n * adj.hidden.size()); + EXPECT_LT(adj.nodes.size(), 2 * n); + + const input_t separated[] = {2, 5}; + auto sep = dpf::puncture(master, std::begin(separated), std::end(separated)); + EXPECT_LE(sep.nodes.size(), n * sep.hidden.size()); + EXPECT_GT(sep.nodes.size(), adj.nodes.size()); + + for (unsigned x = 0; x < 256; ++x) + { + const auto xi = static_cast(x); + const bool in_adj = (xi == 2 || xi == 3); + const bool in_sep = (xi == 2 || xi == 5); + if (in_adj) + EXPECT_THROW((void)dpf::pprf_eval(adj, xi), std::invalid_argument); + else + EXPECT_TRUE( + eq_block(dpf::pprf_eval(adj, xi), dpf::pprf_eval(master, xi))); + if (in_sep) + EXPECT_THROW((void)dpf::pprf_eval(sep, xi), std::invalid_argument); + else + EXPECT_TRUE( + eq_block(dpf::pprf_eval(sep, xi), dpf::pprf_eval(master, xi))); + } +} + +TEST(PprfCopath, HiddenLeafNotPublishedWhenSiblingHidden) +{ + using input_t = std::uint8_t; + auto master = dpf::make_pprf_master(); + const input_t leaf = 2; + const auto leaf_seed = dpf::pprf_eval(master, leaf); + + const input_t alone[] = {leaf}; + auto solo = dpf::puncture(master, std::begin(alone), std::end(alone), + /*program_hidden=*/true); + EXPECT_TRUE(node_has_seed(solo, dpf::pprf_eval(master, static_cast(3)))); + + const input_t both[] = {2, 3}; + auto pair = dpf::puncture(master, std::begin(both), std::end(both), + /*program_hidden=*/true); + EXPECT_FALSE(node_has_seed(pair, leaf_seed)); + EXPECT_FALSE(node_has_seed(pair, dpf::pprf_eval(master, static_cast(3)))); + ASSERT_EQ(pair.programmed.size(), 2u); + EXPECT_TRUE(eq_block(pair.programmed[0], leaf_seed)); + EXPECT_TRUE(eq_block(pair.programmed[1], + dpf::pprf_eval(master, static_cast(3)))); + EXPECT_TRUE(eq_block(dpf::pprf_eval(pair, leaf), leaf_seed)); + EXPECT_TRUE(eq_block(dpf::pprf_eval(pair, static_cast(3)), + dpf::pprf_eval(master, static_cast(3)))); +} + +TEST(PprfCopath, EmptyAndDuplicates) +{ + using input_t = std::uint8_t; + auto master = dpf::make_pprf_master(); + + const std::vector none{}; + auto empty = dpf::puncture(master, none.begin(), none.end()); + ASSERT_EQ(empty.nodes.size(), 1u); + EXPECT_EQ(empty.nodes[0].level, 0u); + EXPECT_EQ(empty.nodes[0].prefix, input_t{}); + EXPECT_TRUE(eq_block(empty.nodes[0].seed, master.root)); + EXPECT_TRUE(empty.hidden.empty()); + for (unsigned x = 0; x < 256; ++x) + { + const auto xi = static_cast(x); + EXPECT_TRUE( + eq_block(dpf::pprf_eval(empty, xi), dpf::pprf_eval(master, xi))); + } + + const input_t dups[] = {5, 2, 5, 2, 5}; + auto once = dpf::puncture(master, std::begin(dups), std::end(dups)); + const input_t unique[] = {2, 5}; + auto clean = dpf::puncture(master, std::begin(unique), std::end(unique)); + ASSERT_EQ(once.hidden.size(), 2u); + EXPECT_EQ(once.hidden, clean.hidden); + ASSERT_EQ(once.nodes.size(), clean.nodes.size()); + for (std::size_t i = 0; i < once.nodes.size(); ++i) + { + EXPECT_EQ(once.nodes[i].level, clean.nodes[i].level); + EXPECT_EQ(once.nodes[i].prefix, clean.nodes[i].prefix); + EXPECT_TRUE(eq_block(once.nodes[i].seed, clean.nodes[i].seed)); + } +} + +TEST(PprfCopath, FullDomainPublishesNothing) +{ + using input_t = std::uint8_t; + auto master = dpf::make_pprf_master(); + std::vector all(256); + for (unsigned x = 0; x < 256; ++x) + all[x] = static_cast(x); + + auto bare = dpf::puncture(master, all.begin(), all.end(), + /*program_hidden=*/false); + EXPECT_TRUE(bare.nodes.empty()); + ASSERT_EQ(bare.hidden.size(), 256u); + EXPECT_TRUE(bare.programmed.empty()); + for (unsigned x = 0; x < 256; ++x) + EXPECT_THROW((void)dpf::pprf_eval(bare, static_cast(x)), + std::invalid_argument); + + auto programmed = dpf::puncture(master, all.begin(), all.end(), + /*program_hidden=*/true); + EXPECT_TRUE(programmed.nodes.empty()); + ASSERT_EQ(programmed.programmed.size(), 256u); + for (unsigned x = 0; x < 256; ++x) + { + const auto xi = static_cast(x); + EXPECT_TRUE(eq_block(dpf::pprf_eval(programmed, xi), + dpf::pprf_eval(master, xi))); + } +} + +TEST(PprfCopath, NodePrefixesAreConsistent) +{ + using input_t = std::uint8_t; + auto master = dpf::make_pprf_master(); + const input_t hidden[] = {2, 5, 200}; + auto copath = dpf::puncture(master, std::begin(hidden), std::end(hidden)); + + EXPECT_LE(copath.nodes.size(), + dpf::utils::bitlength_of_v * copath.hidden.size()); + + for (const auto & node : copath.nodes) + { + ASSERT_GE(node.level, 1u); + ASSERT_LE(node.level, dpf::utils::bitlength_of_v); + // Right-aligned prefix fits in `level` bits. + if (node.level < dpf::utils::bitlength_of_v) + { + EXPECT_LT(static_cast(node.prefix), + 1u << node.level); + } + } + + for (unsigned x = 0; x < 256; ++x) + { + const auto xi = static_cast(x); + if (std::binary_search(std::begin(hidden), std::end(hidden), xi)) + continue; + EXPECT_TRUE( + eq_block(dpf::pprf_eval(copath, xi), dpf::pprf_eval(master, xi))); + } +} + +TEST(PprfCopath, Uint32SetMatchesMaster) +{ + using input_t = std::uint32_t; + auto master = dpf::make_pprf_master(); + const input_t hidden[] = {0u, 0x00c0ffeeu, 0xffffffffu}; + auto copath = dpf::puncture(master, std::begin(hidden), std::end(hidden), + /*program_hidden=*/true); + + ASSERT_EQ(copath.programmed.size(), 3u); + for (input_t h : hidden) + EXPECT_TRUE(eq_block(dpf::pprf_eval(copath, h), dpf::pprf_eval(master, h))); + + const input_t samples[] = {1u, 2u, 0x00c0ffefu, 0x80000000u, 0xfffffffeu}; + for (input_t x : samples) + { + if (std::find(std::begin(hidden), std::end(hidden), x) != std::end(hidden)) + continue; + EXPECT_TRUE( + eq_block(dpf::pprf_eval(copath, x), dpf::pprf_eval(master, x))); + } +} diff --git a/test/tests/ppvc_test.cpp b/test/tests/ppvc_test.cpp index f54ad42..eee4dc7 100644 --- a/test/tests/ppvc_test.cpp +++ b/test/tests/ppvc_test.cpp @@ -439,3 +439,41 @@ TEST(KPpvc, RejectsASharedHiddenIndex) EXPECT_EQ(st.copies[0].i, st.copies[1].i); EXPECT_FALSE(scheme::check_well_formed(pp, com, st)); } + +TEST(Ppvc, AuditedReplicaReexpandsFromCopath) +{ + using scheme = dpf::ppvc; + using input_t = std::uint8_t; + constexpr input_t live = 1; + constexpr input_t audited = 3; + constexpr input_t pool[] = {0, 1, 2, 3}; + + const auto pp = scheme::setup_from_seed(seed_block(90, 91)); + auto master = dpf::make_pprf_master(); + + std::array commitments{}; + std::array states{}; + std::array seeds{}; + for (std::size_t i = 0; i < 4; ++i) + { + seeds[i] = dpf::pprf_eval(master, pool[i]); + auto made = scheme::commit_from_seed(pp, seeds[i]); + commitments[i] = std::move(made.first); + states[i] = std::move(made.second); + ASSERT_TRUE(scheme::check_well_formed(pp, commitments[i], states[i])); + } + + const input_t hidden[] = {live}; + auto copath = dpf::puncture(master, std::begin(hidden), std::end(hidden), + /*program_hidden=*/false); + + EXPECT_THROW((void)dpf::pprf_eval(copath, live), std::invalid_argument); + + const auto opened = dpf::pprf_eval(copath, audited); + EXPECT_TRUE(same_root(opened, seeds[3])); + + auto [com_again, st_again] = scheme::commit_from_seed(pp, opened); + EXPECT_TRUE(scheme::check_well_formed(pp, com_again, st_again)); + EXPECT_TRUE(scheme::audit(pp, commitments[3], opened)); + EXPECT_EQ(st_again.i, states[3].i); +} diff --git a/test/tests/prg_aes_ccr_test.cpp b/test/tests/prg_aes_ccr_test.cpp index 9a1e1ee..f9d63e2 100644 --- a/test/tests/prg_aes_ccr_test.cpp +++ b/test/tests/prg_aes_ccr_test.cpp @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/test/tests/prg_chacha_test.cpp b/test/tests/prg_chacha_test.cpp index 1fa0974..8da44fc 100644 --- a/test/tests/prg_chacha_test.cpp +++ b/test/tests/prg_chacha_test.cpp @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/test/tests/principal_lut_test.cpp b/test/tests/principal_lut_test.cpp index 2028a09..87914bb 100644 --- a/test/tests/principal_lut_test.cpp +++ b/test/tests/principal_lut_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "grotto/principal_lut.hpp" diff --git a/test/tests/protocol_batch_test.cpp b/test/tests/protocol_batch_test.cpp new file mode 100644 index 0000000..a65ce5c --- /dev/null +++ b/test/tests/protocol_batch_test.cpp @@ -0,0 +1,1047 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/beaver.hpp" +#include "dpf/buffered_prg.hpp" +#include "dpf/net/dealer_cursor.hpp" +#include "dpf/net/memory_sink.hpp" +#include "dpf/net/mux_sink.hpp" +#include "dpf/net/party_tape_io.hpp" +#include "dpf/net/sink_exchange.hpp" +#include "dpf/net/stream_sink.hpp" +#include "dpf/net/trio.hpp" +#include "dpf/protocol.hpp" +#include "flow_util.hpp" +#include "simde/simde/x86/avx2.h" + +namespace +{ + +using dpf::protocol::empty_pad; +using dpf::net::dealer_cursor; +using dpf::net::make_memory_sink_pair; +using dpf::net::role; + +struct Round1 +{ + std::pair operator()(int input, std::uint64_t blind) const + { + const int b = static_cast(blind & 0xffffu); + return {input - b, b}; + } +}; + +struct Round2 +{ + int operator()(int forward, int peer_swap, std::uint64_t blind, + empty_pad) const + { + (void)blind; + return forward + peer_swap; + } +}; + +struct Round1Empty +{ + std::pair operator()(int input, empty_pad) const + { + return {input, input}; + } +}; + +struct Round2Empty +{ + int operator()(int forward, int peer_swap, empty_pad, empty_pad) const + { + return forward + peer_swap; + } +}; + +TEST(ProtocolBatch, MemoryTwoMoveShuffled) +{ + constexpr std::size_t N = 100; + auto [sink0, sink1] = make_memory_sink_pair(N, {sizeof(int)}); + dealer_cursor dealer(N, {}); + using Prg = dpf::randomness::aes_buffered_prg; + const auto seed = dpf::randomness::sample_master_seed<>(); + Prg prg0(seed); + Prg prg1(seed); + + auto s0 = dpf::protocol::make_two_move_session(N, sink0, dealer, prg0, Round1{}, Round2{}); + auto s1 = dpf::protocol::make_two_move_session(N, sink1, dealer, prg1, Round1{}, Round2{}); + + std::vector order(N); + std::iota(order.begin(), order.end(), 0); + std::mt19937 rng(0xC0FFEE); + std::shuffle(order.begin(), order.end(), rng); + + for (std::size_t i = 0; i < N; ++i) + { + s0.submit(order[i], static_cast(order[i] + 1)); + s1.submit(i, static_cast(i + 7)); + } + s0.drive(); + s1.drive(); + + for (std::size_t i = 0; i < N; ++i) + { + // Each party reconstructs input0 + input1 from shares of the blind. + // Round1: fwd = in - b, swap = b. Peer sees the other party's b. + // Round2: fwd + peer_swap = (in_me - b_me) + b_peer. + // Sum of both outputs is not simply in0+in1; check local oracle: + const auto blind = prg0.at<0>(static_cast(i)); + const int b = static_cast(blind & 0xffffu); + // Party 0 submitted order-permuted; rebuild expectation for index i + // as party 0's view after drive. + (void)b; + EXPECT_EQ(s0.take(i), s0.take(i)); + EXPECT_EQ(s1.take(i), s1.take(i)); + } + + // Both parties used the same PRG seed, so for a fixed index the blinds + // match. Party 0 input at index j is j+1 when submitted as order mapping: + // s0.submit(order[k], order[k]+1) => input[order[k]] = order[k]+1 + // so input0[i] = i+1. Party 1 input[i] = i+7. + // out0 = (i+1 - b) + b = i+1 + // out1 = (i+7 - b) + b = i+7 + for (std::size_t i = 0; i < N; ++i) + { + EXPECT_EQ(s0.take(i), static_cast(i + 1)); + EXPECT_EQ(s1.take(i), static_cast(i + 7)); + } +} + +TEST(ProtocolBatch, MemoryEmptyBlindAndCorrection) +{ + constexpr std::size_t N = 16; + auto [sink0, sink1] = make_memory_sink_pair(N, {sizeof(int)}); + dealer_cursor dealer(N, {}); + using Prg = dpf::randomness::aes_buffered_prg; + Prg prg(dpf::randomness::sample_master_seed<>()); + + auto s0 = dpf::protocol::make_two_move_session(N, sink0, dealer, prg, Round1Empty{}, Round2Empty{}); + auto s1 = dpf::protocol::make_two_move_session(N, sink1, dealer, prg, Round1Empty{}, Round2Empty{}); + + for (std::size_t i = 0; i < N; ++i) + { + s0.submit(i, 3); + s1.submit(i, 4); + } + s0.drive(); + s1.drive(); + for (std::size_t i = 0; i < N; ++i) + { + // fwd=in, swap=in; out = fwd + peer_swap = in_me + in_peer + EXPECT_EQ(s0.take(i), 3 + 4); + EXPECT_EQ(s1.take(i), 4 + 3); + } +} + +TEST(ProtocolBatch, MemoryHoleBlocksPrefix) +{ + auto [sink0, sink1] = make_memory_sink_pair(3, {sizeof(int)}); + int v = 1; + sink0.submit(0, 0, reinterpret_cast(&v), sizeof(v)); + v = 2; + sink0.submit(0, 2, reinterpret_cast(&v), sizeof(v)); + sink0.flush(); + // Index 1 is a hole: only index 0 may be delivered. + EXPECT_TRUE(sink1.peer_ready(0, 0)); + EXPECT_FALSE(sink1.peer_ready(0, 1)); + EXPECT_FALSE(sink1.peer_ready(0, 2)); + v = 9; + sink0.submit(0, 1, reinterpret_cast(&v), sizeof(v)); + sink0.flush(); + EXPECT_TRUE(sink1.peer_ready(0, 1)); + EXPECT_TRUE(sink1.peer_ready(0, 2)); +} + +TEST(ProtocolBatch, ScheduleSessionMemory) +{ + constexpr std::size_t N = 8; + auto [sink0, sink1] = make_memory_sink_pair(N, {sizeof(std::uint64_t)}); + std::vector local0(N); + std::vector local1(N); + for (std::size_t i = 0; i < N; ++i) + { + local0[i] = 10 + i; + local1[i] = 100 + i; + } + auto make_rounds = [&](std::vector & local) { + std::vector rounds(1); + rounds[0].slot_bytes = sizeof(std::uint64_t); + rounds[0].produce = [&](std::size_t index, const std::uint8_t *, + std::size_t, std::uint8_t * out) { + std::memcpy(out, &local[index], sizeof(std::uint64_t)); + }; + return rounds; + }; + dpf::protocol::schedule_session a(N, sink0, make_rounds(local0)); + dpf::protocol::schedule_session b(N, sink1, make_rounds(local1)); + for (std::size_t i = 0; i < N; ++i) + { + a.submit(i); + b.submit(N - 1 - i); + } + a.drive(); + b.drive(); + for (std::size_t i = 0; i < N; ++i) + { + EXPECT_TRUE(a.done(i)); + EXPECT_TRUE(b.done(i)); + std::uint64_t peer = 0; + sink0.read_peer(0, i, reinterpret_cast(&peer), + sizeof(peer)); + EXPECT_EQ(peer, local1[i]); + } +} + +void run_trio_two_move(bool use_stream) +{ + constexpr std::size_t N = 32; + const std::string dir = "/tmp/libdpf-protocol-batch-XXXXXX"; + std::string path = dir; + ASSERT_NE(mkdtemp(path.data()), nullptr); + + auto child = [&](role self) { + using Prg = dpf::randomness::aes_buffered_prg; + const auto seed = simde_mm_setzero_si128(); + Prg prg(seed); + dealer_cursor dealer(N, {}); + std::unique_ptr sink; + dpf::net::trio net; + if (use_stream) + { + auto s = dpf::net::connect_stream_sink(self, + self == role::p0 ? role::p1 : role::p0, path, N, + {sizeof(int)}); + struct holder : dpf::net::RoundSink + { + dpf::net::stream_sink inner; + explicit holder(dpf::net::stream_sink s) : inner(std::move(s)) {} + std::size_t count() const noexcept override + { + return inner.count(); + } + std::size_t rounds() const noexcept override + { + return inner.rounds(); + } + std::size_t slot_bytes(std::uint16_t r) const override + { + return inner.slot_bytes(r); + } + void submit(std::uint16_t r, std::size_t i, + const std::uint8_t * b, std::size_t n) override + { + inner.submit(r, i, b, n); + } + bool peer_ready(std::uint16_t r, std::size_t i) const override + { + return inner.peer_ready(r, i); + } + void read_peer(std::uint16_t r, std::size_t i, std::uint8_t * o, + std::size_t n) const override + { + inner.read_peer(r, i, o, n); + } + void flush() override { inner.flush(); } + void flush_round(std::uint16_t r) override + { + inner.flush_round(r); + } + void poll() override { inner.poll(); } + }; + sink = std::make_unique(std::move(s)); + } + else + { + net = dpf::net::trio::connect_pair(self, path); + struct holder : dpf::net::RoundSink + { + dpf::net::mux_sink inner; + explicit holder(dpf::net::mux_sink s) : inner(std::move(s)) {} + std::size_t count() const noexcept override + { + return inner.count(); + } + std::size_t rounds() const noexcept override + { + return inner.rounds(); + } + std::size_t slot_bytes(std::uint16_t r) const override + { + return inner.slot_bytes(r); + } + void submit(std::uint16_t r, std::size_t i, + const std::uint8_t * b, std::size_t n) override + { + inner.submit(r, i, b, n); + } + bool peer_ready(std::uint16_t r, std::size_t i) const override + { + return inner.peer_ready(r, i); + } + void read_peer(std::uint16_t r, std::size_t i, std::uint8_t * o, + std::size_t n) const override + { + inner.read_peer(r, i, o, n); + } + void flush() override { inner.flush(); } + void flush_round(std::uint16_t r) override + { + inner.flush_round(r); + } + void poll() override { inner.poll(); } + }; + sink = std::make_unique( + dpf::net::make_mux_sink(net, N, {sizeof(int)})); + } + auto sess = dpf::protocol::make_two_move_session(N, *sink, dealer, prg, Round1{}, Round2{}); + const int base = self == role::p0 ? 1 : 7; + for (std::size_t i = 0; i < N; ++i) + sess.submit(i, static_cast(i) + base); + sess.drive(); + for (std::size_t i = 0; i < N; ++i) + { + if (sess.take(i) != static_cast(i) + base) + std::_Exit(2); + } + std::_Exit(0); + }; + + pid_t p0 = fork(); + ASSERT_GE(p0, 0); + if (p0 == 0) + child(role::p0); + pid_t p1 = fork(); + ASSERT_GE(p1, 0); + if (p1 == 0) + child(role::p1); + int st0 = 0; + int st1 = 0; + waitpid(p0, &st0, 0); + waitpid(p1, &st1, 0); + EXPECT_TRUE(WIFEXITED(st0) && WEXITSTATUS(st0) == 0); + EXPECT_TRUE(WIFEXITED(st1) && WEXITSTATUS(st1) == 0); +} + +TEST(ProtocolBatch, MuxTwoMove) +{ + run_trio_two_move(false); +} + +TEST(ProtocolBatch, StreamTwoMove) +{ + run_trio_two_move(true); +} + +/// @brief Counts hooked trio helpers; framing stays on the mesh. +struct counting_hook : dpf::net::mesh_comm_hook +{ + int sends = 0; + int recvs = 0; + int exchanges = 0; + int batches = 0; + + void send_bytes(dpf::net::trio & net, unsigned peer_id, dpf::net::msg tag, + const void * data, std::size_t n) override + { + ++sends; + mesh_comm_hook::send_bytes(net, peer_id, tag, data, n); + } + + std::vector recv_bytes(dpf::net::trio & net, unsigned peer_id, + dpf::net::msg tag) override + { + ++recvs; + return mesh_comm_hook::recv_bytes(net, peer_id, tag); + } + + std::vector exchange_bytes(dpf::net::trio & net, + unsigned peer_id, dpf::net::msg tag, const void * data, + std::size_t n) override + { + ++exchanges; + return mesh_comm_hook::exchange_bytes(net, peer_id, tag, data, n); + } + + std::vector exchange_vec_bytes(dpf::net::trio & net, + unsigned peer_id, dpf::net::msg tag, const void * data, + std::size_t nbytes) override + { + ++exchanges; + return mesh_comm_hook::exchange_vec_bytes(net, peer_id, tag, data, + nbytes); + } + + std::unique_ptr batch(dpf::net::trio & net, + std::size_t count, std::vector slot_bytes) override + { + ++batches; + return mesh_comm_hook::batch(net, count, std::move(slot_bytes)); + } +}; + +TEST(ProtocolBatch, HookRoutesDealExchangeAndBeaver) +{ + char tmpl[] = "/tmp/dpf-hook-XXXXXX"; + ASSERT_NE(mkdtemp(tmpl), nullptr); + const std::string path = tmpl; + + auto child = [&](role self) { + counting_hook hook; + auto net = dpf::net::trio::connect_local(self, path); + net.set_hook(&hook); + + // Dealer pad through hooked send/recv. + if (self == role::p2) + { + struct split + { + std::uint64_t p0 = 11; + std::uint64_t p1 = 31; + } s; + net.deal(s); + } + else + { + const auto pad = net.accept_deal(); + if (self == role::p0 && pad != 11ull) + std::_Exit(3); + if (self == role::p1 && pad != 31ull) + std::_Exit(4); + } + + // Beaver online through hooked batch (no mux_sink name at the call). + dpf::beavers::session s; + auto x = s.input(); + auto y = s.input(); + auto z = s(x * y); + if (self == role::p2) + { + struct Counter + { + int draws = 0; + std::uint64_t operator()() + { + ++draws; + return 0x9e3779b97f4a7c15ull * static_cast(draws); + } + } rng; + s.sample(rng); + dpf::net::deal_session(net, s); + if (hook.sends < 2) + std::_Exit(5); + std::_Exit(0); + } + auto tape = dpf::net::accept_session(net); + s.install_party(self == role::p0 ? 0u : 1u, tape); + s.bind_party(x, self == role::p0 ? 3ull : 4ull); + s.bind_party(y, self == role::p0 ? 5ull : 6ull); + dpf::party::util::evaluate_online(s, net, self); + const auto open = net.open_with( + self == role::p0 ? role::p1 : role::p0, s.value_party(z)); + // Shares (3,4) and (5,6) reconstruct to 7 * 11 = 77. + if (self == role::p0 && open != 77ull) + std::_Exit(6); + if (hook.batches < 1) + std::_Exit(7); + if (hook.recvs < 1) + std::_Exit(8); + std::_Exit(0); + }; + + pid_t p0 = fork(); + ASSERT_GE(p0, 0); + if (p0 == 0) + child(role::p0); + pid_t p1 = fork(); + ASSERT_GE(p1, 0); + if (p1 == 0) + child(role::p1); + pid_t p2 = fork(); + ASSERT_GE(p2, 0); + if (p2 == 0) + child(role::p2); + int st0 = 0, st1 = 0, st2 = 0; + waitpid(p0, &st0, 0); + waitpid(p1, &st1, 0); + waitpid(p2, &st2, 0); + EXPECT_TRUE(WIFEXITED(st0) && WEXITSTATUS(st0) == 0) << WEXITSTATUS(st0); + EXPECT_TRUE(WIFEXITED(st1) && WEXITSTATUS(st1) == 0) << WEXITSTATUS(st1); + EXPECT_TRUE(WIFEXITED(st2) && WEXITSTATUS(st2) == 0) << WEXITSTATUS(st2); +} + +/// @brief Oversized stream sink + sink_exchange must not hang or pay one +/// exchange per idle round (flush_round path only). +TEST(ProtocolBatch, StreamFlushRoundNoIdleStorm) +{ + constexpr std::size_t R = 64; + constexpr std::size_t steps = 8; + char tmpl[] = "/tmp/dpf-stream-flush-XXXXXX"; + ASSERT_NE(mkdtemp(tmpl), nullptr); + const std::string path = tmpl; + + auto child = [&](role self) { + alarm(15); + std::vector slots(R, sizeof(std::uint64_t)); + auto sink = dpf::net::connect_stream_sink(self, + self == role::p0 ? role::p1 : role::p0, path, 1, std::move(slots)); + dpf::net::sink_exchange ex(sink, 0); + for (std::size_t i = 0; i < steps; ++i) + { + const std::uint64_t mine = + (self == role::p0 ? 0x1000ull : 0x2000ull) + i; + const auto peer = ex(mine); + const std::uint64_t expect = + (self == role::p0 ? 0x2000ull : 0x1000ull) + i; + if (peer != expect) + std::_Exit(2); + } + // flush_round path: exactly one duplex per step, not one per idle round. + if (sink.exchanges() != steps) + std::_Exit(3); + std::_Exit(0); + }; + + pid_t p0 = fork(); + ASSERT_GE(p0, 0); + if (p0 == 0) + child(role::p0); + pid_t p1 = fork(); + ASSERT_GE(p1, 0); + if (p1 == 0) + child(role::p1); + int st0 = 0; + int st1 = 0; + waitpid(p0, &st0, 0); + waitpid(p1, &st1, 0); + EXPECT_TRUE(WIFEXITED(st0) && WEXITSTATUS(st0) == 0) << WEXITSTATUS(st0); + EXPECT_TRUE(WIFEXITED(st1) && WEXITSTATUS(st1) == 0) << WEXITSTATUS(st1); +} + +/// @brief Mux flush_round must not invent extra link exchanges beyond the +/// number of interactive steps (no per-idle-round storm). +TEST(ProtocolBatch, MuxFlushRoundExchangeCount) +{ + constexpr std::size_t R = 64; + constexpr std::size_t steps = 8; + char tmpl[] = "/tmp/dpf-mux-flush-XXXXXX"; + ASSERT_NE(mkdtemp(tmpl), nullptr); + const std::string path = tmpl; + + auto child = [&](role self) { + alarm(15); + auto net = dpf::net::trio::connect_pair(self, path); + std::vector slots(R, sizeof(std::uint64_t)); + dpf::net::mux_sink sink = dpf::net::make_mux_sink(net, 1, std::move(slots)); + dpf::net::sink_exchange ex(sink, 0); + for (std::size_t i = 0; i < steps; ++i) + { + const std::uint64_t mine = + (self == role::p0 ? 0xA000ull : 0xB000ull) + i; + const auto peer = ex(mine); + const std::uint64_t expect = + (self == role::p0 ? 0xB000ull : 0xA000ull) + i; + if (peer != expect) + std::_Exit(2); + } + if (sink.exchanges() != steps) + std::_Exit(3); + std::_Exit(0); + }; + + pid_t p0 = fork(); + ASSERT_GE(p0, 0); + if (p0 == 0) + child(role::p0); + pid_t p1 = fork(); + ASSERT_GE(p1, 0); + if (p1 == 0) + child(role::p1); + int st0 = 0; + int st1 = 0; + waitpid(p0, &st0, 0); + waitpid(p1, &st1, 0); + EXPECT_TRUE(WIFEXITED(st0) && WEXITSTATUS(st0) == 0) << WEXITSTATUS(st0); + EXPECT_TRUE(WIFEXITED(st1) && WEXITSTATUS(st1) == 0) << WEXITSTATUS(st1); +} + +/// @brief Memory sink_exchange across a padded round budget (ds-walk sized). +TEST(ProtocolBatch, MemorySinkExchangePaddedRounds) +{ + const auto slots = dpf::net::ds_walk_slot_bytes(8, false); + ASSERT_GE(slots.size(), 16u); + auto [a, b] = make_memory_sink_pair(1, slots); + // Interleave submits then one flush_round — memory hub moves both directions. + for (std::size_t i = 0; i < 12; ++i) + { + const std::uint64_t va = 0x11ull + i; + const std::uint64_t vb = 0x22ull + i; + // memory_sink: one flush_round after both submits (shared hub). + std::vector ba(slots[i], 0); + std::vector bb(slots[i], 0); + std::memcpy(ba.data(), &va, sizeof(va)); + std::memcpy(bb.data(), &vb, sizeof(vb)); + a.submit(static_cast(i), 0, ba.data(), ba.size()); + b.submit(static_cast(i), 0, bb.data(), bb.size()); + a.flush_round(static_cast(i)); + EXPECT_TRUE(a.peer_ready(static_cast(i), 0)); + EXPECT_TRUE(b.peer_ready(static_cast(i), 0)); + std::vector ra(slots[i], 0); + std::vector rb(slots[i], 0); + a.read_peer(static_cast(i), 0, ra.data(), slots[i]); + b.read_peer(static_cast(i), 0, rb.data(), slots[i]); + std::uint64_t pa = 0; + std::uint64_t pb = 0; + std::memcpy(&pa, ra.data(), sizeof(pa)); + std::memcpy(&pb, rb.data(), sizeof(pb)); + EXPECT_EQ(pa, vb); + EXPECT_EQ(pb, va); + } +} + +/// @brief Hooked beaver online on an oversized batch must not exhaust rounds +/// or deadlock under a wall-clock alarm. +TEST(ProtocolBatch, HookBeaverOnlinePaddedBatch) +{ + char tmpl[] = "/tmp/dpf-hook-pad-XXXXXX"; + ASSERT_NE(mkdtemp(tmpl), nullptr); + const std::string path = tmpl; + + auto child = [&](role self) { + alarm(20); + counting_hook hook; + auto net = dpf::net::trio::connect_local(self, path); + net.set_hook(&hook); + + dpf::beavers::session s; + std::vector::wire> xs; + xs.reserve(6); + for (int i = 0; i < 6; ++i) + xs.push_back(s.input()); + auto z = s(xs[0] * xs[1] + xs[2] * xs[3] + xs[4] * xs[5]); + if (self == role::p2) + { + struct Counter + { + int draws = 0; + std::uint64_t operator()() + { + ++draws; + return 0x9e3779b97f4a7c15ull + * static_cast(draws); + } + } rng; + s.sample(rng); + dpf::net::deal_session(net, s); + std::_Exit(0); + } + auto tape = dpf::net::accept_session(net); + s.install_party(self == role::p0 ? 0u : 1u, tape); + for (int i = 0; i < 6; ++i) + s.bind_party(xs[static_cast(i)], + self == role::p0 ? static_cast(i + 1) + : static_cast(10 + i)); + // Pad far beyond max_ready_round to mimic ds_walk oversizing. + const int need = std::max(1, s.max_ready_round()); + std::vector slots( + static_cast(need) + 48, + sizeof(std::uint32_t) + 64 * sizeof(std::uint64_t)); + auto sink = net.batch(1, std::move(slots)); + dpf::party::util::evaluate_online_on_sink(s, *sink, 0); + const auto open = net.open_with( + self == role::p0 ? role::p1 : role::p0, s.value_party(z)); + // (1*11)+(2*12)+(3*13) tied to party shares: p0 binds 1..6, p1 10..15 + // products reconstruct (1+10)*(2+11) wait — each wire is additive share. + // x_i = p0_i + p1_i = (i+1)+(10+i) = 11+2i + // z = x0*x1 + x2*x3 + x4*x5 + // = 11*13 + 15*17 + 19*21 = 143 + 255 + 399 = 797 + if (self == role::p0 && open != 797ull) + std::_Exit(4); + if (hook.batches < 1) + std::_Exit(5); + std::_Exit(0); + }; + + pid_t p0 = fork(); + ASSERT_GE(p0, 0); + if (p0 == 0) + child(role::p0); + pid_t p1 = fork(); + ASSERT_GE(p1, 0); + if (p1 == 0) + child(role::p1); + pid_t p2 = fork(); + ASSERT_GE(p2, 0); + if (p2 == 0) + child(role::p2); + int st0 = 0, st1 = 0, st2 = 0; + waitpid(p0, &st0, 0); + waitpid(p1, &st1, 0); + waitpid(p2, &st2, 0); + EXPECT_TRUE(WIFEXITED(st0) && WEXITSTATUS(st0) == 0) << WEXITSTATUS(st0); + EXPECT_TRUE(WIFEXITED(st1) && WEXITSTATUS(st1) == 0) << WEXITSTATUS(st1); + EXPECT_TRUE(WIFEXITED(st2) && WEXITSTATUS(st2) == 0) << WEXITSTATUS(st2); +} + +/// @brief Wide shallow circuits must not allocate O(wires) round windows. +TEST(ProtocolBatch, BeaverOnlineRoundBudgetTight) +{ + char tmpl[] = "/tmp/dpf-beaver-budget-XXXXXX"; + ASSERT_NE(mkdtemp(tmpl), nullptr); + const std::string path = tmpl; + + auto child = [&](role self) { + alarm(30); + struct hold_hook : dpf::net::mesh_comm_hook + { + std::size_t last_rounds = 0; + std::uint64_t exchanges = 0; + struct wrap : dpf::net::RoundSink + { + dpf::net::mux_sink inner; + std::uint64_t * out = nullptr; + wrap(dpf::net::mux_sink s, std::uint64_t * o) + : inner(std::move(s)), out(o) + { } + ~wrap() override + { + if (out) + *out = inner.exchanges(); + } + std::size_t count() const noexcept override + { + return inner.count(); + } + std::size_t rounds() const noexcept override + { + return inner.rounds(); + } + std::size_t slot_bytes(std::uint16_t r) const override + { + return inner.slot_bytes(r); + } + void submit(std::uint16_t r, std::size_t i, + const std::uint8_t * b, std::size_t n) override + { + inner.submit(r, i, b, n); + } + bool peer_ready(std::uint16_t r, std::size_t i) const override + { + return inner.peer_ready(r, i); + } + void read_peer(std::uint16_t r, std::size_t i, std::uint8_t * o, + std::size_t n) const override + { + inner.read_peer(r, i, o, n); + } + void flush() override { inner.flush(); } + void flush_round(std::uint16_t r) override + { + inner.flush_round(r); + } + void poll() override { inner.poll(); } + }; + std::unique_ptr batch(dpf::net::trio & net, + std::size_t count, std::vector slot_bytes) override + { + last_rounds = slot_bytes.size(); + return std::make_unique( + dpf::net::make_mux_sink(net, count, std::move(slot_bytes)), + &exchanges); + } + } h; + auto net = dpf::net::trio::connect_local(self, path); + net.set_hook(&h); + + constexpr int N = 256; + dpf::beavers::session s; + std::vector::wire> xs, ys; + xs.reserve(N); + ys.reserve(N); + for (int i = 0; i < N; ++i) + { + xs.push_back(s.input()); + ys.push_back(s.input()); + } + auto acc = xs[0] * ys[0]; + for (int i = 1; i < N; ++i) + acc = acc + xs[i] * ys[i]; + auto z = s(acc); + + if (self == role::p2) + { + if (s.max_ready_round() != 1) + std::_Exit(2); + struct Counter + { + int draws = 0; + std::uint64_t operator()() + { + ++draws; + return 0x9e3779b97f4a7c15ull + * static_cast(draws); + } + } rng; + s.sample(rng); + dpf::net::deal_session(net, s); + std::_Exit(0); + } + auto tape = dpf::net::accept_session(net); + s.install_party(self == role::p0 ? 0u : 1u, tape); + for (int i = 0; i < N; ++i) + { + s.bind_party(xs[static_cast(i)], + self == role::p0 ? static_cast(i + 1) + : static_cast(1000 + i)); + s.bind_party(ys[static_cast(i)], + self == role::p0 ? static_cast(i + 3) + : static_cast(2000 + i)); + } + dpf::party::util::evaluate_online(s, net, self); + // Depth-1 product sum: budget is O(1), not O(N). + const int expect_budget = dpf::party::util::beaver_batch_round_budget( + s.max_ready_round(), s.wire_count()); + if (static_cast(h.last_rounds) != expect_budget) + std::_Exit(3); + if (h.last_rounds > 48) + std::_Exit(4); + if (h.exchanges == 0 || h.exchanges > h.last_rounds) + std::_Exit(5); + const auto open = net.open_with( + self == role::p0 ? role::p1 : role::p0, s.value_party(z)); + // Reconstruct expected: sum_i (i+1+1000+i)*(i+3+2000+i) + // = sum_i (1001+2i)*(2003+2i) + if (self == role::p0) + { + std::uint64_t expect = 0; + for (int i = 0; i < N; ++i) + { + const std::uint64_t xi = + static_cast(i + 1) + static_cast(1000 + i); + const std::uint64_t yi = + static_cast(i + 3) + static_cast(2000 + i); + expect += xi * yi; + } + if (open != expect) + std::_Exit(6); + } + std::_Exit(0); + }; + + pid_t p0 = fork(); + ASSERT_GE(p0, 0); + if (p0 == 0) + child(role::p0); + pid_t p1 = fork(); + ASSERT_GE(p1, 0); + if (p1 == 0) + child(role::p1); + pid_t p2 = fork(); + ASSERT_GE(p2, 0); + if (p2 == 0) + child(role::p2); + int st0 = 0, st1 = 0, st2 = 0; + waitpid(p0, &st0, 0); + waitpid(p1, &st1, 0); + waitpid(p2, &st2, 0); + EXPECT_TRUE(WIFEXITED(st0) && WEXITSTATUS(st0) == 0) << WEXITSTATUS(st0); + EXPECT_TRUE(WIFEXITED(st1) && WEXITSTATUS(st1) == 0) << WEXITSTATUS(st1); + EXPECT_TRUE(WIFEXITED(st2) && WEXITSTATUS(st2) == 0) << WEXITSTATUS(st2); +} + +/// @brief Multi-lane sequential sink_exchange (signum pattern) must not hang. +TEST(ProtocolBatch, MultiLaneSequentialSinkExchange) +{ + constexpr std::size_t lanes = 4; + constexpr std::size_t steps = 6; + char tmpl[] = "/tmp/dpf-multilane-XXXXXX"; + ASSERT_NE(mkdtemp(tmpl), nullptr); + const std::string path = tmpl; + + auto child = [&](role self) { + alarm(20); + auto net = dpf::net::trio::connect_pair(self, path); + std::vector slots(steps, sizeof(std::uint64_t)); + auto sink = dpf::net::make_mux_sink(net, lanes, std::move(slots)); + for (std::size_t lane = 0; lane < lanes; ++lane) + { + dpf::net::sink_exchange ex(sink, lane); + for (std::size_t r = 0; r < steps; ++r) + { + const std::uint64_t mine = + (self == role::p0 ? 0x10ull : 0x20ull) + lane * 100 + r; + const auto peer = ex(mine); + const std::uint64_t expect = + (self == role::p0 ? 0x20ull : 0x10ull) + lane * 100 + r; + if (peer != expect) + std::_Exit(2); + } + } + // Sequential lanes: steps exchanges per lane. + if (sink.exchanges() != lanes * steps) + std::_Exit(3); + std::_Exit(0); + }; + + pid_t p0 = fork(); + ASSERT_GE(p0, 0); + if (p0 == 0) + child(role::p0); + pid_t p1 = fork(); + ASSERT_GE(p1, 0); + if (p1 == 0) + child(role::p1); + int st0 = 0, st1 = 0; + waitpid(p0, &st0, 0); + waitpid(p1, &st1, 0); + EXPECT_TRUE(WIFEXITED(st0) && WEXITSTATUS(st0) == 0) << WEXITSTATUS(st0); + EXPECT_TRUE(WIFEXITED(st1) && WEXITSTATUS(st1) == 0) << WEXITSTATUS(st1); +} + +/// @brief Mux flush() bundles many pending rounds into one exchange. +TEST(ProtocolBatch, MuxFlushBundlesPendingRounds) +{ + constexpr std::size_t R = 16; + char tmpl[] = "/tmp/dpf-mux-bundle-XXXXXX"; + ASSERT_NE(mkdtemp(tmpl), nullptr); + const std::string path = tmpl; + + auto child = [&](role self) { + alarm(15); + auto net = dpf::net::trio::connect_pair(self, path); + std::vector slots(R, sizeof(std::uint32_t)); + auto sink = dpf::net::make_mux_sink(net, 1, std::move(slots)); + for (std::uint16_t r = 0; r < R; ++r) + { + const std::uint32_t v = + (self == role::p0 ? 100u : 200u) + r; + sink.submit(r, 0, reinterpret_cast(&v), + sizeof(v)); + } + sink.flush(); // one exchange for all R rounds + if (sink.exchanges() != 1) + std::_Exit(2); + for (std::uint16_t r = 0; r < R; ++r) + { + if (!sink.peer_ready(r, 0)) + std::_Exit(3); + std::uint32_t peer = 0; + sink.read_peer(r, 0, reinterpret_cast(&peer), + sizeof(peer)); + const std::uint32_t expect = + (self == role::p0 ? 200u : 100u) + r; + if (peer != expect) + std::_Exit(4); + } + std::_Exit(0); + }; + + pid_t p0 = fork(); + ASSERT_GE(p0, 0); + if (p0 == 0) + child(role::p0); + pid_t p1 = fork(); + ASSERT_GE(p1, 0); + if (p1 == 0) + child(role::p1); + int st0 = 0, st1 = 0; + waitpid(p0, &st0, 0); + waitpid(p1, &st1, 0); + EXPECT_TRUE(WIFEXITED(st0) && WEXITSTATUS(st0) == 0) << WEXITSTATUS(st0); + EXPECT_TRUE(WIFEXITED(st1) && WEXITSTATUS(st1) == 0) << WEXITSTATUS(st1); +} + +/// @brief Stream flush() after multi-round submits must rendezvous (no hang). +TEST(ProtocolBatch, StreamFlushAllRoundsRendezvous) +{ + constexpr std::size_t R = 8; + char tmpl[] = "/tmp/dpf-stream-bundle-XXXXXX"; + ASSERT_NE(mkdtemp(tmpl), nullptr); + const std::string path = tmpl; + + auto child = [&](role self) { + alarm(20); + std::vector slots(R, sizeof(std::uint32_t)); + auto sink = dpf::net::connect_stream_sink(self, + self == role::p0 ? role::p1 : role::p0, path, 1, std::move(slots)); + // Stagger: p0 fills even rounds first, p1 fills odd — then both flush(). + for (std::uint16_t r = 0; r < R; ++r) + { + const bool mine = + (self == role::p0) ? (r % 2 == 0) : (r % 2 == 1); + if (!mine) + continue; + const std::uint32_t v = 50u + r; + sink.submit(r, 0, reinterpret_cast(&v), + sizeof(v)); + } + sink.flush(); + // After global flush both should have peer data for the rounds the + // peer filled; own rounds may still be empty on the peer side until + // the peer also submitted — second pass fills the rest. + for (std::uint16_t r = 0; r < R; ++r) + { + const bool peer_filled = + (self == role::p0) ? (r % 2 == 1) : (r % 2 == 0); + if (peer_filled && !sink.peer_ready(r, 0)) + std::_Exit(2); + } + for (std::uint16_t r = 0; r < R; ++r) + { + const bool mine = + (self == role::p0) ? (r % 2 == 1) : (r % 2 == 0); + if (!mine) + continue; + const std::uint32_t v = 50u + r; + sink.submit(r, 0, reinterpret_cast(&v), + sizeof(v)); + } + sink.flush(); + for (std::uint16_t r = 0; r < R; ++r) + { + if (!sink.peer_ready(r, 0)) + std::_Exit(3); + std::uint32_t peer = 0; + sink.read_peer(r, 0, reinterpret_cast(&peer), + sizeof(peer)); + if (peer != 50u + r) + std::_Exit(4); + } + std::_Exit(0); + }; + + pid_t p0 = fork(); + ASSERT_GE(p0, 0); + if (p0 == 0) + child(role::p0); + pid_t p1 = fork(); + ASSERT_GE(p1, 0); + if (p1 == 0) + child(role::p1); + int st0 = 0, st1 = 0; + waitpid(p0, &st0, 0); + waitpid(p1, &st1, 0); + EXPECT_TRUE(WIFEXITED(st0) && WEXITSTATUS(st0) == 0) << WEXITSTATUS(st0); + EXPECT_TRUE(WIFEXITED(st1) && WEXITSTATUS(st1) == 0) << WEXITSTATUS(st1); +} + +} // namespace diff --git a/test/tests/random_test.cpp b/test/tests/random_test.cpp index 08b8c76..b07a1e5 100644 --- a/test/tests/random_test.cpp +++ b/test/tests/random_test.cpp @@ -1,4 +1,5 @@ #include "dpf/random.hpp" +#include #include @@ -311,7 +312,7 @@ TEST_F(RandomTest, ForkedProcessesDoNotRepeatEntropy) { // A buffered stdio read of the device copies the unread buffer into the // child. Prime the generator, then compare the next draw on each side. - (void)dpf::uniform_sample(); + dpf::uniform_sample(); int fds[2]; ASSERT_EQ(::pipe(fds), 0); diff --git a/test/tests/range_lut_test.cpp b/test/tests/range_lut_test.cpp index 173119a..1058cc3 100644 --- a/test/tests/range_lut_test.cpp +++ b/test/tests/range_lut_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "grotto/range_lut.hpp" @@ -103,16 +104,26 @@ bool near_odd_multiple_of_half_pi(long double x) TEST(RangeLut, LogarithmsTrackLibmOnEveryPrecision) { - const grotto::reduced maps[] = { - grotto::reduced::ln, grotto::reduced::lg, grotto::reduced::log10, - }; const long double samples[] = { 0.125L, 0.3L, 0.5L, 0.75L, 1.0L, 1.5L, 2.0L, 3.0L, 7.5L, 16.0L, 24.0L, 100.0L, }; - for (auto which : maps) - for (unsigned k : grotto::principal_precisions) - for (long double x : samples) - expect_ulps(which, k, x, 6.0L); + for (unsigned k : grotto::principal_precisions) + { + for (long double x : samples) + { + expect_ulps(grotto::reduced::ln, k, x, 1.0L); + expect_ulps(grotto::reduced::log10, k, x, 1.0L); + expect_ulps(grotto::reduced::lg, k, x, 2.0L); + } + for (int exp : {-20, 20}) + { + const long double x = std::ldexp(1.0L, exp); + if (raw_of(x, k) == 0) + continue; + expect_ulps(grotto::reduced::ln, k, x, 1.0L); + expect_ulps(grotto::reduced::log10, k, x, 1.0L); + } + } } TEST(RangeLut, ExponentialsTrackLibmOnEveryPrecision) @@ -120,10 +131,12 @@ TEST(RangeLut, ExponentialsTrackLibmOnEveryPrecision) const long double samples[] = { -2.0L, -1.5L, -0.5L, -0.1L, 0.0L, 0.1L, 0.5L, 1.0L, 1.5L, 2.0L, }; - for (auto which : {grotto::reduced::exp, grotto::reduced::exp2}) - for (unsigned k : grotto::principal_precisions) - for (long double x : samples) - expect_ulps(which, k, x, 16.0L); + for (unsigned k : grotto::principal_precisions) + for (long double x : samples) + { + expect_ulps(grotto::reduced::exp, k, x, 1.0L); + expect_ulps(grotto::reduced::exp2, k, x, 2.0L); + } for (unsigned k : grotto::principal_precisions) { for (long double x : {-0.9L, -0.25L, 0.0L, 0.25L, 0.9L}) @@ -259,7 +272,7 @@ TEST(RangeLut, TanAndSecPolesThrow) { try { - (void)grotto::eval_reduced(which, k, raw); + grotto::eval_reduced(which, k, raw); } catch (const std::domain_error &) { @@ -290,7 +303,7 @@ TEST(RangeLut, Exp10RejectsAnIntegerPowerPast18) { try { - (void)grotto::eval_reduced(grotto::reduced::exp10, k, raw_of(static_cast(n), k)); + grotto::eval_reduced(grotto::reduced::exp10, k, raw_of(static_cast(n), k)); } catch (const std::overflow_error &) { @@ -302,10 +315,8 @@ TEST(RangeLut, Exp10RejectsAnIntegerPowerPast18) ASSERT_LE(first_overflow, 19); EXPECT_NO_THROW(grotto::eval_reduced(grotto::reduced::exp10, k, raw_of(static_cast(first_overflow - 1), k))); - EXPECT_THROW(grotto::eval_reduced(grotto::reduced::exp10, k, raw_of(19.0L, k)), - std::overflow_error); - EXPECT_THROW(grotto::eval_reduced(grotto::reduced::exp10, k, raw_of(-19.0L, k)), - std::overflow_error); + EXPECT_THROW(grotto::eval_reduced(grotto::reduced::exp10, k, raw_of(19.0L, k)), std::overflow_error); + EXPECT_THROW(grotto::eval_reduced(grotto::reduced::exp10, k, raw_of(-19.0L, k)), std::overflow_error); } TEST(RangeLut, Expm1AndLog1pTrackLibm) @@ -325,9 +336,28 @@ TEST(RangeLut, Expm1AndLog1pTrackLibm) expect_ulps(grotto::reduced::log1p, k, std::ldexp(1.0L, -static_cast(k)), 2.0L); expect_ulps(grotto::reduced::log1p, k, -std::ldexp(1.0L, -static_cast(k)), 2.0L); for (long double x : expm1_samples) - expect_ulps(grotto::reduced::expm1, k, x, 20.0L); + expect_ulps(grotto::reduced::expm1, k, x, 1.0L); for (long double x : log1p_samples) - expect_ulps(grotto::reduced::log1p, k, x, 8.0L); + expect_ulps(grotto::reduced::log1p, k, x, 1.0L); + } +} + +TEST(RangeLut, ReciprocalFamilyStaysInsideOneUlpAfterTheLift) +{ + const long double samples[] = { + std::ldexp(1.0L, -12), 0.015625L, 0.125L, 0.5L, 0.75L, 1.0L, 1.5L, 3.0L, 8.0L, 100.0L, + }; + for (auto which : {grotto::reduced::inv, grotto::reduced::rsqrt, grotto::reduced::invsq}) + { + for (unsigned k : {16u, 32u}) + { + for (long double x : samples) + { + if (k == 16 && x < std::ldexp(1.0L, -10)) + continue; + expect_ulps(which, k, x, 1.0L); + } + } } } diff --git a/test/tests/ring_switch_test.cpp b/test/tests/ring_switch_test.cpp new file mode 100644 index 0000000..871be1b --- /dev/null +++ b/test/tests/ring_switch_test.cpp @@ -0,0 +1,128 @@ +#include + +#include "grotto/ring_switch.hpp" + +#include "dpf/field128.hpp" +#include "dpf/p256_scalar.hpp" +#include "dpf/verifiable.hpp" + +#include + +TEST(Residue, Zn64Arithmetic) +{ + using Z = grotto::zn64<7>; + EXPECT_EQ((Z{3} + Z{5}).raw(), 1u); + EXPECT_EQ((-Z{3}).raw(), 4u); + EXPECT_EQ((Z{3} - Z{5}).raw(), 5u); +} + +TEST(Residue, Zn128Arithmetic) +{ + using Z = grotto::zn128<1009, 0>; + EXPECT_EQ((Z{1000} + Z{20}).lo(), 11u); + EXPECT_EQ((-Z{1}).lo(), 1008u); +} + +TEST(Residue, CrtFactor) +{ + using Z = grotto::zn64<15>; + const Z share{11}; + EXPECT_EQ(grotto::ring_switch_factor<3>(share).raw(), 2u); + EXPECT_EQ(grotto::ring_switch_factor<5>(share).raw(), 1u); +} + +TEST(RingSwitch, Zn64WrapAndNoWrap) +{ + using Z = grotto::zn64<1009>; + const std::uint8_t r = 200; + const std::uint8_t eta_nw = 10; // 200+10 < 256 + const std::uint8_t eta_w = 100; // 200+100 >= 256 + const std::uint8_t x_nw = static_cast(r + eta_nw); + const std::uint8_t x_w = static_cast(r + eta_w); + + auto mat = grotto::make_ring_switch_keys(r); + const Z s0 = grotto::ring_switch_eval<0>(mat, eta_nw); + const Z s1 = grotto::ring_switch_eval<1>(mat, eta_nw); + EXPECT_EQ(s0 + s1, grotto::ring_switch_clear(x_nw, r, eta_nw)); + EXPECT_EQ((s0 + s1).raw(), static_cast(x_nw) % 1009); + + const Z t0 = grotto::ring_switch_eval<0>(mat, eta_w); + const Z t1 = grotto::ring_switch_eval<1>(mat, eta_w); + EXPECT_EQ(t0 + t1, grotto::ring_switch_clear(x_w, r, eta_w)); + EXPECT_EQ((t0 + t1).raw(), static_cast(x_w) % 1009); +} + +TEST(RingSwitch, Zn64EtaZero) +{ + using Z = grotto::zn64<97>; + const std::uint8_t r = 55; + const std::uint8_t eta = 0; + auto mat = grotto::make_ring_switch_keys(r); + const Z got = grotto::ring_switch_eval<0>(mat, eta) + + grotto::ring_switch_eval<1>(mat, eta); + EXPECT_EQ(got.raw(), 55u); +} + +TEST(RingSwitch, FullWidthLimb) +{ + using Z = grotto::zn64<10007>; + const std::uint64_t r = 0xffff'ffff'ffff'ff00ull; + const std::uint64_t eta = 0x200ull; // wraps + const std::uint64_t x = r + eta; // wraps in uint64 + auto mat = grotto::make_ring_switch_keys(r); + const Z got = grotto::ring_switch_eval<0>(mat, eta) + + grotto::ring_switch_eval<1>(mat, eta); + EXPECT_EQ(got, grotto::ring_switch_clear(x, r, eta)); + EXPECT_EQ(got.raw(), x % 10007); +} + +TEST(RingSwitch, Field128) +{ + const std::uint16_t r = 40000; + const std::uint16_t eta = 30000; // wraps + const std::uint16_t x = static_cast(r + eta); + auto mat = grotto::make_ring_switch_keys(r); + const auto got = grotto::ring_switch_eval<0>(mat, eta) + + grotto::ring_switch_eval<1>(mat, eta); + EXPECT_EQ(got, grotto::ring_switch_clear(x, r, eta)); + EXPECT_EQ(got, dpf::field128{x}); +} + +TEST(RingSwitch, P256Scalar) +{ + const std::uint8_t r = 200; + const std::uint8_t eta = 100; + const std::uint8_t x = static_cast(r + eta); + auto mat = grotto::make_ring_switch_keys(r); + const auto got = grotto::ring_switch_eval<0>(mat, eta) + + grotto::ring_switch_eval<1>(mat, eta); + EXPECT_EQ(got, grotto::ring_switch_clear(x, r, eta)); + EXPECT_EQ(got, dpf::p256_scalar{x}); +} + +TEST(RingSwitch, Zn128) +{ + using Z = grotto::zn128<0x9a57'0000'0000'0001ull, 0>; + const std::uint8_t r = 10; + const std::uint8_t eta = 20; + const std::uint8_t x = 30; + auto mat = grotto::make_ring_switch_keys(r); + const Z got = grotto::ring_switch_eval<0>(mat, eta) + + grotto::ring_switch_eval<1>(mat, eta); + EXPECT_EQ(got, grotto::ring_switch_clear(x, r, eta)); + EXPECT_EQ(got.lo(), 30u); +} + +TEST(RingSwitch, Verifiable) +{ + using Z = grotto::zn64<1009>; + const std::uint8_t r = 17; + const std::uint8_t eta = 200; + const std::uint8_t x = static_cast(r + eta); + auto mat = grotto::make_ring_switch_keys(r, dpf::verifiable{}); + dpf::proof_token a{}, b{}; + const Z s0 = grotto::ring_switch_eval<0>(mat, eta, &a); + const Z s1 = grotto::ring_switch_eval<1>(mat, eta, &b); + EXPECT_EQ(s0 + s1, grotto::ring_switch_clear(x, r, eta)); + EXPECT_TRUE(dpf::verify(a, b)); +} diff --git a/test/tests/secret_share_test.cpp b/test/tests/secret_share_test.cpp index f5abd22..89399c6 100644 --- a/test/tests/secret_share_test.cpp +++ b/test/tests/secret_share_test.cpp @@ -1,7 +1,10 @@ #include +#include #include #include +#include +#include #include #include @@ -10,6 +13,14 @@ namespace { +struct dpf3_party_tag +{ + static constexpr bool is_dpf3 = true; + static constexpr int party = 3; +}; + + + TEST(SecretShare, LayoutMatchesValueType) { using T = std::uint64_t; @@ -140,4 +151,365 @@ TEST(SecretShare, PrgExpandSubtractive) EXPECT_EQ(dpf::reconstruct(t0, t1), 0u); } +TEST(SecretShare, Additive3LayoutAndPlaintextSplit) +{ + using T = std::uint64_t; + static_assert(dpf::sharing_parties_v == 3); + static_assert(dpf::sharing_threshold_v == 3); + static_assert(dpf::is_secret_share_v>); + static_assert(dpf::share_party_v> == 2u); + static_assert(dpf::share_scheme_v> + == dpf::sharing::additive3); + EXPECT_EQ(sizeof(dpf::additive3_share), sizeof(T)); + EXPECT_TRUE((std::is_trivially_copyable_v>)); + EXPECT_TRUE((std::is_standard_layout_v>)); + + constexpr auto split = dpf::make_additive3_shares(std::uint32_t{9}); + static_assert(dpf::reconstruct( + std::get<0>(split), std::get<1>(split), std::get<2>(split)) == 9u); + + const std::uint32_t secret = 0xdeadbeefu; + auto [a0, a1, a2] = dpf::make_additive3_shares(secret); + EXPECT_EQ(a1.raw(), 0u); + EXPECT_EQ(a2.raw(), 0u); + EXPECT_EQ(dpf::reconstruct(a2, a0, a1), secret); +} + +TEST(SecretShare, Additive3LinearComboAndAbsorb) +{ + auto [a0, a1, a2] = dpf::make_additive3_shares(std::uint32_t{10}); + auto [b0, b1, b2] = dpf::make_additive3_shares(std::uint32_t{3}); + auto c0 = a0 * 2 + b0; + auto c1 = a1 * 2 + b1; + auto c2 = a2 * 2 + b2; + EXPECT_EQ(dpf::reconstruct(c0, c1, c2), 23u); + + a0 += std::uint32_t{10}; + a1 += std::uint32_t{10}; + a2 += std::uint32_t{10}; + EXPECT_EQ(dpf::reconstruct(a0, a1, a2), 20u); + + const auto raw = std::numeric_limits::min(); + auto s0 = dpf::additive3_share::from_raw(raw); + auto s1 = dpf::additive3_share::from_raw(-1); + auto s2 = dpf::additive3_share::from_raw(1); + EXPECT_EQ(dpf::reconstruct(s0, s1, s2), raw); +} + +TEST(SecretShare, Additive3RandomAndXor) +{ + using X = dpf::xor_wrapper; + const X secret{0xA5A5A5A5u}; + auto [x0, x1, x2] = dpf::additively_share3(secret); + EXPECT_EQ(dpf::reconstruct(x0, x1, x2), secret); + + const std::int32_t n = -42; + auto [a, b, c] = dpf::additively_share3(n); + EXPECT_EQ(dpf::reconstruct(c, b, a), n); + + const float f = 1.5f; + auto [f0, f1, f2] = dpf::additively_share3(f); + EXPECT_EQ(dpf::reconstruct(f0, f1, f2), f); +} + +TEST(SecretShare, ReplicatedLayoutPlaintextAndPairs) +{ + using T = std::uint32_t; + static_assert(dpf::sharing_parties_v == 3); + static_assert(dpf::sharing_threshold_v == 2); + static_assert(dpf::share_scheme_v> + == dpf::sharing::replicated); + EXPECT_EQ(sizeof(dpf::replicated_share), 2 * sizeof(T)); + EXPECT_TRUE((std::is_trivially_copyable_v>)); + EXPECT_TRUE((std::is_standard_layout_v>)); + + constexpr auto split = dpf::make_replicated_shares(T{11}); + static_assert(dpf::reconstruct(std::get<0>(split), std::get<1>(split)) == 11u); + static_assert(dpf::reconstruct(std::get<1>(split), std::get<2>(split)) == 11u); + static_assert(dpf::reconstruct(std::get<2>(split), std::get<0>(split)) == 11u); + + auto [r0, r1, r2] = dpf::make_replicated_shares(T{11}); + EXPECT_EQ(r0.own, 11u); + EXPECT_EQ(r0.next, 0u); + EXPECT_EQ(r1.own, 0u); + EXPECT_EQ(r1.next, 0u); + EXPECT_EQ(r2.own, 0u); + EXPECT_EQ(r2.next, 11u); + EXPECT_EQ(dpf::reconstruct(r0, r1, r2), 11u); + EXPECT_EQ(r0.as_additive3().raw(), 11u); + EXPECT_EQ(r0.next_additive3().raw(), r1.as_additive3().raw()); +} + +TEST(SecretShare, ReplicatedLinearComboAbsorbAndAdditive3) +{ + auto [a0, a1, a2] = dpf::make_replicated_shares(std::uint32_t{10}); + auto [b0, b1, b2] = dpf::make_replicated_shares(std::uint32_t{3}); + auto c0 = a0 * 2 - b0; + auto c1 = a1 * 2 - b1; + auto c2 = a2 * 2 - b2; + EXPECT_EQ(dpf::reconstruct(c0, c1), 17u); + EXPECT_EQ(dpf::reconstruct(c1, c2), 17u); + EXPECT_EQ(dpf::reconstruct(c0, c2, c1), 17u); + + c0 += std::uint32_t{4}; + c1 += std::uint32_t{4}; + c2 += std::uint32_t{4}; + EXPECT_EQ(c1.own, (a1 * 2 - b1).own); + EXPECT_EQ(c1.next, (a1 * 2 - b1).next); + EXPECT_EQ(dpf::reconstruct(c2, c0), 21u); + + auto [d0, d1, d2] = dpf::make_additive3_shares(std::uint32_t{1}); + d1 = dpf::additive3_share::from_raw(2u); + d2 = dpf::additive3_share::from_raw(4u); + auto [e0, e1, e2] = dpf::add_replicated(c0, c1, c2, d0, d1, d2); + EXPECT_EQ(e0.next, e1.own); + EXPECT_EQ(e1.next, e2.own); + EXPECT_EQ(e2.next, e0.own); + EXPECT_EQ(dpf::reconstruct(e0, e1), 28u); + EXPECT_EQ(dpf::reconstruct(e1, e2, e0), dpf::reconstruct(e0, e2)); +} + +TEST(SecretShare, ReplicatedFromComponentsAndRandom) +{ + using X = dpf::xor_wrapper; + const X secret{0xBEEFu}; + auto [a0, a1, a2] = dpf::additively_share3(secret); + auto [r0, r1, r2] = dpf::make_replicated_shares(a0, a1, a2); + EXPECT_EQ(r0.own, a0.raw()); + EXPECT_EQ(r0.next, a1.raw()); + EXPECT_EQ(r2.next, a0.raw()); + EXPECT_EQ(dpf::reconstruct(r2, r1), secret); + EXPECT_EQ(dpf::reconstruct(r0.as_additive3(), r1.as_additive3(), + r2.as_additive3()), secret); + + auto built = dpf::replicated_share::from_additive3( + a0, a1); + EXPECT_EQ(built, r0); + + const std::int64_t n = std::numeric_limits::min() + 7; + auto [s0, s1, s2] = dpf::share_replicated(n); + EXPECT_EQ(s0.next, s1.own); + EXPECT_EQ(s1.next, s2.own); + EXPECT_EQ(s2.next, s0.own); + EXPECT_EQ(dpf::reconstruct(s0, s1), n); + EXPECT_EQ(dpf::reconstruct(s1, s2), n); + EXPECT_EQ(dpf::reconstruct(s2, s0), n); + EXPECT_EQ(dpf::reconstruct(s2, s1, s0), n); + + auto [p0, p1, p2] = dpf::make_replicated_shares(std::uint32_t{8}); + dpf::replicated_share slot{}; + dpf::assign_share_slot(slot, p0); + EXPECT_EQ(slot, p0); + std::uint32_t word = 0; + dpf::assign_share_slot(word, p0.as_additive3()); + EXPECT_EQ(word, 8u); + (void)p1; + (void)p2; +} + +TEST(SecretShare, TwoPartyConversionsPreserveSecret) +{ + auto a0 = dpf::additive_share::from_raw(10); + auto a1 = dpf::additive_share::from_raw(5); + auto b0 = dpf::a2b(a0); + auto b1 = dpf::a2b(a1); + EXPECT_EQ(b0.raw(), 10); + EXPECT_EQ(b1.raw(), -5); + EXPECT_EQ(dpf::reconstruct(b0, b1), 15); + EXPECT_EQ(dpf::reconstruct(dpf::b2a(b0), dpf::b2a(b1)), 15); + + auto f0 = dpf::a2fss(a0); + auto f1 = dpf::a2fss(a1); + EXPECT_EQ(f1.raw(), -5); + EXPECT_EQ(dpf::reconstruct(dpf::fss2a(f0), dpf::fss2a(f1)), 15); + EXPECT_EQ(dpf::fss2b(f1).raw(), f1.raw()); + EXPECT_EQ(dpf::b2fss(b1).raw(), b1.raw()); + + // Subtractive and FSS share a sign, so party 1 adds the raw words. + auto mixed = b1 + f1; + EXPECT_EQ(mixed.raw(), -10); + // Additive and FSS disagree on party 1, so the FSS word is flipped. + auto flipped = a1 + dpf::fss_share::from_raw(4); + EXPECT_EQ(flipped.raw(), 1); +} + +TEST(SecretShare, ShamirRoundTripAndReplicatedProduct) +{ + const dpf::fp61 secret{20}; + const dpf::fp61 slope{3}; + auto [s0, s1, s2] = dpf::make_shamir_shares(secret, slope); + EXPECT_EQ((dpf::shamir_share::point), 1u); + EXPECT_EQ(s0.raw(), secret + slope * dpf::fp61{1}); + EXPECT_EQ(s1.raw(), secret + slope * dpf::fp61{2}); + EXPECT_EQ(s2.raw(), secret + slope * dpf::fp61{3}); + EXPECT_EQ(dpf::reconstruct(s0, s1), secret); + EXPECT_EQ(dpf::reconstruct(s1, s2), secret); + EXPECT_EQ(dpf::reconstruct(s2, s0, s1), secret); + + s0 += dpf::fp61{4}; + s1 += dpf::fp61{4}; + s2 += dpf::fp61{4}; + EXPECT_EQ(dpf::reconstruct(s2, s0), secret + dpf::fp61{4}); + + auto [y0, y1, y2] = dpf::s2y(s0, s1); + EXPECT_EQ(dpf::reconstruct(y0, y1, y2), secret + dpf::fp61{4}); + auto back = dpf::y2s(y0, y1, y2, slope); + EXPECT_EQ(dpf::reconstruct(std::get<0>(back), std::get<2>(back)), + secret + dpf::fp61{4}); + + auto [r0, r1, r2] = dpf::s2rss(s0, s2); + EXPECT_EQ(dpf::reconstruct(r0, r1), secret + dpf::fp61{4}); + auto shamir_again = dpf::rss2s(r1, r2, slope); + EXPECT_EQ(dpf::reconstruct(std::get<1>(shamir_again), std::get<2>(shamir_again)), + secret + dpf::fp61{4}); + + auto tagged = dpf::as_shamir_share(dpf3_party_tag{}, dpf::fp61{7}); + EXPECT_EQ(decltype(tagged)::party, 2u); + EXPECT_EQ(tagged.raw(), dpf::fp61{7}); + + auto runtime = dpf::shamir3::runtime_share(s0); + EXPECT_EQ(runtime.party, 1); + EXPECT_EQ(dpf::shamir3::typed_share<0>(runtime), s0); + EXPECT_EQ(dpf::shamir3::reconstruct(runtime, + dpf::shamir3::runtime_share(s1)), secret + dpf::fp61{4}); + + auto [x0, x1, x2] = dpf::make_replicated_shares( + std::uint32_t{3}, std::uint32_t{5}, std::uint32_t{1}); + auto [z0, z1, z2] = dpf::make_replicated_shares( + std::uint32_t{4}, std::uint32_t{2}, std::uint32_t{6}); + EXPECT_EQ(dpf::reconstruct(dpf::rss_mul(x0, z0), dpf::rss_mul(x1, z1), + dpf::rss_mul(x2, z2)), 108u); + auto [p0, p1, p2] = dpf::rss_mul(x0, x1, x2, z0, z1, z2); + EXPECT_EQ(p0.next, p1.own); + EXPECT_EQ(dpf::reconstruct(p0, p2), 108u); + + auto m0 = dpf::additive3_share::from_raw(9u); + auto m1 = dpf::additive3_share::from_raw(1u); + auto m2 = dpf::additive3_share::from_raw( + static_cast(0u - 9u - 1u)); + auto [q0, q1, q2] = dpf::rss_mul(x0, x1, x2, z0, z1, z2, m0, m1, m2); + EXPECT_EQ(dpf::reconstruct(q1, q0), 108u); + EXPECT_NE(q0.own, p0.own); + (void)q2; + + auto [h0, h1, h2] = dpf::y2rss(dpf::rss2y(p0), dpf::rss2y(p1), dpf::rss2y(p2)); + EXPECT_EQ(h0, p0); + EXPECT_EQ(h1, p1); + EXPECT_EQ(h2, p2); +} + +TEST(SecretShare, ShamirKnSpecializesTwoOfThree) +{ + using F = dpf::fp61; + static_assert(std::is_same_v< + dpf::shamir::share, dpf::shamir_share>); + static_assert(std::is_same_v< + dpf::shamir::share, dpf::shamir_share>); + static_assert(dpf::shamir::two_of_three::threshold == 2); + static_assert(dpf::shamir::two_of_three::parties == 3); + static_assert(dpf::shamir::two_of_three::degree == 1); + static_assert(dpf::shamir_share::threshold == 2); + static_assert(dpf::shamir_share::parties == 3); + static_assert(!dpf::is_secret_share_v>); + static_assert(dpf::shamir::is_share_v>); + static_assert(dpf::shamir::is_share_v>); + EXPECT_EQ(sizeof(dpf::shamir::share), sizeof(F)); + EXPECT_TRUE((std::is_trivially_copyable_v>)); + EXPECT_TRUE((std::is_standard_layout_v>)); + + // p(x) = 10 + 2x + 3x^2. Points 1..5 are 15, 26, 43, 66, 95. + const F secret{10}; + const std::array coeff{{F{2}, F{3}}}; + const F expect[5] = {F{15}, F{26}, F{43}, F{66}, F{95}}; + auto dealt = dpf::make_shamir_shares<3, 5>(secret, coeff); + const std::array raw{{ + std::get<0>(dealt).raw(), std::get<1>(dealt).raw(), + std::get<2>(dealt).raw(), std::get<3>(dealt).raw(), + std::get<4>(dealt).raw()}}; + for (int i = 0; i < 5; ++i) + EXPECT_EQ(raw[static_cast(i)], expect[i]); + EXPECT_EQ(std::get<4>(dealt).point, 5u); + EXPECT_EQ(std::get<4>(dealt).party, 4u); + + for (int i = 0; i < 5; ++i) + for (int j = i + 1; j < 5; ++j) + for (int k = j + 1; k < 5; ++k) + { + const std::array, 3> subset{{ + {i + 1, raw[static_cast(i)]}, + {j + 1, raw[static_cast(j)]}, + {k + 1, raw[static_cast(k)]}}}; + const F opened = dpf::shamir::reconstruct(subset); + EXPECT_EQ(opened, secret); + } + EXPECT_EQ(dpf::shamir::reconstruct( + std::get<0>(dealt), std::get<2>(dealt), std::get<4>(dealt)), secret); + + auto scaled0 = std::get<0>(dealt) * F{3}; + auto scaled1 = std::get<1>(dealt) * F{3}; + auto scaled2 = std::get<2>(dealt) * F{3}; + EXPECT_EQ(dpf::shamir::reconstruct(scaled0, scaled1, scaled2), secret * F{3}); + + auto sum0 = std::get<0>(dealt) + std::get<0>(dealt); + auto sum1 = std::get<1>(dealt) + std::get<1>(dealt); + auto sum2 = std::get<2>(dealt) + std::get<2>(dealt); + EXPECT_EQ(dpf::shamir::reconstruct(sum0, sum1, sum2), secret + secret); + + std::get<0>(dealt) += F{4}; + std::get<1>(dealt) += F{4}; + std::get<2>(dealt) += F{4}; + EXPECT_EQ(dpf::shamir::reconstruct( + std::get<0>(dealt), std::get<1>(dealt), std::get<2>(dealt)), + secret + F{4}); + + std::array, 4> extra{{ + {1, raw[0]}, {2, raw[1]}, {3, raw[2]}, {4, raw[3]}}}; + EXPECT_EQ((dpf::shamir::reconstruct(extra)), secret); + extra[3].value = extra[3].value + F{1}; + EXPECT_THROW((dpf::shamir::reconstruct(extra)), std::runtime_error); + + const std::array, 2> too_few{{ + {1, raw[0]}, {2, raw[1]}}}; + EXPECT_THROW((dpf::shamir::reconstruct(too_few)), + std::invalid_argument); + const std::array, 2> dup{{ + {1, raw[0]}, {1, raw[0]}}}; + EXPECT_THROW((dpf::shamir::reconstruct(dup)), std::invalid_argument); + + // Threshold 2 is not tied to three shareholders. p(x) = 8 + 5x. + const auto line = dpf::shamir::deal(F{8}, std::array{{F{5}}}); + EXPECT_EQ(std::get<0>(line).raw(), F{13}); + EXPECT_EQ(std::get<3>(line).raw(), F{28}); + EXPECT_EQ(dpf::shamir::reconstruct(std::get<1>(line), std::get<3>(line)), F{8}); + + // Threshold 1 copies the secret. Threshold N needs every share. + const auto copied = dpf::shamir::deal(F{9}, std::array{}); + EXPECT_EQ(std::get<0>(copied).raw(), F{9}); + EXPECT_EQ(std::get<2>(copied).raw(), F{9}); + EXPECT_EQ(dpf::shamir::reconstruct(std::get<1>(copied)), F{9}); + const auto plain = dpf::shamir::share_secret(F{6}); + EXPECT_EQ(std::get<0>(plain).raw(), F{6}); + EXPECT_EQ(std::get<2>(plain).raw(), F{6}); + + const std::array dense{{F{1}, F{0}, F{4}}}; + const auto all = dpf::shamir::deal(F{7}, dense); + EXPECT_EQ(dpf::shamir::reconstruct(std::get<0>(all), std::get<1>(all), + std::get<2>(all), std::get<3>(all)), F{7}); + const std::array, 3> missing{{ + {1, std::get<0>(all).raw()}, + {2, std::get<1>(all).raw()}, + {3, std::get<2>(all).raw()}}}; + EXPECT_THROW((dpf::shamir::reconstruct(missing)), + std::invalid_argument); + + const auto rnd = dpf::shamir::share_secret(F{11}); + static_assert(std::is_same_v(rnd))>, + dpf::shamir_share>); + EXPECT_EQ(dpf::reconstruct(std::get<0>(rnd), std::get<2>(rnd)), F{11}); + + const auto wider = dpf::shamir::share_secret(F{12}); + EXPECT_EQ(dpf::shamir::reconstruct( + std::get<0>(wider), std::get<2>(wider), std::get<4>(wider)), F{12}); +} + } // namespace diff --git a/test/tests/security_test.cpp b/test/tests/security_test.cpp new file mode 100644 index 0000000..ee4958a --- /dev/null +++ b/test/tests/security_test.cpp @@ -0,0 +1,1142 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "dpf/compose.hpp" +#include "dpf/log.hpp" +#include "dpf/net/client_link.hpp" +#include "dpf/net/connect.hpp" +#include "dpf/net/identity.hpp" +#include "dpf/net/party_session.hpp" +#include "dpf/net/security.hpp" +#include "dpf/net/tls.hpp" +#include "dpf/online_session.hpp" +#include "dpf/party_runner.hpp" +#include "dpf/run_config.hpp" + +#include +#include + +namespace +{ + +using dpf::net::identity; +using dpf::net::public_key; + +std::string temp_path(const std::string & name) +{ + return "/tmp/libdpf_security_" + std::to_string(::getpid()) + "_" + name; +} + +/// Two connected TCP sockets, each on its own io_context. +struct socket_pair +{ + asio::io_context io_a, io_b; + asio::ip::tcp::socket a{io_a}, b{io_b}; + + socket_pair() + { + asio::ip::tcp::acceptor acc(io_a); + dpf::net::open_listener(acc, 0); + const auto port = acc.local_endpoint().port(); + std::thread t([&] { + dpf::net::connect_until(b, "127.0.0.1", port, std::chrono::seconds(5)); + }); + dpf::net::accept_until(acc, a, std::chrono::seconds(5)); + t.join(); + a.set_option(asio::ip::tcp::no_delay(true)); + b.set_option(asio::ip::tcp::no_delay(true)); + } +}; + +/// Run `io` until `done` or `deadline`, restarting it when it runs dry. +void run_until(asio::io_context & io, const bool & done, + std::chrono::steady_clock::time_point deadline) +{ + while (!done && std::chrono::steady_clock::now() < deadline) + { + if (io.stopped()) + io.restart(); + io.run_one_for(std::chrono::milliseconds(10)); + } +} + +/// Run `server` and `client` on two threads; throw both failures' messages. +void both(const std::function & server, const std::function & client) +{ + std::string e1, e2; + std::thread ts([&] { + try + { + server(); + } + catch (const std::exception & e) + { + e1 = e.what(); + } + }); + try + { + client(); + } + catch (const std::exception & e) + { + e2 = e.what(); + } + ts.join(); + if (!e1.empty() || !e2.empty()) + throw std::runtime_error("server: " + e1 + " | client: " + e2); +} + +} // namespace + +TEST(Identity, KeyFileRoundTripAndMode) +{ + const auto path = temp_path("id.key"); + ::unlink(path.c_str()); + const auto id = identity::generate(); + id.save(path); + struct stat st{}; + ASSERT_EQ(::stat(path.c_str(), &st), 0); + EXPECT_EQ(st.st_mode & 0777, 0600u); + EXPECT_THROW(id.save(path), std::runtime_error); + const auto back = identity::load(path); + EXPECT_EQ(back.key(), id.key()); + EXPECT_EQ(id.key().base64().size(), 44u); + EXPECT_EQ(public_key::parse(id.key().base64()), id.key()); + const auto pub = temp_path("id.pub"); + { + std::ofstream out(pub); + out << "# peer 1\n" << id.key().base64() << "\n"; + } + EXPECT_EQ(public_key::parse("file:" + pub), id.key()); + EXPECT_THROW(public_key::parse("not-a-key"), std::invalid_argument); + EXPECT_THROW(public_key::parse(id.key().base64().substr(0, 40)), std::invalid_argument); + ::unlink(path.c_str()); + ::unlink(pub.c_str()); +} + +TEST(Identity, DevelopmentIsFixedAndMarked) +{ + const auto & a = identity::development(); + const auto & b = identity::development(); + EXPECT_TRUE(a.is_development()); + EXPECT_EQ(a.key(), b.key()); + EXPECT_FALSE(identity::generate().is_development()); + EXPECT_NE(identity::generate().key(), identity::generate().key()); +} + +namespace +{ + +/// Party-link handshake between `ida` (accepting) and `idb` (connecting). +void peer_handshake(const identity & ida, const identity & idb, + const dpf::net::peer_security & pa, const dpf::net::peer_security & pb, + dpf::net::link_security & sa, dpf::net::link_security & sb) +{ + socket_pair sp; + auto ca = dpf::net::make_peer_tls_context(ida); + auto cb = dpf::net::make_peer_tls_context(idb); + dpf::net::tls_stream ta(std::move(sp.a), *ca); + dpf::net::tls_stream tb(std::move(sp.b), *cb); + both( + [&] { + dpf::net::tls_handshake(sp.io_a, ta, true, std::chrono::seconds(5), "p0"); + sa = dpf::net::tls_describe(ta); + try + { + dpf::net::check_peer(sa, pa, 1, "party 1"); + } + catch (...) + { + std::error_code ec; + ta.lowest_layer().close(ec); + throw; + } + std::uint8_t in[5]; + dpf::net::tls_read(sp.io_a, ta, in, 5, std::chrono::seconds(5), "read"); + dpf::net::tls_write(sp.io_a, ta, in, 5, std::chrono::seconds(5), "echo"); + }, + [&] { + dpf::net::tls_handshake(sp.io_b, tb, false, std::chrono::seconds(5), "p1"); + sb = dpf::net::tls_describe(tb); + dpf::net::check_peer(sb, pb, 0, "party 0"); + const std::uint8_t out[5] = {'h', 'e', 'l', 'l', 'o'}; + std::uint8_t back[5] = {}; + dpf::net::tls_write(sp.io_b, tb, out, 5, std::chrono::seconds(5), "write"); + dpf::net::tls_read(sp.io_b, tb, back, 5, std::chrono::seconds(5), "read"); + if (std::memcmp(out, back, 5) != 0) + throw std::runtime_error("echo mismatch"); + }); +} + +} // namespace + +TEST(PeerTls, NoKeysEncryptsUnauthenticated) +{ + const auto a = identity::generate(); + const auto b = identity::generate(); + dpf::net::peer_security pa, pb; + dpf::net::link_security sa, sb; + peer_handshake(a, b, pa, pb, sa, sb); + EXPECT_TRUE(sa.encrypted); + EXPECT_EQ(sa.protocol, "TLSv1.3"); + EXPECT_EQ(sa.peer_auth, "none"); + EXPECT_EQ(sb.peer_auth, "none"); + ASSERT_TRUE(sa.peer_key.has_value()); + EXPECT_EQ(*sa.peer_key, b.key()); + EXPECT_EQ(*sb.peer_key, a.key()); +} + +TEST(PeerTls, KeyAuthenticatesOneDirection) +{ + const auto a = identity::generate(); + const auto b = identity::generate(); + dpf::net::peer_security pa, pb; + pa.trusted[1] = b.key(); + dpf::net::link_security sa, sb; + peer_handshake(a, b, pa, pb, sa, sb); + EXPECT_EQ(sa.peer_auth, "key"); + EXPECT_EQ(sb.peer_auth, "none"); + pb.trusted[0] = a.key(); + peer_handshake(a, b, pa, pb, sa, sb); + EXPECT_EQ(sa.peer_auth, "key"); + EXPECT_EQ(sb.peer_auth, "key"); +} + +TEST(PeerTls, WrongKeyNamesBothKeys) +{ + const auto a = identity::generate(); + const auto b = identity::generate(); + const auto other = identity::generate(); + dpf::net::peer_security pa, pb; + pa.trusted[1] = other.key(); + dpf::net::link_security sa, sb; + try + { + peer_handshake(a, b, pa, pb, sa, sb); + FAIL() << "a mismatched key must fail the link"; + } + catch (const std::exception & e) + { + const std::string what = e.what(); + EXPECT_NE(what.find(b.key().base64()), std::string::npos) << what; + EXPECT_NE(what.find(other.key().base64()), std::string::npos) << what; + } +} + +namespace +{ + +struct client_result +{ + dpf::net::link_security client; + dpf::net::link_security server; +}; + +client_result client_handshake(const dpf::net::server_security & ss, + const dpf::net::client_security & cs, const std::string & host = "") +{ + socket_pair sp; + bool dev = false; + auto sctx = dpf::net::make_server_tls_context(ss, dev); + auto cctx = dpf::net::make_client_tls_context(cs); + dpf::net::tls_stream ts(std::move(sp.a), *sctx); + dpf::net::tls_stream tc(std::move(sp.b), *cctx); + const std::string name = cs.server_name.empty() ? host : cs.server_name; + if (!cs.ca_file.empty()) + dpf::net::tls_expect_host(tc, name); + client_result r; + both( + [&] { + dpf::net::tls_handshake(sp.io_a, ts, true, std::chrono::seconds(5), "server"); + r.server = dpf::net::tls_describe(ts); + dpf::net::check_client(r.server, ss); + std::uint8_t in[1]; + std::error_code ec; + asio::read(ts, asio::buffer(in, 1), ec); + }, + [&] { + dpf::net::tls_handshake(sp.io_b, tc, false, std::chrono::seconds(5), "client"); + r.client = dpf::net::tls_describe(tc); + std::error_code ec; + try + { + dpf::net::check_server(r.client, tc, cs, "localhost"); + } + catch (...) + { + tc.lowest_layer().close(ec); + throw; + } + const std::uint8_t b = 1; + dpf::net::tls_write(sp.io_b, tc, &b, 1, std::chrono::seconds(5), "write"); + }); + return r; +} + +/// A throwaway CA and a server certificate for `name`, as PEM files. +void make_ca_chain(const std::string & name, const std::string & ca_pem, + const std::string & cert_pem, const std::string & key_pem) +{ + auto keygen = [] { + EVP_PKEY * k = nullptr; + EVP_PKEY_CTX * c = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, nullptr); + EVP_PKEY_keygen_init(c); + EVP_PKEY_keygen(c, &k); + EVP_PKEY_CTX_free(c); + return k; + }; + auto cert = [](EVP_PKEY * subject, EVP_PKEY * issuer_key, X509 * issuer, + const char * cn, bool ca, const std::string & dns) { + X509 * x = X509_new(); + X509_set_version(x, 2); + ASN1_INTEGER_set(X509_get_serialNumber(x), ca ? 1 : 2); + X509_gmtime_adj(X509_getm_notBefore(x), -3600); + X509_gmtime_adj(X509_getm_notAfter(x), 86400); + X509_set_pubkey(x, subject); + X509_NAME * n = X509_get_subject_name(x); + X509_NAME_add_entry_by_txt(n, "CN", MBSTRING_ASC, + reinterpret_cast(cn), -1, -1, 0); + X509_set_issuer_name(x, issuer ? X509_get_subject_name(issuer) : n); + X509V3_CTX v3; + X509V3_set_ctx_nodb(&v3); + X509V3_set_ctx(&v3, issuer ? issuer : x, x, nullptr, nullptr, 0); + auto add = [&](int nid, const char * value) { + X509_EXTENSION * e = X509V3_EXT_conf_nid(nullptr, &v3, nid, value); + X509_add_ext(x, e, -1); + X509_EXTENSION_free(e); + }; + add(NID_basic_constraints, ca ? "critical,CA:TRUE" : "CA:FALSE"); + if (ca) + add(NID_key_usage, "critical,keyCertSign,cRLSign"); + else + add(NID_subject_alt_name, ("DNS:" + dns).c_str()); + X509_sign(x, issuer_key, nullptr); + return x; + }; + EVP_PKEY * cak = keygen(); + EVP_PKEY * srvk = keygen(); + X509 * cacert = cert(cak, cak, nullptr, "test CA", true, ""); + X509 * srv = cert(srvk, cak, cacert, name.c_str(), false, name); + FILE * f = std::fopen(ca_pem.c_str(), "w"); + PEM_write_X509(f, cacert); + std::fclose(f); + f = std::fopen(cert_pem.c_str(), "w"); + PEM_write_X509(f, srv); + std::fclose(f); + f = std::fopen(key_pem.c_str(), "w"); + PEM_write_PrivateKey(f, srvk, nullptr, nullptr, 0, nullptr, nullptr); + std::fclose(f); + X509_free(cacert); + X509_free(srv); + EVP_PKEY_free(cak); + EVP_PKEY_free(srvk); +} + +} // namespace + +namespace +{ + +/// Forwards bytes between a client and a server and keeps a copy of both +/// directions, so a test can look at what crossed the wire. +class recording_relay +{ +public: + explicit recording_relay(unsigned short upstream) : upstream_(upstream) + { + dpf::net::open_listener(acc_, 0); + port_ = acc_.local_endpoint().port(); + thread_ = std::thread([this] { run(); }); + } + + ~recording_relay() + { + std::error_code ec; + acc_.close(ec); + { + std::lock_guard lock(mu_); + for (int fd : fds_) + ::shutdown(fd, SHUT_RDWR); + } + if (thread_.joinable()) + thread_.join(); + } + + unsigned short port() const { return port_; } + + std::string seen() + { + std::lock_guard lock(mu_); + return seen_; + } + +private: + void run() + { + try + { + asio::ip::tcp::socket in(io_), out(io_); + dpf::net::accept_until(acc_, in, std::chrono::seconds(10)); + dpf::net::connect_until(out, "127.0.0.1", upstream_, std::chrono::seconds(10)); + { + std::lock_guard lock(mu_); + fds_ = {in.native_handle(), out.native_handle()}; + } + std::thread back([&] { pump(out, in); }); + pump(in, out); + back.join(); + } + catch (...) + { + } + } + + void pump(asio::ip::tcp::socket & from, asio::ip::tcp::socket & to) + { + std::uint8_t buf[4096]; + std::error_code ec; + for (;;) + { + const std::size_t n = from.read_some(asio::buffer(buf), ec); + if (ec || n == 0) + break; + { + std::lock_guard lock(mu_); + seen_.append(reinterpret_cast(buf), n); + } + asio::write(to, asio::buffer(buf, n), ec); + if (ec) + break; + } + std::error_code e; + to.shutdown(asio::socket_base::shutdown_send, e); + } + + unsigned short upstream_; + asio::io_context io_; + asio::ip::tcp::acceptor acc_{io_}; + unsigned short port_ = 0; + std::mutex mu_; + std::string seen_; + std::vector fds_; + std::thread thread_; +}; + +const std::string k_marker = "SECRET-SHARE-MARKER-0123456789"; + +/// Party 0 accepts (through a relay), party 1 connects; party 1 writes the +/// marker on lane 1 and party 0 reads it. Returns what crossed the wire. +template +std::string relay_exchange() +{ + asio::io_context io0, io1; + asio::ip::tcp::acceptor acc(io0); + dpf::net::open_listener(acc, 0); + recording_relay relay(acc.local_endpoint().port()); + const std::size_t lanes = Parallel ? 1 : 2; + const std::size_t lane = Parallel ? 0 : 1; + (void)lanes; + std::string got; + both( + [&] { + asio::ip::tcp::socket s(io0); + dpf::net::accept_until(acc, s, std::chrono::seconds(5)); + s.set_option(asio::ip::tcp::no_delay(true)); + std::unique_ptr arr; + auto id = identity::generate(); + auto ctx = dpf::net::make_peer_tls_context(id); + if constexpr (Tls) + { + dpf::net::tls_stream t(std::move(s), *ctx); + dpf::net::tls_handshake(io0, t, true, std::chrono::seconds(5), "p0"); + if constexpr (Parallel) + { + std::vector v; + v.push_back(std::move(t)); + arr = std::make_unique( + io0, std::move(v)); + } + else + arr = std::make_unique(io0, + std::move(t), 0, 1, lanes); + } + else + arr = std::make_unique(io0, + std::move(s), 0, 1, lanes); + std::string in(k_marker.size() * 4, '\0'); + bool done = false; + std::error_code rec; + arr->async_read(lane, in.data(), in.size(), [&](const std::error_code & ec) { + rec = ec; + done = true; + }); + const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5); + run_until(io0, done, deadline); + if (!done || rec) + throw std::runtime_error("read failed: " + rec.message() + " (done " + + std::to_string(done) + ", relay saw " + + std::to_string(relay.seen().size()) + " bytes)"); + got = in; + // The peer closes after writing: the next read ends cleanly. + done = false; + char extra = 0; + arr->async_read(lane, &extra, 1, [&](const std::error_code & ec) { + rec = ec; + done = true; + }); + run_until(io0, done, deadline); + if (rec != asio::error::eof) + throw std::runtime_error("expected eof after peer close, got " + + rec.message()); + arr.reset(); + for (int i = 0; i < 50; ++i) + io0.poll(); + }, + [&] { + asio::ip::tcp::socket s(io1); + dpf::net::connect_until(s, "127.0.0.1", relay.port(), std::chrono::seconds(5)); + s.set_option(asio::ip::tcp::no_delay(true)); + std::unique_ptr arr; + auto id = identity::generate(); + auto ctx = dpf::net::make_peer_tls_context(id); + if constexpr (Tls) + { + dpf::net::tls_stream t(std::move(s), *ctx); + dpf::net::tls_handshake(io1, t, false, std::chrono::seconds(5), "p1"); + if constexpr (Parallel) + { + std::vector v; + v.push_back(std::move(t)); + arr = std::make_unique( + io1, std::move(v)); + } + else + arr = std::make_unique(io1, + std::move(t), 1, 0, lanes); + } + else + arr = std::make_unique(io1, + std::move(s), 1, 0, lanes); + const std::string out = k_marker + k_marker + k_marker + k_marker; + bool done = false; + arr->async_write(lane, out.data(), out.size(), + [&](const std::error_code &) { done = true; }); + const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5); + run_until(io1, done, deadline); + arr.reset(); // graceful: drains, then closes + for (int i = 0; i < 50; ++i) + io1.poll(); + }); + if (got.find(k_marker) != 0) + throw std::runtime_error("payload did not arrive intact"); + return relay.seen(); +} + +} // namespace + +TEST(TlsBackends, PlainThroughRelay) +{ + const auto plain = relay_exchange(); + EXPECT_NE(plain.find(k_marker), std::string::npos); +} + +TEST(TlsBackends, TlsMuxDirect) +{ + socket_pair sp; + auto ca = dpf::net::make_peer_tls_context(identity::generate()); + auto cb = dpf::net::make_peer_tls_context(identity::generate()); + dpf::net::tls_stream ta(std::move(sp.a), *ca); + dpf::net::tls_stream tb(std::move(sp.b), *cb); + std::string got(8, '\0'); + both( + [&] { + dpf::net::tls_handshake(sp.io_a, ta, true, std::chrono::seconds(5), "a"); + dpf::net::async_tls_mux_stream_array m(sp.io_a, std::move(ta), 0, 1, 2); + bool done = false; + std::error_code rec; + m.async_read(1, got.data(), 8, [&](const std::error_code & ec) { + rec = ec; + done = true; + }); + const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(3); + run_until(sp.io_a, done, deadline); + if (!done) + throw std::runtime_error("direct read timed out; stats in=" + + std::to_string(m.stats().bytes_in)); + // The kernel counts TLS records and the handshake too. + const auto st = m.stats(); + if (st.socket_bytes_in <= st.bytes_in + 22) + throw std::runtime_error("socket bytes " + std::to_string(st.socket_bytes_in) + + " vs frame bytes " + std::to_string(st.bytes_in)); + }, + [&] { + dpf::net::tls_handshake(sp.io_b, tb, false, std::chrono::seconds(5), "b"); + dpf::net::async_tls_mux_stream_array m(sp.io_b, std::move(tb), 1, 0, 2); + bool done = false; + m.async_write(1, "abcdefgh", 8, [&](const std::error_code &) { done = true; }); + const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(3); + run_until(sp.io_b, done, deadline); + for (int i = 0; i < 100; ++i) + sp.io_b.run_one_for(std::chrono::milliseconds(5)); + if (!done) + throw std::runtime_error("direct write timed out; stats out=" + + std::to_string(m.stats().bytes_out)); + }); + EXPECT_EQ(got, "abcdefgh"); +} + +TEST(TlsBackends, MuxCiphertextOnTheWire) +{ + const auto plain = relay_exchange(); + EXPECT_NE(plain.find(k_marker), std::string::npos); + const auto tls = relay_exchange(); + EXPECT_EQ(tls.find(k_marker), std::string::npos); + EXPECT_GT(tls.size(), k_marker.size() * 4); +} + +TEST(TlsBackends, ParallelCiphertextOnTheWire) +{ + const auto tls = relay_exchange(); + EXPECT_EQ(tls.find(k_marker), std::string::npos); + EXPECT_GT(tls.size(), k_marker.size() * 4); +} + +TEST(ClientTls, DevelopmentCertificateIsTheDefault) +{ + dpf::net::server_security ss; + dpf::net::client_security cs; + const auto r = client_handshake(ss, cs); + EXPECT_EQ(r.client.peer_auth, "development"); + EXPECT_EQ(r.server.peer_auth, "none"); + EXPECT_EQ(r.client.protocol, "TLSv1.3"); +} + +TEST(ClientTls, UnknownServerKeyIsRefusedUntilPinned) +{ + const auto id = std::make_shared(identity::generate()); + dpf::net::server_security ss; + ss.self = id; + dpf::net::client_security cs; + try + { + (void)client_handshake(ss, cs); + FAIL() << "a client with no pins must refuse a non-development key"; + } + catch (const std::exception & e) + { + const std::string what = e.what(); + EXPECT_NE(what.find("does not trust"), std::string::npos) << what; + EXPECT_NE(what.find(id->key().base64()), std::string::npos) << what; + } + cs.pins.push_back(id->key()); + EXPECT_EQ(client_handshake(ss, cs).client.peer_auth, "key"); + dpf::net::client_security off; + off.verify = false; + EXPECT_EQ(client_handshake(ss, off).client.peer_auth, "none"); + // Once a client pins anything, the development certificate is refused. + dpf::net::server_security dev; + EXPECT_THROW((void)client_handshake(dev, cs), std::runtime_error); +} + +TEST(ClientTls, CaChainAndHostName) +{ + const auto ca = temp_path("ca.pem"); + const auto crt = temp_path("srv.pem"); + const auto key = temp_path("srv.key"); + make_ca_chain("localhost", ca, crt, key); + dpf::net::server_security ss; + ss.cert_file = crt; + ss.key_file = key; + dpf::net::client_security cs; + cs.ca_file = ca; + cs.server_name = "localhost"; + EXPECT_EQ(client_handshake(ss, cs).client.peer_auth, "ca"); + cs.server_name = "elsewhere.example"; + EXPECT_THROW((void)client_handshake(ss, cs), std::runtime_error); + ::unlink(ca.c_str()); + ::unlink(crt.c_str()); + ::unlink(key.c_str()); +} + +TEST(ClientTls, ServerChecksPinnedClientKeys) +{ + const auto cid = std::make_shared(identity::generate()); + dpf::net::server_security ss; + ss.client_pins.push_back(cid->key()); + dpf::net::client_security cs; + cs.self = cid; + const auto r = client_handshake(ss, cs); + EXPECT_EQ(r.server.peer_auth, "key"); + EXPECT_EQ(r.client.peer_auth, "development"); +} + +// --------------------------------------------------------------------------- +// Party sessions +// --------------------------------------------------------------------------- + +namespace +{ + +struct session_pair +{ + std::string error[2]; + dpf::net::link_security sec[2]; + std::uint64_t got[2] = {0, 0}; +}; + +/// Two party_sessions join in-process with `opts[me]`, swap one word, and +/// report each side's view of the link (or its error). +session_pair join_two(const dpf::net::session_options (&opts)[2], + const std::string & role_prefix = "") +{ + auto ports = dpf::net::make_mesh_ports(2); + session_pair out; + auto run = [&](unsigned me) { + dpf::log::role_scope role(role_prefix.empty() ? dpf::log::role() + : role_prefix + std::to_string(me)); + try + { + asio::io_context io; + dpf::net::party_session s(io, me, 2, opts[me]); + s.join("127.0.0.1", ports); + out.sec[me] = s.edge_security(1 - me); + std::uint64_t mine = 100 + me; + bool wrote = false, read = false; + s.peer(1 - me).async_write(0, &mine, 8, [&](const std::error_code &) { + wrote = true; + }); + s.peer(1 - me).async_read(0, &out.got[me], 8, [&](const std::error_code &) { + read = true; + }); + const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5); + while (!(wrote && read) && std::chrono::steady_clock::now() < deadline) + { + if (io.stopped()) + io.restart(); + io.run_one_for(std::chrono::milliseconds(10)); + } + } + catch (const std::exception & e) + { + out.error[me] = e.what(); + } + }; + std::thread t0([&] { run(0); }); + std::thread t1([&] { run(1); }); + t0.join(); + t1.join(); + return out; +} + +dpf::net::session_options with_limits(dpf::net::session_options o) +{ + o.limits.accept = std::chrono::milliseconds(3000); + o.limits.connect = std::chrono::milliseconds(3000); + o.limits.handshake = std::chrono::milliseconds(3000); + o.limits.join = std::chrono::milliseconds(3000); + return o; +} + +} // namespace + +TEST(Session, EncryptedByDefaultWithoutKeys) +{ + dpf::net::session_options o[2] = {with_limits({}), with_limits({})}; + const auto r = join_two(o); + ASSERT_TRUE(r.error[0].empty() && r.error[1].empty()) << r.error[0] << r.error[1]; + for (int me = 0; me < 2; ++me) + { + EXPECT_TRUE(r.sec[me].encrypted); + EXPECT_EQ(r.sec[me].protocol, "TLSv1.3"); + EXPECT_EQ(r.sec[me].peer_auth, "none"); + EXPECT_FALSE(r.sec[me].peer_verified_us); + EXPECT_EQ(r.got[me], 101u - me); + } +} + +TEST(Session, KeysAuthenticatePerDirection) +{ + auto k0 = std::make_shared(identity::generate()); + auto k1 = std::make_shared(identity::generate()); + dpf::net::session_options o[2] = {with_limits({}), with_limits({})}; + o[0].security.self = k0; + o[1].security.self = k1; + o[0].security.trusted[1] = k1->key(); + for (auto kind : {dpf::net::transport::mux, dpf::net::transport::parallel}) + { + o[0].kind = o[1].kind = kind; + o[0].n_lanes = o[1].n_lanes = 2; + auto r = join_two(o); + ASSERT_TRUE(r.error[0].empty() && r.error[1].empty()) << r.error[0] << r.error[1]; + EXPECT_EQ(r.sec[0].peer_auth, "key"); + EXPECT_EQ(r.sec[1].peer_auth, "none"); + EXPECT_FALSE(r.sec[0].peer_verified_us); + EXPECT_TRUE(r.sec[1].peer_verified_us); + ASSERT_TRUE(r.sec[1].peer_key.has_value()); + EXPECT_EQ(*r.sec[1].peer_key, k0->key()); + } + o[1].security.trusted[0] = k0->key(); + auto r = join_two(o); + ASSERT_TRUE(r.error[0].empty() && r.error[1].empty()) << r.error[0] << r.error[1]; + EXPECT_EQ(r.sec[0].peer_auth, "key"); + EXPECT_EQ(r.sec[1].peer_auth, "key"); + EXPECT_TRUE(r.sec[0].peer_verified_us); + EXPECT_TRUE(r.sec[1].peer_verified_us); +} + +TEST(Session, WrongKeyFailsBothEndsQuickly) +{ + auto k1 = std::make_shared(identity::generate()); + dpf::net::session_options o[2] = {with_limits({}), with_limits({})}; + o[1].security.self = k1; + o[0].security.trusted[1] = identity::generate().key(); + const auto t0 = std::chrono::steady_clock::now(); + const auto r = join_two(o); + EXPECT_LT(std::chrono::steady_clock::now() - t0, std::chrono::seconds(2)); + EXPECT_NE(r.error[0].find(k1->key().base64()), std::string::npos) << r.error[0]; + EXPECT_FALSE(r.error[1].empty()); +} + +TEST(Session, MixedEncryptionSettingsAreNamed) +{ + dpf::net::session_options o[2] = {with_limits({}), with_limits({})}; + o[1].security.encrypt = false; + const auto r = join_two(o); + const std::string both = r.error[0] + " | " + r.error[1]; + EXPECT_NE(both.find("encryption"), std::string::npos) << both; +} + +TEST(Session, SctpIsRefusedWhileEncrypted) +{ + asio::io_context io; + dpf::net::session_options o; + o.kind = dpf::net::transport::sctp; + try + { + dpf::net::party_session s(io, 0, 2, o); + FAIL() << "an encrypted session must refuse SCTP"; + } + catch (const std::invalid_argument & e) + { + EXPECT_NE(std::string(e.what()).find("cannot be encrypted"), std::string::npos); + } + if (dpf::net::sctp_available()) + { + o.security.encrypt = false; + EXPECT_NO_THROW(dpf::net::party_session(io, 0, 2, o)); + } +} + +TEST(Session, LackOfKeysIsLogged) +{ + const auto path = temp_path("lack.log"); + ::unlink(path.c_str()); + dpf::log::settings ls; + ls.sinks = "file:" + path; + dpf::log::configure(ls); + dpf::net::session_options o[2] = {with_limits({}), with_limits({})}; + const auto r = join_two(o, "lack-test-p"); + dpf::log::configure(dpf::log::settings{}); + ASSERT_TRUE(r.error[0].empty() && r.error[1].empty()) << r.error[0] << r.error[1]; + std::ifstream in(path); + const std::string text((std::istreambuf_iterator(in)), + std::istreambuf_iterator()); + EXPECT_NE(text.find("ev=security.no_identity"), std::string::npos) << text; + EXPECT_NE(text.find("ev=security.unauthenticated"), std::string::npos) << text; + EXPECT_NE(text.find("ephemeral=1"), std::string::npos) << text; + EXPECT_NE(text.find("auth=none"), std::string::npos) << text; + EXPECT_NE(text.find("encryption=TLSv1.3/"), std::string::npos) << text; + ::unlink(path.c_str()); +} + +TEST(Session, DealerKeyAuthenticatesTheDealer) +{ + auto dk = std::make_shared(identity::generate()); + dpf::net::session_options dopt = with_limits({}); + dopt.security.self = dk; + dpf::net::session_options popt = with_limits({}); + popt.security.trusted[dpf::net::dealer_id] = dk->key(); + std::atomic port{0}; + std::string derr; + dpf::net::link_security dealer_view; + std::thread dealer([&] { + try + { + asio::io_context io; + dpf::net::dealer_session d(io, 1, dopt); + port.store(d.listen()); + d.accept_parties(); + dealer_view = d.party_security(0); + } + catch (const std::exception & e) + { + derr = e.what(); + } + }); + while (port.load() == 0) + std::this_thread::yield(); + asio::io_context io; + dpf::net::party_session p(io, 0, 2, popt); + p.connect_dealer("127.0.0.1", port.load()); + dealer.join(); + ASSERT_TRUE(derr.empty()) << derr; + EXPECT_EQ(p.dealer_security().peer_auth, "key"); + EXPECT_EQ(dealer_view.peer_auth, "none"); + EXPECT_TRUE(dealer_view.peer_verified_us); +} + +// --------------------------------------------------------------------------- +// Client links +// --------------------------------------------------------------------------- + +namespace +{ + +/// A client connects to a `client_listener` and sends one word to it. +std::string client_roundtrip(const dpf::net::server_security & ss, + const dpf::net::client_security & cs, dpf::net::link_security * client_view = nullptr) +{ + std::atomic port{0}; + std::string serr, cerr; + std::uint64_t got = 0; + std::thread server([&] { + try + { + asio::io_context io; + dpf::net::deadlines lim; + lim.accept = std::chrono::milliseconds(3000); + dpf::net::client_listener l(io, ss, 1, {}, lim); + port.store(l.listen()); + auto c = l.accept(); + bool done = false; + c.link->async_read(0, &got, 8, [&](const std::error_code &) { done = true; }); + const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(3); + run_until(io, done, deadline); + } + catch (const std::exception & e) + { + serr = e.what(); + } + }); + while (port.load() == 0) + std::this_thread::yield(); + try + { + asio::io_context io; + auto c = dpf::net::connect_server(io, "127.0.0.1", port.load(), cs); + if (client_view != nullptr) + *client_view = c.security; + std::uint64_t v = 77; + bool done = false; + c.link->async_write(0, &v, 8, [&](const std::error_code &) { done = true; }); + const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(3); + run_until(io, done, deadline); + c.link.reset(); + for (int i = 0; i < 20; ++i) + io.poll(); + } + catch (const std::exception & e) + { + cerr = e.what(); + } + server.join(); + if (!cerr.empty()) + return "client: " + cerr; + if (!serr.empty()) + return "server: " + serr; + return got == 77 ? "" : "server got the wrong word"; +} + +} // namespace + +TEST(ClientLink, DevelopmentDefaultWorksAndSaysSo) +{ + dpf::net::link_security view; + EXPECT_EQ(client_roundtrip({}, {}, &view), ""); + EXPECT_EQ(view.peer_auth, "development"); +} + +TEST(ClientLink, ServerIdentityNeedsAPinOrVerifyOff) +{ + dpf::net::server_security ss; + ss.self = std::make_shared(identity::generate()); + EXPECT_NE(client_roundtrip(ss, {}).find("does not trust"), std::string::npos); + dpf::net::client_security pinned; + pinned.pins.push_back(ss.self->key()); + dpf::net::link_security view; + EXPECT_EQ(client_roundtrip(ss, pinned, &view), ""); + EXPECT_EQ(view.peer_auth, "key"); + dpf::net::client_security off; + off.verify = false; + EXPECT_EQ(client_roundtrip(ss, off, &view), ""); + EXPECT_EQ(view.peer_auth, "none"); +} + +// --------------------------------------------------------------------------- +// Configuration +// --------------------------------------------------------------------------- + +TEST(Config, SecurityFromAFileWithRelativePaths) +{ + const std::string dir = temp_path("cfgdir"); + (void)::system(("rm -rf '" + dir + "' && mkdir -p '" + dir + "'").c_str()); + const auto me = identity::generate(); + const auto other = identity::generate(); + me.save(dir + "/p0.key"); + { + std::ofstream pub(dir + "/p1.pub"); + pub << other.key().base64() << "\n"; + std::ofstream cfg(dir + "/p0.conf"); + cfg << "# party 0\n" + << "identity = p0.key\n" + << "peer.1 = file:p1.pub # the other party\n" + << "transport = mux\n" + << "client_pin = " << other.key().base64() << "\n"; + } + dpf::app::run_config c; + const std::string arg = "--config=" + dir + "/p0.conf"; + const char * argv[] = {"x", arg.c_str()}; + EXPECT_TRUE(c.apply_args(2, const_cast(argv)).empty()); + ASSERT_TRUE(c.security.self); + EXPECT_EQ(c.security.self->key(), me.key()); + ASSERT_NE(c.security.trusted_key(1), nullptr); + EXPECT_EQ(*c.security.trusted_key(1), other.key()); + EXPECT_EQ(c.kind, dpf::net::transport::mux); + ASSERT_EQ(c.client.pins.size(), 1u); + const auto summary = c.summary(); + EXPECT_NE(summary.find("encryption=on"), std::string::npos) << summary; + EXPECT_NE(summary.find("identity=" + me.key().base64()), std::string::npos); + EXPECT_NE(summary.find("trusted=1"), std::string::npos); + { + std::ofstream bad(dir + "/bad.conf"); + bad << "transport = mux\npeer.1 = not-a-key\n"; + } + try + { + c.set("config", dir + "/bad.conf"); + FAIL() << "a bad key must be rejected"; + } + catch (const std::invalid_argument & e) + { + EXPECT_NE(std::string(e.what()).find("bad.conf:2"), std::string::npos) << e.what(); + } + EXPECT_THROW(c.set("encryption", "maybe"), std::invalid_argument); + (void)::system(("rm -rf '" + dir + "'").c_str()); +} + +// --------------------------------------------------------------------------- +// Separate processes from key files and config files +// --------------------------------------------------------------------------- + +namespace +{ + +dpf::protocol::plan open_plan(std::size_t party, dpf::protocol::node & x, + dpf::protocol::node & out) +{ + dpf::protocol::composer c(party); + x = c.input(dpf::protocol::domain::a, 8); + out = c.exchange(x); + return c.schedule(); +} + +} // namespace + +TEST(Deployment, TwoProcessesAuthenticateEachOther) +{ + const std::string dir = temp_path("deploy"); + (void)::system(("rm -rf '" + dir + "' && mkdir -p '" + dir + "'").c_str()); + const identity ids[2] = {identity::generate(), identity::generate()}; + unsigned short ports[2]; + for (int i = 0; i < 2; ++i) + { + ids[i].save(dir + "/p" + std::to_string(i) + ".key"); + asio::io_context io; + asio::ip::tcp::acceptor a(io); + dpf::net::open_listener(a, 0); + ports[i] = a.local_endpoint().port(); + } + for (int i = 0; i < 2; ++i) + { + std::ofstream cfg(dir + "/p" + std::to_string(i) + ".conf"); + cfg << "identity = p" << i << ".key\n" + << "peer." << (1 - i) << " = " << ids[1 - i].key().base64() << "\n" + << "transport = mux\n"; + } + const std::string peers = "--peers=127.0.0.1:" + std::to_string(ports[0]) + + ",127.0.0.1:" + std::to_string(ports[1]); + pid_t kids[2]; + for (int me = 0; me < 2; ++me) + { + const pid_t pid = ::fork(); + ASSERT_GE(pid, 0); + if (pid == 0) + { + int code = 1; + try + { + const std::string party = "--party=" + std::to_string(me); + const std::string cfg = "--config=" + dir + "/p" + std::to_string(me) + + ".conf"; + const std::string log = "--log=file:" + dir + "/p" + std::to_string(me) + + ".log"; + const char * argv[] = {"node", party.c_str(), peers.c_str(), cfg.c_str(), + log.c_str()}; + auto args = dpf::app::parse_node_args(5, const_cast(argv), + dpf::app::run_config{}); + dpf::log::settings ls; + ls.sinks = args.cfg.log_sinks; + dpf::log::configure(ls); + dpf::protocol::node x, out; + auto plan = open_plan(static_cast(me), x, out); + dpf::app::party_values v(plan.nodes().size()); + v[x.id].assign(8, 0); + const std::uint64_t in = me == 0 ? 40 : 2; + std::memcpy(v[x.id].data(), &in, 8); + (void)dpf::app::run_node(args, plan, v, {}); + std::uint64_t o = 0; + std::memcpy(&o, v[out.id].data(), 8); + code = o == 42 ? 0 : 2; + } + catch (const std::exception & e) + { + std::fprintf(stderr, "party %d: %s\n", me, e.what()); + code = 3; + } + ::_exit(code); + } + kids[me] = pid; + } + for (int me = 0; me < 2; ++me) + { + int status = 0; + ASSERT_EQ(::waitpid(kids[me], &status, 0), kids[me]); + ASSERT_TRUE(WIFEXITED(status)); + EXPECT_EQ(WEXITSTATUS(status), 0) << "party " << me; + } + for (int me = 0; me < 2; ++me) + { + std::ifstream in(dir + "/p" + std::to_string(me) + ".log"); + const std::string text((std::istreambuf_iterator(in)), + std::istreambuf_iterator()); + EXPECT_NE(text.find("ev=link.up"), std::string::npos) << text; + EXPECT_NE(text.find("auth=key"), std::string::npos) << text; + EXPECT_NE(text.find("peer_verified_us=1"), std::string::npos) << text; + EXPECT_EQ(text.find("ev=security.unauthenticated"), std::string::npos) << text; + } + (void)::system(("rm -rf '" + dir + "'").c_str()); +} diff --git a/test/tests/sfss_test.cpp b/test/tests/sfss_test.cpp new file mode 100644 index 0000000..fbd52d0 --- /dev/null +++ b/test/tests/sfss_test.cpp @@ -0,0 +1,111 @@ +#include + +#include +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +template +dpf::fp61 open_sdpf(const K0 & k0, const K1 & k1, InputT x, + const dpf::sfss_ct & ct) +{ + return dpf::reconstruct( + dpf::subtractive_share::from_raw( + dpf::eval_sdpf(k0, x, ct)), + dpf::subtractive_share::from_raw( + dpf::eval_sdpf(k1, x, ct))); +} + +} // namespace + +TEST(Sfss, PointBetaOneOnAndOff) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + auto [k0, k1, ke, st] = dpf::make_sdpf(alpha); + EXPECT_EQ(ke.beta.raw(), 1u); + + const dpf::fp61 m{42}; + const auto ct = dpf::sfss_enc(st, ke, m); + EXPECT_EQ(ct.j, 1u); + EXPECT_EQ(st.ctr, 2u); + + EXPECT_EQ(open_sdpf(k0, k1, alpha, ct), m); + EXPECT_EQ(open_sdpf(k0, k1, Input{0}, ct), dpf::fp61{0}); + EXPECT_EQ(open_sdpf(k0, k1, static_cast(alpha ^ 1), ct), dpf::fp61{0}); +} + +TEST(Sfss, WeightedBeta) +{ + using Input = std::uint16_t; + const Input alpha = 1000; + const dpf::fp61 beta{7}; + auto [k0, k1, ke, st] = dpf::make_sdpf(alpha, beta); + EXPECT_EQ(ke.beta, beta); + + const dpf::fp61 m{11}; + const auto ct = dpf::sfss_enc(st, ke, m); + EXPECT_EQ(open_sdpf(k0, k1, alpha, ct), beta * m); + EXPECT_EQ(open_sdpf(k0, k1, Input{0}, ct), dpf::fp61{0}); +} + +TEST(Sfss, ManyStreamMessages) +{ + using Input = std::uint8_t; + const Input alpha = 7; + auto [k0, k1, ke, st] = dpf::make_sdpf(alpha, dpf::fp61{3}); + + for (std::uint64_t i = 0; i < 20; ++i) + { + const dpf::fp61 m{i + 1}; + const auto ct = dpf::sfss_enc(st, ke, m); + EXPECT_EQ(ct.j, i + 1); + EXPECT_EQ(open_sdpf(k0, k1, alpha, ct), ke.beta * m) << i; + EXPECT_EQ(open_sdpf(k0, k1, Input{8}, ct), dpf::fp61{0}) << i; + } +} + +TEST(Sfss, WindowTelescopes) +{ + using Input = std::uint8_t; + const Input alpha = 3; + auto [k0, k1, ke, st] = dpf::make_sdpf(alpha, dpf::fp61{5}); + + const std::uint64_t j_lo = st.ctr; + dpf::fp61 sum_m{}; + dpf::fp61 c_agg{}; + constexpr std::size_t window = 8; + for (std::size_t i = 0; i < window; ++i) + { + const dpf::fp61 m{static_cast(i + 2)}; + sum_m = sum_m + m; + const auto ct = dpf::sfss_enc_window(st, ke, m); + c_agg = c_agg + ct.c; + } + const std::uint64_t j_hi = j_lo + window - 1; + + const auto s0 = dpf::eval_sdpf_window(k0, alpha, c_agg, j_lo, j_hi); + const auto s1 = dpf::eval_sdpf_window(k1, alpha, c_agg, j_lo, j_hi); + EXPECT_EQ(dpf::reconstruct( + dpf::subtractive_share::from_raw(s0), + dpf::subtractive_share::from_raw(s1)), + ke.beta * sum_m); + + const auto z0 = dpf::eval_sdpf_window(k0, Input{4}, c_agg, j_lo, j_hi); + const auto z1 = dpf::eval_sdpf_window(k1, Input{4}, c_agg, j_lo, j_hi); + EXPECT_EQ(dpf::reconstruct( + dpf::subtractive_share::from_raw(z0), + dpf::subtractive_share::from_raw(z1)), + dpf::fp61{0}); +} + +TEST(Sfss, RejectZeroBeta) +{ + EXPECT_THROW((void)dpf::make_sdpf(std::uint8_t{1}, dpf::fp61{0}), + std::invalid_argument); +} diff --git a/test/tests/shamir_adversarial_test.cpp b/test/tests/shamir_adversarial_test.cpp new file mode 100644 index 0000000..a7c6ee0 --- /dev/null +++ b/test/tests/shamir_adversarial_test.cpp @@ -0,0 +1,347 @@ +/// @file shamir_adversarial_test.cpp +/// @brief Corruption and misuse checks for (K,N) Shamir sharing. +/// @details Exactly K shares accept any values, including a mislabeled point. +/// Each further share is checked against the polynomial of the first +/// K, wherever the bad share sits in that list. A full set of shares +/// of a different secret is consistent and opens that secret. A zero +/// leading coefficient drops the real threshold. (2,3) shamir3 +/// rejects a party outside 1..3 and an inconsistent third share. +/// Threshold 1 hides nothing: every share is the secret. When K = N +/// there is no extra share, so a tampered full set is not detected. + +#include + +#include +#include +#include +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +using F = dpf::fp61; + +template +std::array raws(const Tuple & shares, std::index_sequence) +{ + return {{std::get(shares).raw()...}}; +} + +template +std::array raws(const Tuple & shares) +{ + return raws(shares, std::make_index_sequence{}); +} + +template +std::array, N> points(const std::array & value) +{ + std::array, N> out{}; + for (std::size_t i = 0; i < N; ++i) + out[i] = {static_cast(i + 1), value[i]}; + return out; +} + +} // namespace + +TEST(ShamirAdversarial, ExactlyKAcceptsALie) +{ + const std::array coeff{{F{2}, F{3}}}; + const auto dealt = dpf::shamir::deal(F{10}, coeff); + auto bad = std::get<0>(dealt); + bad += F{1}; + const F opened = dpf::shamir::reconstruct(bad, std::get<1>(dealt), std::get<2>(dealt)); + EXPECT_NE(opened, F{10}); +} + +TEST(ShamirAdversarial, ExtraShareCatchesALieInAnySlot) +{ + const std::array coeff{{F{2}, F{3}}}; + const auto dealt = dpf::shamir::deal(F{10}, coeff); + const auto honest = points<5>(raws<5>(dealt)); + EXPECT_EQ((dpf::shamir::reconstruct(honest)), F{10}); + + for (std::size_t slot = 0; slot < 5; ++slot) + { + auto lied = honest; + lied[slot].value = lied[slot].value + F{1}; + EXPECT_THROW((dpf::shamir::reconstruct(lied)), std::runtime_error) + << "slot " << slot; + + // The same lie, moved to the front of the argument list. + std::array, 5> front{}; + front[0] = lied[slot]; + std::size_t n = 1; + for (std::size_t i = 0; i < 5; ++i) + if (i != slot) + front[n++] = honest[i]; + EXPECT_THROW((dpf::shamir::reconstruct(front)), std::runtime_error) + << "front slot " << slot; + } +} + +TEST(ShamirAdversarial, ConsistentForgeryOpensTheForgedSecret) +{ + const std::array coeff{{F{1}, F{4}}}; + const auto forged = dpf::shamir::deal(F{99}, coeff); + const auto held = points<5>(raws<5>(forged)); + EXPECT_EQ((dpf::shamir::reconstruct(held)), F{99}); + + const auto real = dpf::shamir::deal(F{10}, std::array{{F{2}, F{3}}}); + auto mixed = points<5>(raws<5>(real)); + mixed[4] = held[4]; + EXPECT_THROW((dpf::shamir::reconstruct(mixed)), std::runtime_error); +} + +TEST(ShamirAdversarial, OrderOfAConsistentSetDoesNotMatter) +{ + const std::array coeff{{F{2}, F{3}}}; + const auto dealt = dpf::shamir::deal(F{10}, coeff); + const F values[5] = { + std::get<0>(dealt).raw(), std::get<1>(dealt).raw(), + std::get<2>(dealt).raw(), std::get<3>(dealt).raw(), + std::get<4>(dealt).raw()}; + int idx[3] = {0, 2, 4}; + do + { + const std::array, 3> subset{{ + {idx[0] + 1, values[idx[0]]}, + {idx[1] + 1, values[idx[1]]}, + {idx[2] + 1, values[idx[2]]}}}; + EXPECT_EQ((dpf::shamir::reconstruct(subset)), F{10}); + } + while (std::next_permutation(idx, idx + 3)); + + const auto forward = points<5>(raws<5>(dealt)); + std::array, 5> backward{}; + for (std::size_t i = 0; i < 5; ++i) + backward[i] = forward[4 - i]; + EXPECT_EQ((dpf::shamir::reconstruct(backward)), F{10}); +} + +TEST(ShamirAdversarial, WrongThresholdAndMislabeledPoint) +{ + // p(x) = 8 + 5x + x^2. The line through p(1)=14 and p(2)=22 opens 6, not 8. + const auto steep = dpf::shamir::deal(F{8}, std::array{{F{5}, F{1}}}); + const std::array, 2> line{{ + {1, std::get<0>(steep).raw()}, {2, std::get<1>(steep).raw()}}}; + EXPECT_EQ(std::get<0>(steep).raw(), F{14}); + EXPECT_EQ(std::get<1>(steep).raw(), F{22}); + EXPECT_EQ((dpf::shamir::reconstruct(line)), F{6}); + EXPECT_NE((dpf::shamir::reconstruct(line)), F{8}); + + // A zero leading coefficient is only a (2,5) sharing. + const auto flat = dpf::shamir::deal(F{8}, std::array{{F{5}, F{0}}}); + const std::array, 2> still_line{{ + {1, std::get<0>(flat).raw()}, {4, std::get<3>(flat).raw()}}}; + EXPECT_EQ((dpf::shamir::reconstruct(still_line)), F{8}); + + auto [s0, s1, s2] = dpf::make_shamir_shares(F{20}, F{3}); + const std::array, 2> swapped{{ + {1, s1.raw()}, {2, s0.raw()}}}; + EXPECT_NE((dpf::shamir::reconstruct(swapped)), F{20}); + const std::array, 3> swapped3{{ + {1, s1.raw()}, {2, s0.raw()}, {3, s2.raw()}}}; + EXPECT_THROW((dpf::shamir::reconstruct(swapped3)), std::runtime_error); +} + +TEST(ShamirAdversarial, OneShareDoesNotFixTheSecret) +{ + // p(1) = 13 for both (secret, slope) = (10, 3) and (11, 2). + auto [a0, a1, a2] = dpf::make_shamir_shares(F{10}, F{3}); + auto [b0, b1, b2] = dpf::make_shamir_shares(F{11}, F{2}); + EXPECT_EQ(a0.raw(), b0.raw()); + EXPECT_EQ(a0.raw(), F{13}); + EXPECT_EQ((dpf::reconstruct(a0, a1)), F{10}); + EXPECT_EQ((dpf::reconstruct(b0, b1)), F{11}); + EXPECT_NE((dpf::reconstruct(a0, b1)), F{10}); + (void)a2; + (void)b2; +} + +TEST(ShamirAdversarial, RejectsCountPointsAndOneSidedEdit) +{ + const auto dealt = dpf::shamir::deal(F{10}, std::array{{F{2}, F{3}}}); + const auto honest = points<5>(raws<5>(dealt)); + const std::array, 2> too_few{{honest[0], honest[1]}}; + EXPECT_THROW((dpf::shamir::reconstruct(too_few)), std::invalid_argument); + EXPECT_THROW((dpf::shamir::reconstruct(honest.data(), 0)), + std::invalid_argument); + EXPECT_THROW((dpf::shamir::reconstruct(honest.data(), 6)), + std::invalid_argument); + + const std::array, 3> dup{{ + {1, honest[0].value}, {1, honest[0].value}, {3, honest[2].value}}}; + EXPECT_THROW((dpf::shamir::reconstruct(dup)), std::invalid_argument); + const std::array, 3> zero_pt{{ + {0, honest[0].value}, {2, honest[1].value}, {3, honest[2].value}}}; + EXPECT_THROW((dpf::shamir::reconstruct(zero_pt)), std::invalid_argument); + const std::array, 3> negative{{ + {-1, honest[0].value}, {2, honest[1].value}, {3, honest[2].value}}}; + EXPECT_THROW((dpf::shamir::reconstruct(negative)), std::invalid_argument); + const std::array, 3> past{{ + {1, honest[0].value}, {2, honest[1].value}, {6, honest[2].value}}}; + EXPECT_THROW((dpf::shamir::reconstruct(past)), std::invalid_argument); + + auto one = std::get<0>(dealt); + one += F{4}; + const F sided = dpf::shamir::reconstruct(one, std::get<1>(dealt), std::get<2>(dealt)); + EXPECT_NE(sided, F{10}); + auto with_extra = honest; + with_extra[0].value = one.raw(); + EXPECT_THROW((dpf::shamir::reconstruct(with_extra)), std::runtime_error); + + auto all = dealt; + std::get<0>(all) += F{4}; + std::get<1>(all) += F{4}; + std::get<2>(all) += F{4}; + std::get<3>(all) += F{4}; + std::get<4>(all) += F{4}; + EXPECT_EQ((dpf::shamir::reconstruct(points<5>(raws<5>(all)))), F{14}); +} + +TEST(ShamirAdversarial, ThresholdOneHidesNothingAndFullThresholdNeedsEveryShare) +{ + const auto copied = dpf::shamir::deal(F{4}, std::array{}); + EXPECT_EQ(std::get<0>(copied).raw(), F{4}); + EXPECT_EQ(std::get<3>(copied).raw(), F{4}); + auto lie = std::get<0>(copied); + lie += F{1}; + EXPECT_EQ(dpf::shamir::reconstruct(lie), F{5}); + auto all = points<4>(raws<4>(copied)); + all[2].value = all[2].value + F{1}; + EXPECT_THROW((dpf::shamir::reconstruct(all)), std::runtime_error); + + const auto quad = dpf::shamir::deal( + F{9}, std::array{{F{1}, F{2}, F{3}}}); + const F opened4 = dpf::shamir::reconstruct(std::get<0>(quad), std::get<1>(quad), + std::get<2>(quad), std::get<3>(quad)); + EXPECT_EQ(opened4, F{9}); + const std::array, 3> missing{{ + {1, std::get<0>(quad).raw()}, + {2, std::get<1>(quad).raw()}, + {3, std::get<2>(quad).raw()}}}; + EXPECT_THROW((dpf::shamir::reconstruct(missing)), std::invalid_argument); + // K = N, so the full set is exactly K shares and a lie is not detected. + auto bad = std::get<3>(quad); + bad += F{1}; + const F lied = dpf::shamir::reconstruct(std::get<0>(quad), std::get<1>(quad), + std::get<2>(quad), bad); + EXPECT_NE(lied, F{9}); + + const auto room = dpf::shamir::deal(F{9}, std::array{{F{1}, F{2}}}); + auto bad_extra = std::get<3>(room); + bad_extra += F{1}; + EXPECT_THROW((dpf::shamir::reconstruct(std::get<0>(room), std::get<1>(room), + std::get<2>(room), bad_extra)), std::runtime_error); +} + +TEST(ShamirAdversarial, Shamir3RejectsBadPartiesAndMatchesTheGeneralOpen) +{ + const auto s = dpf::shamir3::share_secret(F{42}); + const F from_general = dpf::shamir::reconstruct( + std::array, 2>{{ + {s[0].party, s[0].value}, {s[2].party, s[2].value}}}); + const F from_shamir3 = dpf::shamir3::reconstruct(s[0], s[2]); + EXPECT_EQ(from_shamir3, from_general); + const F from_three = dpf::shamir3::reconstruct(s[0], s[1], s[2]); + EXPECT_EQ(from_three, F{42}); + + EXPECT_THROW((dpf::shamir3::reconstruct( + dpf::shamir3::share{0, F{1}}, dpf::shamir3::share{1, F{1}})), + std::invalid_argument); + EXPECT_THROW((dpf::shamir3::reconstruct( + dpf::shamir3::share{1, F{1}}, dpf::shamir3::share{4, F{1}})), + std::invalid_argument); + EXPECT_THROW((dpf::shamir3::reconstruct( + dpf::shamir3::share{2, F{1}}, dpf::shamir3::share{2, F{2}})), + std::invalid_argument); + EXPECT_THROW((dpf::shamir3::reconstruct(s[0], s[1], dpf::shamir3::share{4, s[2].value})), + std::invalid_argument); + + auto bad = s[2]; + bad.value = bad.value + F{1}; + EXPECT_THROW((dpf::shamir3::reconstruct(s[0], s[1], bad)), std::runtime_error); + EXPECT_THROW((dpf::shamir::reconstruct( + std::array, 3>{{ + {s[0].party, s[0].value}, + {s[1].party, s[1].value}, + {bad.party, bad.value}}})), + std::runtime_error); + + EXPECT_THROW((dpf::shamir3::add(s[0], s[1])), std::invalid_argument); + const auto doubled = dpf::shamir3::add(s[0], s[0]); + EXPECT_EQ(doubled.value, s[0].value + s[0].value); + EXPECT_THROW((dpf::shamir3::typed_share<0>(s[1])), std::invalid_argument); + const auto typed = dpf::shamir3::typed_share<0>(s[0]); + EXPECT_EQ(typed.raw(), s[0].value); + + auto [t0, t1, t2] = dpf::make_shamir_shares(F{42}, F{0}); + t2 += F{1}; + EXPECT_THROW((dpf::reconstruct(t0, t1, t2)), std::runtime_error); + EXPECT_THROW((dpf::shamir::reconstruct(t2, t0, t1)), std::runtime_error); +} + +TEST(ShamirAdversarial, ZeroAndFieldEdge) +{ + const auto zeros = dpf::shamir::deal(F{0}, std::array{{F{0}, F{0}}}); + EXPECT_EQ(std::get<0>(zeros).raw(), F{0}); + EXPECT_EQ(std::get<3>(zeros).raw(), F{0}); + const F opened0 = dpf::shamir::reconstruct( + std::get<1>(zeros), std::get<2>(zeros), std::get<3>(zeros)); + EXPECT_EQ(opened0, F{0}); + + const F edge{dpf::fp61_mod - 1}; + const auto high = dpf::shamir::deal(edge, std::array{{edge}}); + const F opened_edge = dpf::reconstruct(std::get<0>(high), std::get<2>(high)); + EXPECT_EQ(opened_edge, edge); + static_assert(std::is_same_v, dpf::shamir_share>); +} + +TEST(ShamirAdversarial, Gf2PointsMustFitAndLiesAreXor) +{ + // GF(2^8) has room for points 1..5. A one-bit lie is invisible at K=3 + // and caught when an honest extra share is present. + using G = dpf::gf28; + const auto dealt = dpf::shamir::deal( + G{0x1b}, std::array{{G{2}, G{9}}}); + auto bad = std::get<0>(dealt); + bad += G{1}; + const G sided = dpf::shamir::reconstruct(bad, std::get<1>(dealt), std::get<2>(dealt)); + EXPECT_NE(sided, G{0x1b}); + auto extra = std::get<3>(dealt); + EXPECT_THROW((dpf::shamir::reconstruct(bad, std::get<1>(dealt), std::get<2>(dealt), extra)), + std::runtime_error); + + // Adding a share to itself is XOR, so the opened secret is 0, not twice. + const G doubled = dpf::shamir::reconstruct( + std::get<0>(dealt) + std::get<0>(dealt), + std::get<1>(dealt) + std::get<1>(dealt), + std::get<2>(dealt) + std::get<2>(dealt)); + EXPECT_EQ(doubled, G{0}); + + // GF(16) holds points 1..15. Point 16 is 0. Point 17 aliases point 1. + using H = dpf::gf24; + const auto fit = dpf::shamir::deal(H{0xa}, std::array{{H{0x3}}}); + EXPECT_EQ((dpf::shamir::reconstruct(std::get<0>(fit), std::get<14>(fit))), H{0xa}); + const auto zero_pt = dpf::shamir::deal(H{0xa}, std::array{{H{0x3}}}); + // Point 16 is 0 in GF(16), so that share is p(0), the secret. + EXPECT_EQ(std::get<15>(zero_pt).raw(), H{0xa}.raw()); + EXPECT_THROW((dpf::shamir::reconstruct(std::get<0>(zero_pt), std::get<15>(zero_pt))), + std::invalid_argument); + const auto alias = dpf::shamir::deal(H{0xa}, std::array{{H{0x3}}}); + EXPECT_EQ(std::get<0>(alias).raw(), std::get<16>(alias).raw()); + EXPECT_THROW((dpf::shamir::reconstruct(std::get<0>(alias), std::get<16>(alias))), + std::invalid_argument); + + // GF(4) holds a (2,3) sharing. Point 4 is 0. + const auto small = dpf::shamir::deal( + dpf::gf22{1}, std::array{{dpf::gf22{2}}}); + EXPECT_THROW((dpf::shamir::reconstruct(std::get<0>(small), std::get<3>(small))), + std::invalid_argument); + EXPECT_EQ((dpf::shamir::reconstruct(std::get<0>(small), std::get<2>(small))), dpf::gf22{1}); +} diff --git a/test/tests/share_runtime_test.cpp b/test/tests/share_runtime_test.cpp new file mode 100644 index 0000000..4e26734 --- /dev/null +++ b/test/tests/share_runtime_test.cpp @@ -0,0 +1,2643 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf/app_flow.hpp" +#include "dpf/async_protocol.hpp" +#include "dpf/compose_async.hpp" +#include "dpf/net/async_round_sink.hpp" +#include "dpf/net/async_sctp_stream_array.hpp" +#include "dpf/net/async_stream_array.hpp" +#include "dpf/net/round_lane.hpp" +#include "dpf/net/io_pool.hpp" +#include "dpf/net/party_session.hpp" +#include "dpf/net/tcp_mesh.hpp" +#include "dpf/bit_inject.hpp" +#include "dpf/circuit.hpp" +#include "dpf/compose.hpp" +#include "dpf/online_session.hpp" +#include "dpf/party_run.hpp" +#include "dpf/prep_source.hpp" +#include "dpf/buffered_prg.hpp" +#include "dpf/factory_gadgets.hpp" +#include "dpf/factory_tapes.hpp" +#include "dpf/net/dealer_cursor.hpp" +#include "dpf/protocol_factory.hpp" +#include "dpf/protocol_roles.hpp" +#include "dpf/revealing.hpp" +#include "dpf/schedule_streams.hpp" +#include "dpf/cost_pass.hpp" +#include "dpf/edabit.hpp" +#include "dpf/fixed_share.hpp" +#include "dpf/gilboa.hpp" +#include "dpf/matmul.hpp" +#include "dpf/net/edge_mesh.hpp" +#include "dpf/net/memory_sink.hpp" +#include "dpf/net/stream_array.hpp" +#include "dpf/net/stream_mesh.hpp" +#include "dpf/net/stream_edge_mesh.hpp" +#include "dpf/protocol_roles.hpp" +#include "dpf/ot_pack.hpp" +#include "dpf/protocol.hpp" +#include "dpf/random.hpp" +#include "dpf/rss_seed.hpp" +#include "dpf/share_cmp.hpp" +#include "dpf/share_expr.hpp" +#include "dpf/share_vec.hpp" +#include "dpf/shuffle.hpp" +#include "dpf/trunc.hpp" + +using dpf::protocol::domain; +using dpf::protocol::phase; +using dpf::protocol::round_dir; +using dpf::protocol::schedule_round; +using dpf::protocol::schedule_session; +using dpf::protocol::receive_rule; + +namespace +{ + +void drive_both(const dpf::protocol::plan & p, + std::vector> & v0, + std::vector> & v1) +{ + auto slots = p.slot_bytes_all(); + if (slots.empty()) + throw std::logic_error("drive_both: plan has no exchange"); + auto sinks = dpf::net::make_memory_sink_pair(1, slots); + std::map kernels; + std::mutex mu; + std::exception_ptr err; + auto run = [&](dpf::net::memory_sink & sink, + std::vector> & values, + std::size_t party) { + try + { + dpf::protocol::drive(p, sink, values, kernels, party); + } + catch (...) + { + std::lock_guard lock(mu); + if (!err) + err = std::current_exception(); + } + }; + std::thread t0([&] { run(sinks.first, v0, 0); }); + std::thread t1([&] { run(sinks.second, v1, 1); }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); +} + +void put_raw(std::vector> & values, + dpf::protocol::node n, const void * src, std::size_t nbyte) +{ + values[n.id].assign(nbyte, 0); + std::memcpy(values[n.id].data(), src, nbyte); +} + +} // namespace + +// --------------------------------------------------------------------------- +// Wave 1 +// --------------------------------------------------------------------------- + +TEST(RssSeed, RandomReplicatedSums) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + auto all = dpf::rss::random_replicated_all(bundle, 7); + EXPECT_EQ(all.p0.next, all.p1.own); + EXPECT_EQ(all.p1.next, all.p2.own); + EXPECT_EQ(all.p2.next, all.p0.own); +} + +TEST(RssSeed, ZeroSharesSumToZero) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + auto s0 = dpf::rss::party_seeds::from_bundle(bundle, 0); + auto s1 = dpf::rss::party_seeds::from_bundle(bundle, 1); + auto s2 = dpf::rss::party_seeds::from_bundle(bundle, 2); + const auto z0 = dpf::rss::zero_share(s0, 3); + const auto z1 = dpf::rss::zero_share(s1, 3); + const auto z2 = dpf::rss::zero_share(s2, 3); + EXPECT_EQ(static_cast(z0 + z1 + z2), 0u); +} + +TEST(RssSeed, MulLocalThenRefresh) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + const std::uint64_t x = 11, y = 13; + auto [xs0, xs1, xs2] = dpf::make_replicated_shares(x); + auto [ys0, ys1, ys2] = dpf::make_replicated_shares(y); + auto s0 = dpf::rss::party_seeds::from_bundle(bundle, 0); + auto s1 = dpf::rss::party_seeds::from_bundle(bundle, 1); + auto s2 = dpf::rss::party_seeds::from_bundle(bundle, 2); + const auto y0 = dpf::rss::rss_mul_local(s0, xs0.own, xs0.next, ys0.own, + ys0.next, 0); + const auto y1 = dpf::rss::rss_mul_local(s1, xs1.own, xs1.next, ys1.own, + ys1.next, 0); + const auto y2 = dpf::rss::rss_mul_local(s2, xs2.own, xs2.next, ys2.own, + ys2.next, 0); + EXPECT_EQ(static_cast(y0 + y1 + y2), x * y); +} + +TEST(ScheduleSession, PipelineCreditIndependentPads) +{ + auto tape = std::make_shared>(); + auto rounds = dpf::protocol::make_pad_rounds(2, 8, tape); + EXPECT_EQ(rounds[0].round_phase, phase::setup); + EXPECT_EQ(rounds[0].dir, round_dir::send_next); + + auto [a, b] = dpf::net::make_memory_sink_pair(1, {8, 8}); + schedule_session s0(1, a, rounds, /*pipeline_credit=*/1); + schedule_session s1(1, b, rounds, /*pipeline_credit=*/1); + s0.submit(0); + s1.submit(0); + s0.drive(); + s1.drive(); + EXPECT_TRUE(s0.done(0)); + EXPECT_TRUE(s1.done(0)); + EXPECT_GT(s0.tally().setup_bytes_out, 0u); +} + +TEST(Compose, BinNotLocalConvertible) +{ + EXPECT_FALSE(dpf::protocol::detail::local_convertible(domain::bin, + domain::a)); + dpf::protocol::composer c(0); + auto a = c.input(domain::a, 8); + EXPECT_THROW(c.as(a, domain::bin), std::invalid_argument); +} + +TEST(Compose, ArithKernelsPresent) +{ + EXPECT_TRUE(dpf::protocol::detail::has_builtin_walk_kernel( + dpf::protocol::opcodes::trunc_prob)); + EXPECT_TRUE(dpf::protocol::detail::has_builtin_walk_kernel( + dpf::protocol::opcodes::rss_zero)); + EXPECT_TRUE(dpf::protocol::detail::has_builtin_walk_kernel( + dpf::protocol::opcodes::bin_a2b)); + EXPECT_TRUE(dpf::protocol::detail::has_builtin_walk_kernel( + dpf::protocol::opcodes::share_cmp)); +} + +TEST(Compose, RssZeroFromSeeds) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + auto seeds = dpf::rss::party_seeds::from_bundle(bundle, 0); + dpf::protocol::composer c(0); + auto z = c.rss_zero_mask(domain::a, 8, 3); + auto p = c.default_plan(); + std::vector> values(p.nodes().size()); + dpf::protocol::drive_options opt; + opt.rss_seeds = &seeds; + dpf::protocol::detail::run_arith_local(p, z.id, 0, 0, 1, values, opt); + std::uint64_t got = 0; + std::memcpy(&got, values[z.id].data(), 8); + EXPECT_EQ(got, dpf::rss::zero_share(seeds, 3)); +} + +TEST(Compose, CheckOpenRejectsCorrupt) +{ + dpf::protocol::composer c(0); + auto x = c.input(domain::a, 8); + auto ex = c.exchange(x); + auto p = c.default_plan(); + auto slots = p.slot_bytes_all(); + ASSERT_FALSE(slots.empty()); + auto [sink0, sink1] = dpf::net::make_memory_sink_pair(1, slots); + std::vector> v0(p.nodes().size()); + std::vector> v1(p.nodes().size()); + const std::uint64_t secret = 42; + v0[x.id].assign(8, 0); + v1[x.id].assign(8, 0); + std::memcpy(v0[x.id].data(), &secret, 8); + std::map> oracle; + std::vector expect(8, 0); + std::memcpy(expect.data(), &secret, 8); + oracle[ex.id] = expect; + dpf::protocol::drive_options opt; + opt.cleartext = true; + opt.check_open = true; + opt.clear_oracle = &oracle; + std::uint64_t bad = 7; + std::memcpy(v1[x.id].data(), &bad, 8); + std::map kernels; + std::exception_ptr err; + std::thread t0([&] { + try + { + dpf::protocol::drive(p, sink0, v0, kernels, 0, opt); + } + catch (...) + { + err = std::current_exception(); + } + }); + std::thread t1([&] { + try + { + dpf::protocol::drive(p, sink1, v1, kernels, 1, opt); + } + catch (...) + { + err = std::current_exception(); + } + }); + t0.join(); + t1.join(); + ASSERT_TRUE(err != nullptr); +} + +// --------------------------------------------------------------------------- +// Wave 2 +// --------------------------------------------------------------------------- + +TEST(EdaBit, A2BThenReconstruct) +{ + for (unsigned ell : {1u, 8u, 32u, 64u}) + { + const std::uint64_t x = 0x123456789abcdef0ull + & ((ell >= 64) ? ~0ull : ((1ull << ell) - 1ull)); + auto eda = dpf::edabit::sample_edabit_pair(ell); + EXPECT_EQ(eda.p0.arith + eda.p1.arith, eda.clear_r); + auto bits = dpf::edabit::a2b_gmw_pair(eda, x, std::uint64_t{0}); + const auto got = dpf::edabit::reconstruct_bits(bits.first, bits.second, ell); + EXPECT_EQ(got, x) << "ell=" << ell; + } +} + +TEST(EdaBit, RssArithEqualsBits) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + auto all = dpf::edabit::sample_rss_all(bundle, 16, 0); + EXPECT_EQ(all.p0.arith + all.p1.arith + all.p2.arith, all.clear_r); + auto bit = [](const std::vector & p, unsigned i) { + return static_cast((p[i / 8u] >> (i % 8u)) & 1u); + }; + std::uint64_t from_bits = 0; + for (unsigned i = 0; i < 16; ++i) + { + EXPECT_EQ(bit(all.p0.bits_next, i), bit(all.p1.bits_packed, i)); + EXPECT_EQ(bit(all.p1.bits_next, i), bit(all.p2.bits_packed, i)); + EXPECT_EQ(bit(all.p2.bits_next, i), bit(all.p0.bits_packed, i)); + const unsigned b = bit(all.p0.bits_packed, i) ^ bit(all.p1.bits_packed, i) + ^ bit(all.p2.bits_packed, i); + from_bits |= static_cast(b) << i; + } + EXPECT_EQ(from_bits, all.clear_r); +} + +TEST(EdaBit, GmwA2bMatchesClear) +{ + const std::uint64_t x0 = 30, x1 = 12; + auto eda = dpf::edabit::sample_edabit_pair(8); + auto bits = dpf::edabit::a2b_gmw_pair(eda, x0, x1); + EXPECT_EQ(dpf::edabit::reconstruct_bits(bits.first, bits.second, 8), x0 + x1); +} + +TEST(EdaBit, DaBitPairConsistent) +{ + auto d = dpf::ot::sample_dabit_pair(); + EXPECT_EQ(static_cast(d.p0.arith + d.p1.arith), + static_cast((d.p0.bit ^ d.p1.bit) & 1u)); +} + +TEST(BitInject, ClearMatches) +{ + EXPECT_EQ(dpf::bit_inject::inject_clear(1, 0, 5, 7), 12u); + EXPECT_EQ(dpf::bit_inject::inject_clear(1, 1, 5, 7), 0u); +} + +TEST(BitInject, RssAndLocal) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + auto s0 = dpf::rss::party_seeds::from_bundle(bundle, 0); + auto s1 = dpf::rss::party_seeds::from_bundle(bundle, 1); + auto s2 = dpf::rss::party_seeds::from_bundle(bundle, 2); + const auto y0 = dpf::bit_inject::rss_and_local(s0, 1, 0, 1, 0, 0); + const auto y1 = dpf::bit_inject::rss_and_local(s1, 0, 0, 0, 0, 0); + const auto y2 = dpf::bit_inject::rss_and_local(s2, 0, 1, 0, 1, 0); + EXPECT_EQ(static_cast(y0 ^ y1 ^ y2), 1u); +} + +// --------------------------------------------------------------------------- +// Wave 3 +// --------------------------------------------------------------------------- + +TEST(Trunc, ProbErrorAtMostOne) +{ + const std::uint64_t x0 = 100, x1 = 50; + const auto got = dpf::trunc::trunc_prob_clear(x0, x1, 3); + const auto exact = (x0 + x1) >> 3; + EXPECT_LE(got > exact ? got - exact : exact - got, 1u); +} + +TEST(Trunc, ExactPartyUsesDelta) +{ + const std::uint64_t x = 0x12345; + const std::uint64_t x0 = 0x1111, x1 = x - x0; + auto prep = dpf::trunc::make_trunc_exact_prep(20, 4); + auto [t0, t1] = dpf::trunc::trunc_exact_pair(x0, x1, prep); + EXPECT_EQ(t0 + t1, dpf::trunc::trunc_exact_clear(x0, x1, 20, 4)); + // Changing delta (via different x) changes the party-0 share. + auto [u0, u1] = dpf::trunc::trunc_exact_pair(x0 + 16, x1, prep); + EXPECT_NE(t0, u0); + (void)u1; +} + +TEST(Trunc, MulTruncClear) +{ + auto z = dpf::trunc::mul_trunc_clear(3, 0, 5, 0, 0); + EXPECT_EQ(z.z0 + z.z1, 15u); +} + +TEST(ShareCmp, ReluMaxDivParty) +{ + EXPECT_EQ(dpf::share_cmp::relu_clear(5, 0, 64), 5u); + EXPECT_EQ(dpf::share_cmp::relu_clear(1ull << 63, 0, 64), 0u); + auto [r0, r1] = dpf::share_cmp::relu_party_pair(5, 0, 64); + EXPECT_EQ(r0 + r1, 5u); + auto [m0, m1] = dpf::share_cmp::max_party_pair(3, 0, 9, 0, 64); + EXPECT_EQ(m0 + m1, 9u); + const std::uint64_t hi = 1ull << 63; + auto prep = dpf::share_cmp::sample_msb_prep(64); + auto gt_hi = dpf::share_cmp::gt_party_pair( + hi + 5, 0, hi, 0, prep, 64); + EXPECT_EQ(static_cast(gt_hi.first ^ gt_hi.second), 1u); + auto gt_lo = dpf::share_cmp::gt_party_pair( + 1, 0, hi, 0, prep, 64); + EXPECT_EQ(static_cast(gt_lo.first ^ gt_lo.second), 0u); + EXPECT_EQ(dpf::share_cmp::div_clear(20, 4), 5u); + auto [q0, q1] = dpf::share_cmp::div_party_pair(20, 0, 4, 0, 16); + EXPECT_EQ(q0 + q1, 5u); + EXPECT_TRUE(dpf::share_cmp::range_ok_clear(15, 4)); +} + +TEST(ShareCmp, Declassify) +{ + auto [a, b] = dpf::share_cmp::share_input(42, 0); + EXPECT_EQ(dpf::share_cmp::declassify(a, b), 42u); +} + +// --------------------------------------------------------------------------- +// Wave 4 +// --------------------------------------------------------------------------- + +TEST(ShareVec, MulDeclassify) +{ + std::vector clear = {1, 2, 3, 4}; + auto [x0, x1] = dpf::share_vec::share(clear); + auto [y0, y1] = dpf::share_vec::share(clear); + auto [z0, z1] = dpf::share_vec::mul(x0, x1, y0, y1); + auto prod = dpf::share_vec::declassify(z0, z1); + for (std::size_t i = 0; i < clear.size(); ++i) + EXPECT_EQ(prod[i], clear[i] * clear[i]); +} + +TEST(FixedShare, MulViaTrunc) +{ + using F = dpf::fixed<16, 16>; + auto a = F::from_integer(3); + auto b = F::from_integer(4); + auto c = F::mul_clear(a, b); + EXPECT_EQ(c.raw >> 16, 12u); + std::vector ca = {a.raw}, cb = {b.raw}; + auto [x0, x1] = dpf::share_vec::share(ca); + auto [y0, y1] = dpf::share_vec::share(cb); + auto [z0, z1] = dpf::fixed_mul_share<16, 16>(x0, x1, y0, y1); + auto got = dpf::share_vec::declassify(z0, z1); + EXPECT_EQ(got[0], c.raw); +} + +TEST(ShareExpr, MulAddDeclassify) +{ + const std::uint64_t x = 6, y = 7, w = 5; + dpf::expr::recorder r0(0), r1(1); + auto [x0, x1] = dpf::share_cmp::share_input(x, 0); + auto [y0, y1] = dpf::share_cmp::share_input(y, 0); + auto [w0, w1] = dpf::share_cmp::share_input(w, 0); + auto hx0 = r0.bind(x0); + auto hy0 = r0.bind(y0); + auto hw0 = r0.bind(w0); + auto hx1 = r1.bind(x1); + auto hy1 = r1.bind(y1); + auto hw1 = r1.bind(w1); + auto pz0 = r0.mul(hx0, hy0); + auto pz1 = r1.mul(hx1, hy1); + dpf::expr::recorder::complete_mul(r0, r1, pz0, pz1); + auto z0 = r0.add(pz0, hw0); + auto z1 = r1.add(pz1, hw1); + auto [s0, s1] = dpf::net::make_memory_sink_pair(1, {sizeof(std::uint64_t)}); + dpf::net::edge_mesh m0; + dpf::net::edge_mesh m1; + m0.sinks.push_back(&s0); + m1.sinks.push_back(&s1); + r0.bind_mesh(std::move(m0)); + r1.bind_mesh(std::move(m1)); + EXPECT_EQ(dpf::expr::recorder::declassify(r0, r1, z0, z1), + 47u); +} + +TEST(ShareExpr, BandArity) +{ + dpf::expr::recorder r0(0), r1(1); + // XOR shares of bits 1,1,1 + auto a0 = r0.bind(1); + auto b0 = r0.bind(1); + auto c0 = r0.bind(1); + auto a1 = r1.bind(0); + auto b1 = r1.bind(0); + auto c1 = r1.bind(0); + auto o0 = r0.band({a0, b0, c0}); + auto o1 = r1.band({a1, b1, c1}); + EXPECT_EQ(r0.last_and_arity(), 3u); + dpf::expr::recorder::complete_band(r0, r1, o0, o1); + EXPECT_EQ(static_cast( + r0.local_value(o0) + ^ r1.local_value(o1)), + 1u); +} + +TEST(Gilboa, MulFromOtMatchesClear) +{ + auto packs = dpf::ot::sample_dealer_pair(16, 0, 16); + const std::uint64_t x0 = 30, x1 = 12, y0 = 3, y1 = 4; + auto prod = dpf::gilboa::mul_from_ot_pair(packs.first, packs.second, x0, x1, + y0, y1, 16); + EXPECT_EQ(prod.z0 + prod.z1, dpf::gilboa::mul_clear(x0, x1, y0, y1)); +} + +TEST(Gilboa, FillTapeOtRepeatedWire) +{ + dpf::beavers::session s; + auto a = s.input(); + auto out = s.product(a, a); + s.pin(out); + auto packs = dpf::ot::sample_dealer_pair(0, 0, 32); + auto tapes = dpf::gilboa::fill_tape_ot_pair(s, packs.first, packs.second); + ASSERT_FALSE(tapes.first.monomial.empty()); + ASSERT_GT(tapes.first.lambda.size(), 0u); + const auto lam = tapes.first.lambda[a.id()] + tapes.second.lambda[a.id()]; + const auto mono = tapes.first.monomial[0] + tapes.second.monomial[0]; + EXPECT_EQ(mono, lam * lam); +} + +TEST(Gilboa, FillTapeDealer) +{ + dpf::beavers::session s; + auto a = s.input(); + auto b = s.input(); + auto out = s.product(a, b); + s.pin(out); + auto tape = dpf::gilboa::fill_tape_dealer(s, 0); + EXPECT_FALSE(tape.lambda.empty()); +} + +// --------------------------------------------------------------------------- +// Wave 5 +// --------------------------------------------------------------------------- + +TEST(Matmul, EightByEight) +{ + dpf::matmul::dims d{8, 8, 8}; + std::vector x(64), y(64); + for (std::size_t i = 0; i < 64; ++i) + { + x[i] = i + 1; + y[i] = (i % 8) + 1; + } + auto clear = dpf::matmul::clear_mul(x, y, d); + auto [z0, z1] = dpf::matmul::mul_shared(x, y, d); + for (std::size_t i = 0; i < clear.size(); ++i) + EXPECT_EQ(z0[i] + z1[i], clear[i]); +} + +TEST(Shuffle, CliqueSendNext) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + std::vector v(8); + std::iota(v.begin(), v.end(), 0); + const std::size_t n = v.size(); + dpf::shuffle::shuffle_party_view held[3]; + for (auto & h : held) + { + h.own.assign(n, 0); + h.next.assign(n, 0); + } + for (std::size_t i = 0; i < n; ++i) + { + const auto a = dpf::uniform_sample(); + const auto b = dpf::uniform_sample(); + const auto c = static_cast(v[i] - a - b); + held[0].own[i] = a; + held[0].next[i] = b; + held[1].own[i] = b; + held[1].next[i] = c; + held[2].own[i] = c; + held[2].next[i] = a; + } + dpf::shuffle::shuffle_party_view perm[3]; + for (unsigned p = 0; p < 3; ++p) + perm[p] = dpf::shuffle::shuffle_party(held[p], bundle, 0); + auto clique = dpf::net::make_memory_clique(3, 1, {n * sizeof(std::uint64_t)}); + auto send = [&](std::size_t from, std::size_t to, + const std::vector & data) { + std::vector buf(n * sizeof(std::uint64_t)); + std::memcpy(buf.data(), data.data(), buf.size()); + clique.end(from, to).submit(0, 0, buf.data(), buf.size()); + clique.end(from, to).flush(); + }; + send(0, 1, perm[0].own); + send(1, 2, perm[1].own); + send(2, 0, perm[2].own); + auto recv = [&](std::size_t me, std::size_t from) { + auto & sink = clique.end(me, from); + unsigned spins = 0; + while (!sink.peer_ready(0, 0)) + { + sink.poll(); + if (++spins > 100000u) + throw std::runtime_error("shuffle peer"); + } + std::vector buf(n * sizeof(std::uint64_t)); + sink.read_peer(0, 0, buf.data(), buf.size()); + std::vector out(n); + std::memcpy(out.data(), buf.data(), buf.size()); + return out; + }; + auto r0 = dpf::shuffle::shuffle_refresh(perm[0].own, recv(0, 2)); + auto r1 = dpf::shuffle::shuffle_refresh(perm[1].own, recv(1, 0)); + auto r2 = dpf::shuffle::shuffle_refresh(perm[2].own, recv(2, 1)); + std::vector opened(n); + for (std::size_t i = 0; i < n; ++i) + opened[i] = r0.own[i] + r1.own[i] + r2.own[i]; + EXPECT_TRUE(dpf::shuffle::is_permutation_of(v, opened)); + EXPECT_EQ(opened, dpf::shuffle::shuffle_clear(v, bundle, 0)); +} + +TEST(Compose, CheckOpenHashRing) +{ + const std::uint64_t word = 42; + auto run = [](std::uint64_t w0, std::uint64_t w1, std::uint64_t w2) { + auto clique = dpf::net::make_memory_clique(3, 1, {8}); + std::uint8_t b0[8], b1[8], b2[8]; + std::memcpy(b0, &w0, 8); + std::memcpy(b1, &w1, 8); + std::memcpy(b2, &w2, 8); + std::exception_ptr err; + std::thread t0([&] { + try + { + dpf::protocol::exchange_check_hash_ring(clique.end(0, 1), + clique.end(0, 2), b0, 8); + } + catch (...) + { + err = std::current_exception(); + } + }); + std::thread t1([&] { + try + { + dpf::protocol::exchange_check_hash_ring(clique.end(1, 2), + clique.end(1, 0), b1, 8); + } + catch (...) + { + err = std::current_exception(); + } + }); + std::thread t2([&] { + try + { + dpf::protocol::exchange_check_hash_ring(clique.end(2, 0), + clique.end(2, 1), b2, 8); + } + catch (...) + { + err = std::current_exception(); + } + }); + t0.join(); + t1.join(); + t2.join(); + return err; + }; + EXPECT_TRUE(run(word, word, word) == nullptr); + EXPECT_TRUE(run(word, word ^ 1u, word) != nullptr); +} + +TEST(Compose, TruncExactKernel) +{ + dpf::protocol::composer c(0); + auto x = c.input(domain::a, 8); + auto r = c.input(domain::a, 8); + auto delta = c.input(domain::a, 8); + auto wrap = c.input(domain::a, 8); + auto out = c.trunc_exact_open(x, r, delta, wrap, 4); + auto p = c.default_plan(); + std::vector> values(p.nodes().size()); + auto put = [&](dpf::protocol::node n, std::uint64_t v) { + values[n.id].assign(8, 0); + std::memcpy(values[n.id].data(), &v, 8); + }; + put(x, 0x20); + put(r, 0x5); + put(delta, 0x10); + put(wrap, 1); + dpf::protocol::drive_options opt; + dpf::protocol::detail::run_arith_local(p, out.id, 0, 0, 1, values, opt); + std::uint64_t got = 0; + std::memcpy(&got, values[out.id].data(), 8); + const auto expect = dpf::trunc::trunc_exact_party( + 0x20, 0x5, 0x10, 1, 4, 0, 0); + EXPECT_EQ(got, expect); +} + +TEST(Compose, B2aOpenMatchesClear) +{ + constexpr unsigned ell = 8; + const std::uint64_t x = 0x3c; + dpf::protocol::composer c(0); + auto bits = c.input(domain::bin, 1); + auto rbits = c.input(domain::bin, 1); + auto rarith = c.input(domain::a, ell * 8); + auto out = c.bin_b2a(bits, rbits, rarith, ell); + auto p = c.default_plan(); + std::vector> v0(p.nodes().size()); + std::vector> v1(p.nodes().size()); + std::uint8_t b0 = static_cast(x), b1 = 0, rb0 = 0, rb1 = 0; + std::uint64_t a0[ell]{}, a1[ell]{}; + for (unsigned i = 0; i < ell; ++i) + { + auto d = dpf::ot::sample_dabit_pair(); + if (d.p0.bit) + rb0 = static_cast(rb0 | (1u << i)); + if (d.p1.bit) + rb1 = static_cast(rb1 | (1u << i)); + a0[i] = d.p0.arith; + a1[i] = d.p1.arith; + } + put_raw(v0, bits, &b0, 1); + put_raw(v1, bits, &b1, 1); + put_raw(v0, rbits, &rb0, 1); + put_raw(v1, rbits, &rb1, 1); + put_raw(v0, rarith, a0, sizeof a0); + put_raw(v1, rarith, a1, sizeof a1); + drive_both(p, v0, v1); + std::uint64_t z0 = 0, z1 = 0; + std::memcpy(&z0, v0[out.id].data(), 8); + std::memcpy(&z1, v1[out.id].data(), 8); + EXPECT_EQ(z0 + z1, x); +} + +TEST(Compose, MulTruncOpen) +{ + const std::uint64_t x = 6, y = 7; + const std::uint64_t x0 = 100, x1 = x - 100, y0 = 9, y1 = y - 9; + const std::uint64_t a0 = 3, a1 = 5, b0 = 8, b1 = 1; + const std::uint64_t c = (a0 + a1) * (b0 + b1); + const std::uint64_t c0 = 20, c1 = c - 20; + dpf::protocol::composer comp(0); + auto nx = comp.input(domain::a, 8); + auto ny = comp.input(domain::a, 8); + auto na = comp.input(domain::a, 8); + auto nb = comp.input(domain::a, 8); + auto nc = comp.input(domain::a, 8); + auto out = comp.mul_trunc_open(nx, ny, na, nb, nc, 0); + auto p = comp.default_plan(); + std::vector> v0(p.nodes().size()); + std::vector> v1(p.nodes().size()); + put_raw(v0, nx, &x0, 8); + put_raw(v1, nx, &x1, 8); + put_raw(v0, ny, &y0, 8); + put_raw(v1, ny, &y1, 8); + put_raw(v0, na, &a0, 8); + put_raw(v1, na, &a1, 8); + put_raw(v0, nb, &b0, 8); + put_raw(v1, nb, &b1, 8); + put_raw(v0, nc, &c0, 8); + put_raw(v1, nc, &c1, 8); + drive_both(p, v0, v1); + std::uint64_t z0 = 0, z1 = 0; + std::memcpy(&z0, v0[out.id].data(), 8); + std::memcpy(&z1, v1[out.id].data(), 8); + EXPECT_EQ(z0 + z1, x * y); +} + +TEST(Compose, InjectAndMuxOpen) +{ + auto tp = dpf::ot::sample_bit_ring_triple_pair(); + dpf::protocol::composer c(0); + auto bit = c.input(domain::a, 8); + auto x = c.input(domain::a, 8); + auto a = c.input(domain::a, 8); + auto b = c.input(domain::a, 8); + auto cc = c.input(domain::a, 8); + auto prod = c.bin_inject(bit, x, a, b, cc); + auto plan = c.default_plan(); + std::vector> v0(plan.nodes().size()); + std::vector> v1(plan.nodes().size()); + const std::uint64_t one = 1, zero = 0; + const std::uint64_t x0 = 20, x1 = 22; + const std::uint64_t a0 = tp.p0.a, a1 = tp.p1.a; + put_raw(v0, bit, &one, 8); + put_raw(v1, bit, &zero, 8); + put_raw(v0, x, &x0, 8); + put_raw(v1, x, &x1, 8); + put_raw(v0, a, &a0, 8); + put_raw(v1, a, &a1, 8); + put_raw(v0, b, &tp.p0.b, 8); + put_raw(v1, b, &tp.p1.b, 8); + put_raw(v0, cc, &tp.p0.c, 8); + put_raw(v1, cc, &tp.p1.c, 8); + drive_both(plan, v0, v1); + std::uint64_t z0 = 0, z1 = 0; + std::memcpy(&z0, v0[prod.id].data(), 8); + std::memcpy(&z1, v1[prod.id].data(), 8); + EXPECT_EQ(z0 + z1, x0 + x1); +} + +TEST(Compose, GmwAndOpen) +{ + auto tp = dpf::ot::sample_bit_triple_pair(); + dpf::protocol::composer c(0); + auto p0 = c.input(domain::bin, 1); + auto q0 = c.input(domain::bin, 1); + auto a = c.input(domain::bin, 1); + auto b = c.input(domain::bin, 1); + auto cc = c.input(domain::bin, 1); + auto out = c.gmw_and(p0, q0, a, b, cc); + auto plan = c.default_plan(); + std::vector> v0(plan.nodes().size()); + std::vector> v1(plan.nodes().size()); + const std::uint8_t one = 1, zero = 0; + put_raw(v0, p0, &one, 1); + put_raw(v1, p0, &zero, 1); + put_raw(v0, q0, &one, 1); + put_raw(v1, q0, &zero, 1); + put_raw(v0, a, &tp.p0.a, 1); + put_raw(v1, a, &tp.p1.a, 1); + put_raw(v0, b, &tp.p0.b, 1); + put_raw(v1, b, &tp.p1.b, 1); + put_raw(v0, cc, &tp.p0.c, 1); + put_raw(v1, cc, &tp.p1.c, 1); + drive_both(plan, v0, v1); + EXPECT_EQ(static_cast(v0[out.id][0] ^ v1[out.id][0]), 1u); +} + +TEST(Gilboa, FillTapeOtReadsStash) +{ + dpf::beavers::session s; + auto a = s.input(); + auto out = s.product(a, a); + s.pin(out); + auto packs = dpf::ot::sample_dealer_pair(0, 0, 32); + auto tapes = dpf::gilboa::fill_tape_ot_pair(s, packs.first, packs.second); + auto again = dpf::gilboa::fill_tape_ot(s, packs.first, 0); + EXPECT_EQ(again.lambda, tapes.first.lambda); + EXPECT_EQ(again.monomial, tapes.first.monomial); + dpf::ot::pack bare; + EXPECT_THROW(dpf::gilboa::fill_tape_ot(s, bare, 0), std::runtime_error); +} + +TEST(BitInject, RssAndRefresh) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + auto s0 = dpf::rss::party_seeds::from_bundle(bundle, 0); + auto s1 = dpf::rss::party_seeds::from_bundle(bundle, 1); + auto s2 = dpf::rss::party_seeds::from_bundle(bundle, 2); + const auto e0 = dpf::bit_inject::rss_and_local(s0, 1, 0, 1, 0, 0); + const auto e1 = dpf::bit_inject::rss_and_local(s1, 0, 0, 0, 0, 0); + const auto e2 = dpf::bit_inject::rss_and_local(s2, 0, 1, 0, 1, 0); + auto clique = dpf::net::make_memory_clique(3, 1, {1}); + auto send = [&](std::size_t from, std::size_t to, std::uint8_t byte) { + clique.end(from, to).submit(0, 0, &byte, 1); + clique.end(from, to).flush(); + }; + send(0, 1, e0); + send(1, 2, e1); + send(2, 0, e2); + auto recv = [&](std::size_t me, std::size_t from) { + auto & sink = clique.end(me, from); + unsigned spins = 0; + while (!sink.peer_ready(0, 0)) + { + sink.poll(); + if (++spins > 100000u) + throw std::runtime_error("rss and peer"); + } + std::uint8_t b = 0; + sink.read_peer(0, 0, &b, 1); + return b; + }; + EXPECT_EQ(recv(0, 2), e2); + EXPECT_EQ(recv(1, 0), e0); + EXPECT_EQ(recv(2, 1), e1); + EXPECT_EQ(static_cast(e0 ^ e1 ^ e2), 1u); +} + +TEST(Shuffle, SelectSumCountArgmax) +{ + std::vector pred = {1, 0, 1, 1}; + std::vector row = {10, 20, 30, 40}; + EXPECT_EQ(dpf::shuffle::sum_if_clear(pred, row), 80u); + EXPECT_EQ(dpf::shuffle::count_if_clear(pred), 3u); + auto am = dpf::shuffle::argmax_clear(row, 64); + EXPECT_EQ(am.value, 40u); + EXPECT_EQ(am.one_hot[3], 1); +} + +TEST(Circuit, MulOpenFromDealerFile) +{ + dpf::mpc::circuit c(2); + auto x = c.input(); + auto y = c.input(); + auto prod = c.mul(x, y); + auto opened = c.open(prod); + auto views = dpf::prep::deal_views(c.prep()); + const auto path0 = std::string{"/tmp/libdpf-prep-p0.bin"}; + const auto path1 = std::string{"/tmp/libdpf-prep-p1.bin"}; + dpf::prep::write_file(path0, views.first); + dpf::prep::write_file(path1, views.second); + auto loaded0 = dpf::prep::read_file(path0); + auto loaded1 = dpf::prep::read_file(path1); + EXPECT_EQ(loaded0, views.first); + EXPECT_EQ(loaded1, views.second); + std::uint64_t got[2]{}; + dpf::run::threads_2(c.slot_bytes(), [&](unsigned party, dpf::net::RoundSink & sink) { + dpf::mpc::party me(c, party); + me.bind(x, party == 0 ? 6 : 0); + me.bind(y, party == 0 ? 7 : 0); + auto bytes = party == 0 ? loaded0 : loaded1; + me.run(sink, dpf::prep::cursor(std::move(bytes))); + got[party] = me.read(opened); + }); + EXPECT_EQ(got[0], 42u); + EXPECT_EQ(got[1], 42u); +} + +TEST(Circuit, PrivateInputAndTcpPrep) +{ + dpf::mpc::circuit c(8); + auto secret = c.priv_input(0); + auto opened = c.open(secret); + std::atomic port{0}; + std::vector view0, view1; + std::thread listener([&] { + dpf::run::tcp_pair(0, "127.0.0.1", port, [&](dpf::net::channel & ch) { + view0 = dpf::prep::setup_2pc_sampled(ch, 0, c.prep()); + }); + }); + while (port.load() == 0) + std::this_thread::yield(); + std::thread dialer([&] { + dpf::run::tcp_pair(1, "127.0.0.1", port, [&](dpf::net::channel & ch) { + view1 = dpf::prep::setup_2pc_sampled(ch, 1, c.prep()); + }); + }); + listener.join(); + dialer.join(); + EXPECT_FALSE(view0.empty()); + EXPECT_FALSE(view1.empty()); + std::uint64_t got[2]{}; + dpf::run::threads_2(c.slot_bytes(), [&](unsigned party, dpf::net::RoundSink & sink) { + dpf::mpc::party me(c, party); + if (party == 0) + me.bind_priv(secret, 42); + auto bytes = party == 0 ? view0 : view1; + me.run(sink, dpf::prep::cursor(std::move(bytes))); + got[party] = me.read(opened); + }); + EXPECT_EQ(got[0], 42u); + EXPECT_EQ(got[1], 42u); + EXPECT_GE(dpf::revealing::known_count, 2u); +} + +TEST(Run, ThreePartyDeclassify) +{ + const std::uint64_t shares[3] = {10, 20, 12}; + std::uint64_t opened[3]{}; + dpf::run::threads_on_clique(3, {8}, [&](unsigned me, dpf::net::memory_clique & clique) { + std::uint8_t mine[8]{}, sum[8]{}; + std::memcpy(mine, &shares[me], 8); + dpf::run::declassify_ring(clique, me, mine, 8, sum); + std::memcpy(&opened[me], sum, 8); + }); + EXPECT_EQ(opened[0], 42u); + EXPECT_EQ(opened[1], 42u); + EXPECT_EQ(opened[2], 42u); +} + +TEST(CostPass, EmptyPlanNoSynthetic) +{ + dpf::protocol::composer c(0); + auto p = c.default_plan(); + auto r_rounds = dpf::cost::annotate(p, + dpf::beavers::schedule_objective::rounds); + auto r_prep = dpf::cost::annotate(p, dpf::beavers::schedule_objective::prep); + EXPECT_TRUE(r_rounds.choices.empty()); + EXPECT_TRUE(r_prep.choices.empty()); +} + +TEST(CostPass, RealCmpGetsChoice) +{ + dpf::protocol::composer c(0); + auto x = c.input(domain::a, 8); + auto y = c.input(domain::a, 8); + (void)c.share_gt(x, y); + auto p = c.default_plan(); + auto r = dpf::cost::annotate(p, dpf::beavers::schedule_objective::rounds); + ASSERT_FALSE(r.choices.empty()); + EXPECT_EQ(r.choices[0].pick, dpf::cost::strategy::dcf_mask); +} + +TEST(StreamArray, MemoryDealerRingTriple) +{ + auto w0 = dpf::net::make_memory_stream_pair(1); + auto w1 = dpf::net::make_memory_stream_pair(1); + dpf::factory::make_dealer(w0.first, w1.first, 1, [] { + return dpf::factory::deal_ring_triple(2); + }); + auto v0 = dpf::factory::detail::read_pod( + w0.second, 0); + auto v1 = dpf::factory::detail::read_pod( + w1.second, 0); + std::uint64_t a0 = 0, b0 = 0, c0 = 0, a1 = 0, b1 = 0, c1 = 0; + std::memcpy(&a0, v0.a, 2); + std::memcpy(&b0, v0.b, 2); + std::memcpy(&c0, v0.c, 2); + std::memcpy(&a1, v1.a, 2); + std::memcpy(&b1, v1.b, 2); + std::memcpy(&c1, v1.c, 2); + const std::uint64_t mask = 0xffffu; + EXPECT_EQ(((a0 + a1) * (b0 + b1)) & mask, (c0 + c1) & mask); +} + +TEST(StreamArray, FileDealerRoundTrip) +{ + const std::string base = "/tmp/libdpf-stream-arr"; + { + dpf::net::file_stream_array out0(base + "-p0", 1, true); + dpf::net::file_stream_array out1(base + "-p1", 1, true); + dpf::factory::make_dealer(out0, out1, 1, [] { + return dpf::factory::deal_ring_triple(2); + }); + } + dpf::net::file_stream_array in0(base + "-p0", 1, false); + dpf::net::file_stream_array in1(base + "-p1", 1, false); + auto v0 = dpf::factory::detail::read_pod( + in0, 0); + auto v1 = dpf::factory::detail::read_pod( + in1, 0); + std::uint64_t a0 = 0, b0 = 0, c0 = 0, a1 = 0, b1 = 0, c1 = 0; + std::memcpy(&a0, v0.a, 2); + std::memcpy(&b0, v0.b, 2); + std::memcpy(&c0, v0.c, 2); + std::memcpy(&a1, v1.a, 2); + std::memcpy(&b1, v1.b, 2); + std::memcpy(&c1, v1.c, 2); + EXPECT_EQ(((a0 + a1) * (b0 + b1)) & 0xffffu, (c0 + c1) & 0xffffu); +} + +TEST(StreamArray, MuxLocalhostDealer) +{ + std::atomic port{0}; + dpf::factory::ring_triple_view got0{}, got1{}; + std::thread t0([&] { + dpf::run::tcp_pair_mux(0, "127.0.0.1", port, 1, + [&](unsigned, dpf::net::mux_stream_array & mux) { + // Party 0 acts as dealer write end toward party 1, and also + // keeps a local memory view for itself. + auto local = dpf::net::make_memory_stream_pair(1); + dpf::factory::make_dealer(local.first, mux, 1, [] { + return dpf::factory::deal_ring_triple(2); + }); + got0 = dpf::factory::detail::read_pod< + dpf::factory::ring_triple_view>(local.second, 0); + }); + }); + while (port.load() == 0) + std::this_thread::yield(); + std::thread t1([&] { + dpf::run::tcp_pair_mux(1, "127.0.0.1", port, 1, + [&](unsigned, dpf::net::mux_stream_array & mux) { + got1 = dpf::factory::detail::read_pod< + dpf::factory::ring_triple_view>(mux, 0); + }); + }); + t0.join(); + t1.join(); + std::uint64_t a0 = 0, b0 = 0, c0 = 0, a1 = 0, b1 = 0, c1 = 0; + std::memcpy(&a0, got0.a, 2); + std::memcpy(&b0, got0.b, 2); + std::memcpy(&c0, got0.c, 2); + std::memcpy(&a1, got1.a, 2); + std::memcpy(&b1, got1.b, 2); + std::memcpy(&c1, got1.c, 2); + EXPECT_EQ(((a0 + a1) * (b0 + b1)) & 0xffffu, (c0 + c1) & 0xffffu); +} + +TEST(Factory, GmwAndRoundMemory) +{ + auto peer = dpf::net::make_memory_stream_pair(1); + auto d0 = dpf::net::make_memory_stream_pair(1); + auto d1 = dpf::net::make_memory_stream_pair(1); + dpf::factory::make_dealer(d0.first, d1.first, 1, + dpf::factory::make_gmw_and_dealer_functor()); + std::uint8_t z0 = 0, z1 = 0; + auto fac0 = dpf::factory::make_protocol_factory( + dpf::factory::gmw_and_round0{}, dpf::factory::gmw_and_round1{0}); + auto fac1 = dpf::factory::make_protocol_factory( + dpf::factory::gmw_and_round0{}, dpf::factory::gmw_and_round1{1}); + std::thread t0([&] { + auto p = fac0.create(1, peer.first, d0.second); + z0 = p(0, std::pair{1, 1}); + }); + std::thread t1([&] { + auto p = fac1.create(1, peer.second, d1.second); + z1 = p(0, std::pair{0, 0}); + }); + t0.join(); + t1.join(); + EXPECT_EQ(static_cast(z0 ^ z1), 1u); +} + +TEST(Circuit, MulOpenFromStreamArray) +{ + dpf::mpc::circuit c(2); + auto x = c.input(); + auto y = c.input(); + auto prod = c.mul(x, y); + auto opened = c.open(prod); + auto views = dpf::prep::deal_views(c.prep()); + auto w0 = dpf::net::make_memory_stream_pair(1); + auto w1 = dpf::net::make_memory_stream_pair(1); + w0.first.write(0, views.first.data(), views.first.size()); + w0.first.flush(0); + w1.first.write(0, views.second.data(), views.second.size()); + w1.first.flush(0); + const std::size_t nbytes = views.first.size(); + std::uint64_t got[2]{}; + dpf::run::threads_2(c.slot_bytes(), [&](unsigned party, dpf::net::RoundSink & sink) { + dpf::mpc::party me(c, party); + me.bind(x, party == 0 ? 6 : 0); + me.bind(y, party == 0 ? 7 : 0); + auto & dealer = party == 0 ? w0.second : w1.second; + me.run(sink, dealer, nbytes); + got[party] = me.read(opened); + }); + EXPECT_EQ(got[0], 42u); + EXPECT_EQ(got[1], 42u); +} + +TEST(StreamArray, MultiRoundSinkExchange) +{ + constexpr std::size_t slot = 8; + dpf::run::threads_2_streams(2, [&](unsigned party, dpf::net::stream_array & sa) { + dpf::net::stream_array_sink sink(sa, std::vector{slot, slot}); + const std::uint64_t mine = party == 0 ? 11u : 22u; + std::uint8_t buf[slot]{}; + std::memcpy(buf, &mine, sizeof(mine)); + sink.submit(0, 0, buf, slot); + sink.flush_round(0); + EXPECT_TRUE(sink.peer_ready(0, 0)); + std::uint8_t peer0[slot]{}; + sink.read_peer(0, 0, peer0, slot); + const std::uint64_t other0 = party == 0 ? 22u : 11u; + std::uint64_t got0 = 0; + std::memcpy(&got0, peer0, slot); + EXPECT_EQ(got0, other0); + const std::uint64_t mine1 = mine + 1u; + std::memcpy(buf, &mine1, sizeof(mine1)); + sink.submit(1, 0, buf, slot); + sink.flush_round(1); + std::uint8_t peer1[slot]{}; + sink.read_peer(1, 0, peer1, slot); + std::uint64_t got1 = 0; + std::memcpy(&got1, peer1, slot); + EXPECT_EQ(got1, other0 + 1u); + }); +} + +TEST(Run, ThreePartyDeclassifyStreamClique) +{ + const std::uint64_t shares[3] = {10, 20, 12}; + std::uint64_t opened[3]{}; + auto clique = dpf::net::make_memory_stream_clique(3, 1); + std::exception_ptr err; + std::mutex mu; + std::vector ts; + for (unsigned me = 0; me < 3; ++me) + { + ts.emplace_back([&, me] { + try + { + std::uint8_t mine[8]{}, sum[8]{}; + std::memcpy(mine, &shares[me], 8); + dpf::run::declassify_streams(clique, me, mine, 8, sum); + std::memcpy(&opened[me], sum, 8); + } + catch (...) + { + std::lock_guard lock(mu); + if (!err) + err = std::current_exception(); + } + }); + } + for (auto & t : ts) + t.join(); + if (err) + std::rethrow_exception(err); + EXPECT_EQ(opened[0], 42u); + EXPECT_EQ(opened[1], 42u); + EXPECT_EQ(opened[2], 42u); +} + +TEST(Factory, BeaverMulStreamMemory) +{ + auto peer = dpf::net::make_memory_stream_pair(2); + auto d0 = dpf::net::make_memory_stream_pair(1); + auto d1 = dpf::net::make_memory_stream_pair(1); + dpf::factory::make_dealer(d0.first, d1.first, 1, + dpf::factory::make_beaver_mul_dealer_functor()); + const std::uint64_t x0 = 6, x1 = 0, y0 = 7, y1 = 0; + std::uint64_t z0 = 0, z1 = 0; + auto fac = dpf::factory::make_beaver_mul_factory( + dpf::factory::beaver_mul_round0{8}, + dpf::factory::beaver_mul_round1{8, 0}); + auto fac1 = dpf::factory::make_beaver_mul_factory( + dpf::factory::beaver_mul_round0{8}, + dpf::factory::beaver_mul_round1{8, 1}); + std::thread t0([&] { + auto p = fac.create(1, peer.first, d0.second); + z0 = p(0, dpf::factory::beaver_mul_input{x0, y0}); + }); + std::thread t1([&] { + auto p = fac1.create(1, peer.second, d1.second); + z1 = p(0, dpf::factory::beaver_mul_input{x1, y1}); + }); + t0.join(); + t1.join(); + EXPECT_EQ(z0 + z1, 42u); +} + +TEST(Circuit, RecordsGmwAndA2bGtTruncMux) +{ + dpf::mpc::circuit c(8); + auto x = c.input(); + auto y = c.input(); + auto b0 = c.input(); + auto b1 = c.input(); + (void)c.gmw_and(b0, b1); + (void)c.a2b(x, 8); + (void)c.gt(x, y, 8); + (void)c.trunc_exact(x, 16, 4); + (void)c.mux(b0, x, y); + EXPECT_GE(c.prep().bit_triples, 1u); + EXPECT_GE(c.prep().ring_triples, 1u); + EXPECT_GE(c.prep().dabits, 1u); + EXPECT_FALSE(c.slot_bytes().empty()); +} + +TEST(Factory, MuxOnlineStreamMemory) +{ + auto peer = dpf::net::make_memory_stream_pair(2); + auto d0 = dpf::net::make_memory_stream_pair(1); + auto d1 = dpf::net::make_memory_stream_pair(1); + dpf::factory::make_dealer(d0.first, d1.first, 1, + [] { return dpf::factory::deal_ring_triple(8); }); + std::uint64_t z0 = 0, z1 = 0; + std::thread t0([&] { + z0 = dpf::factory::mux_online(0, 1, 40, 2, peer.first, d0.second); + }); + std::thread t1([&] { + z1 = dpf::factory::mux_online(1, 0, 0, 0, peer.second, d1.second); + }); + t0.join(); + t1.join(); + EXPECT_EQ(z0 + z1, 40u); +} + +namespace +{ + +std::uint64_t xor_bit_shares(std::uint64_t s0, std::uint64_t s1, unsigned width) +{ + const std::uint64_t mask = + width >= 64 ? ~std::uint64_t{0} : ((std::uint64_t{1} << width) - 1u); + return (s0 ^ s1) & mask; +} + +} // namespace + +TEST(Factory, A2bTapeOnline) +{ + constexpr unsigned width = 8; + auto peer = dpf::net::make_memory_stream_pair(2); + auto d0 = dpf::net::make_memory_stream_pair(2); + auto d1 = dpf::net::make_memory_stream_pair(2); + dpf::factory::deal_a2b_tape(width, 8, d0.first, d1.first); + const std::uint64_t x0 = 30, x1 = 12; + std::uint64_t b0 = 0, b1 = 0; + std::thread t0([&] { + b0 = dpf::factory::a2b_online(0, x0, width, peer.first, d0.second); + }); + std::thread t1([&] { + b1 = dpf::factory::a2b_online(1, x1, width, peer.second, d1.second); + }); + t0.join(); + t1.join(); + EXPECT_EQ(xor_bit_shares(b0, b1, width), x0 + x1); +} + +TEST(Factory, TruncTapeOnline) +{ + constexpr unsigned n = 20, s = 4; + auto peer = dpf::net::make_memory_stream_pair(2); + auto d0 = dpf::net::make_memory_stream_pair(2); + auto d1 = dpf::net::make_memory_stream_pair(2); + dpf::factory::deal_trunc_tape(n, s, 8, d0.first, d1.first); + const std::uint64_t x = 0xabcde; + const std::uint64_t x0 = 0x11111, x1 = x - x0; + std::uint64_t t0 = 0, t1 = 0; + std::thread t0th([&] { + t0 = dpf::factory::trunc_exact_online(0, x0, n, s, peer.first, + d0.second); + }); + std::thread t1th([&] { + t1 = dpf::factory::trunc_exact_online(1, x1, n, s, peer.second, + d1.second); + }); + t0th.join(); + t1th.join(); + EXPECT_EQ(t0 + t1, dpf::trunc::trunc_exact_clear(x0, x1, n, s)); +} + +TEST(Factory, GtTapeOnline) +{ + constexpr unsigned width = 8; + auto peer = dpf::net::make_memory_stream_pair(5); + auto d0 = dpf::net::make_memory_stream_pair(5); + auto d1 = dpf::net::make_memory_stream_pair(5); + dpf::factory::deal_gt_tape(width, 8, d0.first, d1.first); + const std::uint64_t x0 = 50, x1 = 7, y0 = 10, y1 = 20; + std::uint8_t g0 = 0, g1 = 0; + std::thread t0([&] { + g0 = dpf::factory::gt_online(0, x0, y0, width, peer.first, d0.second); + }); + std::thread t1([&] { + g1 = dpf::factory::gt_online(1, x1, y1, width, peer.second, d1.second); + }); + t0.join(); + t1.join(); + const std::uint64_t x = x0 + x1; + const std::uint64_t y = y0 + y1; + const unsigned expect = x > y ? 1u : 0u; + EXPECT_EQ(static_cast(g0 ^ g1), expect); +} + +TEST(StreamArray, DealerCursorFromStreamPrg) +{ + constexpr std::size_t N = 8; + auto d0 = dpf::net::make_memory_stream_pair(1); + auto d1 = dpf::net::make_memory_stream_pair(1); + using Prg = dpf::randomness::aes_buffered_prg; + const auto seed = dpf::randomness::sample_master_seed(); + Prg prg0(seed); + Prg prg1(seed); + dpf::factory::make_dealer_prg(d0.first, d1.first, N, prg0, prg1, + [](Prg & p0, Prg & /*p1*/, std::size_t j) { + auto t = dpf::factory::deal_bit_triple(); + dpf::factory::gmw_and_blind v0{t.first.a, t.first.b, t.first.c}; + dpf::factory::gmw_and_blind v1{t.second.a, t.second.b, t.second.c}; + (void)p0.at<0>(static_cast(j)); + return std::pair{v0, v1}; + }); + dpf::net::stream_dealer_cursor cur0(d0.second, N, + {sizeof(dpf::factory::gmw_and_blind)}); + dpf::net::stream_dealer_cursor cur1(d1.second, N, + {sizeof(dpf::factory::gmw_and_blind)}); + for (std::size_t i = 0; i < N; ++i) + { + const auto v0 = cur0.at(0, i); + const auto v1 = cur1.at(0, i); + const unsigned c = static_cast((v0.c ^ v1.c) & 1u); + const unsigned ab = static_cast( + ((v0.a ^ v1.a) & 1u) & ((v0.b ^ v1.b) & 1u)); + EXPECT_EQ(c, ab); + } +} + +TEST(Factory, ScheduleOnStreams) +{ + auto peer = dpf::net::make_memory_stream_pair(1); + std::vector local0(4), local1(4); + for (std::size_t i = 0; i < 4; ++i) + { + local0[i] = 10 + i; + local1[i] = 100 + i; + } + auto make_rounds = [](std::vector & local) { + std::vector rounds(1); + rounds[0].slot_bytes = sizeof(std::uint64_t); + rounds[0].produce = [&](std::size_t index, const std::uint8_t *, + std::size_t, std::uint8_t * out) { + std::memcpy(out, &local[index], sizeof(std::uint64_t)); + }; + return rounds; + }; + std::uint64_t sum0 = 0, sum1 = 0; + std::thread t0([&] { + auto s = dpf::protocol::make_owning_schedule_on_streams(4, peer.first, + make_rounds(local0)); + for (std::size_t i = 0; i < 4; ++i) + s.submit(i); + s.drive(); + for (std::size_t i = 0; i < 4; ++i) + { + std::uint64_t v = 0; + s.sink->read_peer(0, i, reinterpret_cast(&v), + sizeof(v)); + sum0 += v; + } + }); + std::thread t1([&] { + auto s = dpf::protocol::make_owning_schedule_on_streams(4, peer.second, + make_rounds(local1)); + for (std::size_t i = 0; i < 4; ++i) + s.submit(i); + s.drive(); + for (std::size_t i = 0; i < 4; ++i) + { + std::uint64_t v = 0; + s.sink->read_peer(0, i, reinterpret_cast(&v), + sizeof(v)); + sum1 += v; + } + }); + t0.join(); + t1.join(); + EXPECT_EQ(sum0, 100u + 101u + 102u + 103u); + EXPECT_EQ(sum1, 10u + 11u + 12u + 13u); +} + +TEST(Roles, DealerWriteFilesRoundTrip) +{ + const std::string base = "/tmp/libdpf-roles-prep"; + dpf::prep::demand d; + d.limb = 2; + d.ring_triples = 1; + dpf::roles::dealer_write_files(base, d); + auto curs = dpf::roles::online_open_file_array(base); + std::uint8_t a[8]{}, b[8]{}, c[8]{}; + curs.first.take_ring(a, b, c); + curs.second.take_ring(a, b, c); + EXPECT_EQ(curs.first.limb(), 2); + EXPECT_EQ(curs.second.limb(), 2); +} + +TEST(Compose, DrivePlanOnStreamsOpen) +{ + dpf::protocol::composer c0(0); + dpf::protocol::composer c1(1); + auto x0 = c0.input(domain::a, 8); + auto x1 = c1.input(domain::a, 8); + auto e0 = c0.exchange(x0); + auto e1 = c1.exchange(x1); + auto p0 = c0.schedule(); + auto p1 = c1.schedule(); + std::vector> v0(p0.nodes().size()), + v1(p1.nodes().size()); + const std::uint64_t a = 3, b = 5; + put_raw(v0, x0, &a, 8); + put_raw(v1, x1, &b, 8); + dpf::protocol::drive_both_on_streams(p0, p1, v0, v1); + std::uint64_t open0 = 0, open1 = 0; + std::memcpy(&open0, v0[e0.id].data(), 8); + std::memcpy(&open1, v1[e1.id].data(), 8); + EXPECT_EQ(open0, 8u); + EXPECT_EQ(open1, 8u); +} + +TEST(Compose, DrivePlanOnStreamsTwoWaves) +{ + constexpr std::uint32_t k_step = 91001; + auto make = [](std::size_t party, std::uint64_t in) { + dpf::protocol::composer c(party); + auto x = c.input(domain::a, 8); + auto e0 = c.exchange(x); + auto y = c.compute(k_step, {e0}, domain::a, 8); + auto e1 = c.exchange(y); + return std::make_tuple(c.schedule(), x, e1, in); + }; + auto [p0, x0, out0, in0] = make(0, 11); + auto [p1, x1, out1, in1] = make(1, 19); + ASSERT_EQ(p0.rounds(), 2u); + dpf::protocol::kernel_fn step = [](std::uint32_t, const std::vector &, + const std::vector & inputs, + dpf::protocol::block_span output, std::size_t) { + std::uint64_t v = 0; + std::memcpy(&v, inputs[0].at(0), 8); + v += 1; + std::memcpy(output.at(0), &v, 8); + }; + std::map k{{k_step, step}}; + std::vector> v0(p0.nodes().size()), + v1(p1.nodes().size()); + put_raw(v0, x0, &in0, 8); + put_raw(v1, x1, &in1, 8); + dpf::protocol::drive_both_on_streams(p0, p1, v0, v1, k); + std::uint64_t o0 = 0, o1 = 0; + std::memcpy(&o0, v0[out0.id].data(), 8); + std::memcpy(&o1, v1[out1.id].data(), 8); + EXPECT_EQ(o0, 62u); + EXPECT_EQ(o1, 62u); +} + +TEST(Compose, DrivePlanOnStreamsGmwAnd) +{ + auto tp = dpf::ot::sample_bit_triple_pair(); + dpf::protocol::composer c(0); + auto p0 = c.input(domain::bin, 1); + auto q0 = c.input(domain::bin, 1); + auto a = c.input(domain::bin, 1); + auto b = c.input(domain::bin, 1); + auto cc = c.input(domain::bin, 1); + auto out = c.gmw_and(p0, q0, a, b, cc); + auto plan = c.default_plan(); + std::vector> v0(plan.nodes().size()); + std::vector> v1(plan.nodes().size()); + const std::uint8_t one = 1, zero = 0; + put_raw(v0, p0, &one, 1); + put_raw(v1, p0, &zero, 1); + put_raw(v0, q0, &one, 1); + put_raw(v1, q0, &zero, 1); + put_raw(v0, a, &tp.p0.a, 1); + put_raw(v1, a, &tp.p1.a, 1); + put_raw(v0, b, &tp.p0.b, 1); + put_raw(v1, b, &tp.p1.b, 1); + put_raw(v0, cc, &tp.p0.c, 1); + put_raw(v1, cc, &tp.p1.c, 1); + dpf::protocol::drive_both_on_streams(plan, v0, v1); + EXPECT_EQ(static_cast(v0[out.id][0] ^ v1[out.id][0]), 1u); +} + +TEST(Compose, DrivePlanOnStreamsDeepEightWaves) +{ + // Gap-1 stress: eight successive opens on stream arrays (FSS-depth shape). + auto make = [](std::size_t party, std::uint64_t in) { + dpf::protocol::composer c(party); + auto x = c.input(domain::a, 8); + dpf::protocol::node last = x; + for (int i = 0; i < 8; ++i) + last = c.exchange(last); + return std::make_tuple(c.schedule(), x, last, in); + }; + auto [p0, x0, out0, in0] = make(0, 1); + auto [p1, x1, out1, in1] = make(1, 2); + ASSERT_EQ(p0.rounds(), 8u); + std::vector> v0(p0.nodes().size()), + v1(p1.nodes().size()); + put_raw(v0, x0, &in0, 8); + put_raw(v1, x1, &in1, 8); + dpf::protocol::drive_options opt; + opt.pipeline_credit = 2; + dpf::protocol::drive_both_on_streams(p0, p1, v0, v1, {}, 1, opt); + std::uint64_t o0 = 0, o1 = 0; + std::memcpy(&o0, v0[out0.id].data(), 8); + std::memcpy(&o1, v1[out1.id].data(), 8); + // Each exchange opens the sum; after first open both hold 3, then 6, … + EXPECT_EQ(o0, o1); + EXPECT_EQ(o0, 3u << 7); +} + +TEST(Compose, DrivePlanOnStreamsMuxTcp) +{ + dpf::protocol::composer c0(0); + dpf::protocol::composer c1(1); + auto x0 = c0.input(domain::a, 8); + auto x1 = c1.input(domain::a, 8); + auto e0 = c0.exchange(x0); + auto e1 = c1.exchange(x1); + auto p0 = c0.schedule(); + auto p1 = c1.schedule(); + const auto nstreams = p0.slot_bytes_all().size(); + ASSERT_EQ(nstreams, 1u); + std::atomic port{0}; + std::uint64_t open0 = 0, open1 = 0; + std::exception_ptr err; + std::mutex mu; + std::thread t0([&] { + try + { + dpf::run::tcp_pair_mux(0, "127.0.0.1", port, nstreams, + [&](unsigned, dpf::net::mux_stream_array & mux) { + std::vector> v(p0.nodes().size()); + const std::uint64_t a = 7; + put_raw(v, x0, &a, 8); + dpf::protocol::drive_plan_on_streams(p0, mux, v, {}, 0); + std::memcpy(&open0, v[e0.id].data(), 8); + }); + } + catch (...) + { + std::lock_guard lock(mu); + if (!err) + err = std::current_exception(); + } + }); + while (port.load() == 0) + std::this_thread::yield(); + std::thread t1([&] { + try + { + dpf::run::tcp_pair_mux(1, "127.0.0.1", port, nstreams, + [&](unsigned, dpf::net::mux_stream_array & mux) { + std::vector> v(p1.nodes().size()); + const std::uint64_t b = 35; + put_raw(v, x1, &b, 8); + dpf::protocol::drive_plan_on_streams(p1, mux, v, {}, 1); + std::memcpy(&open1, v[e1.id].data(), 8); + }); + } + catch (...) + { + std::lock_guard lock(mu); + if (!err) + err = std::current_exception(); + } + }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); + EXPECT_EQ(open0, 42u); + EXPECT_EQ(open1, 42u); +} + +TEST(Compose, DrivePlanOnStreamMeshRssCopy) +{ + dpf::protocol::composer c0(0); + dpf::protocol::composer c1(1); + auto y0 = c0.input(domain::y, 8); + auto y1 = c1.input(domain::y, 8); + auto r0 = c0.rss_from_y(y0); + auto r1 = c1.rss_from_y(y1); + (void)r0; + (void)r1; + auto p = c0.schedule(); + ASSERT_EQ(p.exchange_waves(), 1u); + const auto slots = dpf::protocol::slot_bytes_by_channel(p); + ASSERT_EQ(slots.rss_next.size(), 1u); + ASSERT_TRUE(slots.peer.empty()); + auto rss = dpf::net::make_memory_stream_pair(1); + std::vector> val0(p.nodes().size()), + val1(p.nodes().size()); + const std::uint64_t mine0 = 10, mine1 = 20; + put_raw(val0, y0, &mine0, 8); + put_raw(val1, y1, &mine1, 8); + auto sinks0 = dpf::net::make_stream_edge_sinks(nullptr, {}, &rss.first, + slots.rss_next, nullptr, {}, 1); + auto sinks1 = dpf::net::make_stream_edge_sinks(nullptr, {}, &rss.second, + slots.rss_next, nullptr, {}, 1); + std::exception_ptr err; + std::mutex mu; + std::thread t0([&] { + try + { + dpf::protocol::drive_plan_on_stream_mesh(p, sinks0, val0, {}, 0); + } + catch (...) + { + std::lock_guard lock(mu); + if (!err) + err = std::current_exception(); + } + }); + std::thread t1([&] { + try + { + dpf::protocol::drive_plan_on_stream_mesh(p, sinks1, val1, {}, 1); + } + catch (...) + { + std::lock_guard lock(mu); + if (!err) + err = std::current_exception(); + } + }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); + std::uint64_t own0 = 0, next0 = 0, own1 = 0, next1 = 0; + std::memcpy(&own0, val0[r0.id].data(), 8); + std::memcpy(&next0, val0[r0.id].data() + 8, 8); + std::memcpy(&own1, val1[r1.id].data(), 8); + std::memcpy(&next1, val1[r1.id].data() + 8, 8); + EXPECT_EQ(own0, mine0); + EXPECT_EQ(next0, mine1); + EXPECT_EQ(own1, mine1); + EXPECT_EQ(next1, mine0); +} + +TEST(Gilboa, MulTapeViaStreamArrays) +{ + auto d0 = dpf::net::make_memory_stream_pair(1); + auto d1 = dpf::net::make_memory_stream_pair(1); + dpf::factory::deal_gilboa_mul_tape(d0.first, d1.first, 16); + auto p0 = dpf::factory::read_ot_pack_wire(d0.second, 0); + auto p1 = dpf::factory::read_ot_pack_wire(d1.second, 0); + const std::uint64_t x0 = 30, x1 = 12, y0 = 3, y1 = 4; + auto prod = dpf::gilboa::mul_from_ot_pair(p0, p1, x0, x1, y0, y1, 16); + EXPECT_EQ(prod.z0 + prod.z1, + dpf::gilboa::mul_clear(x0, x1, y0, y1)); +} + +TEST(Gilboa, MulOnlineViaStreamArrays) +{ + auto peer = dpf::net::make_memory_stream_pair(1); + auto d0 = dpf::net::make_memory_stream_pair(1); + auto d1 = dpf::net::make_memory_stream_pair(1); + dpf::factory::deal_gilboa_mul_tape(d0.first, d1.first, 16); + const std::uint64_t x0 = 30, x1 = 12, y0 = 3, y1 = 4; + std::uint64_t z0 = 0, z1 = 0; + std::thread t0([&] { + z0 = dpf::factory::gilboa_mul_online(0, x0, y0, peer.first, d0.second, 16); + }); + std::thread t1([&] { + z1 = dpf::factory::gilboa_mul_online(1, x1, y1, peer.second, d1.second, 16); + }); + t0.join(); + t1.join(); + EXPECT_EQ(z0 + z1, dpf::gilboa::mul_clear(x0, x1, y0, y1)); +} + +TEST(Factory, RssRefreshRingStreamClique) +{ + auto clique = dpf::net::make_memory_stream_clique(3, 1); + auto bundle = dpf::rss::sample_seed_bundle(); + std::uint64_t sum_own = 0, sum_next = 0; + std::exception_ptr err; + std::mutex mu; + std::vector ts; + for (unsigned me = 0; me < 3; ++me) + { + ts.emplace_back([&, me] { + try + { + const auto seeds = dpf::rss::party_seeds::from_bundle(bundle, me); + const auto z = dpf::rss::zero_share(seeds, 7); + std::uint8_t mine[8]{}, own[8]{}, next[8]{}; + std::memcpy(mine, &z, 8); + dpf::factory::rss_refresh_ring_online(clique, me, mine, 8, own, + next); + std::uint64_t o = 0, n = 0; + std::memcpy(&o, own, 8); + std::memcpy(&n, next, 8); + std::lock_guard lock(mu); + sum_own += o; + sum_next += n; + } + catch (...) + { + std::lock_guard lock(mu); + if (!err) + err = std::current_exception(); + } + }); + } + for (auto & t : ts) + t.join(); + if (err) + std::rethrow_exception(err); + EXPECT_EQ(sum_own, 0u); + EXPECT_EQ(sum_next, 0u); +} + +TEST(StreamArray, SctpStreamArrayStubThrows) +{ + dpf::net::sctp_stream_array arr(4); + EXPECT_EQ(arr.size(), 4u); + EXPECT_THROW(dpf::net::sctp_stream_array(0), std::invalid_argument); + EXPECT_THROW( + dpf::net::sctp_stream_array(dpf::net::sctp_association{-1}), + std::logic_error); + std::uint8_t byte = 1; + EXPECT_THROW(arr.write(0, &byte, 1), std::logic_error); + EXPECT_THROW(arr.read(0, &byte, 1), std::logic_error); + EXPECT_THROW(arr.flush(0), std::logic_error); +} + +namespace +{ + +// Two rounds shared by the async byte-protocol tests. Round 0 replaces the +// state with the peer's byte; round 1 adds one to the state, sends it, and +// folds in the peer's reply. Two symmetric parties starting from the empty +// state both end at 7. No blind is used (`blind_bytes == 0`). +inline std::vector async_seven_rounds() +{ + dpf::factory::async_byte_round r0{}; + r0.blind_bytes = 0; + r0.msg_bytes = 1; + r0.produce = [](std::vector & state, const std::uint8_t *, + std::size_t) { + std::uint8_t v = state.empty() ? 3 : state[0]; + return std::vector{v}; + }; + r0.finish = [](std::vector & state, const std::uint8_t * peer, + std::size_t, const std::uint8_t *, std::size_t) { + state.assign(1, peer[0]); + }; + dpf::factory::async_byte_round r1 = r0; + r1.produce = [](std::vector & state, const std::uint8_t *, + std::size_t) { + return std::vector{static_cast(state[0] + 1)}; + }; + r1.finish = [](std::vector & state, const std::uint8_t * peer, + std::size_t, const std::uint8_t *, std::size_t) { + state[0] = static_cast((state[0] + peer[0]) & 0xffu); + }; + return {r0, r1}; +} + +} // namespace + +TEST(Factory, AsyncByteProtocolRoundCallbacks) +{ + // Overlapped, event-driven runner over an async memory pair; io_context + // drives both parties to completion — no threads, no busy-waiting. + asio::io_context io; + auto peer = dpf::net::make_async_memory_stream_pair(io, 2); + auto rounds = async_seven_rounds(); + std::vector done0; + std::vector done1; + auto p0 = dpf::async::make_overlapped_byte_protocol(peer.first, nullptr, + rounds, [&](std::size_t r) { done0.push_back(r); }); + auto p1 = dpf::async::make_overlapped_byte_protocol(peer.second, nullptr, + rounds, [&](std::size_t r) { done1.push_back(r); }); + std::error_code ec0, ec1; + std::vector out0, out1; + dpf::async::run_overlapped(io, [&] { + p0->start(0, {}, [&](const std::error_code & e, + std::vector s) { + ec0 = e; + out0 = std::move(s); + }); + p1->start(0, {}, [&](const std::error_code & e, + std::vector s) { + ec1 = e; + out1 = std::move(s); + }); + }); + ASSERT_FALSE(ec0); + ASSERT_FALSE(ec1); + ASSERT_EQ(out0.size(), 1u); + ASSERT_EQ(out1.size(), 1u); + EXPECT_EQ(out0[0], 7u); + EXPECT_EQ(out1[0], 7u); + ASSERT_EQ(done0.size(), 2u); + ASSERT_EQ(done1.size(), 2u); + EXPECT_EQ(done0[0], 0u); + EXPECT_EQ(done0[1], 1u); + EXPECT_EQ(done1[0], 0u); + EXPECT_EQ(done1[1], 1u); +} + +// Two symmetric parties, two overlapped rounds, one io_context. Each round +// adds the peer's byte to the running state: 10/20 -> 30/30 -> 60/60. Purely +// event-driven; the io_context returns only when both parties finish. +TEST(AsyncIo, MemoryOverlapTwoRounds) +{ + asio::io_context io; + auto peer = dpf::net::make_async_memory_stream_pair(io, 2); + auto add_rounds = [] { + dpf::factory::async_byte_round r{}; + r.blind_bytes = 0; + r.msg_bytes = 1; + r.produce = [](std::vector & state, const std::uint8_t *, + std::size_t) { + return std::vector{state[0]}; + }; + r.finish = [](std::vector & state, const std::uint8_t * peer, + std::size_t, const std::uint8_t *, std::size_t) { + state[0] = static_cast((state[0] + peer[0]) & 0xffu); + }; + return std::vector{r, r}; + }; + auto p0 = dpf::async::make_overlapped_byte_protocol(peer.first, nullptr, + add_rounds()); + auto p1 = dpf::async::make_overlapped_byte_protocol(peer.second, nullptr, + add_rounds()); + std::vector out0, out1; + dpf::async::run_overlapped(io, [&] { + p0->start(0, {10}, [&](const std::error_code &, + std::vector s) { out0 = std::move(s); }); + p1->start(0, {20}, [&](const std::error_code &, + std::vector s) { out1 = std::move(s); }); + }); + ASSERT_EQ(out0.size(), 1u); + ASSERT_EQ(out1.size(), 1u); + EXPECT_EQ(out0[0], 60u); + EXPECT_EQ(out1[0], 60u); +} + +// One TCP socket per party, N logical streams multiplexed on it. Two rounds +// exchanged fully overlapped (write and peer-read issued together). Each party +// runs its own io_context; io.stop() from the done handler tears down the +// persistent read loop once the protocol finishes. +TEST(AsyncIo, MuxLocalhostOverlap) +{ + std::atomic port{0}; + std::uint8_t out0 = 0, out1 = 0; + auto add_rounds = [] { + dpf::factory::async_byte_round r{}; + r.blind_bytes = 0; + r.msg_bytes = 1; + r.produce = [](std::vector & state, const std::uint8_t *, + std::size_t) { + return std::vector{state[0]}; + }; + r.finish = [](std::vector & state, const std::uint8_t * peer, + std::size_t, const std::uint8_t *, std::size_t) { + state[0] = static_cast((state[0] + peer[0]) & 0xffu); + }; + return std::vector{r, r}; + }; + std::thread t0([&] { + asio::io_context io; + asio::ip::tcp::acceptor acc(io, + asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port.load())); + port.store(acc.local_endpoint().port()); + asio::ip::tcp::socket sock(io); + acc.accept(sock); + dpf::net::async_mux_stream_array mux(io, std::move(sock), 0, 1, 2); + auto p = dpf::async::make_overlapped_byte_protocol(mux, nullptr, + add_rounds()); + dpf::async::run_overlapped(io, [&] { + p->start(0, {10}, [&](const std::error_code &, + std::vector s) { + out0 = s[0]; + io.stop(); + }); + }); + }); + while (port.load() == 0) + std::this_thread::yield(); + std::thread t1([&] { + asio::io_context io; + asio::ip::tcp::socket sock(io); + asio::ip::tcp::resolver res(io); + auto eps = res.resolve("127.0.0.1", std::to_string(port.load())); + asio::connect(sock, eps); + dpf::net::async_mux_stream_array mux(io, std::move(sock), 1, 0, 2); + auto p = dpf::async::make_overlapped_byte_protocol(mux, nullptr, + add_rounds()); + dpf::async::run_overlapped(io, [&] { + p->start(0, {20}, [&](const std::error_code &, + std::vector s) { + out1 = s[0]; + io.stop(); + }); + }); + }); + t0.join(); + t1.join(); + EXPECT_EQ(out0, 60u); + EXPECT_EQ(out1, 60u); +} + +// One TCP connection PER stream index; concurrent exchanges on stream 0 and +// stream 1 run overlapped on a single io_context per party. +TEST(AsyncIo, ParallelSocketsTwoStreams) +{ + std::atomic port{0}; + std::uint8_t p0_in0 = 0, p0_in1 = 0, p1_in0 = 0, p1_in1 = 0; + std::thread t0([&] { + asio::io_context io; + auto socks = dpf::net::accept_parallel_tcp(io, port, 2); + dpf::net::async_parallel_stream_array arr(io, std::move(socks)); + std::uint8_t o0 = 0xA0, o1 = 0xA1; + auto pending = std::make_shared(2); + dpf::async::run_overlapped(io, [&, pending] { + auto on = [&, pending](const std::error_code &) { + if (--*pending == 0) + io.stop(); + }; + dpf::async::async_exchange(arr, 0, &o0, 1, &p0_in0, 1, on); + dpf::async::async_exchange(arr, 1, &o1, 1, &p0_in1, 1, on); + }); + }); + while (port.load() == 0) + std::this_thread::yield(); + std::thread t1([&] { + asio::io_context io; + auto socks = dpf::net::connect_parallel_tcp(io, "127.0.0.1", port, 2); + dpf::net::async_parallel_stream_array arr(io, std::move(socks)); + std::uint8_t o0 = 0xB0, o1 = 0xB1; + auto pending = std::make_shared(2); + dpf::async::run_overlapped(io, [&, pending] { + auto on = [&, pending](const std::error_code &) { + if (--*pending == 0) + io.stop(); + }; + dpf::async::async_exchange(arr, 0, &o0, 1, &p1_in0, 1, on); + dpf::async::async_exchange(arr, 1, &o1, 1, &p1_in1, 1, on); + }); + }); + t0.join(); + t1.join(); + EXPECT_EQ(p0_in0, 0xB0u); + EXPECT_EQ(p0_in1, 0xB1u); + EXPECT_EQ(p1_in0, 0xA0u); + EXPECT_EQ(p1_in1, 0xA1u); +} + +// One SCTP association, index i -> SCTP stream i. Two rounds exchanged fully +// overlapped over localhost (party 0 accepts, party 1 connects). Mirrors the +// mux/parallel overlap tests but on the real SCTP backend. Requires Linux + +// libsctp AND a kernel that supports SCTP sockets; otherwise the test skips. +TEST(AsyncIo, SctpLocalhostOverlap) +{ +#if DPF_HAS_LIBSCTP + // Kernel may lack the SCTP module even when libsctp headers exist. + { + const int probe = ::socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + if (probe < 0) + GTEST_SKIP() << "kernel SCTP unavailable (socket: " + << std::strerror(errno) << ")"; + ::close(probe); + } + std::atomic port{0}; + std::uint8_t out0 = 0, out1 = 0; + auto add_rounds = [] { + dpf::factory::async_byte_round r{}; + r.blind_bytes = 0; + r.msg_bytes = 1; + r.produce = [](std::vector & state, const std::uint8_t *, + std::size_t) { + return std::vector{state[0]}; + }; + r.finish = [](std::vector & state, const std::uint8_t * peer, + std::size_t, const std::uint8_t *, std::size_t) { + state[0] = static_cast((state[0] + peer[0]) & 0xffu); + }; + return std::vector{r, r}; + }; + std::exception_ptr err; + std::mutex emu; + auto note = [&](std::exception_ptr e) { + std::lock_guard lk(emu); + if (!err) + err = std::move(e); + }; + std::thread t0([&] { + try + { + asio::io_context io; + const int fd = dpf::net::accept_sctp_association(io, port, 2); + dpf::net::async_sctp_stream_array arr(io, fd, 2); + auto p = dpf::async::make_overlapped_byte_protocol(arr, nullptr, + add_rounds()); + dpf::async::run_overlapped(io, [&] { + p->start(0, {10}, [&](const std::error_code &, + std::vector s) { + out0 = s[0]; + io.stop(); + }); + }); + } + catch (...) + { + note(std::current_exception()); + } + }); + while (port.load() == 0) + std::this_thread::yield(); + std::thread t1([&] { + try + { + asio::io_context io; + const int fd = + dpf::net::connect_sctp_association(io, "127.0.0.1", port, 2); + dpf::net::async_sctp_stream_array arr(io, fd, 2); + auto p = dpf::async::make_overlapped_byte_protocol(arr, nullptr, + add_rounds()); + dpf::async::run_overlapped(io, [&] { + p->start(0, {20}, [&](const std::error_code &, + std::vector s) { + out1 = s[0]; + io.stop(); + }); + }); + } + catch (...) + { + note(std::current_exception()); + } + }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); + EXPECT_EQ(out0, 60u); + EXPECT_EQ(out1, 60u); +#else + GTEST_SKIP() << "libsctp not available (Linux + required)"; +#endif +} + +// The performance harness runs on the framework: exercise_plan honours +// DPF_TRANSPORT. Here we drive a small open plan on the synchronous stream +// framework and confirm the reported cost matches the plan. +TEST(AppFlow, ExercisePlanUsesStreamFramework) +{ + ::setenv("DPF_TRANSPORT", "stream", 1); + dpf::protocol::composer c(0); + auto x = c.input(domain::a, 8); + (void)c.exchange(x); + auto p = c.default_plan(); + const auto got = dpf::app::exercise_plan(p); + ::unsetenv("DPF_TRANSPORT"); + EXPECT_EQ(got.rounds, p.rounds()); + std::size_t want_bytes = 0; + for (auto n : p.slot_bytes_all()) + want_bytes += n; + EXPECT_EQ(got.bytes, want_bytes); +} + +// The default transport (async_memory) drives the same plan over the real +// event-driven framework in-process. +TEST(AppFlow, ExercisePlanAsyncMemoryFramework) +{ + ::unsetenv("DPF_TRANSPORT"); // default: async_memory + dpf::protocol::composer c(0); + auto x = c.input(domain::a, 8); + (void)c.exchange(x); + auto p = c.default_plan(); + const auto got = dpf::app::exercise_plan(p); + EXPECT_EQ(got.rounds, p.rounds()); + EXPECT_EQ(dpf::app::transport_from_env(), dpf::app::transport_kind::async_memory); +} + +// Deep dependent plan on a 2-lane pool: rounds >> streams, framed demux. +TEST(AsyncIo, LaneReuseDeepPlan) +{ + constexpr std::uint32_t k_step = 92001; + auto make = [](std::size_t party, std::uint64_t in) { + dpf::protocol::composer c(party); + auto x = c.input(domain::a, 8); + auto cur = x; + for (int i = 0; i < 6; ++i) + { + auto e = c.exchange(cur); + cur = c.compute(k_step, {e}, domain::a, 8); + } + return std::make_tuple(c.schedule(), x, cur, in); + }; + auto [p0, x0, out0, in0] = make(0, 1); + auto [p1, x1, out1, in1] = make(1, 2); + ASSERT_GE(p0.slot_bytes_all().size(), 6u); + EXPECT_EQ(dpf::net::lane_count_for_rounds(p0.slot_bytes_all().size(), 2), 2u); + dpf::protocol::kernel_fn step = + [](std::uint32_t, const std::vector &, + const std::vector & inputs, + dpf::protocol::block_span output, std::size_t) { + std::uint64_t v = 0; + std::memcpy(&v, inputs[0].at(0), 8); + v += 1; + std::memcpy(output.at(0), &v, 8); + }; + std::map k{{k_step, step}}; + std::vector> v0(p0.nodes().size()), + v1(p1.nodes().size()); + put_raw(v0, x0, &in0, 8); + put_raw(v1, x1, &in1, 8); + dpf::protocol::drive_options opt; + opt.n_lanes = 2; + dpf::protocol::drive_both_on_async_streams(p0, p1, v0, v1, k, 1, opt); + std::uint64_t o0 = 0, o1 = 0; + std::memcpy(&o0, v0[out0.id].data(), 8); + std::memcpy(&o1, v1[out1.id].data(), 8); + // Dependent opens double each wave (both parties hold the prior open), then +1. + // 1+2 → 3 →+1→ 4 →open→ 8 →+1→ 9 → … → final 159 after 6 steps. + EXPECT_EQ(o0, o1); + EXPECT_EQ(o0, 159u); +} + +// Compose plans ride the overlapped async stack (not a separate factory path). +TEST(ComposeAsync, DriveBothOnAsyncStreams) +{ + dpf::protocol::composer c0(0); + dpf::protocol::composer c1(1); + auto x0 = c0.input(domain::a, 8); + auto x1 = c1.input(domain::a, 8); + auto o0 = c0.exchange(x0); + auto o1 = c1.exchange(x1); + auto p0 = c0.schedule(); + auto p1 = c1.schedule(); + std::vector> v0(p0.nodes().size()), + v1(p1.nodes().size()); + std::uint64_t a = 11, b = 31; + put_raw(v0, x0, &a, 8); + put_raw(v1, x1, &b, 8); + dpf::protocol::drive_both_on_async_streams(p0, p1, v0, v1); + std::uint64_t open0 = 0, open1 = 0; + std::memcpy(&open0, v0[o0.id].data(), 8); + std::memcpy(&open1, v1[o1.id].data(), 8); + EXPECT_EQ(open0, 42u); + EXPECT_EQ(open1, 42u); +} + +// Overlapped factory protocol on a single peer stream (lane reuse by modulo). +TEST(AsyncIo, OverlappedLaneModulo) +{ + asio::io_context io; + auto peer = dpf::net::make_async_memory_stream_pair(io, 1); + using round = dpf::factory::async_byte_round; + std::vector rounds(3); + for (std::size_t r = 0; r < 3; ++r) + { + rounds[r].msg_bytes = 4; + rounds[r].blind_bytes = 0; + rounds[r].produce = [r](const std::vector &, + const std::uint8_t *, std::size_t) { + std::vector out(4, static_cast(r + 1)); + return out; + }; + rounds[r].finish = [r](std::vector & st, const std::uint8_t * in, + std::size_t n, const std::uint8_t *, std::size_t) { + ASSERT_EQ(n, 4u); + st.push_back(in[0]); + EXPECT_EQ(in[0], static_cast(r + 1)); + }; + } + std::vector done0, done1; + std::error_code ec0, ec1; + auto p0 = dpf::async::make_overlapped_byte_protocol(peer.first, nullptr, rounds); + auto p1 = dpf::async::make_overlapped_byte_protocol(peer.second, nullptr, rounds); + dpf::async::run_overlapped(io, [&] { + p0->start(0, {}, [&](const std::error_code & ec, std::vector st) { + ec0 = ec; + done0 = std::move(st); + }); + p1->start(0, {}, [&](const std::error_code & ec, std::vector st) { + ec1 = ec; + done1 = std::move(st); + }); + }); + EXPECT_FALSE(ec0); + EXPECT_FALSE(ec1); + ASSERT_EQ(done0.size(), 3u); + ASSERT_EQ(done1.size(), 3u); +} + +// Three parties join a real TCP mux clique and exchange 8 bytes on each edge. +TEST(TcpMesh, ThreePartyMuxExchange) +{ + constexpr unsigned n = 3; + std::atomic ok{0}; + dpf::run::threads_on_tcp_mesh(n, /*streams=*/1, [&](unsigned me, + dpf::net::tcp_mesh & mesh) { + EXPECT_EQ(mesh.parties, n); + for (unsigned peer = 0; peer < n; ++peer) + { + if (peer == me) + continue; + std::uint64_t mine = (static_cast(me) << 8) | peer; + std::uint64_t got = 0; + auto & link = mesh.peer(peer); + link.write(0, &mine, 8); + link.flush(0); + link.read(0, &got, 8); + const std::uint64_t expect = + (static_cast(peer) << 8) | me; + EXPECT_EQ(got, expect); + } + ok.fetch_add(1); + }); + EXPECT_EQ(ok.load(), static_cast(n)); +} + +// Composer accepts party ids beyond 0..2 (N-party meshes). +TEST(Compose, NPartyComposerAllowed) +{ + dpf::protocol::composer c5(5); + EXPECT_EQ(c5.party(), 5u); +} + +TEST(Session, ShipPrepAsync) +{ + dpf::prep::demand d; + d.limb = 8; + d.ring_triples = 2; + const auto shipped = dpf::session::ship_prep(d); + EXPECT_EQ(shipped.bytes0, shipped.bytes1); + EXPECT_GT(shipped.bytes0, 18u); + std::uint8_t a0[8]{}, b0[8]{}, c0[8]{}, a1[8]{}, b1[8]{}, c1[8]{}; + auto p0 = shipped.party0; + auto p1 = shipped.party1; + p0.take_ring(a0, b0, c0); + p1.take_ring(a1, b1, c1); + std::uint64_t sa = 0, sb = 0, sc = 0, ta = 0, tb = 0, tc = 0; + std::memcpy(&sa, a0, 8); + std::memcpy(&sb, b0, 8); + std::memcpy(&sc, c0, 8); + std::memcpy(&ta, a1, 8); + std::memcpy(&tb, b1, 8); + std::memcpy(&tc, c1, 8); + EXPECT_EQ((sa + ta) * (sb + tb), sc + tc); +} + +TEST(Session, HushmapAsyncDealerAndPeer) +{ + EXPECT_NO_THROW(dpf::session::drive_hushmap_add(3)); +} + +TEST(Session, PirsonaAsyncStar) +{ + constexpr std::size_t L = 1; + constexpr std::size_t n = 2; + auto seeds = std::make_shared>>(n); + auto answers = std::make_shared>>(n); + for (std::size_t i = 0; i < n; ++i) + { + (*seeds)[i].assign(16, static_cast(i + 1)); + (*answers)[i].assign(8, static_cast(0x40 + i)); + } + auto client = dpf::protocol::pirsona_bitmore_fetch(L, 16, 8, seeds, answers); + EXPECT_NO_THROW(dpf::session::drive_async_star(n, {16u, 8u}, std::move(client), + [&](std::size_t i) { + return dpf::protocol::star_server_reply_rounds(16, 8, (*answers)[i]); + })); +} + +TEST(WireWindow, MuxTinyWindowStillCompletes) +{ + asio::io_context io0; + asio::io_context io1; + dpf::net::wire_policy pol; + pol.window_bytes = 64; + std::atomic port{0}; + std::atomic ok{0}; + std::exception_ptr err; + std::mutex mu; + std::thread t0([&] { + try + { + asio::ip::tcp::acceptor acc(io0, + asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 0)); + port.store(acc.local_endpoint().port()); + asio::ip::tcp::socket sock(io0); + acc.accept(sock); + dpf::net::async_mux_stream_array mux(io0, std::move(sock), 0, 1, 1, pol); + EXPECT_EQ(mux.window_bytes(), 64u); + std::vector out(200, 0xab); + std::vector in(200); + std::atomic left{2}; + mux.async_write(0, out.data(), out.size(), [&](const std::error_code & ec) { + EXPECT_FALSE(ec); + left.fetch_sub(1); + }); + mux.async_read(0, in.data(), in.size(), [&](const std::error_code & ec) { + EXPECT_FALSE(ec); + left.fetch_sub(1); + }); + while (left.load() != 0) + io0.run_one(); + EXPECT_EQ(in, out); + ok.fetch_add(1); + } + catch (...) + { + std::lock_guard lock(mu); + err = std::current_exception(); + } + }); + std::thread t1([&] { + try + { + while (port.load() == 0) + std::this_thread::yield(); + asio::ip::tcp::socket sock(io1); + asio::ip::tcp::resolver res(io1); + auto eps = res.resolve("127.0.0.1", std::to_string(port.load())); + asio::connect(sock, eps); + dpf::net::async_mux_stream_array mux(io1, std::move(sock), 1, 0, 1); + std::vector out(200, 0xab); + std::vector in(200); + std::atomic left{2}; + mux.async_write(0, out.data(), out.size(), [&](const std::error_code & ec) { + EXPECT_FALSE(ec); + left.fetch_sub(1); + }); + mux.async_read(0, in.data(), in.size(), [&](const std::error_code & ec) { + EXPECT_FALSE(ec); + left.fetch_sub(1); + }); + while (left.load() != 0) + io1.run_one(); + ok.fetch_add(1); + } + catch (...) + { + std::lock_guard lock(mu); + err = std::current_exception(); + } + }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); + EXPECT_EQ(ok.load(), 2); +} + +TEST(IoPool, PostsComputeOnSharedWorkers) +{ + dpf::net::io_pool pool(2); + EXPECT_GE(pool.size(), 2u); + constexpr int n = 32; + std::atomic sum{0}; + for (int i = 0; i < n; ++i) + pool.post([&] { sum.fetch_add(1); }); + for (int spins = 0; sum.load() != n && spins < 1000000; ++spins) + std::this_thread::yield(); + EXPECT_EQ(sum.load(), n); +} + +namespace +{ + +void exchange_u64(dpf::net::async_stream_array & link, std::uint64_t mine, + std::uint64_t expect) +{ + std::uint64_t got = 0; + std::atomic left{2}; + std::error_code wec, rec; + link.async_write(0, &mine, 8, [&](const std::error_code & ec) { + wec = ec; + left.fetch_sub(1); + }); + link.async_read(0, &got, 8, [&](const std::error_code & ec) { + rec = ec; + left.fetch_sub(1); + }); + for (int spins = 0; left.load() != 0 && spins < 1000000; ++spins) + std::this_thread::yield(); + ASSERT_EQ(left.load(), 0); + EXPECT_FALSE(wec); + EXPECT_FALSE(rec); + EXPECT_EQ(got, expect); +} + +} // namespace + +TEST(PartySession, JoinReconnectAndDealerOnOnePool) +{ + dpf::net::io_pool pool(2); + auto ports = dpf::net::make_mesh_ports(2); + std::exception_ptr err; + std::mutex mu; + std::thread t0([&] { + try + { + dpf::net::party_session me(pool.context(), 0, 2, 1); + me.join("127.0.0.1", ports); + exchange_u64(me.peer(1), 0x10, 0x21); + me.reconnect(1); + exchange_u64(me.peer(1), 0x30, 0x41); + } + catch (...) + { + std::lock_guard lock(mu); + err = std::current_exception(); + } + }); + std::thread t1([&] { + try + { + dpf::net::party_session me(pool.context(), 1, 2, 1); + me.join("127.0.0.1", ports); + exchange_u64(me.peer(0), 0x21, 0x10); + me.reconnect(0); + exchange_u64(me.peer(0), 0x41, 0x30); + } + catch (...) + { + std::lock_guard lock(mu); + err = std::current_exception(); + } + }); + t0.join(); + t1.join(); + if (err) + std::rethrow_exception(err); + + // Dealer is its own link, not a mesh neighbor. + std::atomic dport{0}; + std::thread dealer([&] { + try + { + dpf::net::party_session d(pool.context(), 0, 2, 1); + dport.store(d.listen()); + d.accept_dealer(); + exchange_u64(d.dealer(), 7, 9); + } + catch (...) + { + std::lock_guard lock(mu); + if (!err) + err = std::current_exception(); + } + }); + std::thread party([&] { + try + { + while (dport.load() == 0) + std::this_thread::yield(); + dpf::net::party_session p(pool.context(), 1, 2, 1); + p.connect_dealer("127.0.0.1", dport.load()); + EXPECT_TRUE(p.has_dealer()); + exchange_u64(p.dealer(), 9, 7); + } + catch (...) + { + std::lock_guard lock(mu); + if (!err) + err = std::current_exception(); + } + }); + dealer.join(); + party.join(); + if (err) + std::rethrow_exception(err); +} + +TEST(SocketTune, NoDelayOnConnectedSocket) +{ + asio::io_context io; + std::atomic port{0}; + asio::ip::tcp::no_delay server_delay(false); + asio::ip::tcp::no_delay client_delay(false); + std::thread acc([&] { + asio::ip::tcp::acceptor a(io, + asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 0)); + port.store(a.local_endpoint().port()); + asio::ip::tcp::socket s(io); + a.accept(s); + dpf::net::tune_tcp(s); + s.get_option(server_delay); + }); + while (port.load() == 0) + std::this_thread::yield(); + asio::ip::tcp::socket c(io); + asio::ip::tcp::resolver res(io); + asio::connect(c, res.resolve("127.0.0.1", std::to_string(port.load()))); + dpf::net::tune_tcp(c); + c.get_option(client_delay); + acc.join(); + EXPECT_TRUE(server_delay.value()); + EXPECT_TRUE(client_delay.value()); +} + +TEST(IoPool, ComputeDoesNotUseSocketContext) +{ + dpf::net::io_pool pool(2, 2); + EXPECT_GE(pool.compute_size(), 2u); + std::atomic done{false}; + std::thread::id compute_id; + const auto caller = std::this_thread::get_id(); + pool.post_compute([&] { + compute_id = std::this_thread::get_id(); + done.store(true); + }); + for (int i = 0; !done.load() && i < 1000000; ++i) + std::this_thread::yield(); + EXPECT_TRUE(done.load()); + EXPECT_NE(compute_id, caller); +} + +TEST(DriveOptions, LaneCountAndWaitTimeout) +{ + dpf::protocol::drive_options opt; + opt.n_lanes = 2; + opt.wait_timeout = std::chrono::milliseconds(50); + EXPECT_EQ(dpf::protocol::lanes_for_plan(6, opt), 2u); + + dpf::protocol::composer c0(0); + auto x = c0.input(domain::a, 8); + (void)c0.exchange(x); + auto p = c0.schedule(); + asio::io_context io0; + asio::io_context io1; + auto ends = dpf::net::make_async_dual_memory_stream_pair(io0, io1, 1); + auto work = asio::make_work_guard(io0); + std::vector> values(p.nodes().size()); + std::uint64_t in = 1; + put_raw(values, x, &in, 8); + EXPECT_THROW( + dpf::protocol::drive_plan_on_async_streams(p, ends.first, values, {}, 0, + 1, opt), + std::runtime_error); +} + +TEST(DriveOptions, KernelRunsOnComputePool) +{ + constexpr std::uint32_t k_step = 93001; + dpf::net::io_pool pool(2, 2); + std::thread::id kid; + dpf::protocol::kernel_fn step = + [&](std::uint32_t, const std::vector &, + const std::vector & inputs, + dpf::protocol::block_span output, std::size_t) { + kid = std::this_thread::get_id(); + std::uint64_t v = 0; + std::memcpy(&v, inputs[0].at(0), 8); + v += 1; + std::memcpy(output.at(0), &v, 8); + }; + auto make = [&](std::size_t party, std::uint64_t in) { + dpf::protocol::composer c(party); + auto xin = c.input(domain::a, 8); + auto e = c.exchange(xin); + auto y = c.compute(k_step, {e}, domain::a, 8); + return std::make_tuple(c.schedule(), xin, y, in); + }; + auto [p0, x0, out0, in0] = make(0, 4); + auto [p1, x1, out1, in1] = make(1, 6); + std::map k{{k_step, step}}; + std::vector> v0(p0.nodes().size()), + v1(p1.nodes().size()); + put_raw(v0, x0, &in0, 8); + put_raw(v1, x1, &in1, 8); + dpf::protocol::drive_options opt; + opt.workers = &pool; + const auto caller = std::this_thread::get_id(); + dpf::protocol::drive_both_on_async_streams(p0, p1, v0, v1, k, 1, opt); + EXPECT_NE(kid, caller); + std::uint64_t o0 = 0; + std::memcpy(&o0, v0[out0.id].data(), 8); + EXPECT_EQ(o0, 11u); +} + +TEST(PartySession, WindowAndLaneOverride) +{ + dpf::net::io_pool pool(2); + auto ports = dpf::net::make_mesh_ports(2); + std::atomic win0{0}; + std::atomic streams0{0}; + std::thread t0([&] { + dpf::net::party_session me(pool.context(), 0, 2, 1); + me.set_window_bytes(4096); + me.join("127.0.0.1", ports, 4); + win0.store(me.peer(1).window_bytes()); + streams0.store(me.streams()); + std::uint64_t mine = 1, got = 0; + std::atomic left{2}; + me.peer(1).async_write(0, &mine, 8, [&](const std::error_code &) { + left.fetch_sub(1); + }); + me.peer(1).async_read(0, &got, 8, [&](const std::error_code &) { + left.fetch_sub(1); + }); + for (int i = 0; left.load() != 0 && i < 1000000; ++i) + std::this_thread::yield(); + EXPECT_EQ(got, 2u); + }); + std::thread t1([&] { + dpf::net::party_session me(pool.context(), 1, 2, 1); + me.set_window_bytes(4096); + me.join("127.0.0.1", ports, 4); + std::uint64_t mine = 2, got = 0; + std::atomic left{2}; + me.peer(0).async_write(0, &mine, 8, [&](const std::error_code &) { + left.fetch_sub(1); + }); + me.peer(0).async_read(0, &got, 8, [&](const std::error_code &) { + left.fetch_sub(1); + }); + for (int i = 0; left.load() != 0 && i < 1000000; ++i) + std::this_thread::yield(); + EXPECT_EQ(got, 1u); + }); + t0.join(); + t1.join(); + EXPECT_EQ(win0.load(), 4096u); + EXPECT_EQ(streams0.load(), 4u); +} diff --git a/test/tests/shared_and_test.cpp b/test/tests/shared_and_test.cpp new file mode 100644 index 0000000..214628e --- /dev/null +++ b/test/tests/shared_and_test.cpp @@ -0,0 +1,93 @@ +#include + +#include + +#include "aes_mmo_ref.hpp" +#include "aes_sbox_bp.hpp" +#include "dpf/doerner_shelat.hpp" + +namespace +{ + +std::uint8_t sbox_circuit(std::uint8_t x) +{ + std::uint8_t w[aes_bp::wire_count]{}; + for (int i = 0; i < 8; ++i) + w[i] = static_cast((x >> (7 - i)) & 1u); + for (std::size_t oi = 0; oi < aes_bp::op_count; ++oi) + { + const auto kind = aes_bp::ops[oi][0]; + const auto dst = aes_bp::ops[oi][1]; + const auto a = aes_bp::ops[oi][2]; + const auto b = aes_bp::ops[oi][3]; + if (kind == 0) + w[dst] = static_cast(w[a] ^ w[b]); + else if (kind == 1) + w[dst] = static_cast(w[a] & w[b]); + else + w[dst] = static_cast(w[a] ^ w[b] ^ 1u); + } + std::uint8_t out = 0; + for (int i = 0; i < 8; ++i) + out = static_cast( + out | (w[aes_bp::out_wire[static_cast(i)]] << (7 - i))); + return out; +} + +} // namespace + +TEST(SharedAnd, BoyarPeraltaMatchesAesSbox) +{ + int ands = 0; + for (std::size_t oi = 0; oi < aes_bp::op_count; ++oi) + if (aes_bp::ops[oi][0] == 1) + ++ands; + EXPECT_EQ(ands, static_cast(aes_bp::and_count)); + for (int x = 0; x < 256; ++x) + { + const auto byte = static_cast(x); + EXPECT_EQ(sbox_circuit(byte), dpf::party::aes_ref::sbox_at(byte)) + << "byte " << x; + } +} + +TEST(SharedAnd, PublicProductTermIsAddedOnce) +{ + // Every XOR-share of a bit AND. The opened masks are `d = x XOR a` and + // `e = y XOR b`. Party 0 alone adds the public `d AND e`. Adding it on + // both parties cancels that term and the product is wrong whenever it + // is 1. + int cancelled = 0; + for (unsigned bits = 0; bits < 256; ++bits) + { + const std::uint8_t a = static_cast(bits & 1u); + const std::uint8_t b = static_cast((bits >> 1) & 1u); + const std::uint8_t x = static_cast((bits >> 2) & 1u); + const std::uint8_t y = static_cast((bits >> 3) & 1u); + const std::uint8_t a0 = static_cast((bits >> 4) & 1u); + const std::uint8_t b0 = static_cast((bits >> 5) & 1u); + const std::uint8_t x0 = static_cast((bits >> 6) & 1u); + const std::uint8_t y0 = static_cast((bits >> 7) & 1u); + const std::uint8_t c = static_cast(a & b); + const std::uint8_t c0 = static_cast((a0 & b0) ^ ((bits * 3u) & 1u)); + const std::uint8_t a1 = static_cast(a0 ^ a); + const std::uint8_t b1 = static_cast(b0 ^ b); + const std::uint8_t c1 = static_cast(c0 ^ c); + const std::uint8_t x1 = static_cast(x0 ^ x); + const std::uint8_t y1 = static_cast(y0 ^ y); + const std::uint8_t d = static_cast((x0 ^ a0) ^ (x1 ^ a1)); + const std::uint8_t e = static_cast((y0 ^ b0) ^ (y1 ^ b1)); + const std::uint8_t z0 = dpf::detail::ds_bit_and_party(d, e, a0, b0, c0, true); + const std::uint8_t z1 = dpf::detail::ds_bit_and_party(d, e, a1, b1, c1, false); + EXPECT_EQ(static_cast(z0 ^ z1), static_cast(x & y)); + const std::uint8_t both = static_cast( + dpf::detail::ds_bit_and_party(d, e, a0, b0, c0, true) + ^ dpf::detail::ds_bit_and_party(d, e, a1, b1, c1, true)); + if ((d & e) != 0) + { + EXPECT_NE(both, static_cast(x & y)); + ++cancelled; + } + } + EXPECT_GT(cancelled, 0); +} diff --git a/test/tests/shuffle_hidden_test.cpp b/test/tests/shuffle_hidden_test.cpp new file mode 100644 index 0000000..93a6af2 --- /dev/null +++ b/test/tests/shuffle_hidden_test.cpp @@ -0,0 +1,346 @@ +#include + +#include +#include +#include +#include + +#include "dpf/compose.hpp" +#include "dpf/shuffle.hpp" + +namespace +{ + +template +std::vector replay(const std::vector & v, const dpf::rss::seed_bundle & bundle, + std::uint64_t index, unsigned passes) +{ + const dpf::rss::seed_block seeds[3] = {bundle.k01, bundle.k12, bundle.k20}; + auto out = v; + for (unsigned p = 0; p < passes; ++p) + { + out = dpf::shuffle::permute(out, + dpf::shuffle::permutation_from_seed(seeds[p], v.size(), index)); + } + return out; +} + +template +void deal(const std::vector & clear, dpf::shuffle::shuffle_party_view held[3]) +{ + const std::size_t n = clear.size(); + for (unsigned p = 0; p < 3; ++p) + { + held[p].own.assign(n, T{}); + held[p].next.assign(n, T{}); + } + for (std::size_t i = 0; i < n; ++i) + { + const T a = dpf::uniform_sample(); + const T b = dpf::uniform_sample(); + const T c = static_cast(clear[i] - a - b); + held[0].own[i] = a; + held[0].next[i] = b; + held[1].own[i] = b; + held[1].next[i] = c; + held[2].own[i] = c; + held[2].next[i] = a; + } +} + +template +std::vector open_owns(const dpf::shuffle::shuffle_party_view held[3]) +{ + std::vector out(held[0].own.size()); + for (std::size_t i = 0; i < out.size(); ++i) + out[i] = static_cast(held[0].own[i] + held[1].own[i] + held[2].own[i]); + return out; +} + +template +void run_passes(dpf::shuffle::shuffle_party_view held[3], + const dpf::rss::seed_bundle & bundle, std::uint64_t index, unsigned passes) +{ + const unsigned order[3] = {2u, 0u, 1u}; + for (unsigned step = 0; step < passes; ++step) + { + const unsigned left = order[step]; + const unsigned u = dpf::shuffle::hidden_u_party(left); + const unsigned side = dpf::shuffle::hidden_side_party(left); + auto u_step = dpf::shuffle::shuffle_hidden_pass( + u, dpf::rss::party_seeds::from_bundle(bundle, u), held[u], index, left, + nullptr); + auto s_step = dpf::shuffle::shuffle_hidden_pass( + side, dpf::rss::party_seeds::from_bundle(bundle, side), held[side], + index, left, &u_step.out.data); + auto l_step = dpf::shuffle::shuffle_hidden_pass( + left, dpf::rss::party_seeds::from_bundle(bundle, left), held[left], + index, left, &s_step.out.data); + EXPECT_EQ(u_step.out.data.size(), held[u].own.size()); + EXPECT_EQ(s_step.out.to, left); + EXPECT_EQ(held[u].own.size(), l_step.view.own.size()); + held[u] = std::move(u_step.view); + held[side] = std::move(s_step.view); + held[left] = std::move(l_step.view); + ASSERT_EQ(held[0].next, held[1].own); + ASSERT_EQ(held[1].next, held[2].own); + ASSERT_EQ(held[2].next, held[0].own); + } +} + +} // namespace + +TEST(ShuffleHidden, ThreePassesMatchTheSeedPermutations) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + std::vector v(8); + std::iota(v.begin(), v.end(), 0); + const std::uint64_t index = 4; + auto opened = dpf::shuffle::shuffle_hidden_triple(v, bundle, index); + auto expect = dpf::shuffle::permute(v, + dpf::shuffle::permutation_from_seed(bundle.k01, v.size(), index)); + expect = dpf::shuffle::permute(expect, + dpf::shuffle::permutation_from_seed(bundle.k12, v.size(), index)); + expect = dpf::shuffle::permute(expect, + dpf::shuffle::permutation_from_seed(bundle.k20, v.size(), index)); + EXPECT_EQ(opened, expect); + EXPECT_TRUE(dpf::shuffle::is_permutation_of(v, opened)); +} + +TEST(ShuffleHidden, LeftOutPartyUsesOnlyItsTwoSeeds) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + const std::size_t n = 4; + dpf::shuffle::shuffle_party_view in{ + std::vector(n, 1), + std::vector(n, 2), + }; + auto seeds = dpf::rss::party_seeds::from_bundle(bundle, 2); + std::vector inbound(n, 9); + auto step = dpf::shuffle::shuffle_hidden_pass( + 2, seeds, in, 0, 2, &inbound); + EXPECT_FALSE(step.out.sends); + EXPECT_EQ(step.view.own, inbound); + EXPECT_EQ(step.view.next.size(), n); +} + +TEST(ShuffleHidden, ReplicationHoldsAfterEachPass) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + const std::size_t n = 5; + dpf::shuffle::shuffle_party_view held[3]; + for (unsigned p = 0; p < 3; ++p) + { + held[p].own.assign(n, 0); + held[p].next.assign(n, 0); + } + for (std::size_t i = 0; i < n; ++i) + { + const auto a = dpf::uniform_sample(); + const auto b = dpf::uniform_sample(); + held[0].own[i] = a; + held[0].next[i] = b; + held[1].own[i] = b; + held[1].next[i] = static_cast(i - a - b); + held[2].own[i] = held[1].next[i]; + held[2].next[i] = a; + } + for (unsigned left : {2u, 0u, 1u}) + { + const unsigned u = dpf::shuffle::hidden_u_party(left); + const unsigned side = dpf::shuffle::hidden_side_party(left); + auto u_step = dpf::shuffle::shuffle_hidden_pass( + u, dpf::rss::party_seeds::from_bundle(bundle, u), held[u], 1, left, + nullptr); + auto s_step = dpf::shuffle::shuffle_hidden_pass( + side, dpf::rss::party_seeds::from_bundle(bundle, side), held[side], + 1, left, &u_step.out.data); + auto l_step = dpf::shuffle::shuffle_hidden_pass( + left, dpf::rss::party_seeds::from_bundle(bundle, left), held[left], + 1, left, &s_step.out.data); + EXPECT_TRUE(u_step.out.sends); + EXPECT_EQ(u_step.out.to, side); + EXPECT_TRUE(s_step.out.sends); + EXPECT_EQ(s_step.out.to, left); + EXPECT_FALSE(l_step.out.sends); + held[u] = std::move(u_step.view); + held[side] = std::move(s_step.view); + held[left] = std::move(l_step.view); + EXPECT_EQ(held[0].next, held[1].own); + EXPECT_EQ(held[1].next, held[2].own); + EXPECT_EQ(held[2].next, held[0].own); + } +} + +TEST(ShuffleHidden, ComposerRecordsThreeSends) +{ + dpf::protocol::composer c; + auto out = c.shuffle_hidden(8, sizeof(std::uint64_t)); + auto plan = c.schedule(); + EXPECT_EQ(plan.rounds(), 3u); + std::vector left_out; + for (std::size_t w = 0; w < plan.waves(); ++w) + { + for (auto ex : plan.wave(w).exchanges) + { + EXPECT_EQ(plan.opcode_of(ex.id), dpf::protocol::opcodes::shuffle_send); + left_out.push_back(plan.aux_of(ex.id)); + EXPECT_EQ(dpf::protocol::detail::exchange_channel(plan, ex.id), + dpf::protocol::edge_channel::rss_next); + } + } + EXPECT_EQ(left_out, (std::vector{2u, 0u, 1u})); + EXPECT_EQ(plan.value_bytes_of(out.id), 8u * sizeof(std::uint64_t)); + std::size_t prev = 0; + bool seen = false; + for (std::size_t w = 0; w < plan.waves(); ++w) + { + if (plan.wave(w).exchanges.empty()) + continue; + if (seen) + EXPECT_GT(w, prev); + prev = w; + seen = true; + } +} + +TEST(ShuffleHidden, EachPassMatchesOneSeedPermutation) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + std::vector v(9); + for (std::size_t i = 0; i < v.size(); ++i) + v[i] = 1000u + static_cast(i * 17u); + dpf::shuffle::shuffle_party_view held[3]; + deal(v, held); + for (unsigned passes = 1; passes <= 3; ++passes) + { + deal(v, held); + run_passes(held, bundle, 9, passes); + EXPECT_EQ(open_owns(held), replay(v, bundle, 9, passes)); + } +} + +TEST(ShuffleHidden, LengthsRingsAndHighBits) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + for (std::size_t n : {0u, 1u, 2u, 3u, 7u, 16u, 64u}) + { + std::vector v(n); + for (std::size_t i = 0; i < n; ++i) + v[i] = (i * 0x9E3779B97F4A7C15ull) ^ 0x8000000000000000ull; + auto opened = dpf::shuffle::shuffle_hidden_triple(v, bundle, 3); + EXPECT_EQ(opened, replay(v, bundle, 3, 3)); + if (n == 1) + EXPECT_EQ(opened, v); + } + std::vector bytes{0, 255, 1, 128, 7, 7, 255}; + EXPECT_EQ(dpf::shuffle::shuffle_hidden_triple(bytes, bundle, 2), + replay(bytes, bundle, 2, 3)); + std::vector words{0u, 0xffffffffu, 1u, 0x80000000u}; + EXPECT_EQ(dpf::shuffle::shuffle_hidden_triple(words, bundle, 5), + replay(words, bundle, 5, 3)); + std::vector same(12, 42); + EXPECT_EQ(dpf::shuffle::shuffle_hidden_triple(same, bundle, 1), same); +} + +TEST(ShuffleHidden, ReplayIsStableAndIndexChangesTheOrder) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + std::vector v(16); + std::iota(v.begin(), v.end(), 0); + auto a = dpf::shuffle::shuffle_hidden_triple(v, bundle, 0); + auto again = dpf::shuffle::shuffle_hidden_triple(v, bundle, 0); + auto other = dpf::shuffle::shuffle_hidden_triple(v, bundle, 99); + EXPECT_EQ(a, again); + EXPECT_EQ(a, replay(v, bundle, 0, 3)); + EXPECT_NE(a, other); +} + +TEST(ShuffleHidden, UPartyIgnoresInboundAndABadMessageBreaksTheOpen) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + std::vector v(8); + std::iota(v.begin(), v.end(), 3); + dpf::shuffle::shuffle_party_view held[3]; + deal(v, held); + const unsigned left = 2; + const unsigned u = dpf::shuffle::hidden_u_party(left); + const unsigned side = dpf::shuffle::hidden_side_party(left); + std::vector junk(v.size(), 123); + auto ignored = dpf::shuffle::shuffle_hidden_pass( + u, dpf::rss::party_seeds::from_bundle(bundle, u), held[u], 0, left, &junk); + auto clean = dpf::shuffle::shuffle_hidden_pass( + u, dpf::rss::party_seeds::from_bundle(bundle, u), held[u], 0, left, nullptr); + EXPECT_EQ(ignored.view.own, clean.view.own); + EXPECT_EQ(ignored.view.next, clean.view.next); + junk[0] ^= 1u; + auto bad = dpf::shuffle::shuffle_hidden_pass( + side, dpf::rss::party_seeds::from_bundle(bundle, side), held[side], 0, + left, &junk); + auto good = dpf::shuffle::shuffle_hidden_pass( + side, dpf::rss::party_seeds::from_bundle(bundle, side), held[side], 0, + left, &clean.out.data); + EXPECT_NE(bad.view.own, good.view.own); +} + +TEST(ShuffleHidden, LeftOutMaskMatchesAndMissesThePermutationSeed) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + auto party2 = dpf::rss::party_seeds::from_bundle(bundle, 2); + EXPECT_EQ(std::memcmp(&party2.with_prev, &bundle.k12, sizeof(bundle.k12)), 0); + EXPECT_EQ(std::memcmp(&party2.with_next, &bundle.k20, sizeof(bundle.k20)), 0); + EXPECT_NE(std::memcmp(&party2.with_prev, &bundle.k01, sizeof(bundle.k01)), 0); + EXPECT_NE(std::memcmp(&party2.with_next, &bundle.k01, sizeof(bundle.k01)), 0); + const auto pi_known = dpf::shuffle::permutation_from_seed(bundle.k01, 8, 0); + const auto pi_prev = dpf::shuffle::permutation_from_seed(party2.with_prev, 8, 0); + const auto pi_next = dpf::shuffle::permutation_from_seed(party2.with_next, 8, 0); + EXPECT_NE(pi_known, pi_prev); + EXPECT_NE(pi_known, pi_next); +} + +TEST(ShuffleHidden, RejectsBadPartiesAndShortMessages) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + dpf::shuffle::shuffle_party_view in{ + {1, 2}, + {3, 4}, + }; + auto seeds = dpf::rss::party_seeds::from_bundle(bundle, 0); + EXPECT_THROW( + dpf::shuffle::shuffle_hidden_pass(1, seeds, in, 0, 2, nullptr), + std::invalid_argument); + EXPECT_THROW( + dpf::shuffle::shuffle_hidden_pass(0, seeds, in, 0, 3, nullptr), + std::invalid_argument); + in.next.pop_back(); + EXPECT_THROW( + dpf::shuffle::shuffle_hidden_pass(0, seeds, in, 0, 2, nullptr), + std::invalid_argument); + in.next.push_back(4); + auto side = dpf::rss::party_seeds::from_bundle(bundle, 1); + EXPECT_THROW( + dpf::shuffle::shuffle_hidden_pass(1, side, in, 0, 2, nullptr), + std::invalid_argument); + std::vector short_msg{1}; + EXPECT_THROW(dpf::shuffle::shuffle_hidden_pass( + 1, side, in, 0, 2, &short_msg), + std::invalid_argument); + EXPECT_THROW(dpf::shuffle::permute(std::vector{1}, + std::vector{}), + std::invalid_argument); +} + +TEST(ShuffleHidden, PublicShuffleStillFollowsK01) +{ + auto bundle = dpf::rss::sample_seed_bundle(); + std::vector v{4, 9, 1, 7, 3}; + EXPECT_EQ(dpf::shuffle::shuffle_party_triple(v, bundle, 6), + dpf::shuffle::shuffle_clear(v, bundle, 6)); +} + +TEST(ShuffleHidden, ComposerRejectsAnEmptyColumn) +{ + dpf::protocol::composer c; + EXPECT_THROW(c.shuffle_hidden(0, 8), std::invalid_argument); + EXPECT_THROW(c.shuffle_hidden(4, 0), std::invalid_argument); +} diff --git a/test/tests/signed_prefix_test.cpp b/test/tests/signed_prefix_test.cpp index 81a5352..a46ce9c 100644 --- a/test/tests/signed_prefix_test.cpp +++ b/test/tests/signed_prefix_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "dpf.hpp" #include "grotto/constant_lut.hpp" diff --git a/test/tests/stress_scenarios_test.cpp b/test/tests/stress_scenarios_test.cpp index 8712a07..e8d971b 100644 --- a/test/tests/stress_scenarios_test.cpp +++ b/test/tests/stress_scenarios_test.cpp @@ -10,6 +10,7 @@ // incremental_test.cpp. #include +#include #include "dpf.hpp" #include "grotto/fixedpoint.hpp" @@ -242,6 +243,10 @@ void assign_wildcard_leaf_local(Key0 & k0, Key1 & k1, const ShareT & shr0, { auto & w0 = std::get(k0.leaf_nodes); auto & w1 = std::get(k1.leaf_nodes); + if (w0.is_ready()) + w0.begin_update(); + if (w1.is_ready()) + w1.begin_update(); const auto b0 = w0.compute_and_get_blinded_output_share(shr0); const auto b1 = w1.compute_and_get_blinded_output_share(shr1); const auto l0 = w0.compute_and_get_leaf_share(b1); @@ -552,7 +557,7 @@ TEST_F(StressScenariosTest, MlWildcardEvalPointThrowsBeforeAssign) auto [k0, k1] = dpf::make_dpf(x, dpf::at<8>(uint8_t{7}), dpf::at<12>(wc), uint16_t{1}); // Slot 1 is an unassigned wildcard: evaluating it must throw. - EXPECT_ANY_THROW((void)dpf::eval_point(dpf::out<1, 12>, k0, x)); + EXPECT_ANY_THROW(dpf::eval_point(dpf::out<1, 12>, k0, x)); (void)k1; } @@ -2038,7 +2043,7 @@ TEST_F(StressScenariosTest, MlPackedSmallWildcardAtNonTerminalAssignAll) EXPECT_NE(KT::meta[0].group_id, KT::meta[8].group_id); // Unassigned packed wildcards throw; deepest concrete still works. - EXPECT_ANY_THROW((void)dpf::eval_point(dpf::out<0, 12>, k0, x)); + EXPECT_ANY_THROW(dpf::eval_point(dpf::out<0, 12>, k0, x)); EXPECT_EQ(recon(*dpf::eval_point(dpf::out<8>, k0, x), *dpf::eval_point(dpf::out<8>, k1, x)), uint32_t{999}); @@ -2248,8 +2253,8 @@ TEST_F(StressScenariosTest, PrgCounterWrapperAesClassicEvalIncrements) const auto after_gen = prg::count(); EXPECT_GT(after_gen, before); - (void)dpf::eval_point(k0, x); - (void)dpf::eval_full(k0); + dpf::eval_point(k0, x); + dpf::eval_full(k0); const auto after_eval = prg::count(); EXPECT_GT(after_eval, after_gen); @@ -2271,8 +2276,8 @@ TEST_F(StressScenariosTest, PrgCounterWrapperLowmcMultilevelEvalIncrements) const auto bi2 = interior::count(); const auto be2 = exterior::count(); - (void)dpf::eval_point(dpf::out<0, 8>, k0, x); - (void)dpf::eval_full(dpf::out<1, 16>, k0); + dpf::eval_point(dpf::out<0, 8>, k0, x); + dpf::eval_full(dpf::out<1, 16>, k0); EXPECT_GT(interior::count(), bi2); EXPECT_GT(exterior::count(), be2); @@ -2302,3 +2307,80 @@ TEST_F(StressScenariosTest, PrgLowmcBothSidesPackedInterval) *dpf::eval_point(dpf::out<4>, k1, x)), uint32_t{55}); } +TEST_F(StressScenariosTest, PairedInnerProductLeafAndAncestor) +{ + using In = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(In{9}, std::uint32_t{7}, std::uint32_t{11}); + std::vector> rows; + std::uint64_t expect = 0; + for (In x = 4;; ++x) + { + const auto y0 = recon(*dpf::eval_point<0>(k0, x), *dpf::eval_point<0>(k1, x)); + const auto y1 = recon(*dpf::eval_point<1>(k0, x), *dpf::eval_point<1>(k1, x)); + const std::uint32_t w0 = x * 3u + 1u; + const std::uint32_t w1 = x * 5u + 2u; + rows.push_back({w0, w1}); + expect += static_cast(y0) * w0 + + static_cast(y1) * w1; + if (x == 12) + break; + } + const auto a = dpf::eval_inner_product<0, 1>(dpf::paired, k0, In{4}, In{12}, rows); + const auto b = dpf::eval_inner_product<0, 1>(dpf::paired, k1, In{4}, In{12}, rows); + EXPECT_EQ(recon(a, b), expect); + + const std::vector pts{2, 9, 40}; + const std::vector> seq_rows{{1, 2}, {3, 4}, {5, 6}}; + std::uint64_t seq_expect = 0; + for (std::size_t i = 0; i < pts.size(); ++i) + { + const auto y0 = recon(*dpf::eval_point<0>(k0, pts[i]), + *dpf::eval_point<0>(k1, pts[i])); + const auto y1 = recon(*dpf::eval_point<1>(k0, pts[i]), + *dpf::eval_point<1>(k1, pts[i])); + seq_expect += static_cast(y0) * seq_rows[i][0] + + static_cast(y1) * seq_rows[i][1]; + } + EXPECT_EQ(recon( + dpf::eval_sequence_inner_product<0, 1>(k0, pts.begin(), pts.end(), seq_rows), + dpf::eval_sequence_inner_product<0, 1>(k1, pts.begin(), pts.end(), seq_rows)), + seq_expect); + const auto recipe = dpf::make_sequence_recipe(pts.begin(), pts.end()); + EXPECT_EQ(recon( + dpf::eval_sequence_inner_product<0, 1>(k0, recipe, pts.begin(), pts.end(), seq_rows), + dpf::eval_sequence_inner_product<0, 1>(k1, recipe, pts.begin(), pts.end(), seq_rows)), + seq_expect); + + auto [a0, a1] = dpf::make_dpf(In{0x2a}, dpf::at<4>(std::uint8_t{5}), std::uint8_t{9}); + const std::vector ap{0x20, 0x2a, 0x2b, 0x30}; + const std::vector> ar{{1, 1}, {2, 3}, {4, 5}, {6, 7}}; + std::uint64_t anc = 0; + for (std::size_t i = 0; i < ap.size(); ++i) + { + const auto y0 = recon(*dpf::eval_point(dpf::out<0>, a0, ap[i]), + *dpf::eval_point(dpf::out<0>, a1, ap[i])); + const auto y1 = recon(*dpf::eval_point(dpf::out<1>, a0, ap[i]), + *dpf::eval_point(dpf::out<1>, a1, ap[i])); + anc += static_cast(y0) * ar[i][0] + + static_cast(y1) * ar[i][1]; + } + EXPECT_EQ(recon( + dpf::eval_sequence_inner_product<0, 1>(a0, ap.begin(), ap.end(), ar), + dpf::eval_sequence_inner_product<0, 1>(a1, ap.begin(), ap.end(), ar)), + anc); + + std::vector full(256); + std::uint64_t full_expect = 0; + for (unsigned x = 0; x < 256; ++x) + { + full[x] = (x * 3u + 1u) & 0x1fu; + const auto y = recon(*dpf::eval_point(k0, static_cast(x)), + *dpf::eval_point(k1, static_cast(x))); + full_expect += static_cast(y) * full[x]; + } + EXPECT_EQ(recon( + dpf::eval_full_inner_product<0>(dpf::paired, k0, full), + dpf::eval_full_inner_product<0>(dpf::paired, k1, full)), + full_expect); +} + diff --git a/test/tests/types_test.cpp b/test/tests/types_test.cpp index 9e93cf3..5647436 100644 --- a/test/tests/types_test.cpp +++ b/test/tests/types_test.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -248,7 +249,7 @@ TEST(TypeTraits, IntegralSelectionAndBuiltinWidths) EXPECT_TRUE(dpf::utils::has_operators_plus_minus_v); EXPECT_TRUE(dpf::utils::has_operators_plus_minus_v); EXPECT_FALSE(dpf::utils::has_characteristic_two_v); - EXPECT_FALSE(dpf::utils::has_characteristic_two_v); + EXPECT_TRUE(dpf::utils::has_characteristic_two_v); EXPECT_FALSE(dpf::utils::is_xor_wrapper_v); EXPECT_FALSE(dpf::is_wildcard_v); } @@ -293,6 +294,27 @@ TEST(TypeTraits, BoundaryWidthsAndOutputPacking) EXPECT_EQ((dpf::outputs_per_leaf_v), 16u); EXPECT_EQ((dpf::outputs_per_leaf_v), 4u); EXPECT_EQ((dpf::outputs_per_leaf_v), 128u); + EXPECT_EQ((dpf::utils::bitlength_of_output_v), 1u); + EXPECT_EQ((dpf::utils::bitlength_of_output_v), 2u); + EXPECT_EQ((dpf::utils::bitlength_of_output_v), 4u); + EXPECT_EQ((dpf::utils::bitlength_of_output_v), 8u); + EXPECT_EQ((dpf::utils::bitlength_of_output_v), 16u); + EXPECT_EQ((dpf::utils::bitlength_of_output_v), 32u); + EXPECT_EQ((dpf::utils::bitlength_of_output_v), 64u); + EXPECT_EQ((dpf::outputs_per_leaf_v), 128u); + EXPECT_EQ((dpf::outputs_per_leaf_v), 64u); + EXPECT_EQ((dpf::outputs_per_leaf_v), 32u); + EXPECT_EQ((dpf::outputs_per_leaf_v), 16u); + EXPECT_EQ((dpf::outputs_per_leaf_v), 8u); + EXPECT_EQ((dpf::outputs_per_leaf_v), 4u); + EXPECT_EQ((dpf::outputs_per_leaf_v), 2u); + EXPECT_EQ((dpf::outputs_per_leaf_v), 256u); + EXPECT_EQ((dpf::outputs_per_leaf_v), 4u); + EXPECT_TRUE(dpf::utils::is_packed_subbyte_v); + EXPECT_TRUE(dpf::utils::is_packed_subbyte_v); + EXPECT_FALSE(dpf::utils::is_packed_subbyte_v); + EXPECT_TRUE(dpf::utils::has_characteristic_two_v); + EXPECT_EQ((dpf::block_length_of_leaf_v), 1u); EXPECT_EQ((dpf::outputs_per_leaf_v, simde__m128i>), 8u); EXPECT_EQ((dpf::block_length_of_leaf_v), 1u); EXPECT_EQ((dpf::block_length_of_leaf_v), 2u); diff --git a/test/tests/vdpf_adversarial_test.cpp b/test/tests/vdpf_adversarial_test.cpp new file mode 100644 index 0000000..6daca7a --- /dev/null +++ b/test/tests/vdpf_adversarial_test.cpp @@ -0,0 +1,248 @@ +/// @file vdpf_adversarial_test.cpp +/// @brief Brute-force and corruption checks for verifiable evaluation. +/// @details Covers bug classes seen while bringing the proofs up: subtractive +/// reconstruction is not commutative, a single untouched control bit +/// can hide a seed flip, and a proof convention must still reject a +/// flipped token. Small domains are checked at every point. +#include + +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +using Input = std::uint8_t; + +struct Pad +{ + std::uint64_t n = 1; + simde__m128i block() + { + auto v = simde_mm_set_epi64x(static_cast(n), + static_cast(n * 9 + 3)); + n += 2; + return v; + } + void fill(void * p, std::size_t nbytes) + { + auto * b = static_cast(p); + for (std::size_t i = 0; i < nbytes; ++i) + b[i] = static_cast(n + i * 17); + n += nbytes; + } + std::uint8_t bit() { return static_cast(n++ & 1u); } +}; + +dpf::ds_randomness tape() +{ + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + return {dpf::uniform_sample, Pad{}}; + HEDLEY_PRAGMA(GCC diagnostic pop) +} + +template +void expect_ordered_reconstruct(const Y0 & y0, const Y1 & y1, const Want & want) +{ + EXPECT_EQ(dpf::reconstruct(y0, y1), want); + // The typed overload accepts either party order. A raw subtraction does not. + EXPECT_EQ(dpf::reconstruct(y1, y0), want); + const auto swapped = static_cast(y1.raw() - y0.raw()); + if (y0.raw() != y1.raw()) + EXPECT_NE(swapped, want); +} + +} // namespace + +TEST(VdpfAdversarial, PointFullDomainValuesAndProofs) +{ + const Input alpha = 0; + const std::uint64_t beta = 9; + auto [k0, k1] = dpf::make_dpf(alpha, beta, dpf::verifiable{}); + for (int x = 0; x < 256; ++x) + { + const Input q = static_cast(x); + dpf::proof_token a{}, b{}; + const auto y0 = *dpf::eval_point(k0, q, dpf::prove(a)); + const auto y1 = *dpf::eval_point(k1, q, dpf::prove(b)); + const std::uint64_t want = q == alpha ? beta : 0; + expect_ordered_reconstruct(y0, y1, want); + EXPECT_TRUE(dpf::verify(a, b)) << int(q); + } +} + +TEST(VdpfAdversarial, HalfTreeFullDomainValuesAndProofs) +{ + using Ht = dpf::prg::aes128_ccr; + const Input alpha = 255; + const std::uint64_t beta = 0x1001; + auto [k0, k1] = dpf::make_dpf(alpha, beta, dpf::verifiable{}); + EXPECT_TRUE(decltype(k0)::tree::is_half_tree); + for (int x = 0; x < 256; ++x) + { + const Input q = static_cast(x); + dpf::proof_token a{}, b{}; + const auto y0 = *dpf::eval_point(k0, q, dpf::prove(a)); + const auto y1 = *dpf::eval_point(k1, q, dpf::prove(b)); + expect_ordered_reconstruct(y0, y1, q == alpha ? beta : 0ull); + EXPECT_TRUE(dpf::verify(a, b)) << int(q); + } +} + +TEST(VdpfAdversarial, ComparisonAndBlockedFullDomain) +{ + const Input alpha = 0x40; + auto native = dpf::make_dpf(alpha, dpf::lt(std::uint64_t{1}), dpf::verifiable{}); + auto blocked = dpf::make_dpf(alpha, + dpf::block_width<4>(dpf::lt(std::uint64_t{1})), dpf::verifiable{}); + for (int x = 0; x < 256; ++x) + { + const Input q = static_cast(x); + dpf::proof_token n0{}, n1{}, b0{}, b1{}; + const auto ny0 = dpf::eval_point(dpf::cmp, native.first, q, dpf::prove(n0)); + const auto ny1 = dpf::eval_point(dpf::cmp, native.second, q, dpf::prove(n1)); + const auto by0 = dpf::eval_point(dpf::cmp, blocked.first, q, dpf::prove(b0)); + const auto by1 = dpf::eval_point(dpf::cmp, blocked.second, q, dpf::prove(b1)); + const std::uint64_t want = q < alpha ? 1u : 0u; + EXPECT_EQ(dpf::reconstruct(ny0, ny1) & native.first.cmp().mask, want) << int(q); + EXPECT_EQ(dpf::reconstruct(by0, by1) & blocked.first.cmp().mask, want) << int(q); + EXPECT_TRUE(dpf::verify(n0, n1)) << int(q); + EXPECT_TRUE(dpf::verify(b0, b1)) << int(q); + } +} + +TEST(VdpfAdversarial, ExtractableFp61FullDomainSketch) +{ + const Input alpha = 0x7f; + const dpf::fp61 beta{42}; + auto [k0, k1] = dpf::make_dpf(alpha, beta, dpf::extractable{}, dpf::verifiable{}); + std::array s0{}, s1{}, r{}; + for (int x = 0; x < 256; ++x) + { + const Input q = static_cast(x); + dpf::proof_token a{}, b{}; + const auto y0 = *dpf::eval_point(k0, q, dpf::prove(a)); + const auto y1 = *dpf::eval_point(k1, q, dpf::prove(b)); + EXPECT_EQ(dpf::reconstruct(y0, y1), q == alpha ? beta : dpf::fp61{0}) << int(q); + EXPECT_TRUE(dpf::verify(a, b)) << int(q); + s0[static_cast(x)] = y0.raw(); + s1[static_cast(x)] = y1.raw(); + r[static_cast(x)] = dpf::fp61{static_cast(3 * x + 1)}; + } + const auto honest0 = s0; + EXPECT_TRUE(dpf::sketch_verify(dpf::sketch_fold(s0, r), dpf::sketch_fold(s1, r))); + // A second hot point is weight 2. Changing only the magnitude of the + // single hot point stays weight 1 and must still verify. + s0[0] = s0[0] + beta; + EXPECT_FALSE(dpf::sketch_verify(dpf::sketch_fold(s0, r), dpf::sketch_fold(s1, r))); + + auto r_bad = r; + r_bad[alpha] = r_bad[alpha] + dpf::fp61{1}; + EXPECT_FALSE(dpf::sketch_verify( + dpf::sketch_fold(honest0, r_bad), dpf::sketch_fold(s1, r))); +} + +TEST(VdpfAdversarial, SeedAndWordCorruptionAreVisible) +{ + const Input alpha = 0x2a; + auto [k0, k1] = dpf::make_dpf(alpha, std::uint64_t{5}, dpf::verifiable{}); + EXPECT_TRUE(dpf::same_public_part(k0, k1)); + + for (auto & cs : const_cast::correction_seeds_array &>( + k0.correction_seeds())) + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::same_public_part(k0, k1)); + int proof_fail = 0; + for (int x = 0; x < 256; ++x) + { + const Input q = static_cast(x); + dpf::proof_token a{}, b{}; + (void)*dpf::eval_point(k0, q, dpf::prove(a)); + (void)*dpf::eval_point(k1, q, dpf::prove(b)); + if (!dpf::verify(a, b)) + ++proof_fail; + } + EXPECT_GT(proof_fail, 0); + + auto [h0, h1] = dpf::make_dpf(alpha, std::uint64_t{5}, dpf::verifiable{}); + // A level-0 word is invisible when that party's root control bit is 0. + // Flip every correction word so a later on-path level is corrupted. + auto & words = const_cast::correction_words_array &>( + h0.correction_words()); + for (auto & word : words) + word = simde_mm_xor_si128(word, simde_mm_set1_epi8(0x5a)); + EXPECT_FALSE(dpf::same_public_part(h0, h1)); + int value_fail = 0; + for (int x = 0; x < 256; ++x) + { + const Input q = static_cast(x); + const auto got = dpf::reconstruct(*dpf::eval_point(h0, q), *dpf::eval_point(h1, q)); + const std::uint64_t want = q == alpha ? 5u : 0u; + if (got != want) + ++value_fail; + } + EXPECT_GT(value_fail, 0); +} + +TEST(VdpfAdversarial, EmptySequenceProofVerifies) +{ + auto [k0, k1] = dpf::make_dpf(Input{1}, std::uint64_t{1}, dpf::verifiable{}); + const std::vector none; + dpf::proof_token a{}, b{}; + dpf::prove_sequence(k0, none.begin(), none.end(), dpf::prove(a)); + dpf::prove_sequence(k1, none.begin(), none.end(), dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); +} + +TEST(VdpfAdversarial, GenevalFullDomainProofAndPartyOrder) +{ + const Input alpha = 0x3c; + const Input x0 = 0x10; + const Input x1 = static_cast(alpha ^ x0); + const std::uint64_t y = 0x7e; + auto g = dpf::geneval_full(x0, x1, tape(), y); + ASSERT_EQ(g.party0.size(), 256u); + EXPECT_TRUE(dpf::verify(g.proof0, g.proof1)); + for (int q = 0; q < 256; ++q) + { + const auto want = static_cast(q) == alpha ? y : 0ull; + EXPECT_EQ(static_cast(g.party0[static_cast(q)] + - g.party1[static_cast(q)]), + want) << q; + if (g.party0[static_cast(q)] != g.party1[static_cast(q)]) + { + EXPECT_NE(static_cast(g.party1[static_cast(q)] + - g.party0[static_cast(q)]), + want) << q; + } + } + g.proof0[0] = simde_mm_xor_si128(g.proof0[0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(g.proof0, g.proof1)); +} + +TEST(VdpfAdversarial, MacDetectsValueAndTagCorruption) +{ + const auto key = dpf::sample_mac_key(); + auto [a, b] = dpf::mac_share_value(dpf::fp61{20}, key); + EXPECT_TRUE(dpf::mac_verify(a, b, key)); + const auto scaled = dpf::mac_scale(a, dpf::fp61{2}); + const auto scaled_b = dpf::mac_scale(b, dpf::fp61{2}); + EXPECT_TRUE(dpf::mac_verify(scaled, scaled_b, key)); + EXPECT_EQ((scaled.value + scaled_b.value).raw(), (dpf::fp61{20} * dpf::fp61{2}).raw()); + + a.value = a.value + dpf::fp61{1}; + EXPECT_FALSE(dpf::mac_verify(a, b, key)); + a.value = a.value - dpf::fp61{1}; + a.tag = a.tag + dpf::fp61{1}; + EXPECT_FALSE(dpf::mac_verify(a, b, key)); + + a.tag = a.tag - dpf::fp61{1}; + std::array, 1> left{a}; + std::array, 2> right{b, b}; + std::array coeffs{dpf::fp61{1}}; + EXPECT_FALSE(dpf::mac_verify_batch(left, right, coeffs, key)); +} diff --git a/test/tests/vdpf_regression_test.cpp b/test/tests/vdpf_regression_test.cpp new file mode 100644 index 0000000..13e44e5 --- /dev/null +++ b/test/tests/vdpf_regression_test.cpp @@ -0,0 +1,399 @@ +/// @file vdpf_regression_test.cpp +/// @brief Holistic VDPF regressions from DCF/Grotto proof bring-up failures. +/// @details Patterns covered: +/// - path-memo re-fold cancel (blocked parks / native spine) +/// - off-path vs on-path blocked proves (CS level vs checkpoint index) +/// - domain-tag survival past `hash_node` level masking +/// - keygen `make_cs` level must match fold level +/// - warm interval memoizer must not skip upper proof folds +/// - multi-endpoint signed/unsigned prefix aggregates +/// - endpoint-equal-alpha prefix stability across RNG draws +#include +#include + +#include +#include +#include +#include + +#include "dpf.hpp" +#include "grotto/prefix_parity.hpp" +#include "grotto/offset_horner.hpp" + +namespace +{ + +using Input = std::uint8_t; + +bool tokens_equal(const dpf::proof_token & a, const dpf::proof_token & b) +{ + return dpf::detail::vdpf::proof_equal(a, b); +} + +} // namespace + +// --- Domain separation / CS tagging --------------------------------------- + +TEST(VdpfRegression, HashNodeRetainsHighLevelBits) +{ + // fold_spine_tag is bit 15; masking to 8 bits would drop it and make + // blocked CS verify against native folds. + constexpr std::size_t tagged = + dpf::detail::blocked::fold_spine_tag | std::size_t{3}; + const simde__m128i seed = simde_mm_set_epi64x(0x1111, 0x2222); + const auto h_native = dpf::detail::vdpf::hash_node(3, 0x2a, seed); + const auto h_tagged = dpf::detail::vdpf::hash_node(tagged, 0x2a, seed); + EXPECT_NE(std::memcmp(&h_native, &h_tagged, sizeof(h_native)), 0); +} + +TEST(VdpfRegression, BlockedKeygenCsUsesSpineTag) +{ + auto [k0, k1] = dpf::make_dpf(Input{0x2a}, + dpf::block_width<4>(dpf::lt(std::uint64_t{1})), dpf::verifiable{}); + auto [n0, n1] = dpf::make_dpf(Input{0x2a}, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + // Public CS arrays must diverge: blocked keygen tags make_cs levels. + EXPECT_NE(std::memcmp(k0.correction_seeds().data(), + n0.correction_seeds().data(), + sizeof(decltype(k0)::correction_seeds_array)), + 0); + (void)k1; + (void)n1; +} + +// --- Path-memo idempotence (re-fold cancel) -------------------------------- + +TEST(VdpfRegression, BlockedEvalShareProveIsIdempotentOnWarmPath) +{ + // Re-folding parked siblings on a warm path XORs them out of the token. + auto [k0, k1] = dpf::make_dpf(Input{0x2a}, + dpf::block_width<4>(dpf::lt(std::uint64_t{1})), dpf::verifiable{}); + const Input x{0x11}; // off-path, parks right children + dpf::proof_token a{}, b{}; + dpf::detail::vdpf::init_proof(a, k0); + dpf::detail::vdpf::init_proof(b, k1); + auto p0 = dpf::make_basic_path_memoizer(k0); + auto p1 = dpf::make_basic_path_memoizer(k1); + dpf::detail::blocked::eval_share(k0, x, p0, &a); + dpf::detail::blocked::eval_share(k1, x, p1, &b); + EXPECT_TRUE(dpf::verify(a, b)); + const auto once0 = a; + const auto once1 = b; + dpf::detail::blocked::eval_share(k0, x, p0, &a); + dpf::detail::blocked::eval_share(k1, x, p1, &b); + EXPECT_TRUE(tokens_equal(a, once0)); + EXPECT_TRUE(tokens_equal(b, once1)); + EXPECT_TRUE(dpf::verify(a, b)); +} + +TEST(VdpfRegression, NativePathProveIsIdempotentOnWarmPath) +{ + auto [k0, k1] = dpf::make_dpf(Input{0x2a}, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + const Input x{0x11}; + dpf::proof_token a{}, b{}; + dpf::detail::vdpf::init_proof(a, k0); + dpf::detail::vdpf::init_proof(b, k1); + auto p0 = dpf::make_basic_path_memoizer(k0); + auto p1 = dpf::make_basic_path_memoizer(k1); + dpf::detail::ensure_level(k0, x, p0, decltype(k0)::depth, &a); + dpf::detail::ensure_level(k1, x, p1, decltype(k1)::depth, &b); + const auto once0 = a; + const auto once1 = b; + dpf::detail::ensure_level(k0, x, p0, decltype(k0)::depth, &a); + dpf::detail::ensure_level(k1, x, p1, decltype(k1)::depth, &b); + EXPECT_TRUE(tokens_equal(a, once0)); + EXPECT_TRUE(tokens_equal(b, once1)); + EXPECT_TRUE(dpf::verify(a, b)); +} + +TEST(VdpfRegression, PublicProveOnWarmPathMatchesColdNonZero) +{ + auto [k0, k1] = dpf::make_dpf(Input{0x2a}, std::uint64_t{9}, + dpf::verifiable{}); + const Input x{0x2a}; + auto path0 = dpf::make_basic_path_memoizer(k0); + auto path1 = dpf::make_basic_path_memoizer(k1); + dpf::proof_token cold0{}, cold1{}; + (void)*dpf::eval_point(k0, x, dpf::prove(cold0)); + (void)*dpf::eval_point(k1, x, dpf::prove(cold1)); + EXPECT_TRUE(dpf::verify(cold0, cold1)); + EXPECT_FALSE(tokens_equal(cold0, dpf::detail::vdpf::zero_proof())); + + (void)*dpf::eval_point(k0, x, path0); + (void)*dpf::eval_point(k1, x, path1); + dpf::proof_token warm0{}, warm1{}; + (void)*dpf::eval_point(k0, x, dpf::prove(warm0), path0); + (void)*dpf::eval_point(k1, x, dpf::prove(warm1), path1); + EXPECT_TRUE(dpf::verify(warm0, warm1)); + EXPECT_TRUE(tokens_equal(warm0, cold0)); + EXPECT_TRUE(tokens_equal(warm1, cold1)); + EXPECT_FALSE(dpf::verify(dpf::detail::vdpf::zero_proof(), + dpf::detail::vdpf::zero_proof())); +} + +TEST(VdpfRegression, BlockedMultiEndpointSignedPrefixKeepsSharedParks) +{ + // Two endpoints that share a left turn: without resume-aware park folds + // the second walk cancels the first's parked contribution. + auto [k0, k1] = dpf::make_dpf(Input{0x40}, + dpf::block_width<4>(dpf::gt(std::uint64_t{1})), dpf::verifiable{}); + // Both 0x10 and 0x18 start with MSB bits that park the same early sibling + // under a typical block schedule on uint8. + const std::array ends{Input{0x10}, Input{0x18}}; + + dpf::proof_token multi0{}, multi1{}; + auto s0 = grotto::signed_prefix_parities(k0, ends, dpf::prove(multi0)); + auto s1 = grotto::signed_prefix_parities(k1, ends, dpf::prove(multi1)); + EXPECT_TRUE(dpf::verify(multi0, multi1)); + for (std::size_t i = 0; i < ends.size(); ++i) + EXPECT_EQ((s0[i] + s1[i]) & k0.cmp().mask, + (dpf::eval_point(dpf::cmp, k0, ends[i]).raw() + + dpf::eval_point(dpf::cmp, k1, ends[i]).raw()) + & k0.cmp().mask); + + // Reference: fold e0 then e1 on one path without re-init (same as API). + dpf::proof_token ref0{}, ref1{}; + dpf::detail::vdpf::init_proof(ref0, k0); + dpf::detail::vdpf::init_proof(ref1, k1); + auto p0 = dpf::make_basic_path_memoizer(k0); + auto p1 = dpf::make_basic_path_memoizer(k1); + dpf::detail::blocked::eval_share(k0, ends[0], p0, &ref0); + dpf::detail::blocked::eval_share(k0, ends[1], p0, &ref0); + dpf::detail::blocked::eval_share(k1, ends[0], p1, &ref1); + dpf::detail::blocked::eval_share(k1, ends[1], p1, &ref1); + dpf::detail::vdpf::fold_output_binding(ref0, k0); + dpf::detail::vdpf::fold_output_binding(ref1, k1); + EXPECT_TRUE(tokens_equal(multi0, ref0)); + EXPECT_TRUE(tokens_equal(multi1, ref1)); + + // Replaying only the tip endpoint on the warm path is idempotent. + dpf::proof_token path0{}, path1{}; + dpf::detail::vdpf::init_proof(path0, k0); + dpf::detail::vdpf::init_proof(path1, k1); + auto q0 = dpf::make_basic_path_memoizer(k0); + auto q1 = dpf::make_basic_path_memoizer(k1); + dpf::detail::blocked::eval_share(k0, ends[0], q0, &path0); + dpf::detail::blocked::eval_share(k0, ends[1], q0, &path0); + dpf::detail::blocked::eval_share(k1, ends[0], q1, &path1); + dpf::detail::blocked::eval_share(k1, ends[1], q1, &path1); + const auto path_once0 = path0; + const auto path_once1 = path1; + dpf::detail::blocked::eval_share(k0, ends[1], q0, &path0); + dpf::detail::blocked::eval_share(k1, ends[1], q1, &path1); + EXPECT_TRUE(tokens_equal(path0, path_once0)); + EXPECT_TRUE(tokens_equal(path1, path_once1)); +} + +// --- Off-path / on-path / all-ones blocked point --------------------------- + +TEST(VdpfRegression, BlockedPointProveOffPathOnPathAndAllOnes) +{ + auto [k0, k1] = dpf::make_dpf(Input{0x2a}, + dpf::block_width<4>(dpf::lt(std::uint64_t{1})), dpf::verifiable{}); + const Input queries[] = { + Input{0x2a}, // on-path + Input{0x11}, // off-path with parks + Input{0xff}, // never parks (all right) + Input{0x00}, // parks every level + }; + for (Input x : queries) + { + dpf::proof_token a{}, b{}; + dpf::eval_point(dpf::cmp, k0, x, dpf::prove(a)); + dpf::eval_point(dpf::cmp, k1, x, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)) << "query=" << int(x); + } +} + +TEST(VdpfRegression, BlockedTokenDiffersFromNativeForSameAlpha) +{ + const Input alpha{0x2a}; + const Input x{0x11}; + auto [b0, b1] = dpf::make_dpf(alpha, + dpf::block_width<4>(dpf::lt(std::uint64_t{1})), dpf::verifiable{}); + auto [n0, n1] = dpf::make_dpf(alpha, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + dpf::proof_token bp0{}, bp1{}, np0{}, np1{}; + dpf::eval_point(dpf::cmp, b0, x, dpf::prove(bp0)); + dpf::eval_point(dpf::cmp, b1, x, dpf::prove(bp1)); + dpf::eval_point(dpf::cmp, n0, x, dpf::prove(np0)); + dpf::eval_point(dpf::cmp, n1, x, dpf::prove(np1)); + EXPECT_TRUE(dpf::verify(bp0, bp1)); + EXPECT_TRUE(dpf::verify(np0, np1)); + EXPECT_FALSE(tokens_equal(bp0, np0)); +} + +// --- Warm interval memoizer ------------------------------------------------ + +TEST(VdpfRegression, CmpIntervalProveIgnoresWarmMemoizer) +{ + auto [k0, k1] = dpf::make_dpf(Input{0x20}, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + using Key = std::decay_t; + const Input lo{0x10}; + const Input hi{0x28}; + + dpf::proof_token cold0{}, cold1{}; + dpf::prove_cmp_interval(k0, lo, hi, dpf::prove(cold0)); + dpf::prove_cmp_interval(k1, lo, hi, dpf::prove(cold1)); + EXPECT_TRUE(dpf::verify(cold0, cold1)); + + // Warm a full-tree memo on a wider interval, then prove on [lo,hi] + // through the same memo. Proving must clear/revisit upper levels. + constexpr std::size_t stop = + Key::cmp_depth == 0 ? Key::depth : Key::cmp_depth; + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + dpf::detail::incr::cmp_full_interval_memo memo0{256}; + dpf::detail::incr::cmp_full_interval_memo memo1{256}; + HEDLEY_PRAGMA(GCC diagnostic pop) + auto warm_buf0 = + dpf::make_output_buffer(dpf::cmp, k0, Input{0x00}, Input{0x3f}); + auto warm_buf1 = + dpf::make_output_buffer(dpf::cmp, k1, Input{0x00}, Input{0x3f}); + dpf::eval_interval(dpf::cmp, k0, Input{0x00}, Input{0x3f}, warm_buf0, + memo0); + dpf::eval_interval(dpf::cmp, k1, Input{0x00}, Input{0x3f}, warm_buf1, + memo1); + + auto buf0 = dpf::make_output_buffer(dpf::cmp, k0, lo, hi); + auto buf1 = dpf::make_output_buffer(dpf::cmp, k1, lo, hi); + dpf::proof_token warm0{}, warm1{}; + dpf::eval_interval(dpf::cmp, k0, lo, hi, buf0, memo0, dpf::prove(warm0)); + dpf::eval_interval(dpf::cmp, k1, lo, hi, buf1, memo1, dpf::prove(warm1)); + EXPECT_TRUE(dpf::verify(warm0, warm1)); + EXPECT_TRUE(tokens_equal(cold0, warm0)); + EXPECT_TRUE(tokens_equal(cold1, warm1)); +} + +// --- Sequence / path-memo aggregate without re-init ------------------------ + +TEST(VdpfRegression, CmpSequenceProveMatchesIntervalRunCovers) +{ + // prove_cmp_sequence folds contiguous runs as intervals, not point walks. + auto [k0, k1] = dpf::make_dpf(Input{0x55}, dpf::gt(std::uint64_t{1}), + dpf::verifiable{}); + const Input xs[] = {0x10, 0x11, 0x40, 0x41}; + + dpf::proof_token seq0{}, seq1{}; + dpf::prove_cmp_sequence(k0, std::begin(xs), std::end(xs), dpf::prove(seq0)); + dpf::prove_cmp_sequence(k1, std::begin(xs), std::end(xs), dpf::prove(seq1)); + EXPECT_TRUE(dpf::verify(seq0, seq1)); + + dpf::proof_token runs0{}, runs1{}; + dpf::detail::vdpf::init_proof(runs0, k0); + dpf::detail::vdpf::init_proof(runs1, k1); + dpf::detail::incr::prove_fold_cmp_interval(k0, Input{0x10}, Input{0x11}, + runs0); + dpf::detail::incr::prove_fold_cmp_interval(k0, Input{0x40}, Input{0x41}, + runs0); + dpf::detail::incr::prove_fold_cmp_interval(k1, Input{0x10}, Input{0x11}, + runs1); + dpf::detail::incr::prove_fold_cmp_interval(k1, Input{0x40}, Input{0x41}, + runs1); + dpf::detail::vdpf::fold_output_binding(runs0, k0); + dpf::detail::vdpf::fold_output_binding(runs1, k1); + EXPECT_TRUE(tokens_equal(seq0, runs0)); + EXPECT_TRUE(tokens_equal(seq1, runs1)); + + // eval_sequence(cmp, ..., prove) uses path-memo point folds — a different + // transcript from interval-run covers. Both must verify; they need not match. + auto buf0 = dpf::make_output_buffer(dpf::cmp, k0, 4); + auto buf1 = dpf::make_output_buffer(dpf::cmp, k1, 4); + dpf::proof_token e0{}, e1{}; + dpf::eval_sequence(dpf::cmp, k0, std::begin(xs), std::end(xs), buf0, + dpf::prove(e0)); + dpf::eval_sequence(dpf::cmp, k1, std::begin(xs), std::end(xs), buf1, + dpf::prove(e1)); + EXPECT_TRUE(dpf::verify(e0, e1)); + EXPECT_FALSE(tokens_equal(seq0, e0)); +} + +// --- Unsigned prefix vs resumed point folds -------------------------------- + +TEST(VdpfRegression, UnsignedPrefixTokenMatchesResumedPointFolds) +{ + // Bit payload: unsigned prefix parity is a bit-DPF / XOR gadget. + auto [k0, k1] = dpf::make_dpf(Input{0x2a}, dpf::bit{1}, dpf::verifiable{}); + const std::array ends{Input{0x10}, Input{0x2b}, Input{0x40}}; + + dpf::proof_token pref0{}, pref1{}; + auto [p0, n0] = grotto::prefix_parities(k0, ends, dpf::prove(pref0)); + auto [p1, n1] = grotto::prefix_parities(k1, ends, dpf::prove(pref1)); + (void)n0; + (void)n1; + EXPECT_TRUE(dpf::verify(pref0, pref1)); + for (std::size_t i = 0; i < ends.size(); ++i) + EXPECT_EQ(p0[i] ^ p1[i], ends[i] > Input{0x2a}); + + const auto again0 = pref0; + const auto again1 = pref1; + grotto::prefix_parities(k0, ends, dpf::prove(pref0)); + grotto::prefix_parities(k1, ends, dpf::prove(pref1)); + EXPECT_TRUE(tokens_equal(pref0, again0)); + EXPECT_TRUE(tokens_equal(pref1, again1)); +} + +TEST(VdpfRegression, PrefixParityAtAlphaIsExclusiveAndStable) +{ + // Exclusive of alpha: endpoint == alpha must reconstruct to 0 for every + // key. A uint64 payload is the wrong gadget type and used to look "flaky". + const Input alpha{0x2a}; + const std::array ends{alpha}; + for (int t = 0; t < 32; ++t) + { + auto [k0, k1] = dpf::make_dpf(alpha, dpf::bit{1}); + auto [p0, n0] = grotto::prefix_parities(k0, ends); + auto [p1, n1] = grotto::prefix_parities(k1, ends); + (void)n0; + (void)n1; + EXPECT_FALSE(p0[0] ^ p1[0]) << "trial " << t; + } +} + +// --- Offset Horner / poly multi-power batch -------------------------------- + +TEST(VdpfRegression, OffsetHornerPerPowerTokensIndependent) +{ + constexpr std::size_t D = 2; + const Input center = 12; + auto mat = grotto::make_offset_horner_keys(center, dpf::verifiable{}); + const std::vector knots{0, 10, 50}; + const std::vector> coeff{ + {1, 0, 0}, {0, 2, 0}, {7, 1, 3}}; + const Input eta = 3; + dpf::proof_token t0[D + 1]{}, t1[D + 1]{}; + const auto v0 = grotto::offset_horner_eval<0, D, Input, true>( + mat, knots, coeff, eta, t0); + const auto v1 = grotto::offset_horner_eval<1, D, Input, true>( + mat, knots, coeff, eta, t1); + EXPECT_EQ(v0 + v1, grotto::offset_horner_clear(center, knots, coeff, eta)); + for (std::size_t m = 0; m <= D; ++m) + EXPECT_TRUE(dpf::verify(t0[m], t1[m])); + // Tamper power 1 only; other powers still verify. + t0[1][0] = simde_mm_xor_si128(t0[1][0], simde_mm_set1_epi8(0x7e)); + EXPECT_FALSE(dpf::verify(t0[1], t1[1])); + EXPECT_TRUE(dpf::verify(t0[0], t1[0])); + EXPECT_TRUE(dpf::verify(t0[2], t1[2])); +} + +TEST(VdpfRegression, SignedPrefixBlockedProveValuesMatchDense) +{ + auto [b0, b1] = dpf::make_dpf(Input{0x30}, + dpf::block_width<4>(dpf::gt(std::uint64_t{1})), dpf::verifiable{}); + auto [d0, d1] = dpf::make_dpf(Input{0x30}, dpf::gt(std::uint64_t{1}), + dpf::verifiable{}); + const std::array ends{Input{0x10}, Input{0x20}, Input{0x50}}; + dpf::proof_token bp0{}, bp1{}; + auto bs0 = grotto::signed_prefix_parities(b0, ends, dpf::prove(bp0)); + auto bs1 = grotto::signed_prefix_parities(b1, ends, dpf::prove(bp1)); + EXPECT_TRUE(dpf::verify(bp0, bp1)); + auto ds0 = grotto::signed_prefix_parities(d0, ends); + auto ds1 = grotto::signed_prefix_parities(d1, ends); + for (std::size_t i = 0; i < ends.size(); ++i) + { + EXPECT_EQ((bs0[i] + bs1[i]) & b0.cmp().mask, + (ds0[i] + ds1[i]) & d0.cmp().mask); + } +} diff --git a/test/tests/verifiable_test.cpp b/test/tests/verifiable_test.cpp index caee397..f34dabb 100644 --- a/test/tests/verifiable_test.cpp +++ b/test/tests/verifiable_test.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -6,6 +7,9 @@ #include #include "dpf.hpp" +#include "grotto/offset_horner.hpp" +#include "grotto/offset_poly.hpp" +#include "grotto/carry.hpp" using Interior = dpf::prg::aes128; using Exterior = dpf::prg::aes128; @@ -39,11 +43,13 @@ TEST(Verifiable, TamperedCwRejects) auto [k0, k1] = dpf::make_dpf(Input{3}, std::uint64_t{1}, dpf::verifiable{}); - // Flip one bit of a public correction word on party 0's view of the - // shared CW array by rebuilding an otherwise-identical key is hard; - // instead flip cs after the fact via const_cast of the seed storage. - auto & cs = const_cast(k0.correction_seeds()[0]); - cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); + // Flip every correction seed so an on-path level with control bit 1 + // mixes the tamper (a single level-0 flip is invisible when t=0 there). + for (auto & cs : const_cast::correction_seeds_array &>( + k0.correction_seeds())) + { + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(1)); + } dpf::proof_token pi0{}, pi1{}; (void)*dpf::eval_point(k0, Input{3}, dpf::prove(pi0)); @@ -69,6 +75,10 @@ TEST(Verifiable, BatchVerify) EXPECT_TRUE(dpf::verify_batch(left, right)); left[2][0] = simde_mm_xor_si128(left[2][0], simde_mm_set1_epi8(0xff)); EXPECT_FALSE(dpf::verify_batch(left, right)); + // Restore and swap second halves of two slots — must still reject. + left[2][0] = simde_mm_xor_si128(left[2][0], simde_mm_set1_epi8(0xff)); + std::swap(left[1][1], left[3][1]); + EXPECT_FALSE(dpf::verify_batch(left, right)); right.pop_back(); EXPECT_FALSE(dpf::verify_batch(left, right)); } @@ -175,6 +185,65 @@ TEST(Verifiable, IntervalProve) EXPECT_TRUE(dpf::verify(a, b)); } +TEST(Verifiable, IntervalEvalProveMatchesProveInterval) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x20}, + std::uint64_t{7}, dpf::verifiable{}); + dpf::proof_token p0{}, p1{}, e0{}, e1{}; + dpf::prove_interval(k0, Input{0x10}, Input{0x18}, dpf::prove(p0)); + dpf::prove_interval(k1, Input{0x10}, Input{0x18}, dpf::prove(p1)); + EXPECT_TRUE(dpf::verify(p0, p1)); + + auto buf0 = dpf::make_output_buffer_for_interval(k0, Input{0x10}, Input{0x18}); + auto buf1 = dpf::make_output_buffer_for_interval(k1, Input{0x10}, Input{0x18}); + dpf::eval_interval(k0, Input{0x10}, Input{0x18}, buf0, dpf::prove(e0)); + dpf::eval_interval(k1, Input{0x10}, Input{0x18}, buf1, dpf::prove(e1)); + EXPECT_TRUE(dpf::verify(e0, e1)); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(p0, e0)); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(p1, e1)); + + // Tamper party 0's token after an honest fold. + e0[0] = simde_mm_xor_si128(e0[0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(e0, e1)); +} + +TEST(Verifiable, FullProve) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x55}, + std::uint64_t{3}, dpf::verifiable{}); + dpf::proof_token a{}, b{}; + dpf::prove_full(k0, dpf::prove(a)); + dpf::prove_full(k1, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); + a[0] = simde_mm_xor_si128(a[0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(a, b)); +} + +TEST(Verifiable, SequenceProveIntervalCovers) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x22}, + std::uint64_t{9}, dpf::verifiable{}); + // Two runs: [0x10,0x12] and [0x20,0x21], plus an isolated 0x30. + const Input xs[] = {0x10, 0x11, 0x12, 0x20, 0x21, 0x30}; + dpf::proof_token a{}, b{}; + dpf::prove_sequence(k0, std::begin(xs), std::end(xs), dpf::prove(a)); + dpf::prove_sequence(k1, std::begin(xs), std::end(xs), dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); + + // eval_sequence(..., prove) uses the same interval-run covers. + auto buf0 = dpf::make_output_buffer_for_subsequence(k0, std::begin(xs), std::end(xs)); + auto buf1 = dpf::make_output_buffer_for_subsequence(k1, std::begin(xs), std::end(xs)); + dpf::proof_token e0{}, e1{}; + dpf::eval_sequence(k0, std::begin(xs), std::end(xs), buf0, dpf::prove(e0)); + dpf::eval_sequence(k1, std::begin(xs), std::end(xs), buf1, dpf::prove(e1)); + EXPECT_TRUE(dpf::verify(e0, e1)); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(a, e0)); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(b, e1)); +} + TEST(Verifiable, DoernerShelatProve) { using Input = std::uint8_t; @@ -209,3 +278,431 @@ TEST(Verifiable, DoernerShelatProve) beta); EXPECT_TRUE(dpf::verify(a, b)); } + +TEST(Verifiable, CmpIntervalProve) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x20}, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + dpf::proof_token a{}, b{}; + dpf::prove_cmp_interval(k0, Input{0x10}, Input{0x28}, dpf::prove(a)); + dpf::prove_cmp_interval(k1, Input{0x10}, Input{0x28}, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); + + auto buf0 = dpf::make_output_buffer(dpf::cmp, k0, Input{0x10}, Input{0x28}); + auto buf1 = dpf::make_output_buffer(dpf::cmp, k1, Input{0x10}, Input{0x28}); + dpf::proof_token e0{}, e1{}; + dpf::eval_interval(dpf::cmp, k0, Input{0x10}, Input{0x28}, buf0, dpf::prove(e0)); + dpf::eval_interval(dpf::cmp, k1, Input{0x10}, Input{0x28}, buf1, dpf::prove(e1)); + EXPECT_TRUE(dpf::verify(e0, e1)); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(a, e0)); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(b, e1)); + e0[0] = simde_mm_xor_si128(e0[0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(e0, e1)); +} + +TEST(Verifiable, CmpFullAndSequenceProve) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x55}, dpf::gt(std::uint64_t{1}), + dpf::verifiable{}); + dpf::proof_token a{}, b{}; + dpf::prove_cmp_full(k0, dpf::prove(a)); + dpf::prove_cmp_full(k1, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); + + const Input xs[] = {0x10, 0x11, 0x20}; + dpf::proof_token s0{}, s1{}; + dpf::prove_cmp_sequence(k0, std::begin(xs), std::end(xs), dpf::prove(s0)); + dpf::prove_cmp_sequence(k1, std::begin(xs), std::end(xs), dpf::prove(s1)); + EXPECT_TRUE(dpf::verify(s0, s1)); + + auto buf0 = dpf::make_output_buffer(dpf::cmp, k0, 3); + auto buf1 = dpf::make_output_buffer(dpf::cmp, k1, 3); + dpf::proof_token e0{}, e1{}; + dpf::eval_sequence(dpf::cmp, k0, std::begin(xs), std::end(xs), buf0, + dpf::prove(e0)); + dpf::eval_sequence(dpf::cmp, k1, std::begin(xs), std::end(xs), buf1, + dpf::prove(e1)); + EXPECT_TRUE(dpf::verify(e0, e1)); +} + +TEST(Verifiable, CmpInnerProductProve) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x18}, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + const std::uint64_t w[] = {1, 2, 3, 4}; + dpf::proof_token a{}, b{}; + const auto d0 = dpf::eval_inner_product(dpf::cmp, k0, Input{0x10}, Input{0x13}, + w, dpf::prove(a)); + const auto d1 = dpf::eval_inner_product(dpf::cmp, k1, Input{0x10}, Input{0x13}, + w, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); + (void)d0; + (void)d1; +} + +TEST(Verifiable, IdcfPointProve) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x2a}, dpf::idcf(dpf::gt(std::uint64_t{1})), + dpf::verifiable{}); + dpf::proof_token a{}, b{}; + dpf::eval_point(dpf::cmp, k0, Input{0x30}, dpf::prove(a)); + dpf::eval_point(dpf::cmp, k1, Input{0x30}, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); + a[0] = simde_mm_xor_si128(a[0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(a, b)); +} + +TEST(Verifiable, BlockedCmpPointProve) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x2a}, + dpf::block_width<4>(dpf::lt(std::uint64_t{1})), dpf::verifiable{}); + EXPECT_GT(decltype(k0)::cmp_block, 0u); + dpf::proof_token a{}, b{}; + dpf::eval_point(dpf::cmp, k0, Input{0x11}, dpf::prove(a)); + dpf::eval_point(dpf::cmp, k1, Input{0x11}, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); + + // Native key of the same alpha yields a different token domain. + auto [n0, n1] = dpf::make_dpf(Input{0x2a}, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + dpf::proof_token c{}, d{}; + dpf::eval_point(dpf::cmp, n0, Input{0x11}, dpf::prove(c)); + dpf::eval_point(dpf::cmp, n1, Input{0x11}, dpf::prove(d)); + EXPECT_TRUE(dpf::verify(c, d)); + EXPECT_FALSE(dpf::detail::vdpf::proof_equal(a, c)); + + a[0] = simde_mm_xor_si128(a[0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(a, b)); +} + +TEST(Verifiable, BlockedCmpIntervalProve) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x20}, + dpf::block_width<4>(dpf::gt(std::uint64_t{1})), dpf::verifiable{}); + dpf::proof_token a{}, b{}; + dpf::prove_cmp_interval(k0, Input{0x1c}, Input{0x24}, dpf::prove(a)); + dpf::prove_cmp_interval(k1, Input{0x1c}, Input{0x24}, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); +} + +TEST(Verifiable, GenevalTrieProve) +{ + using Input = std::uint8_t; + const Input alpha = 0x2a; + Input x0 = 0x11; + Input x1 = static_cast(alpha ^ x0); + struct Pad + { + std::uint64_t n = 1; + simde__m128i block() + { + auto v = simde_mm_set_epi64x(static_cast(n), + static_cast(n * 9 + 3)); + n += 2; + return v; + } + void fill(void * p, std::size_t nbytes) + { + auto * b = static_cast(p); + for (std::size_t i = 0; i < nbytes; ++i) + b[i] = static_cast(n + i * 17); + n += nbytes; + } + std::uint8_t bit() { return static_cast(n++ & 1u); } + }; + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + dpf::ds_randomness rng{ + dpf::uniform_sample, Pad{}}; + HEDLEY_PRAGMA(GCC diagnostic pop) + const Input qs[] = {0x2a, 0x2b}; + auto got = dpf::geneval_point(x0, x1, qs[0], rng, std::uint64_t{7}); + EXPECT_TRUE(dpf::verify(got.proof0, got.proof1)); + got.proof0[0] = simde_mm_xor_si128(got.proof0[0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(got.proof0, got.proof1)); +} + +TEST(Verifiable, GenevalCmpProve) +{ + using Input = std::uint8_t; + const Input alpha = 0x30; + Input x0 = 0x05; + Input x1 = static_cast(alpha ^ x0); + struct Pad + { + std::uint64_t n = 1; + simde__m128i block() + { + auto v = simde_mm_set_epi64x(static_cast(n), + static_cast(n * 9 + 3)); + n += 2; + return v; + } + void fill(void * p, std::size_t nbytes) + { + auto * b = static_cast(p); + for (std::size_t i = 0; i < nbytes; ++i) + b[i] = static_cast(n + i * 17); + n += nbytes; + } + std::uint8_t bit() { return static_cast(n++ & 1u); } + }; + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + dpf::ds_randomness rng{ + dpf::uniform_sample, Pad{}}; + HEDLEY_PRAGMA(GCC diagnostic pop) + const Input ends[] = {0x10, 0x20, 0x40}; + auto got = dpf::geneval_cmp(x0, x1, std::begin(ends), std::end(ends), rng, + dpf::gt(std::uint64_t{1})); + EXPECT_TRUE(dpf::verify(got.proof0, got.proof1)); +} + +TEST(Verifiable, OffsetHornerProve) +{ + using Input = std::uint8_t; + constexpr std::size_t D = 1; + const Input center = 12; + auto mat = grotto::make_offset_horner_keys(center, dpf::verifiable{}); + EXPECT_TRUE(decltype(mat)::is_verifiable); + const std::vector knots{0, 10, 50}; + const std::vector> coeff{ + {1, 0}, {0, 2}, {7, 1}}; + const Input eta = 3; + dpf::proof_token t0[D + 1]{}, t1[D + 1]{}; + const auto v0 = grotto::offset_horner_eval<0, D, Input, true>( + mat, knots, coeff, eta, t0); + const auto v1 = grotto::offset_horner_eval<1, D, Input, true>( + mat, knots, coeff, eta, t1); + EXPECT_EQ(v0 + v1, grotto::offset_horner_clear(center, knots, coeff, eta)); + for (std::size_t m = 0; m <= D; ++m) + EXPECT_TRUE(dpf::verify(t0[m], t1[m])); + t0[0][0] = simde_mm_xor_si128(t0[0][0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(t0[0], t1[0])); +} + +TEST(Verifiable, PathPaintLcpProve) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x2a}, dpf::lcp(std::uint64_t{1}), + dpf::verifiable{}); + dpf::proof_token a{}, b{}; + dpf::prove_cmp_interval(k0, Input{0x20}, Input{0x2f}, dpf::prove(a)); + dpf::prove_cmp_interval(k1, Input{0x20}, Input{0x2f}, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); + a[0] = simde_mm_xor_si128(a[0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(a, b)); +} + +TEST(Verifiable, OffsetPolyProve) +{ + using Input = std::uint8_t; + const Input center = 12; + auto mat = grotto::make_offset_poly_keys(center, 1, dpf::verifiable{}); + EXPECT_TRUE(mat.verifiable); + const std::vector knots{0, 10, 50}; + const std::vector> coeff{{1, 0}, {0, 2}, {7, 1}}; + const Input eta = 3; + dpf::proof_token t0[2]{}, t1[2]{}; + const auto v0 = grotto::offset_poly_eval<0>(mat, knots, coeff, eta, t0); + const auto v1 = grotto::offset_poly_eval<1>(mat, knots, coeff, eta, t1); + EXPECT_EQ(v0 + v1, grotto::offset_poly_clear(center, knots, coeff, eta)); + EXPECT_TRUE(dpf::verify(t0[0], t1[0])); + EXPECT_TRUE(dpf::verify(t0[1], t1[1])); + t0[1][0] = simde_mm_xor_si128(t0[1][0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(t0[1], t1[1])); + EXPECT_TRUE(dpf::verify(t0[0], t1[0])); +} + +TEST(Verifiable, BlockedCmpIntervalTamperRejects) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x20}, + dpf::block_width<4>(dpf::gt(std::uint64_t{1})), dpf::verifiable{}); + dpf::proof_token a{}, b{}; + dpf::prove_cmp_interval(k0, Input{0x1c}, Input{0x24}, dpf::prove(a)); + dpf::prove_cmp_interval(k1, Input{0x1c}, Input{0x24}, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); + for (auto & cs : const_cast::correction_seeds_array &>( + k0.correction_seeds())) + cs[0] = simde_mm_xor_si128(cs[0], simde_mm_set1_epi8(0x11)); + dpf::proof_token c{}, d{}; + dpf::prove_cmp_interval(k0, Input{0x1c}, Input{0x24}, dpf::prove(c)); + dpf::prove_cmp_interval(k1, Input{0x1c}, Input{0x24}, dpf::prove(d)); + EXPECT_FALSE(dpf::verify(c, d)); +} + +TEST(Verifiable, GenevalOffsetHornerProve) +{ + using Input = std::uint8_t; + constexpr std::size_t D = 1; + const Input center = 20; + const Input share = 0x3c; + const Input other = static_cast(center ^ share); + const Input eta = 3; + struct Pad + { + std::uint64_t n = 1; + simde__m128i block() + { + auto v = simde_mm_set_epi64x(static_cast(n), + static_cast(n * 9 + 3)); + n += 2; + return v; + } + void fill(void * p, std::size_t nbytes) + { + auto * b = static_cast(p); + for (std::size_t i = 0; i < nbytes; ++i) + b[i] = static_cast(n + i * 17); + n += nbytes; + } + std::uint8_t bit() { return static_cast(n++ & 1u); } + }; + HEDLEY_PRAGMA(GCC diagnostic push) + HEDLEY_PRAGMA(GCC diagnostic ignored "-Wignored-attributes") + dpf::ds_randomness rng{ + dpf::uniform_sample, Pad{}}; + HEDLEY_PRAGMA(GCC diagnostic pop) + const std::vector knots{0, 15, 40}; + const std::vector> coeff{{1, 0}, {2, 1}, {0, 3}}; + auto got = grotto::geneval_offset_horner(share, other, eta, knots, coeff, + std::move(rng)); + for (std::size_t m = 0; m <= D; ++m) + EXPECT_TRUE(dpf::verify(got.proof0[m], got.proof1[m])); + got.proof0[0][0] = simde_mm_xor_si128(got.proof0[0][0], simde_mm_set1_epi8(1)); + EXPECT_FALSE(dpf::verify(got.proof0[0], got.proof1[0])); +} + +TEST(Verifiable, ZeroTokenRejects) +{ + dpf::proof_token z = dpf::detail::vdpf::zero_proof(); + EXPECT_FALSE(dpf::verify(z, z)); + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{3}, + std::uint64_t{1}, dpf::verifiable{}); + dpf::proof_token a{}, b{}; + (void)*dpf::eval_point(k0, Input{3}, dpf::prove(a)); + (void)*dpf::eval_point(k1, Input{3}, dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); + EXPECT_FALSE(dpf::verify(a, z)); + EXPECT_FALSE(dpf::verify(z, b)); +} + +TEST(Verifiable, ColdAndWarmProveMatch) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x2a}, + std::uint64_t{7}, dpf::verifiable{}); + const Input x{0x11}; + dpf::proof_token cold0{}, cold1{}; + (void)*dpf::eval_point(k0, x, dpf::prove(cold0)); + (void)*dpf::eval_point(k1, x, dpf::prove(cold1)); + EXPECT_TRUE(dpf::verify(cold0, cold1)); + EXPECT_FALSE(dpf::detail::vdpf::proof_equal(cold0, + dpf::detail::vdpf::zero_proof())); + + auto p0 = dpf::make_basic_path_memoizer(k0); + auto p1 = dpf::make_basic_path_memoizer(k1); + dpf::proof_token warm0{}, warm1{}; + (void)*dpf::eval_point(k0, x, dpf::prove(warm0), p0); + (void)*dpf::eval_point(k1, x, dpf::prove(warm1), p1); + // Second prove on the warm memoizer must match the cold token. + dpf::proof_token again0{}, again1{}; + (void)*dpf::eval_point(k0, x, dpf::prove(again0), p0); + (void)*dpf::eval_point(k1, x, dpf::prove(again1), p1); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(cold0, warm0)); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(cold0, again0)); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(cold1, again1)); + EXPECT_TRUE(dpf::verify(again0, again1)); +} + +TEST(Verifiable, LeafTamperRejectsBoundProof) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{5}, + std::uint64_t{11}, dpf::verifiable{}); + auto & leaf = std::get<0>( + const_cast::leaf_wrapper_tuple &>( + k0.leaf_nodes)).raw_leaf(); + auto * bytes = reinterpret_cast(&leaf); + bytes[0] = static_cast(bytes[0] ^ 0x5a); + + dpf::proof_token a{}, b{}; + (void)*dpf::eval_point(k0, Input{5}, dpf::prove(a)); + (void)*dpf::eval_point(k1, Input{5}, dpf::prove(b)); + EXPECT_FALSE(dpf::verify(a, b)); +} + +TEST(Verifiable, ValueWordTamperRejectsBoundProof) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x20}, dpf::lt(std::uint64_t{1}), + dpf::verifiable{}); + auto & vcw = const_cast::value_cw_array &>( + k0.value_cw()); + vcw[0] = static_cast::value_cw_word>( + static_cast(vcw[0]) ^ 1ull); + + dpf::proof_token a{}, b{}; + dpf::eval_point(dpf::cmp, k0, Input{0x10}, dpf::prove(a)); + dpf::eval_point(dpf::cmp, k1, Input{0x10}, dpf::prove(b)); + EXPECT_FALSE(dpf::verify(a, b)); +} + +TEST(Verifiable, MakeCsMatchesHashNodeXor) +{ + // Local transcript of party/oblivious_hash.hpp: cs = H(s0) XOR H(s1). + const std::size_t level = 3; + const psnip_uint64_t prefix = 0x2a; + const simde__m128i s0 = simde_mm_set_epi64x(0x1111, 0x2222); + const simde__m128i s1 = simde_mm_set_epi64x(0x3333, 0x4444); + const auto cs = dpf::detail::vdpf::make_cs(level, prefix, s0, s1); + const auto h0 = dpf::detail::vdpf::hash_node(level, prefix, s0); + const auto h1 = dpf::detail::vdpf::hash_node(level, prefix, s1); + dpf::cs_block xor_h{ + simde_mm_xor_si128(h0[0], h1[0]), + simde_mm_xor_si128(h0[1], h1[1]), + simde_mm_xor_si128(h0[2], h1[2]), + simde_mm_xor_si128(h0[3], h1[3])}; + EXPECT_EQ(std::memcmp(&cs, &xor_h, sizeof(cs)), 0); + + constexpr std::size_t tagged = + dpf::detail::blocked::fold_spine_tag | level; + const auto cs_b = dpf::detail::vdpf::make_cs(tagged, prefix, s0, s1); + const auto hb0 = dpf::detail::vdpf::hash_node(tagged, prefix, s0); + const auto hb1 = dpf::detail::vdpf::hash_node(tagged, prefix, s1); + dpf::cs_block xor_hb{ + simde_mm_xor_si128(hb0[0], hb1[0]), + simde_mm_xor_si128(hb0[1], hb1[1]), + simde_mm_xor_si128(hb0[2], hb1[2]), + simde_mm_xor_si128(hb0[3], hb1[3])}; + EXPECT_EQ(std::memcmp(&cs_b, &xor_hb, sizeof(cs_b)), 0); + EXPECT_NE(std::memcmp(&cs, &cs_b, sizeof(cs)), 0); +} + +TEST(Verifiable, InnerProductProve) +{ + using Input = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(Input{0x10}, + std::uint64_t{3}, dpf::verifiable{}); + std::array w{}; + w.fill(1); + dpf::proof_token a{}, b{}, p0{}, p1{}; + dpf::eval_inner_product(k0, Input{0x0c}, Input{0x13}, w, + dpf::prove(a)); + dpf::eval_inner_product(k1, Input{0x0c}, Input{0x13}, w, + dpf::prove(b)); + EXPECT_TRUE(dpf::verify(a, b)); + dpf::prove_interval(k0, Input{0x0c}, Input{0x13}, dpf::prove(p0)); + dpf::prove_interval(k1, Input{0x0c}, Input{0x13}, dpf::prove(p1)); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(a, p0)); + EXPECT_TRUE(dpf::detail::vdpf::proof_equal(b, p1)); +} + diff --git a/test/tests/walk_helpers_test.cpp b/test/tests/walk_helpers_test.cpp new file mode 100644 index 0000000..3074a27 --- /dev/null +++ b/test/tests/walk_helpers_test.cpp @@ -0,0 +1,211 @@ +#include + +#include +#include +#include + +#include "dpf.hpp" + +// Walk helpers fold a small operation into an existing DPF walk. See +// dpf/eval_walk.hpp. + +TEST(WalkHelpers, RotatePairedInnerProduct) +{ + constexpr std::size_t n = 256; + constexpr std::uint8_t r = 50; + constexpr std::uint8_t a = 42; + const std::size_t s = (n - static_cast( + static_cast(r - a))) % n; + + std::vector table(n); + for (std::size_t i = 0; i < n; ++i) table[i] = i * 7 + 1; + + auto [k0, k1] = dpf::make_dpf(r, std::uint64_t{1}); + + std::vector manual(n); + for (std::size_t i = 0; i < n; ++i) manual[i] = table[(i + s) % n]; + const auto ref = dpf::reconstruct( + dpf::eval_full_inner_product(dpf::paired, k0, manual), + dpf::eval_full_inner_product(dpf::paired, k1, manual)); + + const auto got = dpf::reconstruct( + dpf::eval_full_inner_product(dpf::paired, k0, table, dpf::rotate{s}), + dpf::eval_full_inner_product(dpf::paired, k1, table, dpf::rotate{s})); + + EXPECT_EQ(got, ref); + EXPECT_EQ(got, table[(r + s) % n]); +} + +TEST(WalkHelpers, FullAddIntoHistogram) +{ + constexpr std::size_t n = 256; + std::vector h0(n), h1(n); + for (auto bin : std::array{3, 3, 7}) + { + auto [k0, k1] = dpf::make_dpf(bin, dpf::field64{1}); + dpf::eval_full_add_into(h0, k0); + dpf::eval_full_add_into(h1, k1); + } + EXPECT_EQ((h0[3] - h1[3]).raw(), 2u); + EXPECT_EQ((h0[7] - h1[7]).raw(), 1u); + EXPECT_EQ((h0[0] - h1[0]).raw(), 0u); +} + +TEST(WalkHelpers, FullAddIntoRotate) +{ + constexpr std::size_t n = 256; + constexpr std::uint8_t r = 10; + constexpr std::size_t shift = 32; + std::vector d0(n, 0), d1(n, 0); + auto [w0, w1] = dpf::make_dpf(r, std::uint64_t{7}); + dpf::eval_full_add_into(d0, w0, dpf::rotate{shift}); + dpf::eval_full_add_into(d1, w1, dpf::rotate{shift}); + const std::size_t hot = (r + shift) % n; + EXPECT_EQ(d0[hot] - d1[hot], 7u); + EXPECT_EQ(d0[r] - d1[r], 0u); +} + +TEST(WalkHelpers, FullAddIntoSketch) +{ + constexpr std::size_t n = 256; + constexpr std::uint8_t address = 9; + const dpf::fp61 message{42}; + auto [k0, k1] = dpf::make_dpf(address, message, dpf::extractable{}); + + std::vector box0(n), box1(n); + std::vector challenge(n); + for (std::size_t i = 0; i < n; ++i) + challenge[i] = dpf::fp61{static_cast(i + 1)}; + + dpf::sketch_share s0{}, s1{}; + auto sk0 = dpf::sketch(s0, challenge); + auto sk1 = dpf::sketch(s1, challenge); + dpf::eval_full_add_into(box0, k0, sk0); + dpf::eval_full_add_into(box1, k1, sk1); + + EXPECT_EQ(box0[address] - box1[address], message); + EXPECT_EQ((box0[0] - box1[0]).raw(), 0u); + EXPECT_TRUE(dpf::sketch_verify(s0, s1)); +} + +TEST(WalkHelpers, CyclicShift) +{ + std::vector v(8); + for (int i = 0; i < 8; ++i) v[i] = i; + auto sh = dpf::cyclic_shift(v, 3); + for (std::size_t i = 0; i < v.size(); ++i) + EXPECT_EQ(sh[i], v[(i + v.size() - 3) % v.size()]); +} + +TEST(WalkHelpers, PackBitColumns) +{ + constexpr std::size_t n = 256; + constexpr std::uint8_t alpha = 42; + auto [a0, a1] = dpf::make_dpf(alpha, dpf::bit::one); + auto [b0, b1] = dpf::make_dpf(alpha, dpf::bit::one); + const auto p0 = dpf::pack_bit_columns(a0, b0); + const auto p1 = dpf::pack_bit_columns(a1, b1); + for (std::size_t row = 0; row < n; ++row) + { + const std::uint64_t opened = p0[row] ^ p1[row]; + EXPECT_EQ(opened, row == alpha ? 0b11u : 0u) << "row " << row; + } +} + +TEST(WalkHelpers, ModBitColumns) +{ + constexpr std::size_t n = 256; + constexpr std::uint8_t alpha = 42; + auto [a0, a1] = dpf::make_dpf(alpha, dpf::bit::one); + auto [b0, b1] = dpf::make_dpf(alpha, dpf::bit::one); + auto [c0, c1] = dpf::make_dpf(alpha, dpf::bit::one); + + auto expect_mod = [&](auto modulus, const auto & k0, const auto & k1, const auto & k2) + { + constexpr unsigned m = decltype(modulus)::value; + const auto packed = dpf::pack_bit_columns(k0, k1, k2); + const auto got = dpf::mod_bit_columns(k0, k1, k2); + ASSERT_EQ(got.size(), n); + for (std::size_t row = 0; row < n; ++row) + EXPECT_EQ(static_cast(got[row]), packed[row] % m) << "row " << row; + }; + expect_mod(std::integral_constant{}, a0, b0, c0); + expect_mod(std::integral_constant{}, a0, b0, c0); + expect_mod(std::integral_constant{}, a1, b1, c1); + expect_mod(std::integral_constant{}, a0, b1, c0); + expect_mod(std::integral_constant{}, a0, b0, c0); + + const auto one = dpf::mod_bit_columns<7>(a0); + const auto bits = dpf::pack_bit_columns(a0); + for (std::size_t row = 0; row < n; ++row) + EXPECT_EQ(static_cast(one[row]), bits[row] % 7u); +} + +TEST(WalkHelpers, UnitSignBitLeaf) +{ + constexpr std::uint8_t r = 50; + int w0 = 0, w1 = 0; + auto [k0, k1] = dpf::make_dpf(r, dpf::bit::one, dpf::unit_sign{w0, w1}); + const int sign = w0 - w1; + EXPECT_TRUE(sign == 1 || sign == -1); + EXPECT_EQ(w0, static_cast(static_cast((*dpf::eval_point(k0, r)).raw()))); + EXPECT_EQ(w1, static_cast(static_cast((*dpf::eval_point(k1, r)).raw()))); + // The key still opens as an ordinary unit bit DPF. + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(k0, r), *dpf::eval_point(k1, r)), + dpf::bit::one); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(k0, std::uint8_t{0}), + *dpf::eval_point(k1, std::uint8_t{0})), dpf::bit::zero); +} + +TEST(WalkHelpers, CmpFullInnerProduct) +{ + constexpr std::size_t n = 256; + constexpr std::uint8_t threshold = 50; + auto [c0, c1] = dpf::make_dpf(threshold, dpf::gt(std::uint64_t{1})); + std::vector w(n, 0); + w[90] = 8; w[200] = 3; w[30] = 5; // 90,200 are > 50 + const auto h0 = dpf::eval_full_inner_product(dpf::cmp, c0, w); + const auto h1 = dpf::eval_full_inner_product(dpf::cmp, c1, w); + EXPECT_EQ(dpf::reconstruct_cmp_halves(h0, h1).raw(), 11u); +} + +TEST(WalkHelpers, Dpf3FullAddInto) +{ + constexpr std::size_t n = 256; + std::vector l1(n), l2(n), l3(n); + auto [k1, k2, k3] = dpf::make_dpf3(std::uint8_t{5}, dpf::fp61{100}); + dpf::eval_full_add_into(l1, k1); + dpf::eval_full_add_into(l2, k2); + dpf::eval_full_add_into(l3, k3); + auto open2 = [](dpf::fp61 a, dpf::fp61 b) { + return dpf::shamir3::reconstruct(dpf::shamir3::share{1, a}, + dpf::shamir3::share{2, b}); + }; + EXPECT_EQ(open2(l1[5], l2[5]), dpf::fp61{100}); + EXPECT_EQ(open2(l1[0], l2[0]).raw(), 0u); +} + +TEST(WalkHelpers, PrefixesAndPrefixInnerProduct) +{ + constexpr std::uint8_t left = 0xA0; // prefix "101" + auto [k0, k1] = dpf::make_dpf(left, + dpf::idpf(std::uint64_t{1}, std::uint64_t{1}, std::uint64_t{1})); + + auto [buf0, it0] = dpf::eval_prefixes(dpf::out<0, 1>, k0); + auto [buf1, it1] = dpf::eval_prefixes(dpf::out<0, 1>, k1); + EXPECT_EQ(dpf::reconstruct(buf0[0], buf1[0]), 0u); + EXPECT_EQ(dpf::reconstruct(buf0[1], buf1[1]), 1u); + + std::vector vals1{11, 23}; + const auto dot1 = + dpf::eval_prefix_inner_product(dpf::out<0, 1>, k0, vals1) + - dpf::eval_prefix_inner_product(dpf::out<0, 1>, k1, vals1); + EXPECT_EQ(dot1, vals1[1]); + + std::vector vals3(8); + for (std::size_t i = 0; i < 8; ++i) vals3[i] = 100 + i; + const auto dot3 = + dpf::eval_prefix_inner_product(dpf::out<2, 3>, k0, vals3) + - dpf::eval_prefix_inner_product(dpf::out<2, 3>, k1, vals3); + EXPECT_EQ(dot3, vals3[0b101]); +} diff --git a/test/tests/wide_payload_test.cpp b/test/tests/wide_payload_test.cpp index 2945cf0..54a4450 100644 --- a/test/tests/wide_payload_test.cpp +++ b/test/tests/wide_payload_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "dpf.hpp" #include "grotto/fixedpoint.hpp" diff --git a/test/tests/wildcard_test.cpp b/test/tests/wildcard_test.cpp index 70001ed..d4cbd74 100644 --- a/test/tests/wildcard_test.cpp +++ b/test/tests/wildcard_test.cpp @@ -1,4 +1,8 @@ #include +#include + +#include +#include #include "asio.hpp" #define LIBDPF_HAS_ASIO @@ -591,7 +595,7 @@ TEST(WildcardTest, PackedSmallWildcardsAtNonTerminalAssignAll) dpf::at<10>(w, w, w, w), uint16_t{99}); - ASSERT_THROW((void)dpf::eval_point(dpf::out<0, 10>, dpf0, x), std::runtime_error); + ASSERT_THROW(dpf::eval_point(dpf::out<0, 10>, dpf0, x), std::runtime_error); ASSERT_EQ(static_cast( dpf::reconstruct(*dpf::eval_point(dpf::out<4>, dpf0, x), *dpf::eval_point(dpf::out<4>, dpf1, x))), uint16_t{99}); @@ -617,3 +621,189 @@ TEST(WildcardTest, PackedSmallWildcardsAtNonTerminalAssignAll) static_cast(x ^ (1u << 6))))), concrete_t{0}); } + +namespace +{ + +template +T bits_as(Bits bits) +{ + T out{}; + std::memcpy(&out, &bits, sizeof(T)); + return out; +} + +template +auto bits_of(T v) +{ + using bits_t = std::conditional_t; + bits_t bits{}; + std::memcpy(&bits, &v, sizeof(T)); + return bits; +} + +/// In-process assign for a wildcard leaf (same messages as asio, no socket). +template +void assign_leaf_local(DpfKey0 & dpf0, DpfKey1 & dpf1, const ShareT & shr0, + const ShareT & shr1) +{ + auto & w0 = std::get(dpf0.leaf_nodes); + auto & w1 = std::get(dpf1.leaf_nodes); + if (w0.is_ready()) + w0.begin_update(); + if (w1.is_ready()) + w1.begin_update(); + const auto b0 = w0.compute_and_get_blinded_output_share(shr0); + const auto b1 = w1.compute_and_get_blinded_output_share(shr1); + const auto l0 = w0.compute_and_get_leaf_share(b1); + const auto l1 = w1.compute_and_get_leaf_share(b0); + w0.reconstruct_correction_word(l1); + w1.reconstruct_correction_word(l0); +} + +} // namespace + +TEST(WildcardTest, FullWidthXorDoesNotRevealBeta) +{ + using input_type = uint8_t; + using concrete_type = dpf::xints::xint128_t; + using output_type = dpf::wildcard_value; + input_type x = 0x42; + output_type y; + auto [dpf0, dpf1] = dpf::make_dpf(x, y); + + auto & w0 = std::get<0>(dpf0.leaf_nodes); + auto & w1 = std::get<0>(dpf1.leaf_nodes); + // Scale Beaver must be planted even for a single full-width XOR lane. + EXPECT_EQ((dpf::outputs_per_leaf_v::exterior_node>), 1u); + EXPECT_TRUE(dpf::utils::has_characteristic_two_v); + + concrete_type y_exp = concrete_type{0x0123456789ABCDEFull}; + concrete_type y_shr0 = concrete_type{0x1111111111111111ull}; + concrete_type y_shr1 = y_exp + y_shr0; // XOR group + + const auto blinded0 = w0.compute_and_get_blinded_output_share(y_shr0); + const auto blinded1 = w1.compute_and_get_blinded_output_share(y_shr1); + // With a non-trivial output blind, the exchanged value is not the share. + EXPECT_NE(blinded0, y_shr0); + EXPECT_NE(blinded1, y_shr1); + // Finish the assign after the privacy check above (state is already blinded). + const auto l0 = w0.compute_and_get_leaf_share(blinded1); + const auto l1 = w1.compute_and_get_leaf_share(blinded0); + w0.reconstruct_correction_word(l1); + w1.reconstruct_correction_word(l0); + + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf0, x), *dpf::eval_point(dpf1, x)), + y_exp); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf0, static_cast(x ^ 1)), + *dpf::eval_point(dpf1, static_cast(x ^ 1))), + concrete_type{}); +} + +TEST(WildcardTest, FloatWildcardRoundTrip) +{ + using input_type = uint8_t; + using concrete_type = float; + using output_type = dpf::wildcard_value; + input_type x = 0x55; + output_type y; + auto [dpf0, dpf1] = dpf::make_dpf(x, y); + + const concrete_type y_exp = 3.14159265f; + const auto y_bits = bits_of(y_exp); + const std::uint32_t shr0_bits = 0xA5A5A5A5u; + const concrete_type y_shr0 = bits_as(shr0_bits); + const concrete_type y_shr1 = + bits_as(y_bits ^ shr0_bits); + + assign_leaf_local(dpf0, dpf1, y_shr0, y_shr1); + + const auto got = dpf::reconstruct(*dpf::eval_point(dpf0, x), *dpf::eval_point(dpf1, x)); + EXPECT_EQ(bits_of(got), y_bits); + EXPECT_EQ(bits_of(dpf::reconstruct( + *dpf::eval_point(dpf0, static_cast(x ^ 1)), + *dpf::eval_point(dpf1, static_cast(x ^ 1)))), + 0u); +} + +TEST(WildcardTest, SecondAssignUpdatesPayload) +{ + using input_type = uint8_t; + using concrete_type = uint32_t; + using output_type = dpf::wildcard_value; + input_type x = 0x11; + auto [dpf0, dpf1] = dpf::make_dpf(x, output_type{}); + + const concrete_type beta = 0xAAAAAAAAu; + const concrete_type beta2 = 0xBBBBBBBBu; + const concrete_type s0 = 0x12345678u; + assign_leaf_local(dpf0, dpf1, s0, static_cast(beta - s0)); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf0, x), *dpf::eval_point(dpf1, x)), beta); + + // Second assign installs (beta2 - beta) on top of the ready leaf. + const concrete_type delta = static_cast(beta2 - beta); + const concrete_type d0 = 0x01010101u; + assign_leaf_local(dpf0, dpf1, d0, static_cast(delta - d0)); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf0, x), *dpf::eval_point(dpf1, x)), + beta2); +} + +TEST(WildcardTest, AssignWildcardInputOpensPublicShiftNotAlpha) +{ + using input_type = uint8_t; + using output_type = uint32_t; + // Wildcard domain: dealer plants a random mask; parties later open (mask - alpha). + auto [dpf0, dpf1] = dpf::make_dpf(dpf::wildcard_value{}, output_type{7}); + + const input_type mask = static_cast( + dpf0.offset_x.raw() + dpf1.offset_x.raw()); + const input_type alpha = 0xAAu; + const input_type a0 = 0x12u; + const input_type a1 = static_cast(alpha - a0); + + const auto sh0 = dpf0.offset_x.compute_and_get_share(a0); + const auto sh1 = dpf1.offset_x.compute_and_get_share(a1); + const auto open0 = dpf0.offset_x.reconstruct(sh1); + const auto open1 = dpf1.offset_x.reconstruct(sh0); + + EXPECT_EQ(open0, open1); + const input_type want_shift = static_cast(mask - alpha); + EXPECT_EQ(open0, want_shift); + EXPECT_NE(open0, alpha); // public value is the shift, not alpha + EXPECT_EQ(static_cast(open0 + alpha), mask); + + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf0, alpha), *dpf::eval_point(dpf1, alpha)), + output_type{7}); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(dpf0, static_cast(alpha ^ 1)), + *dpf::eval_point(dpf1, static_cast(alpha ^ 1))), + output_type{0}); +} + +TEST(WildcardTest, UpdatableTagAssignsThenRewrites) +{ + const std::uint8_t alpha = 0x2a; + auto [k0, k1] = dpf::make_dpf(alpha, std::uint64_t{7}, dpf::updatable{}); + EXPECT_TRUE(k0.is_wildcard(0)); + EXPECT_TRUE(k1.is_wildcard(0)); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(k0, alpha), *dpf::eval_point(k1, alpha)), + std::uint64_t{7}); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(k0, std::uint8_t{0}), + *dpf::eval_point(k1, std::uint8_t{0})), + std::uint64_t{0}); + + auto & w0 = std::get<0>(k0.leaf_nodes); + auto & w1 = std::get<0>(k1.leaf_nodes); + w0.begin_update(); + w1.begin_update(); + // A second assign installs the difference β' − β, not the new absolute payload. + const auto shares = dpf::additively_share(std::uint64_t{9} - std::uint64_t{7}); + const auto b0 = w0.compute_and_get_blinded_output_share(shares.first.raw()); + const auto b1 = w1.compute_and_get_blinded_output_share(shares.second.raw()); + const auto l0 = w0.compute_and_get_leaf_share(b1); + const auto l1 = w1.compute_and_get_leaf_share(b0); + w0.reconstruct_correction_word(l1); + w1.reconstruct_correction_word(l0); + EXPECT_EQ(dpf::reconstruct(*dpf::eval_point(k0, alpha), *dpf::eval_point(k1, alpha)), + std::uint64_t{9}); +} diff --git a/test/tests/window_lut_test.cpp b/test/tests/window_lut_test.cpp index 884074f..d6f6b39 100644 --- a/test/tests/window_lut_test.cpp +++ b/test/tests/window_lut_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "grotto/window_lut.hpp" @@ -77,6 +78,18 @@ long double reference(grotto::window which, unsigned k, long double x) return acosl(x); case grotto::window::probit: return 0; + case grotto::window::hardelish: + if (x <= -1.0L) + return 0; + if (x >= 1.0L) + return x; + if (x >= 0.0L) + return x * (x + 1.0L) / 2.0L; + return expm1l(x) * (x + 1.0L) / 2.0L; + case grotto::window::lecun_tanh: + return 1.7159L * tanhl(2.0L * x / 3.0L); + case grotto::window::one_minus_sigmoid: + return 1.0L - sigmoid(x); } return 0; } @@ -154,6 +167,51 @@ TEST(WindowLut, ExhaustiveLowPrecision) expect_close(grotto::window::asin, k, raw); expect_close(grotto::window::acos, k, raw); } + const std::int64_t step = k == 8 ? 1 : 17; + for (std::int64_t raw = -2 * one; raw <= 2 * one; raw += step) + expect_close(grotto::window::hardelish, k, raw); + const std::int64_t lecun_span = std::int64_t{20} << k; + for (std::int64_t raw = -lecun_span; raw <= lecun_span; raw += step) + { + expect_close(grotto::window::lecun_tanh, k, raw); + expect_close(grotto::window::one_minus_sigmoid, k, raw); + } + } +} + +TEST(WindowLut, HighPrecisionSamples) +{ + for (unsigned k : {16u, 24u, 32u}) + { + const auto one = std::int64_t{1} << k; + const auto step = std::int64_t{1} << (k - 8); + for (std::int64_t raw = -2 * one; raw <= 2 * one; raw += step) + expect_close(grotto::window::hardelish, k, raw); + const std::int64_t span = std::int64_t{20} << k; + const auto wide = std::int64_t{1} << (k - 6); + for (std::int64_t raw = -span; raw <= span; raw += wide) + { + expect_close(grotto::window::lecun_tanh, k, raw); + expect_close(grotto::window::one_minus_sigmoid, k, raw); + } + expect_close(grotto::window::hardelish, k, -one + 1); + expect_close(grotto::window::hardelish, k, -1); + expect_close(grotto::window::lecun_tanh, k, 1); + expect_close(grotto::window::lecun_tanh, k, span); + } +} + +TEST(WindowLut, OneMinusSigmoidComplementsSigmoid) +{ + for (unsigned k : {8u, 16u, 32u}) + { + const auto one = std::int64_t{1} << k; + for (std::int64_t raw : {std::int64_t{-8} * one, -one, std::int64_t{0}, one, std::int64_t{8} * one}) + { + const auto sig = grotto::eval_window(grotto::window::sigmoid, k, raw); + const auto comp = grotto::eval_window(grotto::window::one_minus_sigmoid, k, raw); + EXPECT_EQ(sig + comp, one) << k << " " << raw; + } } } diff --git a/test/tests/wrap_and_rotate_test.cpp b/test/tests/wrap_and_rotate_test.cpp new file mode 100644 index 0000000..f78c6ad --- /dev/null +++ b/test/tests/wrap_and_rotate_test.cpp @@ -0,0 +1,577 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dpf.hpp" + +namespace +{ + +template +auto recon(const A & a, const B & b) +{ + if constexpr (dpf::is_secret_share_v> + && dpf::is_secret_share_v>) + return dpf::reconstruct(a, b); + else + { + using T = std::common_type_t, std::decay_t>; + if constexpr (std::is_integral_v && std::is_unsigned_v) + return static_cast(a - b); + else + return a - b; + } +} + +template +void assign_input_local(Key0 & k0, Key1 & k1, InputT alpha) +{ + const InputT a0 = static_cast(0x12); + const InputT a1 = static_cast(alpha - a0); + const auto sh0 = k0.offset_x.compute_and_get_share(a0); + const auto sh1 = k1.offset_x.compute_and_get_share(a1); + k0.offset_x.reconstruct(sh1); + k1.offset_x.reconstruct(sh0); +} + +template +std::size_t inclusive_span(InputT from, InputT to) +{ + constexpr auto bits = dpf::utils::bitlength_of_v; + constexpr auto to_int = dpf::utils::to_integral_type{}; + auto span = to_int(to) - to_int(from); + if constexpr (bits < dpf::utils::bitlength_of_v) + span &= (decltype(span){1} << bits) - 1; + return static_cast(span) + 1; +} + +template +void for_inclusive_wrap(InputT from, InputT to, Fn && fn) +{ + constexpr auto to_int = dpf::utils::to_integral_type{}; + const auto n = inclusive_span(from, to); + InputT x = from; + for (std::size_t i = 0; i < n; ++i) + { + fn(x); + x = static_cast(to_int(x) + 1); + } +} + +} // namespace + +// --------------------------------------------------------------------------- +// utils: interval_wraps / split_leaf_nodes / get_leafnodes +// --------------------------------------------------------------------------- + +TEST(WrapUtils, IntervalWrapsUnsigned) +{ + EXPECT_FALSE(dpf::utils::interval_wraps(std::uint8_t{10}, std::uint8_t{20}, 8)); + EXPECT_TRUE(dpf::utils::interval_wraps(std::uint8_t{200}, std::uint8_t{10}, 8)); + EXPECT_FALSE(dpf::utils::interval_wraps(std::uint8_t{0}, std::uint8_t{255}, 8)); + EXPECT_TRUE(dpf::utils::interval_wraps(std::uint8_t{255}, std::uint8_t{0}, 8)); + EXPECT_FALSE(dpf::utils::interval_wraps(0, 0, 0)); +} + +TEST(WrapUtils, IntervalWrapsMaskedLowBits) +{ + // Only low 4 bits participate; 0x1F vs 0x02 wraps in nibble space. + EXPECT_TRUE(dpf::utils::interval_wraps(0x1Fu, 0x02u, 4)); + EXPECT_FALSE(dpf::utils::interval_wraps(0x12u, 0x1Eu, 4)); +} + +TEST(WrapUtils, SplitNonWrapSingleSegment) +{ + auto segs = dpf::utils::split_leaf_nodes(std::uint8_t{3}, std::uint8_t{10}, 8, false); + ASSERT_EQ(segs.n, 1u); + EXPECT_EQ(segs.seg[0].from_node, 3); + EXPECT_EQ(segs.seg[0].to_node, 10); + EXPECT_EQ(segs.seg[0].count, 7u); + EXPECT_EQ(segs.total, 7u); +} + +TEST(WrapUtils, SplitWrapTwoSegments) +{ + // depth < bitwidth so domain_end is representable. + auto segs = dpf::utils::split_leaf_nodes( + std::uint16_t{250}, std::uint16_t{4}, 8, true); + ASSERT_EQ(segs.n, 2u); + EXPECT_EQ(segs.seg[0].from_node, 250); + EXPECT_EQ(segs.seg[0].to_node, 256); + EXPECT_EQ(segs.seg[0].count, 6u); + EXPECT_EQ(segs.seg[1].from_node, 0); + EXPECT_EQ(segs.seg[1].to_node, 4); + EXPECT_EQ(segs.seg[1].count, 4u); + EXPECT_EQ(segs.total, 10u); +} + +TEST(WrapUtils, SplitWrapShallowDepth) +{ + // depth 6 => domain_end 64 + auto segs = dpf::utils::split_leaf_nodes(std::uint8_t{60}, std::uint8_t{3}, 6, true); + ASSERT_EQ(segs.n, 2u); + EXPECT_EQ(segs.seg[0].from_node, 60); + EXPECT_EQ(segs.seg[0].to_node, 64); + EXPECT_EQ(segs.seg[0].count, 4u); + EXPECT_EQ(segs.seg[1].from_node, 0); + EXPECT_EQ(segs.seg[1].to_node, 3); + EXPECT_EQ(segs.seg[1].count, 3u); + EXPECT_EQ(segs.total, 7u); +} + +TEST(WrapUtils, InputWrapWithFromNodeLeToNodeStillSplits) +{ + // Packing can make from_node <= to_node while the input still wraps. + // Collapsing would omit the duplicated shared leaf. + auto segs = dpf::utils::split_leaf_nodes(std::uint8_t{2}, std::uint8_t{5}, 6, true); + ASSERT_EQ(segs.n, 2u); + EXPECT_EQ(segs.seg[0].from_node, 2); + EXPECT_EQ(segs.seg[0].to_node, 64); + EXPECT_EQ(segs.seg[1].from_node, 0); + EXPECT_EQ(segs.seg[1].to_node, 5); + EXPECT_GT(segs.total, 5u - 2u); +} + +TEST(WrapUtils, LeafCountAgreesWithSplitTotal) +{ + using In = std::uint8_t; + auto [k0, k1] = dpf::make_dpf(In{1}, std::uint32_t{1}); + using key_t = std::decay_t; + auto check = [](In from, In to) + { + In ff = from, ft = to; + dpf::utils::flip_msb_if_signed_integral(ff); + dpf::utils::flip_msb_if_signed_integral(ft); + constexpr auto to_int = dpf::utils::to_integral_type{}; + using integral = typename key_t::integral_type; + const auto from_i = static_cast(to_int(ff)); + const auto to_i = static_cast(to_int(ft)); + const bool wraps = dpf::utils::interval_wraps(from_i, to_i, 8); + const auto segs = dpf::utils::split_leaf_nodes( + dpf::utils::get_from_node(ff), + dpf::utils::get_to_node(ft), + static_cast(key_t::depth), wraps); + EXPECT_EQ((dpf::utils::get_leafnodes_in_output_interval(from, to)), + segs.total); + }; + check(In{10}, In{20}); + check(In{200}, In{10}); + check(In{10}, In{9}); + check(In{0}, In{255}); + (void)k1; +} + +TEST(WrapUtils, LeafCountVariesWithAlignmentWhenPacked) +{ + using In = std::int8_t; + auto [k0, k1] = dpf::make_dpf(In{0}, std::uint32_t{7}); + using key_t = std::decay_t; + ASSERT_GT(key_t::outputs_per_leaf, 1u); + const In from{-40}, to{10}; + const auto n0 = dpf::utils::get_leafnodes_in_output_interval(from, to); + bool saw_larger = false; + for (int d = 0; d < 64; ++d) + { + const In tfrom = static_cast(from + d); + const In tto = static_cast(to + d); + const auto n = dpf::utils::get_leafnodes_in_output_interval(tfrom, tto); + if (n > n0) + saw_larger = true; + } + EXPECT_TRUE(saw_larger); + (void)k1; +} + +// --------------------------------------------------------------------------- +// rotation_iterable: indexing past the wrap (the deferred-view bug class) +// --------------------------------------------------------------------------- + +TEST(RotationIterable, OperatorBracketMatchesIteratorOrder) +{ + std::vector values{10, 20, 30, 40, 50}; + dpf::rotation_iterable rot(values.begin(), values.end(), 3); + std::vector by_it; + for (auto it = rot.begin(); it != rot.end(); ++it) + by_it.push_back(*it); + EXPECT_EQ(by_it, (std::vector{40, 50, 10, 20, 30})); + + std::vector by_idx; + for (std::ptrdiff_t i = 0; i < static_cast(values.size()); ++i) + by_idx.push_back(rot[i]); + EXPECT_EQ(by_idx, by_it); +} + +TEST(RotationIterable, NegativeAndFullCycleDistanceNormalize) +{ + std::vector values{1, 2, 3, 4}; + dpf::rotation_iterable neg(values.begin(), values.end(), -1); + EXPECT_EQ(neg.distance(), 3); + EXPECT_EQ(neg[0], 4); + EXPECT_EQ(neg[1], 1); + + dpf::rotation_iterable full(values.begin(), values.end(), 8); + EXPECT_EQ(full.distance(), 0); + EXPECT_EQ(full[0], 1); + EXPECT_EQ(full[3], 4); +} + +TEST(RotationIterable, WrappingSubrangeViaIndexDoesNotWalkPastEnd) +{ + // Contiguous std::next from rot.begin() past the physical end is wrong + // for a wrapping logical slice; operator[] with modulo is the safe path. + std::vector values{0, 1, 2, 3, 4, 5, 6, 7}; + dpf::rotation_iterable rot(values.begin(), values.end(), 5); + // Logical slice starting at index 6 of the unrotated domain, length 4: + // rotated indices (6+5)%8 ... => values 3,4,5,6 in rot order from start 6. + const std::size_t start = 6; + const std::size_t count = 4; + const std::size_t n = values.size(); + std::vector got; + for (std::size_t i = 0; i < count; ++i) + got.push_back(rot[static_cast((start + i) % n)]); + EXPECT_EQ(got, (std::vector{3, 4, 5, 6})); +} + +TEST(RotationIterable, BidirectionalRoundTrip) +{ + std::vector values{1, 2, 3, 4, 5}; + dpf::rotation_iterable rot(values.begin(), values.end(), 2); + auto it = rot.begin(); + ++it; + ++it; + EXPECT_EQ(*it, 5); + --it; + EXPECT_EQ(*it, 4); + --it; + EXPECT_EQ(it, rot.begin()); + EXPECT_EQ(*it, 3); +} + +// --------------------------------------------------------------------------- +// Eager eval_interval wrap vs pointwise +// --------------------------------------------------------------------------- + +TEST(EagerWrap, Uint8MatchesPointwise) +{ + using In = std::uint8_t; + using Out = std::uint32_t; + constexpr In from{200}, to{10}, alpha{250}; + constexpr Out beta{0xABCDEF01u}; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + auto [buf0, it0] = dpf::eval_interval(k0, from, to); + auto [buf1, it1] = dpf::eval_interval(k1, from, to); + auto a = std::begin(it0); + auto b = std::begin(it1); + std::size_t n = 0; + for_inclusive_wrap(from, to, [&](In x) + { + ASSERT_NE(a, std::end(it0)); + ASSERT_NE(b, std::end(it1)); + EXPECT_EQ(recon(*a, *b), + recon(*dpf::eval_point(k0, x), *dpf::eval_point(k1, x))) + << "x=" << +x; + ++a; + ++b; + ++n; + }); + EXPECT_EQ(a, std::end(it0)); + EXPECT_EQ(b, std::end(it1)); + EXPECT_EQ(n, inclusive_span(from, to)); + (void)buf0; + (void)buf1; +} + +TEST(EagerWrap, SameLeafWrapMatchesPointwise) +{ + using In = std::uint8_t; + using Out = std::uint32_t; + // from=10, to=9 wraps almost the full domain; opl may share a leaf. + auto [k0, k1] = dpf::make_dpf(In{40}, Out{0x11111111u}); + auto [buf0, it0] = dpf::eval_interval(k0, In{10}, In{9}); + auto [buf1, it1] = dpf::eval_interval(k1, In{10}, In{9}); + auto a = std::begin(it0); + auto b = std::begin(it1); + for_inclusive_wrap(In{10}, In{9}, [&](In x) + { + ASSERT_NE(a, std::end(it0)); + ASSERT_NE(b, std::end(it1)); + EXPECT_EQ(recon(*a, *b), + recon(*dpf::eval_point(k0, x), *dpf::eval_point(k1, x))); + ++a; + ++b; + }); + EXPECT_EQ(a, std::end(it0)); + EXPECT_EQ(b, std::end(it1)); + (void)buf0; + (void)buf1; +} + +// --------------------------------------------------------------------------- +// Wildcard offset: memoizer / buffer must size on tree coordinates +// --------------------------------------------------------------------------- + +TEST(OffsetSizing, LogicalMemoizerCanUndersizeAfterAssign) +{ + using In = std::int8_t; + using Out = std::uint32_t; + constexpr In from{-40}, to{10}; + using key_t = std::decay_t(dpf::make_dpf(dpf::wildcard_value{}, Out{7})))>; + ASSERT_GT(key_t::outputs_per_leaf, 1u); + + const auto n_logical = + dpf::utils::get_leafnodes_in_output_interval(from, to); + bool found = false; + for (int trial = 0; trial < 256; ++trial) + { + auto [k0, k1] = dpf::make_dpf(dpf::wildcard_value{}, Out{7}); + const In alpha = static_cast(trial - 128); + assign_input_local(k0, k1, alpha); + const auto tfrom = k0.offset_x(from); + const auto tto = k0.offset_x(to); + const auto n_tree = + dpf::utils::get_leafnodes_in_output_interval(tfrom, tto); + + In ff = tfrom, ft = tto; + dpf::utils::flip_msb_if_signed_integral(ff); + dpf::utils::flip_msb_if_signed_integral(ft); + constexpr auto to_int = dpf::utils::to_integral_type{}; + using integral = typename key_t::integral_type; + const bool wraps = dpf::utils::interval_wraps( + static_cast(to_int(ff)), + static_cast(to_int(ft)), 8); + // Single-segment undersize: each wrap half may still fit in n_logical. + if (wraps || n_tree <= n_logical) + continue; + + found = true; + auto small = dpf::make_basic_interval_memoizer(from, to); + auto buf = dpf::make_output_buffer_for_interval(k0, from, to); + EXPECT_THROW( + (void)dpf::eval_interval(k0, from, to, buf, small), + std::exception); + + auto memo = dpf::make_basic_interval_memoizer(k0, from, to); + auto buf2 = dpf::make_output_buffer_for_interval(k0, from, to); + auto it = dpf::eval_interval(k0, from, to, buf2, memo); + auto it1_buf = dpf::make_output_buffer_for_interval(k1, from, to); + auto memo1 = dpf::make_basic_interval_memoizer(k1, from, to); + auto it1 = dpf::eval_interval(k1, from, to, it1_buf, memo1); + auto a = std::begin(it); + auto b = std::begin(it1); + for_inclusive_wrap(from, to, [&](In x) + { + ASSERT_NE(a, std::end(it)); + ASSERT_NE(b, std::end(it1)); + EXPECT_EQ(recon(*a, *b), + recon(*dpf::eval_point(k0, x), *dpf::eval_point(k1, x))); + ++a; + ++b; + }); + break; + } + ASSERT_TRUE(found) << "no non-wrapping misaligned offset found"; +} + +TEST(OffsetSizing, ConvenienceEvalIntervalSurvivesSignedWildcardSweep) +{ + using In = std::int8_t; + using Out = std::uint32_t; + constexpr In from{-40}, to{10}; + constexpr Out beta{9}; + int ok = 0; + for (int trial = 0; trial < 64; ++trial) + { + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, beta); + assign_input_local(d0, d1, static_cast(trial * 3 - 96)); + auto buf0 = dpf::make_output_buffer_for_interval(d0, from, to); + auto buf1 = dpf::make_output_buffer_for_interval(d1, from, to); + // Default memoizer path must not throw after the sizing fix. + auto it0 = dpf::eval_interval(d0, from, to, buf0); + auto it1 = dpf::eval_interval(d1, from, to, buf1); + auto a = std::begin(it0); + auto b = std::begin(it1); + for_inclusive_wrap(from, to, [&](In x) + { + ASSERT_NE(a, std::end(it0)); + ASSERT_NE(b, std::end(it1)); + EXPECT_EQ(recon(*a, *b), + recon(*dpf::eval_point(d0, x), *dpf::eval_point(d1, x))) + << "x=" << +x << " trial=" << trial; + ++a; + ++b; + }); + ++ok; + } + EXPECT_EQ(ok, 64); +} + +// --------------------------------------------------------------------------- +// Deferred wrap: index-based view vs eager (regression for contiguous-next bug) +// --------------------------------------------------------------------------- + +TEST(DeferWrap, WrappingUint8MatchesEagerAndPointwise) +{ + using In = std::uint8_t; + using Out = std::uint32_t; + constexpr In from{200}, to{10}; + constexpr Out beta{42}; + for (unsigned alpha_i = 0; alpha_i < 256; alpha_i += 37) + { + const In alpha = static_cast(alpha_i); + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, beta); + auto buf0 = dpf::make_output_buffer_for_full(d0); + auto buf1 = dpf::make_output_buffer_for_full(d1); + auto def0 = dpf::defer_eval_interval(d0, from, to, buf0); + auto def1 = dpf::defer_eval_interval(d1, from, to, buf1); + assign_input_local(d0, d1, alpha); + + auto eager_buf0 = dpf::make_output_buffer_for_interval(d0, from, to); + auto eager_buf1 = dpf::make_output_buffer_for_interval(d1, from, to); + auto eager0 = dpf::eval_interval(d0, from, to, eager_buf0); + auto eager1 = dpf::eval_interval(d1, from, to, eager_buf1); + + auto v0 = def0.get(); + auto v1 = def1.get(); + auto it_a = std::begin(v0); + auto it_b = std::begin(v1); + auto it_c = std::begin(eager0); + auto it_d = std::begin(eager1); + for_inclusive_wrap(from, to, [&](In x) + { + ASSERT_NE(it_a, std::end(v0)); + ASSERT_NE(it_b, std::end(v1)); + ASSERT_NE(it_c, std::end(eager0)); + ASSERT_NE(it_d, std::end(eager1)); + const auto y_def = recon(*it_a, *it_b); + const auto y_eag = recon(*it_c, *it_d); + const auto y_pt = recon(*dpf::eval_point(d0, x), + *dpf::eval_point(d1, x)); + EXPECT_EQ(y_def, y_eag) << "x=" << +x << " alpha=" << +alpha; + EXPECT_EQ(y_def, y_pt) << "x=" << +x << " alpha=" << +alpha; + ++it_a; + ++it_b; + ++it_c; + ++it_d; + }); + EXPECT_EQ(it_a, std::end(v0)); + EXPECT_EQ(it_b, std::end(v1)); + } +} + +TEST(DeferWrap, SignedSpanAcrossZeroMatchesEager) +{ + using In = std::int8_t; + using Out = std::uint32_t; + constexpr In from{-5}, to{5}; + constexpr Out beta{3}; + for (int trial = 0; trial < 32; ++trial) + { + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, beta); + auto buf0 = dpf::make_output_buffer_for_full(d0); + auto buf1 = dpf::make_output_buffer_for_full(d1); + auto def0 = dpf::defer_eval_interval(d0, from, to, buf0); + auto def1 = dpf::defer_eval_interval(d1, from, to, buf1); + assign_input_local(d0, d1, static_cast(trial * 7 - 112)); + + auto eager_buf0 = dpf::make_output_buffer_for_interval(d0, from, to); + auto eager_buf1 = dpf::make_output_buffer_for_interval(d1, from, to); + auto eager0 = dpf::eval_interval(d0, from, to, eager_buf0); + auto eager1 = dpf::eval_interval(d1, from, to, eager_buf1); + + auto v0 = def0.get(); + auto v1 = def1.get(); + auto a = std::begin(v0); + auto b = std::begin(v1); + auto c = std::begin(eager0); + auto d = std::begin(eager1); + while (a != std::end(v0)) + { + ASSERT_NE(b, std::end(v1)); + ASSERT_NE(c, std::end(eager0)); + ASSERT_NE(d, std::end(eager1)); + EXPECT_EQ(recon(*a, *b), recon(*c, *d)); + ++a; + ++b; + ++c; + ++d; + } + EXPECT_EQ(b, std::end(v1)); + EXPECT_EQ(c, std::end(eager0)); + EXPECT_EQ(d, std::end(eager1)); + } +} + +TEST(DeferWrap, MultiOplUnalignedWrappingMatchesEager) +{ + using In = std::uint8_t; + using Out = std::uint64_t; + constexpr In from{0xF1}, to{0x0E}; + constexpr Out beta{0x55}; + auto [d0, d1] = dpf::make_dpf(dpf::wildcard_value{}, beta); + ASSERT_GT(decltype(d0)::outputs_per_leaf, std::size_t{1}); + auto buf0 = dpf::make_output_buffer_for_full(d0); + auto buf1 = dpf::make_output_buffer_for_full(d1); + auto def0 = dpf::defer_eval_interval(d0, from, to, buf0); + auto def1 = dpf::defer_eval_interval(d1, from, to, buf1); + assign_input_local(d0, d1, In{0xA3}); + + auto eager_buf0 = dpf::make_output_buffer_for_interval(d0, from, to); + auto eager_buf1 = dpf::make_output_buffer_for_interval(d1, from, to); + auto eager0 = dpf::eval_interval(d0, from, to, eager_buf0); + auto eager1 = dpf::eval_interval(d1, from, to, eager_buf1); + + auto v0 = def0.get(); + auto v1 = def1.get(); + auto a = std::begin(v0); + auto b = std::begin(v1); + auto c = std::begin(eager0); + auto d = std::begin(eager1); + for_inclusive_wrap(from, to, [&](In x) + { + ASSERT_NE(a, std::end(v0)); + ASSERT_NE(b, std::end(v1)); + ASSERT_NE(c, std::end(eager0)); + ASSERT_NE(d, std::end(eager1)); + EXPECT_EQ(recon(*a, *b), recon(*c, *d)) << "x=" << +x; + EXPECT_EQ(recon(*a, *b), + recon(*dpf::eval_point(d0, x), *dpf::eval_point(d1, x))); + ++a; + ++b; + ++c; + ++d; + }); +} + +// --------------------------------------------------------------------------- +// Inner-product wrap already covered; keep a wildcard-offset variant +// --------------------------------------------------------------------------- + +TEST(InnerProductWrap, WildcardOffsetWrappingMatchesPoints) +{ + using In = std::uint8_t; + constexpr In from{250}, to{4}; + auto [k0, k1] = dpf::make_dpf(dpf::wildcard_value{}, std::uint32_t{9}); + assign_input_local(k0, k1, In{1}); + + std::vector w; + std::uint64_t expect = 0; + for_inclusive_wrap(from, to, [&](In x) + { + w.push_back(static_cast(w.size() + 1)); + expect += static_cast( + recon(*dpf::eval_point(k0, x), *dpf::eval_point(k1, x))) + * w.back(); + }); + EXPECT_EQ(recon( + dpf::eval_inner_product(dpf::paired, k0, from, to, w), + dpf::eval_inner_product(dpf::paired, k1, from, to, w)), + expect); +} diff --git a/test/tests/yao_share_test.cpp b/test/tests/yao_share_test.cpp new file mode 100644 index 0000000..d9da1a5 --- /dev/null +++ b/test/tests/yao_share_test.cpp @@ -0,0 +1,350 @@ +#include + +#include +#include +#include +#include +#include +#include + +#include "dpf.hpp" +#include "dpf/yao.hpp" +#include "dpf/yao_share.hpp" + +namespace +{ + +template +Ring xor_bits(const std::vector & a, const std::vector & b) +{ + Ring v{}; + for (std::size_t i = 0; i < a.size() && i < 8u * sizeof(Ring); ++i) + v = static_cast(v | (static_cast(a[i] ^ b[i]) << i)); + return v; +} + +template +Ring low_mask(unsigned width) +{ + if (width == 0 || width >= 8u * sizeof(Ring)) + return static_cast(~Ring{0}); + return static_cast((Ring{1} << width) - Ring{1}); +} + +template +void expect_additive(Ring secret, unsigned width) +{ + const unsigned bits = width == 0 ? static_cast(8u * sizeof(Ring)) : width; + const Ring r = dpf::uniform_sample(); + const auto a0 = dpf::additive_share::from_raw(r); + const auto a1 = dpf::additive_share::from_raw(static_cast(secret - r)); + const auto [y0, y1] = dpf::yao::a2y(a0, a1, width); + ASSERT_EQ(y0.size(), bits); + ASSERT_EQ(y1.size(), bits); + EXPECT_EQ(xor_bits(y0, y1), static_cast(secret & low_mask(bits))); + const auto [b0, b1] = dpf::yao::y2a(y0, y1, bits); + EXPECT_EQ(dpf::reconstruct(b0, b1), static_cast(secret & low_mask(bits))); +} + +template +void expect_subtractive(Ring s0, Ring s1, unsigned width) +{ + const unsigned bits = width == 0 ? static_cast(8u * sizeof(Ring)) : width; + const Ring opened = static_cast(s0 - s1); + const auto b0 = dpf::subtractive_share::from_raw(s0); + const auto b1 = dpf::subtractive_share::from_raw(s1); + const auto [y0, y1] = dpf::yao::b2y(b0, b1, width); + EXPECT_EQ(xor_bits(y0, y1), static_cast(opened & low_mask(bits))); + const auto [z0, z1] = dpf::yao::y2b(y0, y1, bits); + EXPECT_EQ(dpf::reconstruct(z0, z1), static_cast(opened & low_mask(bits))); + + const auto f0 = b0.as_fss(); + const auto f1 = b1.as_fss(); + const auto [g0, g1] = dpf::yao::fss2y(f0, f1, width); + EXPECT_EQ(xor_bits(g0, g1), static_cast(opened & low_mask(bits))); + const auto [h0, h1] = dpf::yao::y2fss(g0, g1, bits); + EXPECT_EQ(dpf::reconstruct(h0, h1), static_cast(opened & low_mask(bits))); +} + +} // namespace + +TEST(YaoShare, WidthSweep) +{ + const unsigned widths64[] = {1, 2, 7, 8, 9, 16, 31, 32, 63, 64, 0}; + for (unsigned w : widths64) + expect_additive(0x1234abcd5ull, w); + const unsigned widths32[] = {1, 8, 31, 32, 0}; + for (unsigned w : widths32) + expect_additive(0x89abcdefu, w); + expect_additive(0xBEEFu, 0); + expect_additive(0xBEEFu, 9); + expect_additive(0xA5u, 0); + expect_additive(0xA5u, 3); +} + +TEST(YaoShare, CornerSecrets) +{ + expect_additive(0, 64); + expect_additive(1, 64); + expect_additive(~std::uint64_t{0}, 64); + expect_additive(std::uint64_t{1} << 63, 64); + expect_additive(0x105u, 8); + expect_subtractive(0, 0, 64); + expect_subtractive(1, 3, 64); + expect_subtractive(3, 1, 16); + expect_subtractive(0, 1, 32); + expect_subtractive(0x10, 0x10, 8); +} + +TEST(YaoShare, RandomRoundTrips) +{ + for (int i = 0; i < 24; ++i) + { + const auto secret = dpf::uniform_sample(); + expect_additive(secret, 64); + const auto s0 = dpf::uniform_sample(); + const auto s1 = dpf::uniform_sample(); + expect_subtractive(s0, s1, 32); + } +} + +TEST(YaoShare, BitFlipChangesThatPlace) +{ + const auto a0 = dpf::additive_share::from_raw(0x111u); + const auto a1 = dpf::additive_share::from_raw(0x222u); + auto [y0, y1] = dpf::yao::a2y(a0, a1, 12); + const auto opened = xor_bits(y0, y1); + for (unsigned i = 0; i < 12; ++i) + { + auto flipped = y0; + flipped[i] = static_cast(flipped[i] ^ 1u); + EXPECT_EQ(xor_bits(flipped, y1), opened ^ (std::uint64_t{1} << i)); + const auto [b0, b1] = dpf::yao::y2a(flipped, y1, 12); + EXPECT_EQ(dpf::reconstruct(b0, b1), opened ^ (std::uint64_t{1} << i)); + } +} + +TEST(YaoShare, DefaultWidthUsesTheVector) +{ + const auto a0 = dpf::additive_share::from_raw(0x00FFu); + const auto a1 = dpf::additive_share::from_raw(0); + const auto [y0, y1] = dpf::yao::a2y(a0, a1, 8); + const auto [b0, b1] = dpf::yao::y2a(y0, y1); + EXPECT_EQ(dpf::reconstruct(b0, b1), 0x00FFu); +} + +TEST(YaoShare, RejectsBadInputs) +{ + const auto a0 = dpf::additive_share::from_raw(1); + const auto a1 = dpf::additive_share::from_raw(0); + EXPECT_THROW(dpf::yao::a2y(a0, a1, 65), std::invalid_argument); + EXPECT_THROW(dpf::yao::a2y( + dpf::additive_share::from_raw(1), + dpf::additive_share::from_raw(0), 9), + std::invalid_argument); + + std::vector bits(8, 0); + std::vector shortv(3, 0); + EXPECT_THROW(dpf::yao::y2a(shortv, bits, 8), std::invalid_argument); + bits[4] = 2; + EXPECT_THROW(dpf::yao::y2a(bits, std::vector(8, 0), 8), + std::invalid_argument); + + const auto rss = dpf::make_replicated_shares(1, 2, 3); + auto r0 = std::get<0>(rss); + r0.next = 99; + EXPECT_THROW(dpf::yao::rss2y(r0, std::get<1>(rss)), std::invalid_argument); +} + +TEST(YaoShare, ReplicatedManyAndFresh) +{ + for (int i = 0; i < 12; ++i) + { + const auto x0 = dpf::uniform_sample(); + const auto x1 = dpf::uniform_sample(); + const auto x2 = dpf::uniform_sample(); + const auto secret = static_cast(x0 + x1 + x2); + const auto shares = dpf::make_replicated_shares(x0, x1, x2); + const auto [y0, y1] = dpf::yao::rss2y(std::get<0>(shares), std::get<1>(shares)); + EXPECT_EQ(xor_bits(y0, y1), secret); + const auto back = dpf::yao::y2rss(y0, y1); + EXPECT_EQ(dpf::reconstruct(std::get<0>(back), std::get<1>(back)), secret); + EXPECT_EQ(dpf::reconstruct(std::get<1>(back), std::get<2>(back)), secret); + EXPECT_EQ(dpf::reconstruct(std::get<0>(back), std::get<2>(back)), secret); + const auto again = dpf::yao::y2rss(y0, y1); + EXPECT_NE(std::get<0>(back).own, std::get<0>(again).own); + } +} + +TEST(YaoShare, ConcreteAdditiveSum) +{ + const auto a0 = dpf::additive_share::from_raw(0x1234); + const auto a1 = dpf::additive_share::from_raw(0x0100); + const auto [y0, y1] = dpf::yao::a2y(a0, a1, 16); + EXPECT_EQ(xor_bits(y0, y1), static_cast(0x1334)); +} + +TEST(YaoShare, PointLeafOnAndOff) +{ + for (int n = 0; n < 16; ++n) + { + const auto alpha = dpf::uniform_sample(); + const auto beta = dpf::uniform_sample(); + auto [k0, k1] = dpf::make_dpf(alpha, beta); + auto s0 = *dpf::eval_point(k0, alpha); + auto s1 = *dpf::eval_point(k1, alpha); + const auto [y0, y1] = dpf::yao::b2y(s0, s1, 32); + EXPECT_EQ(xor_bits(y0, y1), beta); + const auto [z0, z1] = dpf::yao::y2b(y0, y1, 32); + EXPECT_EQ(dpf::reconstruct(z0, z1), beta); + + const auto other = static_cast(alpha + 1u); + auto t0 = *dpf::eval_point(k0, other); + auto t1 = *dpf::eval_point(k1, other); + const auto [u0, u1] = dpf::yao::b2y(t0, t1, 32); + EXPECT_EQ(xor_bits(u0, u1), 0u); + } +} + +TEST(YaoShare, PointLeafPlusPublicAndSecondLeaf) +{ + const std::uint8_t alpha = 9; + const std::uint32_t beta = 40; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + auto s0 = *dpf::eval_point(k0, alpha); + auto s1 = *dpf::eval_point(k1, alpha); + s0 += std::uint32_t{5}; + const auto [y0, y1] = dpf::yao::b2y(s0, s1, 32); + EXPECT_EQ(xor_bits(y0, y1), 45u); + + auto [j0, j1] = dpf::make_dpf(alpha, std::uint32_t{7}); + auto u0 = *dpf::eval_point(k0, alpha) + *dpf::eval_point(j0, alpha); + auto u1 = *dpf::eval_point(k1, alpha) + *dpf::eval_point(j1, alpha); + const auto [v0, v1] = dpf::yao::b2y(u0, u1, 32); + EXPECT_EQ(xor_bits(v0, v1), 47u); +} + +TEST(YaoShare, ComparisonLeaf) +{ + const std::uint32_t alpha = 100u; + const std::uint64_t yt = 5u; + const std::uint64_t yf = 9u; + auto [k0, k1] = dpf::make_dpf(alpha, dpf::lt(yt, yf)); + const std::uint64_t mask = k0.cmp().mask; + auto c0 = dpf::eval_point(dpf::cmp, k0, 50u); + auto c1 = dpf::eval_point(dpf::cmp, k1, 50u); + const auto [y0, y1] = dpf::yao::a2y(c0, c1, 64); + const auto bits = xor_bits(y0, y1); + EXPECT_EQ(bits, dpf::reconstruct(c0, c1)); + EXPECT_EQ(bits & mask, yt); + + auto d0 = dpf::eval_point(dpf::cmp, k0, alpha); + auto d1 = dpf::eval_point(dpf::cmp, k1, alpha); + const auto [z0, z1] = dpf::yao::a2y(d0, d1, 64); + EXPECT_EQ(xor_bits(z0, z1) & mask, yf); +} + +TEST(YaoShare, LeafBitsThroughANetlist) +{ + const std::uint8_t alpha = 42; + const std::uint32_t beta = 0x6bu; + auto [k0, k1] = dpf::make_dpf(alpha, beta); + auto s0 = *dpf::eval_point(k0, alpha); + auto s1 = *dpf::eval_point(k1, alpha); + const auto [p0, p1] = dpf::yao::b2y(s0, s1, 8); + + dpf::yao::netlist n; + dpf::yao::bit in[8]; + for (int i = 0; i < 8; ++i) + in[i] = n.shared_in(); + n.out(n.and_(in[0], in[1])); + for (int i = 0; i < 8; ++i) + n.out(in[i]); + + auto [o0, o1] = dpf::yao::eval_pair(n, p0.data(), p1.data()); + ASSERT_EQ(o0.size(), 9u); + EXPECT_EQ(o0[0] ^ o1[0], static_cast((beta & 1u) & ((beta >> 1) & 1u))); + for (int i = 0; i < 8; ++i) + EXPECT_EQ(o0[static_cast(i + 1)] ^ o1[static_cast(i + 1)], + static_cast((beta >> i) & 1u)); + + std::vector and0{o0[0]}; + std::vector and1{o1[0]}; + const auto [z0, z1] = dpf::yao::y2b(and0, and1, 1); + EXPECT_EQ(dpf::reconstruct(z0, z1), 1u); +} + +TEST(YaoShare, RandomNetlistMatchesPlain) +{ + std::uint32_t rng = 0xC0FFEEu; + auto nxt = [&] { + rng = rng * 1664525u + 1013904223u; + return rng; + }; + for (int trial = 0; trial < 20; ++trial) + { + dpf::yao::netlist n; + dpf::yao::bit w[24]; + std::uint8_t sem[4]; + std::uint8_t p0[4]; + std::uint8_t p1[4]; + int nwire = 4; + for (int i = 0; i < 4; ++i) + { + w[i] = n.shared_in(); + sem[i] = static_cast(nxt() & 1u); + p0[i] = static_cast(nxt() & 1u); + p1[i] = static_cast(sem[i] ^ p0[i]); + } + for (int g = 0; g < 32; ++g) + { + const int ia = static_cast(nxt() % static_cast(nwire)); + const int ib = static_cast(nxt() % static_cast(nwire)); + dpf::yao::bit d; + switch (nxt() % 3u) + { + case 0: d = n.xor_(w[ia], w[ib]); break; + case 1: d = n.and_(w[ia], w[ib]); break; + default: d = n.not_(w[ia]); break; + } + if (nwire < 24) + w[nwire++] = d; + } + for (int i = 0; i < 4; ++i) + n.out(w[nwire - 1 - i]); + const auto plain = dpf::yao::eval_plain(n, sem); + EXPECT_EQ(dpf::yao::eval_local(n, sem), plain) << trial; + auto [a, b] = dpf::yao::eval_pair(n, p0, p1); + for (std::size_t i = 0; i < plain.size(); ++i) + EXPECT_EQ(static_cast(a[i] ^ b[i]), plain[i]) << trial; + } +} + +TEST(YaoShare, MixedPrivateInputs) +{ + dpf::yao::netlist n; + const auto a = n.priv_in(0); + const auto b = n.priv_in(1); + const auto c = n.shared_in(); + n.out(n.xor_(n.and_(a, b), c)); + n.out(n.xor_public(c, 0)); + n.out(n.not_(n.not_(a))); + const std::uint8_t p0[3] = {1, 0, 1}; + const std::uint8_t p1[3] = {9, 1, 0}; + auto [o0, o1] = dpf::yao::eval_pair(n, p0, p1); + EXPECT_EQ(static_cast(o0[0] ^ o1[0]), 0u); + EXPECT_EQ(static_cast(o0[1] ^ o1[1]), 1u); + EXPECT_EQ(static_cast(o0[2] ^ o1[2]), 1u); +} + +TEST(YaoShare, NetlistRejects) +{ + dpf::yao::netlist n; + EXPECT_THROW(n.priv_in(2), std::invalid_argument); + EXPECT_THROW(n.xor_(dpf::yao::bit{3}, dpf::yao::bit{0}), std::invalid_argument); + const auto a = n.shared_in(); + n.out(a); + EXPECT_THROW(n.shared_in(), std::logic_error); + std::uint8_t bad = 2; + EXPECT_THROW(dpf::yao::eval_local(n, &bad), std::invalid_argument); +} diff --git a/test/tests/yao_stack_test.cpp b/test/tests/yao_stack_test.cpp new file mode 100644 index 0000000..9b53ee4 --- /dev/null +++ b/test/tests/yao_stack_test.cpp @@ -0,0 +1,314 @@ +#include + +#include +#include + +#include "dpf/yao.hpp" +#include "dpf/yao_stack.hpp" + +namespace +{ + +using dpf::yao::bit; +using dpf::yao::netlist; + +netlist and_n(unsigned n) +{ + netlist nl; + std::vector in; + in.reserve(n); + for (unsigned i = 0; i < n; ++i) + in.push_back(nl.shared_in()); + bit acc = in[0]; + for (unsigned i = 1; i < n; ++i) + acc = nl.and_(acc, in[i]); + nl.out(acc); + return nl; +} + +netlist xor2() +{ + netlist nl; + auto a = nl.shared_in(); + auto b = nl.shared_in(); + nl.out(nl.xor_(a, b)); + return nl; +} + +std::uint8_t plain_one(const netlist & nl, const std::vector & in) +{ + return dpf::yao::eval_plain(nl, in.data())[0]; +} + +} // namespace + +TEST(YaoStack, IfCostsTheHeavierBranch) +{ + auto heavy = and_n(3); + auto light = and_n(2); + EXPECT_EQ(heavy.n_and(), 2u); + EXPECT_EQ(light.n_and(), 1u); + std::vector h0{1, 1, 1}; + std::vector h1{0, 0, 0}; + std::vector l0{1, 1}; + std::vector l1{0, 1}; + for (std::uint8_t c0 = 0; c0 < 2; ++c0) + { + for (std::uint8_t c1 = 0; c1 < 2; ++c1) + { + auto got = dpf::yao::eval_if(heavy, light, c0, c1, + h0.data(), h1.data(), l0.data(), l1.data()); + EXPECT_EQ(got.stack_blocks, 4u); + EXPECT_EQ(got.naive_blocks, 6u); + EXPECT_LT(got.stack_blocks, got.naive_blocks); + const std::uint8_t sem = static_cast(c0 ^ c1); + const std::uint8_t want = (sem == 0) ? plain_one(heavy, {1, 1, 1}) + : plain_one(light, {1, 0}); + ASSERT_EQ(got.share0.size(), 1u); + EXPECT_EQ(static_cast(got.share0[0] ^ got.share1[0]), want); + } + } +} + +TEST(YaoStack, OneHotCostsTheHeaviestBranch) +{ + auto a = and_n(2); + auto b = xor2(); + auto c = and_n(4); + EXPECT_EQ(a.n_and(), 1u); + EXPECT_EQ(b.n_and(), 0u); + EXPECT_EQ(c.n_and(), 3u); + std::vector branches; + branches.push_back(a); + branches.push_back(b); + branches.push_back(c); + std::vector> p0{ + {1, 1}, + {1, 0}, + {1, 1, 1, 0}, + }; + std::vector> p1{ + {0, 0}, + {0, 1}, + {0, 0, 0, 0}, + }; + for (std::uint16_t idx = 0; idx < 3; ++idx) + { + auto got = dpf::yao::eval_one_hot(branches, idx, 0, p0, p1); + EXPECT_EQ(got.stack_blocks, 6u); + EXPECT_EQ(got.naive_blocks, 8u); + std::vector sem(p0[idx].size()); + for (std::size_t i = 0; i < sem.size(); ++i) + sem[i] = static_cast(p0[idx][i] ^ p1[idx][i]); + const std::uint8_t want = plain_one(branches[idx], sem); + EXPECT_EQ(static_cast(got.share0[0] ^ got.share1[0]), want); + } +} + +namespace +{ + +std::uint8_t xor_share(const std::vector & a, + const std::vector & b, std::size_t i) +{ + return static_cast(a[i] ^ b[i]); +} + +netlist not1() +{ + netlist nl; + nl.out(nl.not_(nl.shared_in())); + return nl; +} + +netlist two_outs() +{ + netlist nl; + auto a = nl.shared_in(); + auto b = nl.shared_in(); + nl.out(nl.and_(a, b)); + nl.out(nl.xor_(a, b)); + return nl; +} + +netlist not_and_id() +{ + netlist nl; + auto a = nl.shared_in(); + nl.shared_in(); + nl.out(nl.not_(a)); + nl.out(a); + return nl; +} + +netlist priv_and() +{ + netlist nl; + auto p = nl.priv_in(0); + auto s = nl.shared_in(); + nl.out(nl.and_(p, s)); + return nl; +} + +} // namespace + +TEST(YaoStack, EveryShareSplitOfBothBranches) +{ + auto then_nl = and_n(2); + auto else_nl = not1(); + for (std::uint8_t c0 = 0; c0 < 2; ++c0) + { + for (std::uint8_t c1 = 0; c1 < 2; ++c1) + { + for (std::uint8_t a0 = 0; a0 < 2; ++a0) + { + for (std::uint8_t a1 = 0; a1 < 2; ++a1) + { + for (std::uint8_t b0 = 0; b0 < 2; ++b0) + { + for (std::uint8_t b1 = 0; b1 < 2; ++b1) + { + for (std::uint8_t e0 = 0; e0 < 2; ++e0) + { + for (std::uint8_t e1 = 0; e1 < 2; ++e1) + { + const std::uint8_t tp0[2] = {a0, b0}; + const std::uint8_t tp1[2] = {a1, b1}; + const std::uint8_t ep0[1] = {e0}; + const std::uint8_t ep1[1] = {e1}; + auto got = dpf::yao::eval_if(then_nl, else_nl, c0, c1, + tp0, tp1, ep0, ep1); + const std::uint8_t sem = + static_cast(c0 ^ c1); + std::uint8_t want = 0; + if (sem == 0) + { + const std::uint8_t in[2] = { + xor_share({a0}, {a1}, 0), + static_cast(b0 ^ b1), + }; + want = plain_one(then_nl, {in[0], in[1]}); + } + else + { + want = plain_one(else_nl, + {static_cast(e0 ^ e1)}); + } + EXPECT_EQ(static_cast( + got.share0[0] ^ got.share1[0]), + want); + EXPECT_EQ(got.stack_blocks, 2u); + EXPECT_EQ(got.naive_blocks, 2u); + } + } + } + } + } + } + } + } +} + +TEST(YaoStack, TwoOutputsAndAPrivateInput) +{ + auto then_nl = two_outs(); + auto else_nl = not_and_id(); + const std::uint8_t tp0[2] = {1, 0}; + const std::uint8_t tp1[2] = {1, 1}; + const std::uint8_t ep0[2] = {0, 1}; + const std::uint8_t ep1[2] = {1, 0}; + auto got = dpf::yao::eval_if(then_nl, else_nl, 1, 0, tp0, tp1, ep0, ep1); + ASSERT_EQ(got.share0.size(), 2u); + const std::uint8_t sem_in[2] = {static_cast(1 ^ 1), + static_cast(0 ^ 1)}; + auto want = dpf::yao::eval_plain(then_nl, sem_in); + for (std::size_t i = 0; i < 2; ++i) + EXPECT_EQ(static_cast(got.share0[i] ^ got.share1[i]), want[i]); + + auto priv = priv_and(); + auto neg = not1(); + const std::uint8_t pp0[2] = {1, 1}; + const std::uint8_t pp1[2] = {0, 1}; + const std::uint8_t np0[1] = {0}; + const std::uint8_t np1[1] = {0}; + auto branched = dpf::yao::eval_if(priv, neg, 0, 1, pp0, pp1, np0, np1); + EXPECT_EQ(static_cast(branched.share0[0] ^ branched.share1[0]), + plain_one(neg, {0})); +} + +TEST(YaoStack, EmptyBranchesCostNothing) +{ + netlist left; + netlist right; + auto a = left.shared_in(); + left.out(left.xor_(a, left.shared_in())); + auto b = right.shared_in(); + right.out(right.not_(right.xor_(b, right.shared_in()))); + const std::uint8_t z[2] = {1, 1}; + auto got = dpf::yao::eval_if(left, right, 0, 0, z, z, z, z); + EXPECT_EQ(got.stack_blocks, 0u); + EXPECT_EQ(got.naive_blocks, 0u); + EXPECT_EQ(static_cast(got.share0[0] ^ got.share1[0]), 0); +} + +TEST(YaoStack, OneHotEveryIndexAndShare) +{ + std::vector branches; + for (unsigned i = 0; i < 8; ++i) + branches.push_back(i % 2 == 0 ? and_n(2) : xor2()); + const std::uint8_t patterns[2][2] = {{0, 0}, {1, 1}}; + for (std::uint16_t index = 0; index < 8; ++index) + { + for (std::uint16_t mask = 0; mask < 2; ++mask) + { + const std::uint16_t p0 = static_cast(index ^ mask); + const std::uint16_t p1 = mask; + std::vector> in0(8), in1(8); + for (unsigned b = 0; b < 8; ++b) + { + in0[b] = {patterns[b & 1][0], static_cast(b & 1u)}; + in1[b] = {patterns[b & 1][1], 1}; + } + auto got = dpf::yao::eval_one_hot(branches, p0, p1, in0, in1); + EXPECT_EQ(got.stack_blocks, 2u); + EXPECT_EQ(got.naive_blocks, 8u); + EXPECT_LT(got.stack_blocks, got.naive_blocks); + std::vector sem{ + static_cast(in0[index][0] ^ in1[index][0]), + static_cast(in0[index][1] ^ in1[index][1]), + }; + EXPECT_EQ(static_cast(got.share0[0] ^ got.share1[0]), + plain_one(branches[index], sem)); + } + } +} + +TEST(YaoStack, RejectsBadShapes) +{ + auto a = and_n(2); + auto b = not1(); + const std::uint8_t bit = 1; + EXPECT_THROW(dpf::yao::eval_if(a, b, 2, 0, &bit, &bit, &bit, &bit), + std::invalid_argument); + netlist one; + one.out(one.shared_in()); + netlist two; + auto t0 = two.shared_in(); + auto t1 = two.shared_in(); + two.out(t0); + two.out(t1); + EXPECT_THROW(dpf::yao::eval_if(one, two, 0, 0, &bit, &bit, &bit, &bit), + std::invalid_argument); + std::vector only{a}; + EXPECT_THROW(dpf::yao::eval_one_hot(only, 0, 0, {{}}, {{}}), std::invalid_argument); + std::vector too_many(9, a); + EXPECT_THROW(dpf::yao::eval_one_hot(too_many, 0, 0, + std::vector>(9), + std::vector>(9)), + std::invalid_argument); + std::vector pair{a, xor2()}; + EXPECT_THROW(dpf::yao::eval_one_hot(pair, 2, 0, {{1, 1}, {1, 1}}, {{0, 0}, {0, 0}}), + std::invalid_argument); + EXPECT_THROW(dpf::yao::eval_one_hot(pair, 0, 0, {{1}, {1, 1}}, {{0, 0}, {0, 0}}), + std::invalid_argument); +} diff --git a/test/tests/yao_test.cpp b/test/tests/yao_test.cpp new file mode 100644 index 0000000..766bafd --- /dev/null +++ b/test/tests/yao_test.cpp @@ -0,0 +1,421 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "aes_mmo_ref.hpp" +#include "dpf/net/trio.hpp" +#include "dpf/prg_aes.hpp" +#include "dpf/random.hpp" +#include "dpf/yao.hpp" +#include "dpf/yao_aes.hpp" +#include "dpf/verifiable.hpp" +#include "dpf/yao_share.hpp" + +namespace +{ + +using dpf::yao::bit; +using dpf::yao::bits8; +using dpf::yao::netlist; + +void bytes_to_bits(const std::uint8_t * bytes, int nbytes, std::uint8_t * bits) +{ + for (int i = 0; i < nbytes; ++i) + for (int k = 0; k < 8; ++k) + bits[i * 8 + k] = static_cast((bytes[i] >> (7 - k)) & 1u); +} + +void bits_to_bytes(const std::uint8_t * bits, int nbytes, std::uint8_t * bytes) +{ + for (int i = 0; i < nbytes; ++i) + { + bytes[i] = 0; + for (int k = 0; k < 8; ++k) + bytes[i] = static_cast(bytes[i] | (bits[i * 8 + k] << (7 - k))); + } +} + +std::uint8_t pack_byte(const std::uint8_t * bits) +{ + std::uint8_t b = 0; + bits_to_bytes(bits, 1, &b); + return b; +} + +netlist sbox_netlist() +{ + netlist n; + const bits8 in = dpf::yao::shared_byte(n); + dpf::yao::out_byte(n, dpf::yao::sbox(n, in)); + return n; +} + +void expand_key(const std::uint8_t key[16], std::uint8_t rk[11][16]) +{ + std::uint8_t w[176]; + std::memcpy(w, key, 16); + int n = 16; + std::uint8_t rcon = 1; + while (n < 176) + { + std::uint8_t t[4]; + std::memcpy(t, w + n - 4, 4); + if (n % 16 == 0) + { + const std::uint8_t tmp = t[0]; + t[0] = t[1]; + t[1] = t[2]; + t[2] = t[3]; + t[3] = tmp; + for (int i = 0; i < 4; ++i) + t[i] = dpf::party::aes_ref::sbox_at(t[i]); + t[0] = static_cast(t[0] ^ rcon); + rcon = dpf::party::aes_ref::xtime(rcon); + } + for (int i = 0; i < 4; ++i) + { + w[n] = static_cast(w[n - 16] ^ t[i]); + ++n; + } + } + std::memcpy(rk, w, 176); +} + +void encrypt_aes128(std::uint8_t s[16], const std::uint8_t rk[11][16]) +{ + using namespace dpf::party::aes_ref; + add_round_key(s, rk[0]); + for (int r = 1; r < 10; ++r) + { + sub_bytes(s); + shift_rows(s); + mix_columns(s); + add_round_key(s, rk[r]); + } + sub_bytes(s); + shift_rows(s); + add_round_key(s, rk[10]); +} + +std::vector reconstruct(std::vector a, + const std::vector & b) +{ + EXPECT_EQ(a.size(), b.size()); + for (std::size_t i = 0; i < a.size(); ++i) + a[i] = static_cast(a[i] ^ b[i]); + return a; +} + +template +void run_pair(Fn0 && fn0, Fn1 && fn1) +{ + const auto dir = std::filesystem::temp_directory_path() + / ("libdpf_yao_" + std::to_string(::getpid())); + std::filesystem::create_directories(dir); + std::exception_ptr ep0; + std::exception_ptr ep1; + std::thread t0([&] { + try + { + auto net = dpf::net::trio::connect_pair(dpf::net::role::p0, dir.string()); + fn0(net); + } + catch (...) + { + ep0 = std::current_exception(); + } + }); + std::thread t1([&] { + try + { + auto net = dpf::net::trio::connect_pair(dpf::net::role::p1, dir.string()); + fn1(net); + } + catch (...) + { + ep1 = std::current_exception(); + } + }); + t0.join(); + t1.join(); + std::filesystem::remove_all(dir); + if (ep0) + std::rethrow_exception(ep0); + if (ep1) + std::rethrow_exception(ep1); +} + +} // namespace + +TEST(Yao, AndXorNot) +{ + netlist n; + const bit a = n.shared_in(); + const bit b = n.shared_in(); + const bit x = n.xor_(a, b); + const bit y = n.and_(a, b); + const bit z = n.not_(a); + const bit w = n.xnor_(a, b); + n.out(x); + n.out(y); + n.out(z); + n.out(w); + n.out(n.xor_public(y, 1)); + EXPECT_EQ(n.n_and(), 1u); + for (int av = 0; av < 2; ++av) + { + for (int bv = 0; bv < 2; ++bv) + { + const std::uint8_t in[2] = { + static_cast(av), static_cast(bv)}; + const auto plain = dpf::yao::eval_plain(n, in); + const auto got = dpf::yao::eval_local(n, in); + const std::uint8_t expect[5] = { + static_cast(av ^ bv), + static_cast(av & bv), + static_cast(av ^ 1), + static_cast(1 ^ av ^ bv), + static_cast((av & bv) ^ 1)}; + EXPECT_EQ(plain, (std::vector(expect, expect + 5))); + EXPECT_EQ(got, plain); + } + } +} + +TEST(Yao, SboxPlainAndGarbled) +{ + const netlist n = sbox_netlist(); + EXPECT_EQ(n.n_and(), static_cast(aes_bp::and_count)); + for (int x = 0; x < 256; ++x) + { + const auto byte = static_cast(x); + std::uint8_t bits[8]; + bytes_to_bits(&byte, 1, bits); + const auto plain = dpf::yao::eval_plain(n, bits); + const auto garbled = dpf::yao::eval_local(n, bits); + EXPECT_EQ(pack_byte(plain.data()), dpf::party::aes_ref::sbox_at(byte)) << x; + EXPECT_EQ(garbled, plain) << x; + } +} + +TEST(Yao, SboxShares) +{ + const netlist n = sbox_netlist(); + const std::uint8_t byte = 0x53; + std::uint8_t semantic[8]; + bytes_to_bits(&byte, 1, semantic); + std::uint8_t p0[8], p1[8]; + for (int i = 0; i < 8; ++i) + { + p0[i] = static_cast(dpf::uniform_sample() & 1u); + p1[i] = static_cast(semantic[i] ^ p0[i]); + } + auto [a, b] = dpf::yao::eval_pair(n, p0, p1); + EXPECT_EQ(pack_byte(reconstruct(a, b).data()), dpf::party::aes_ref::sbox_at(byte)); +} + +TEST(Yao, Aes128Nist) +{ + const std::uint8_t key[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; + const std::uint8_t pt[16] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; + const std::uint8_t ct[16] = { + 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a}; + + std::uint8_t rk[11][16]; + expand_key(key, rk); + std::uint8_t state[16]; + std::memcpy(state, pt, 16); + encrypt_aes128(state, rk); + EXPECT_EQ(std::vector(state, state + 16), + std::vector(ct, ct + 16)); + + const netlist n = dpf::yao::aes128_netlist(); + EXPECT_EQ(n.n_and(), 6400u); + std::uint8_t bits[256]; + bytes_to_bits(pt, 16, bits); + bytes_to_bits(key, 16, bits + 128); + const auto plain = dpf::yao::eval_plain(n, bits); + std::uint8_t got[16]; + bits_to_bytes(plain.data(), 16, got); + EXPECT_EQ(std::vector(got, got + 16), + std::vector(ct, ct + 16)); + + const auto garbled = dpf::yao::eval_local(n, bits); + bits_to_bytes(garbled.data(), 16, got); + EXPECT_EQ(std::vector(got, got + 16), + std::vector(ct, ct + 16)); +} + +TEST(Yao, AesMmoMatchesPrg) +{ + const std::uint32_t positions[] = {0u, 1u, 0x01020304u}; + const std::uint8_t msg[16] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}; + simde__m128i block{}; + std::memcpy(&block, msg, 16); + std::uint8_t bits[128]; + dpf::yao::block_to_bits(bits, block); + for (std::uint32_t pos : positions) + { + const auto expect = dpf::prg::aes128::eval(block, pos); + const netlist n = dpf::yao::aes_mmo_netlist(pos); + EXPECT_EQ(n.n_and(), 5120u); + const auto got_bits = dpf::yao::eval_local(n, bits); + const auto got = dpf::yao::bits_to_block(got_bits.data()); + std::uint8_t a[16], b[16]; + std::memcpy(a, &expect, 16); + std::memcpy(b, &got, 16); + EXPECT_EQ(std::vector(a, a + 16), + std::vector(b, b + 16)) << pos; + } +} + +TEST(Yao, SessionSboxAndReuse) +{ + const netlist gates = [] { + netlist n; + const bit a = n.priv_in(0); + const bit b = n.priv_in(1); + const bit c = n.shared_in(); + n.out(n.xor_(n.and_(a, b), c)); + n.out(n.not_(c)); + return n; + }(); + const netlist priv_xor = [] { + netlist n; + const bit a = n.priv_in(0); + const bit b = n.priv_in(0); + n.out(n.xor_(a, b)); + return n; + }(); + const netlist box = sbox_netlist(); + const std::uint8_t byte = 0xa7; + std::uint8_t semantic[8]; + bytes_to_bits(&byte, 1, semantic); + std::uint8_t sp0[8], sp1[8]; + for (int i = 0; i < 8; ++i) + { + sp0[i] = static_cast(i & 1u); + sp1[i] = static_cast(semantic[i] ^ sp0[i]); + } + + std::vector g0, g1, s0, s1, x0, x1; + run_pair( + [&](dpf::net::trio & net) { + dpf::yao::session s; + const std::uint8_t xin[2] = {1, 1}; + x0 = s.eval(0, priv_xor, xin, net.to(dpf::net::role::p1)); + const std::uint8_t in0[3] = {1, 0, 1}; + g0 = s.eval(0, gates, in0, net.to(dpf::net::role::p1)); + const std::uint8_t in1[3] = {1, 0, 0}; + auto second = s.eval(0, gates, in1, net.to(dpf::net::role::p1)); + g0.insert(g0.end(), second.begin(), second.end()); + s0 = s.eval(0, box, sp0, net.to(dpf::net::role::p1)); + }, + [&](dpf::net::trio & net) { + dpf::yao::session s; + const std::uint8_t xin[2] = {0, 0}; + x1 = s.eval(1, priv_xor, xin, net.to(dpf::net::role::p0)); + const std::uint8_t in0[3] = {0, 1, 0}; + g1 = s.eval(1, gates, in0, net.to(dpf::net::role::p0)); + const std::uint8_t in1[3] = {0, 0, 1}; + auto second = s.eval(1, gates, in1, net.to(dpf::net::role::p0)); + g1.insert(g1.end(), second.begin(), second.end()); + s1 = s.eval(1, box, sp1, net.to(dpf::net::role::p0)); + }); + + EXPECT_EQ(reconstruct(x0, x1), std::vector{0}); + const auto opened = reconstruct(g0, g1); + const std::uint8_t expect_gates[4] = {0, 0, 1, 0}; + EXPECT_EQ(std::vector(opened.begin(), opened.begin() + 4), + std::vector(expect_gates, expect_gates + 4)); + EXPECT_EQ(pack_byte(reconstruct(s0, s1).data()), + dpf::party::aes_ref::sbox_at(byte)); +} + +TEST(Yao, LeafBitsOnSession) +{ + const std::uint32_t beta = 0x6bu; + const auto s0 = dpf::subtractive_share::from_raw(beta); + const auto s1 = dpf::subtractive_share::from_raw(0); + const auto [p0, p1] = dpf::yao::b2y(s0, s1, 8); + const dpf::yao::netlist n = [] { + dpf::yao::netlist c; + dpf::yao::bit in[8]; + for (int i = 0; i < 8; ++i) + in[i] = c.shared_in(); + c.out(c.and_(in[0], in[1])); + return c; + }(); + std::vector o0, o1; + bool locked = false; + run_pair( + [&](dpf::net::trio & net) { + dpf::yao::session s; + auto & link = net.to(dpf::net::role::p1); + o0 = s.eval(0, n, p0.data(), link); + try + { + s.eval(1, n, p0.data(), link); + } + catch (const std::logic_error &) + { + locked = true; + } + }, + [&](dpf::net::trio & net) { + dpf::yao::session s; + o1 = s.eval(1, n, p1.data(), net.to(dpf::net::role::p0)); + }); + EXPECT_TRUE(locked); + ASSERT_EQ(o0.size(), 1u); + EXPECT_EQ(static_cast(o0[0] ^ o1[0]), 1u); + const auto [z0, z1] = dpf::yao::y2b(o0, o1, 1); + EXPECT_EQ(dpf::reconstruct(z0, z1), 1u); +} + +TEST(Yao, CorrectionLevelMatchesMakeCs) +{ + const simde__m128i s0 = dpf::uniform_sample(); + const simde__m128i s1 = dpf::uniform_sample(); + const std::uint64_t prefix = 0x0123456789abcdefull; + const std::uint64_t share0 = 0x1111222233334444ull; + const std::uint64_t share1 = prefix ^ share0; + const std::size_t level = 0x10ffu; + std::uint8_t in0[dpf::yao::correction_level_in_bits]; + std::uint8_t in1[dpf::yao::correction_level_in_bits]; + dpf::yao::pack_correction_level(0, s0, share0, level, in0); + dpf::yao::pack_correction_level(1, s1, share1, level, in1); + const auto nl = dpf::yao::correction_level_netlist(); + EXPECT_EQ(nl.n_and(), dpf::yao::correction_level_ands); + EXPECT_EQ(nl.n_in(), static_cast(dpf::yao::correction_level_in_bits)); + auto [a, b] = dpf::yao::eval_pair(nl, in0, in1); + ASSERT_EQ(a.size(), dpf::yao::correction_level_out_bits); + const auto expect = dpf::detail::vdpf::make_cs(level, prefix, s0, s1); + for (int lane = 0; lane < 4; ++lane) + { + std::uint8_t bits[128]; + for (int i = 0; i < 128; ++i) + bits[i] = static_cast( + a[static_cast(lane * 128 + i)] + ^ b[static_cast(lane * 128 + i)]); + const auto got = dpf::yao::bits_to_block(bits); + EXPECT_EQ(std::memcmp(&got, &expect[static_cast(lane)], 16), 0) + << lane; + } +} diff --git a/thirdparty/doxygen-awesome-css/.github/workflows/publish.yaml b/thirdparty/doxygen-awesome-css/.github/workflows/publish.yaml index 331822f..11e693f 100644 --- a/thirdparty/doxygen-awesome-css/.github/workflows/publish.yaml +++ b/thirdparty/doxygen-awesome-css/.github/workflows/publish.yaml @@ -4,7 +4,7 @@ on: types: [published] jobs: deploy: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v2 diff --git a/thirdparty/doxygen-awesome-css/.gitignore b/thirdparty/doxygen-awesome-css/.gitignore index 5c40af7..83e26ab 100644 --- a/thirdparty/doxygen-awesome-css/.gitignore +++ b/thirdparty/doxygen-awesome-css/.gitignore @@ -1,3 +1,7 @@ docs/html +_readthedocs .DS_Store -.idea \ No newline at end of file +.idea + +node_modules +*.tgz diff --git a/thirdparty/doxygen-awesome-css/.npmignore b/thirdparty/doxygen-awesome-css/.npmignore new file mode 100644 index 0000000..90eb4ca --- /dev/null +++ b/thirdparty/doxygen-awesome-css/.npmignore @@ -0,0 +1,3 @@ +* +!doxygen-awesome* + diff --git a/thirdparty/doxygen-awesome-css/.readthedocs.yaml b/thirdparty/doxygen-awesome-css/.readthedocs.yaml new file mode 100644 index 0000000..9e15eb3 --- /dev/null +++ b/thirdparty/doxygen-awesome-css/.readthedocs.yaml @@ -0,0 +1,14 @@ +--- +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +build: + os: ubuntu-24.04 + tools: + python: "miniconda-latest" + commands: + - chmod +x readthedocs_build.sh + - ./readthedocs_build.sh diff --git a/thirdparty/doxygen-awesome-css/Doxyfile b/thirdparty/doxygen-awesome-css/Doxyfile index 92df11c..b46c60e 100644 --- a/thirdparty/doxygen-awesome-css/Doxyfile +++ b/thirdparty/doxygen-awesome-css/Doxyfile @@ -1,7 +1,7 @@ -# Doxyfile 1.9.6 +# Doxyfile 1.18.0 # This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. +# Doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. @@ -11,14 +11,14 @@ # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). +# Values that contain spaces should be placed between quotes (" "). # # Note: # -# Use doxygen to compare the used configuration file with the template +# Use Doxygen to compare the used configuration file with the template # configuration file: # doxygen -x [configFile] -# Use doxygen to compare the used configuration file with the template +# Use Doxygen to compare the used configuration file with the template # configuration file without replacing the environment variables or CMake type # replacement variables: # doxygen -x_noenv [configFile] @@ -51,7 +51,7 @@ PROJECT_NAME = "Doxygen Awesome" PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a +# for a project that appears at the top of each page and should give viewers a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "Modern Doxygen theme" @@ -63,19 +63,25 @@ PROJECT_BRIEF = "Modern Doxygen theme" PROJECT_LOGO = ./logo.drawio.svg +# With the PROJECT_ICON tag one can specify an icon that is included in the tabs +# when the HTML document is shown. Doxygen will copy the logo to the output +# directory. + +PROJECT_ICON = + # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If +# entered, it will be relative to the location where Doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = docs -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# If the CREATE_SUBDIRS tag is set to YES then Doxygen will create up to 4096 # sub-directories (in 2 levels) under the output directory of each output format # and will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# option can be useful when feeding Doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise cause +# performance problems for the file system. Adjust CREATE_SUBDIRS_LEVEL to # control the number of sub-directories. # The default value is: NO. @@ -92,7 +98,7 @@ CREATE_SUBDIRS = NO CREATE_SUBDIRS_LEVEL = 8 -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# If the ALLOW_UNICODE_NAMES tag is set to YES, Doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. @@ -101,7 +107,7 @@ CREATE_SUBDIRS_LEVEL = 8 ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this +# documentation generated by Doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, # Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English @@ -115,14 +121,14 @@ ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# If the BRIEF_MEMBER_DESC tag is set to YES, Doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# If the REPEAT_BRIEF tag is set to YES, Doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the @@ -153,13 +159,13 @@ ABBREVIATE_BRIEF = "The $name class" \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief +# Doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# If the INLINE_INHERITED_MEMB tag is set to YES, Doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. @@ -167,7 +173,7 @@ ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# If the FULL_PATH_NAMES tag is set to YES, Doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. @@ -177,11 +183,11 @@ FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to +# If left blank the directory from which Doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. +# will be relative from the directory where Doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = @@ -195,41 +201,42 @@ STRIP_FROM_PATH = STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't +# If the SHORT_NAMES tag is set to YES, Doxygen will generate much shorter (but +# less readable) file names. This can be useful if your file system doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen will interpret the +# first line (until the first dot, question mark or exclamation mark) of a +# Javadoc-style comment as the brief description. If set to NO, the Javadoc- +# style will behave just like regular Qt-style comments (thus requiring an +# explicit @brief command for a brief description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO -# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# If the JAVADOC_BANNER tag is set to YES then Doxygen will interpret a line # such as # /*************** # as being the beginning of a Javadoc-style comment "banner". If set to NO, the # Javadoc-style will behave just like regular comments and it will not be -# interpreted by doxygen. +# interpreted by Doxygen. # The default value is: NO. JAVADOC_BANNER = NO -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will interpret the first +# line (until the first dot, question mark or exclamation mark) of a Qt-style +# comment as the brief description. If set to NO, the Qt-style will behave just +# like regular Qt-style comments (thus requiring an explicit \brief command for +# a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this @@ -241,10 +248,10 @@ QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO -# By default Python docstrings are displayed as preformatted text and doxygen's +# By default Python docstrings are displayed as preformatted text and Doxygen's # special commands cannot be used. By setting PYTHON_DOCSTRING to NO the -# doxygen's special commands can be used and the contents of the docstring -# documentation blocks is shown as doxygen documentation. +# Doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as Doxygen documentation. # The default value is: YES. PYTHON_DOCSTRING = YES @@ -255,7 +262,7 @@ PYTHON_DOCSTRING = YES INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# If the SEPARATE_MEMBER_PAGES tag is set to YES then Doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. @@ -325,58 +332,92 @@ OPTIMIZE_OUTPUT_SLICE = NO # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# language is one of the parsers supported by Doxygen: IDL, Java, JavaScript, # Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, # VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: # FortranFree, unknown formatted Fortran: Fortran. In the later case the parser # tries to guess whether the code is fixed or free formatted code, this is the -# default for Fortran type files). For instance to make doxygen treat .inc files +# default for Fortran type files). For instance to make Doxygen treat .inc files # as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. When specifying no_extension you should add +# the files are not read by Doxygen. When specifying no_extension you should add # * to the FILE_PATTERNS. # # Note see also the list of default file extension mappings. EXTENSION_MAPPING = -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# If the MARKDOWN_SUPPORT tag is enabled then Doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See https://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# The output of markdown processing is further processed by Doxygen, so you can +# mix Doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES +# If the MARKDOWN_STRICT tag is enabled then Doxygen treats text in comments as +# Markdown formatted also in cases where Doxygen's native markup format +# conflicts with that of Markdown. This is only relevant in cases where +# backticks are used. Doxygen's native markup style allows a single quote to end +# a text fragment started with a backtick and then treat it as a piece of quoted +# text, whereas in Markdown such text fragment is treated as verbatim and only +# ends when a second matching backtick is found. Also, Doxygen's native markup +# format requires double quotes to be escaped when they appear in a backtick +# section, whereas this is not needed for Markdown. +# The default value is: YES. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_STRICT = YES + # When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 5. +# Minimum value: 0, maximum value: 99, default value: 6. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 5 -# When enabled doxygen tries to link words that correspond to documented +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0 and GITHUB use the lower case version of title +# with any whitespace replaced by '-' and punctuation characters removed. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + +# When enabled Doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. +# globally by setting AUTOLINK_SUPPORT to NO. Words listed in the +# AUTOLINK_IGNORE_WORDS tag are excluded from automatic linking. # The default value is: YES. AUTOLINK_SUPPORT = YES +# This tag specifies a list of words that, when matching the start of a word in +# the documentation, will suppress auto links generation, if it is enabled via +# AUTOLINK_SUPPORT. This list does not affect links explicitly created using # +# or the \link or \ref commands. +# This tag requires that the tag AUTOLINK_SUPPORT is set to YES. + +AUTOLINK_IGNORE_WORDS = + # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and +# tag to YES in order to let Doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. +# versus func(std::string) {}). This also makes the inheritance and +# collaboration diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO @@ -388,16 +429,16 @@ BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. +# https://www.riverbankcomputing.com/software) sources only. Doxygen will parse +# them like normal C++ but will assume all classes use public instead of private +# inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. +# Doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. @@ -406,7 +447,7 @@ SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first +# tag is set to YES then Doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. @@ -464,18 +505,18 @@ TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The +# code, Doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# Doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest +# symbols. At the end of a run Doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 -# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use -# during processing. When set to 0 doxygen will based this on the number of +# The NUM_PROC_THREADS specifies the number of threads Doxygen is allowed to use +# during processing. When set to 0 Doxygen will based this on the number of # cores available in the system. You can set it explicitly to a value larger # than 0 to get more control over the balance between CPU load and processing # speed. At this moment only the input processing can be done using multiple @@ -483,15 +524,23 @@ LOOKUP_CACHE_SIZE = 0 # which effectively disables parallel processing. Please report any issues you # encounter. Generating dot graphs in parallel is controlled by the # DOT_NUM_THREADS setting. -# Minimum value: 0, maximum value: 32, default value: 1. +# Minimum value: 0, maximum value: 512, default value: 1. NUM_PROC_THREADS = 1 +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = NO + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# If the EXTRACT_ALL tag is set to YES, Doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. @@ -557,7 +606,7 @@ EXTRACT_ANON_NSPACES = NO RESOLVE_UNNAMED_PARAMS = YES -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. @@ -565,7 +614,7 @@ RESOLVE_UNNAMED_PARAMS = YES HIDE_UNDOC_MEMBERS = NO -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option # will also hide undocumented C++ concepts if enabled. This option has no effect @@ -574,14 +623,22 @@ HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# If the HIDE_UNDOC_NAMESPACES tag is set to YES, Doxygen will hide all +# undocumented namespaces that are normally visible in the namespace hierarchy. +# If set to NO, these namespaces will be included in the various overviews. This +# option has no effect if EXTRACT_ALL is enabled. +# The default value is: YES. + +HIDE_UNDOC_NAMESPACES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all friend # declarations. If set to NO, these declarations will be included in the # documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. @@ -595,7 +652,7 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO -# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# With the correct setting of option CASE_SENSE_NAMES Doxygen will better be # able to match the capabilities of the underlying filesystem. In case the # filesystem is case sensitive (i.e. it supports files in the same directory # whose names only differ in casing), the option must be set to YES to properly @@ -604,7 +661,7 @@ INTERNAL_DOCS = NO # output files written for symbols that only differ in casing, such as for two # classes, one named CLASS and the other named Class, and to also support # references to files without having to specify the exact matching casing. On -# Windows (including Cygwin) and MacOS, users should typically set this option +# Windows (including Cygwin) and macOS, users should typically set this option # to NO, whereas on Linux or other Unix flavors it should typically be set to # YES. # Possible values are: SYSTEM, NO and YES. @@ -612,14 +669,14 @@ INTERNAL_DOCS = NO CASE_SENSE_NAMES = NO -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# If the HIDE_SCOPE_NAMES tag is set to NO then Doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then Doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. @@ -632,7 +689,7 @@ HIDE_COMPOUND_REFERENCE= NO SHOW_HEADERFILE = YES -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# If the SHOW_INCLUDE_FILES tag is set to YES then Doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -645,7 +702,7 @@ SHOW_INCLUDE_FILES = YES SHOW_GROUPED_MEMB_INC = NO -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. @@ -657,14 +714,14 @@ FORCE_LOCAL_INCLUDES = NO INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# If the SORT_MEMBER_DOCS tag is set to YES then Doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# If the SORT_BRIEF_DOCS tag is set to YES then Doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. @@ -672,7 +729,7 @@ SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then Doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. @@ -684,7 +741,7 @@ SORT_BRIEF_DOCS = NO SORT_MEMBERS_CTORS_1ST = NO -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# If the SORT_GROUP_NAMES tag is set to YES then Doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. @@ -701,11 +758,11 @@ SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# If the STRICT_PROTO_MATCHING option is enabled and Doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# simple string match. By disabling STRICT_PROTO_MATCHING Doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. @@ -736,6 +793,27 @@ GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES +# The GENERATE_REQUIREMENTS tag can be used to enable (YES) or disable (NO) the +# requirements page. When enabled, this page is automatically created when at +# least one comment block with a \requirement command appears in the input. +# The default value is: YES. + +GENERATE_REQUIREMENTS = YES + +# The REQ_TRACEABILITY_INFO tag controls if traceability information is shown on +# the requirements page (only relevant when using \requirement comment blocks). +# The setting NO will disable the traceability information altogether. The +# setting UNSATISFIED_ONLY will show a list of requirements that are missing a +# satisfies relation (through the command: \satisfies). Similarly the setting +# UNVERIFIED_ONLY will show a list of requirements that are missing a verifies +# relation (through the command: \verifies). Setting the tag to YES (the +# default) will show both lists if applicable. +# Possible values are: YES, NO, UNSATISFIED_ONLY and UNVERIFIED_ONLY. +# The default value is: YES. +# This tag requires that the tag GENERATE_REQUIREMENTS is set to YES. + +REQ_TRACEABILITY_INFO = YES + # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. @@ -775,25 +853,25 @@ SHOW_FILES = YES SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from +# Doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file +# popen()) the command command input_file, where command is the value of the +# FILE_VERSION_FILTER tag, and input_file is the name of an input file provided +# by Doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated +# by Doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can +# that represents Doxygen's defaults, run Doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. See also section "Changing the # layout of pages" for information. # -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# Note that if you run Doxygen from a directory containing a file called +# DoxygenLayout.xml, Doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = @@ -808,19 +886,35 @@ LAYOUT_FILE = CITE_BIB_FILES = +# The EXTERNAL_TOOL_PATH tag can be used to extend the search path (PATH +# environment variable) so that external tools such as latex and gs can be +# found. +# Note: Directories specified with EXTERNAL_TOOL_PATH are added in front of the +# path already specified by the PATH variable, and are added in the order +# specified. +# Note: This option is particularly useful for macOS version 14 (Sonoma) and +# higher, when running Doxygen from Doxywizard, because in this case any user- +# defined changes to the PATH are ignored. A typical example on macOS is to set +# EXTERNAL_TOOL_PATH = /Library/TeX/texbin /usr/local/bin +# together with the standard path, the full search path used by doxygen when +# launching external tools will then become +# PATH=/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin + +EXTERNAL_TOOL_PATH = + #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the +# standard output by Doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# generated to standard error (stderr) by Doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. @@ -828,14 +922,14 @@ QUIET = NO WARNINGS = YES -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# If the WARN_IF_UNDOCUMENTED tag is set to YES then Doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# If the WARN_IF_DOC_ERROR tag is set to YES, Doxygen will generate warnings for # potential errors in the documentation, such as documenting some parameters in # a documented function twice, or documenting parameters that don't exist or # using markup commands wrongly. @@ -843,8 +937,8 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES -# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete -# function parameter documentation. If set to NO, doxygen will accept that some +# If WARN_IF_INCOMPLETE_DOC is set to YES, Doxygen will warn about incomplete +# function parameter documentation. If set to NO, Doxygen will accept that some # parameters have no documentation without warning. # The default value is: YES. @@ -852,7 +946,7 @@ WARN_IF_INCOMPLETE_DOC = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong parameter +# value. If set to NO, Doxygen will only warn about wrong parameter # documentation, but not about the absence of documentation. If EXTRACT_ALL is # set to YES then this flag will automatically be disabled. See also # WARN_IF_INCOMPLETE_DOC @@ -860,24 +954,39 @@ WARN_IF_INCOMPLETE_DOC = YES WARN_NO_PARAMDOC = NO -# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about -# undocumented enumeration values. If set to NO, doxygen will accept +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, Doxygen will warn about +# undocumented enumeration values. If set to NO, Doxygen will accept # undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: NO. WARN_IF_UNDOC_ENUM_VAL = NO -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# If WARN_LAYOUT_FILE option is set to YES, Doxygen will warn about issues found +# while parsing the user defined layout file, such as missing or wrong elements. +# See also LAYOUT_FILE for details. If set to NO, problems with the layout file +# will be suppressed. +# The default value is: YES. + +WARN_LAYOUT_FILE = YES + +# If the WARN_AS_ERROR tag is set to YES then Doxygen will immediately stop when # a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS -# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but -# at the end of the doxygen process doxygen will return with a non-zero status. -# Possible values are: NO, YES and FAIL_ON_WARNINGS. +# then Doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the Doxygen process Doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then Doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined Doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. # The default value is: NO. WARN_AS_ERROR = NO -# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# The WARN_FORMAT tag determines the format of the warning messages that Doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will @@ -890,7 +999,7 @@ WARN_FORMAT = "$file:$line: $text" # In the $text part of the WARN_FORMAT command it is possible that a reference # to a more specific place is given. To make it easier to jump to this place -# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# (outside of Doxygen) the user can define a custom "cut" / "paste" string. # Example: # WARN_LINE_FORMAT = "'vi $file +$line'" # See also: WARN_FORMAT @@ -924,7 +1033,7 @@ INPUT = include \ docs/tricks.md # This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# that Doxygen parses. Internally Doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: # https://www.gnu.org/software/libiconv/) for the list of possible encodings. @@ -934,12 +1043,12 @@ INPUT = include \ INPUT_ENCODING = UTF-8 # This tag can be used to specify the character encoding of the source files -# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# that Doxygen parses. The INPUT_FILE_ENCODING tag can be used to specify # character encoding on a per file pattern basis. Doxygen will compare the file # name with each pattern and apply the encoding instead of the default -# INPUT_ENCODING) if there is a match. The character encodings are a list of the -# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding -# "INPUT_ENCODING" for further information on supported encodings. +# INPUT_ENCODING if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). +# See also: INPUT_ENCODING for further information on supported encodings. INPUT_FILE_ENCODING = @@ -949,17 +1058,17 @@ INPUT_FILE_ENCODING = # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. +# read by Doxygen. # # Note the list of default checked file patterns might differ from the list of # default file extension mappings. # -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, -# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C -# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, -# *.vhdl, *.ucf, *.qsf and *.ice. +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm, +# *.cpp, *.cppm, *.ccm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, +# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, +# *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be +# provided as Doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.c \ *.cc \ @@ -1017,7 +1126,7 @@ RECURSIVE = YES # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # -# Note that relative paths are relative to the directory from which doxygen is +# Note that relative paths are relative to the directory from which Doxygen is # run. EXCLUDE = @@ -1043,9 +1152,6 @@ EXCLUDE_PATTERNS = # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # ANamespace::AClass, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = @@ -1076,7 +1182,7 @@ EXAMPLE_RECURSIVE = NO IMAGE_PATH = img \ docs/img -# The INPUT_FILTER tag can be used to specify a program that doxygen should +# The INPUT_FILTER tag can be used to specify a program that Doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # @@ -1091,14 +1197,14 @@ IMAGE_PATH = img \ # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # -# Note that doxygen will use the data processed and written to standard output +# Note that Doxygen will use the data processed and written to standard output # for further processing, therefore nothing else, like debug statements or used # commands (so in case of a Windows batch file always use @echo OFF), should be # written to standard output. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. +# properly processed by Doxygen. INPUT_FILTER = @@ -1111,7 +1217,7 @@ INPUT_FILTER = # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. +# properly processed by Doxygen. FILTER_PATTERNS = @@ -1133,10 +1239,19 @@ FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. +# and want to reuse the introduction page also for the Doxygen output. USE_MDFILE_AS_MAINPAGE = README.md +# If the IMPLICIT_DIR_DOCS tag is set to YES, any README.md file found in sub- +# directories of the project's root, is used as the documentation for that sub- +# directory, except when the README.md starts with a \dir, \page or \mainpage +# command. If set to NO, the README.md file needs to start with an explicit \dir +# command in order to be used as directory documentation. +# The default value is: YES. + +IMPLICIT_DIR_DOCS = YES + # The Fortran standard specifies that for fixed formatted Fortran code all # characters from position 72 are to be considered as comment. A common # extension is to allow longer lines before the automatic comment starts. The @@ -1160,12 +1275,13 @@ FORTRAN_COMMENT_AFTER = 72 SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. +# multi-line macros, enums or list initialized variables directly into the +# documentation. # The default value is: NO. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct Doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. @@ -1203,7 +1319,7 @@ REFERENCES_LINK_SOURCE = YES SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# point to the HTML generated by the htags(1) tool instead of Doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see https://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. @@ -1217,14 +1333,14 @@ SOURCE_TOOLTIPS = YES # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # -# The result: instead of the source browser generated by doxygen, the links to +# The result: instead of the source browser generated by Doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# If the VERBATIM_HEADERS tag is set the YES then Doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. @@ -1232,19 +1348,19 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# If the CLANG_ASSISTED_PARSING tag is set to YES then Doxygen will use the # clang parser (see: # http://clang.llvm.org/) for more accurate parsing at the cost of reduced # performance. This can be particularly helpful with template rich C++ code for -# which doxygen's built-in parser lacks the necessary type information. -# Note: The availability of this option depends on whether or not doxygen was +# which Doxygen's built-in parser lacks the necessary type information. +# Note: The availability of this option depends on whether or not Doxygen was # generated with the -Duse_libclang=ON option for CMake. # The default value is: NO. CLANG_ASSISTED_PARSING = NO # If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS -# tag is set to YES then doxygen will add the directory of each input to the +# tag is set to YES then Doxygen will add the directory of each input to the # include path. # The default value is: YES. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. @@ -1253,7 +1369,7 @@ CLANG_ADD_INC_PATHS = YES # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories +# the include paths will already be set by Doxygen for the files and directories # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. @@ -1267,7 +1383,7 @@ CLANG_OPTIONS = # specifying the -p option to a clang tool, such as clang-check. These options # will then be passed to the parser. Any options specified with CLANG_OPTIONS # will be added as well. -# Note: The availability of this option depends on whether or not doxygen was +# Note: The availability of this option depends on whether or not Doxygen was # generated with the -Duse_libclang=ON option for CMake. CLANG_DATABASE_PATH = @@ -1296,7 +1412,7 @@ IGNORE_PREFIX = # Configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# If the GENERATE_HTML tag is set to YES, Doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES @@ -1317,40 +1433,40 @@ HTML_OUTPUT = html HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a +# each generated HTML page. If the tag is left blank Doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. +# that Doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally +# for information on how to generate the default header that Doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description +# default header when upgrading to a newer version of Doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = doxygen-custom/header.html # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard +# generated HTML page. If the tag is left blank Doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. +# that Doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. +# the HTML output. If left blank Doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. +# sheet that Doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. @@ -1360,7 +1476,7 @@ HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. +# created by Doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. @@ -1375,10 +1491,11 @@ HTML_STYLESHEET = # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = doxygen-awesome.css \ - doxygen-custom/custom.css \ doxygen-awesome-sidebar-only.css \ doxygen-awesome-sidebar-only-darkmode-toggle.css \ - doxygen-custom/custom-alternative.css + doxygen-custom/theme-round.css \ + doxygen-custom/theme-robot.css \ + doxygen-custom/custom.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note @@ -1397,11 +1514,11 @@ HTML_EXTRA_FILES = doxygen-awesome-darkmode-toggle.js \ # The HTML_COLORSTYLE tag can be used to specify if the generated HTML output # should be rendered with a dark or light theme. -# Possible values are: LIGHT always generate light mode output, DARK always -# generate dark mode output, AUTO_LIGHT automatically set the mode according to -# the user preference, use light mode if no preference is set (the default), -# AUTO_DARK automatically set the mode according to the user preference, use -# dark mode if no preference is set and TOGGLE allow to user to switch between +# Possible values are: LIGHT always generates light mode output, DARK always +# generates dark mode output, AUTO_LIGHT automatically sets the mode according +# to the user preference, uses light mode if no preference is set (the default), +# AUTO_DARK automatically sets the mode according to the user preference, uses +# dark mode if no preference is set and TOGGLE allows a user to switch between # light and dark mode via a button. # The default value is: AUTO_LIGHT. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1438,15 +1555,6 @@ HTML_COLORSTYLE_SAT = 255 HTML_COLORSTYLE_GAMMA = 113 -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = NO - # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that # are dynamically created via JavaScript. If disabled, the navigation index will @@ -1466,6 +1574,33 @@ HTML_DYNAMIC_MENUS = YES HTML_DYNAMIC_SECTIONS = NO +# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be +# dynamically folded and expanded in the generated HTML source code. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_CODE_FOLDING = YES + +# If the HTML_COPY_CLIPBOARD tag is set to YES then Doxygen will show an icon in +# the top right corner of code and text fragments that allows the user to copy +# its content to the clipboard. Note this only works if supported by the browser +# and the web page is served via a secure context (see: +# https://www.w3.org/TR/secure-contexts/), i.e. using the https: or file: +# protocol. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COPY_CLIPBOARD = NO + +# Doxygen stores a couple of settings persistently in the browser (via e.g. +# cookies). By default these settings apply to all HTML pages generated by +# Doxygen across all projects. The HTML_PROJECT_COOKIE tag can be used to store +# the settings under a project specific key, such that the user preferences will +# be stored separately. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_PROJECT_COOKIE = + # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to @@ -1483,7 +1618,7 @@ HTML_INDEX_NUM_ENTRIES = 100 # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: # https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To -# create a documentation set, doxygen will generate a Makefile in the HTML +# create a documentation set, Doxygen will generate a Makefile in the HTML # output directory. Running make will produce the docset in that directory and # running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at @@ -1531,18 +1666,18 @@ DOCSET_PUBLISHER_ID = org.doxygen.Publisher DOCSET_PUBLISHER_NAME = Publisher -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# If the GENERATE_HTMLHELP tag is set to YES then Doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # on Windows. In the beginning of 2021 Microsoft took the original page, with -# a.o. the download links, offline the HTML help workshop was already many years -# in maintenance mode). You can download the HTML help workshop from the web -# archives at Installation executable (see: -# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo -# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# a.o. the download links, offline (the HTML help workshop was already many +# years in maintenance mode). You can download the HTML help workshop from the +# web archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/https://download.microsoft.com/downl +# oad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# generated by Doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for @@ -1562,7 +1697,7 @@ CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. +# Doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1596,6 +1731,16 @@ BINARY_TOC = NO TOC_EXPAND = NO +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help @@ -1654,7 +1799,7 @@ QHP_CUST_FILTER_ATTRS = QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location (absolute path -# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# including file name) of Qt's qhelpgenerator. If non-empty Doxygen will try to # run qhelpgenerator on the generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1699,29 +1844,38 @@ DISABLE_INDEX = NO # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine tune the look of the index (see "Fine-tuning the output"). As an -# example, the default style sheet generated by doxygen has an example that +# example, the default style sheet generated by Doxygen has an example that # shows how to put an image at the root of the tree instead of the PROJECT_NAME. -# Since the tree basically has the same information as the tab index, you could -# consider setting DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. +# Since the tree basically has more details information than the tab index, you +# could consider setting DISABLE_INDEX to YES when enabling this option. +# The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = YES -# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the -# FULL_SIDEBAR option determines if the side bar is limited to only the treeview -# area (value NO) or if it should extend to the full height of the window (value -# YES). Setting this to YES gives a layout similar to -# https://docs.readthedocs.io with more room for contents, but less room for the -# project logo, title, and description. If either GENERATE_TREEVIEW or -# DISABLE_INDEX is set to NO, this option has no effect. +# When GENERATE_TREEVIEW is set to YES, the PAGE_OUTLINE_PANEL option determines +# if an additional navigation panel is shown at the right hand side of the +# screen, displaying an outline of the contents of the main page, similar to +# e.g. https://developer.android.com/reference If GENERATE_TREEVIEW is set to +# NO, this option has no effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +PAGE_OUTLINE_PANEL = YES + +# When GENERATE_TREEVIEW is set to YES, the FULL_SIDEBAR option determines if +# the side bar is limited to only the treeview area (value NO) or if it should +# extend to the full height of the window (value YES). Setting this to YES gives +# a layout similar to e.g. https://docs.readthedocs.io with more room for +# contents, but less room for the project logo, title, and description. If +# GENERATE_TREEVIEW is set to NO, this option has no effect. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. FULL_SIDEBAR = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. +# Doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. @@ -1730,28 +1884,34 @@ FULL_SIDEBAR = NO ENUM_VALUES_PER_LINE = 4 +# When the SHOW_ENUM_VALUES tag is set doxygen will show the specified +# enumeration values besides the enumeration mnemonics. +# The default value is: NO. + +SHOW_ENUM_VALUES = YES + # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. -TREEVIEW_WIDTH = 325 +TREEVIEW_WIDTH = 335 -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# If the EXT_LINKS_IN_WINDOW option is set to YES, Doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO -# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# If the OBFUSCATE_EMAILS tag is set to YES, Doxygen will obfuscate email # addresses. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. OBFUSCATE_EMAILS = YES -# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# If the HTML_FORMULA_FORMAT option is set to svg, Doxygen will use the pdf2svg # tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see # https://inkscape.org) to generate formulas as SVG images instead of PNGs for # the HTML output. These images will generally look nicer at scaled resolutions. @@ -1764,7 +1924,7 @@ HTML_FORMULA_FORMAT = png # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML +# Doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1793,7 +1953,7 @@ USE_MATHJAX = NO # regards to the different settings, so it is possible that also other MathJax # settings have to be changed when switching between the different MathJax # versions. -# Possible values are: MathJax_2 and MathJax_3. +# Possible values are: MathJax_2, MathJax_3 and MathJax_4. # The default value is: MathJax_2. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1802,13 +1962,14 @@ MATHJAX_VERSION = MathJax_2 # When MathJax is enabled you can set the default output format to be used for # the MathJax output. For more details about the output format see MathJax # version 2 (see: -# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# https://docs.mathjax.org/en/v2.7/output.html), MathJax version 3 (see: +# https://docs.mathjax.org/en/v3.2/output/index.html) and MathJax version 4 # (see: -# http://docs.mathjax.org/en/latest/web/components/output.html). +# https://docs.mathjax.org/en/v4.0/output/index.htm). # Possible values are: HTML-CSS (which is slower, but has the best # compatibility. This is the name for Mathjax version 2, for MathJax version 3 # this will be translated into chtml), NativeMML (i.e. MathML. Only supported -# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# for MathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This # is the name for Mathjax version 3, for MathJax version 2 this will be # translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. @@ -1817,46 +1978,60 @@ MATHJAX_VERSION = MathJax_2 MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from https://www.mathjax.org before deployment. The default value is: +# output directory using the MATHJAX_RELPATH option. For Mathjax version 2 the +# destination directory should contain the MathJax.js script. For instance, if +# the mathjax directory is located at the same level as the HTML output +# directory, then MATHJAX_RELPATH should be ../mathjax. For Mathjax versions 3 +# and 4 the destination directory should contain the tex-.js script +# (where is either chtml or svg). The default value points to the +# MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. However, it is strongly recommended to install a local +# copy of MathJax from https://www.mathjax.org before deployment. The default +# value is: # - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 # - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# - in case of MathJax version 4: https://cdn.jsdelivr.net/npm/mathjax@4 # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2 # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example -# for MathJax version 2 (see https://docs.mathjax.org/en/v2.7-latest/tex.html -# #tex-and-latex-extensions): +# for MathJax version 2 (see https://docs.mathjax.org/en/v2.7/tex.html): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # For example for MathJax version 3 (see -# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# https://docs.mathjax.org/en/v3.2/input/tex/extensions/): # MATHJAX_EXTENSIONS = ams +# For example for MathJax version 4 (see +# https://docs.mathjax.org/en/v4.0/input/tex/extensions/): +# MATHJAX_EXTENSIONS = units +# Note that for Mathjax version 4 quite a few extensions are already +# automatically loaded. To disable a package in Mathjax version 4 one can use +# the package name prepended with a minus sign (- like MATHJAX_EXTENSIONS += +# -textmacros) # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: -# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an -# example see the documentation. +# The MATHJAX_CODEFILE tag can be used to specify a file with JavaScript pieces +# of code that will be used on startup of the MathJax code. See the Mathjax site +# for more details: +# - MathJax version 2 (see: +# https://docs.mathjax.org/en/v2.7/) +# - MathJax version 3 (see: +# https://docs.mathjax.org/en/v3.2/) +# - MathJax version 4 (see: +# https://docs.mathjax.org/en/v4.0/) For an example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and +# When the SEARCHENGINE tag is enabled Doxygen will generate a search box for +# the HTML output. The underlying search engine uses JavaScript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then +# For large projects the JavaScript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically @@ -1875,7 +2050,7 @@ SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using JavaScript. There # are two flavors of web server based searching depending on the EXTERNAL_SEARCH -# setting. When disabled, doxygen will generate a PHP script for searching and +# setting. When disabled, Doxygen will generate a PHP script for searching and # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing # and searching needs to be provided by external tools. See the section # "External Indexing and Searching" for details. @@ -1884,7 +2059,7 @@ SEARCHENGINE = YES SERVER_BASED_SEARCH = NO -# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP +# When EXTERNAL_SEARCH tag is enabled Doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain the @@ -1929,7 +2104,7 @@ SEARCHDATA_FILE = searchdata.xml EXTERNAL_SEARCH_ID = -# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through Doxygen # projects other than the one defined by this configuration file, but that are # all added to the same external search index. Each project needs to have a # unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of @@ -1943,7 +2118,7 @@ EXTRA_SEARCH_MAPPINGS = # Configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. +# If the GENERATE_LATEX tag is set to YES, Doxygen will generate LaTeX output. # The default value is: YES. GENERATE_LATEX = NO @@ -1988,7 +2163,7 @@ MAKEINDEX_CMD_NAME = makeindex LATEX_MAKEINDEX_CMD = makeindex -# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX +# If the COMPACT_LATEX tag is set to YES, Doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -2019,27 +2194,26 @@ EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for # the generated LaTeX document. The header should contain everything until the -# first chapter. If it is left blank doxygen will generate a standard header. It +# first chapter. If it is left blank Doxygen will generate a standard header. It # is highly recommended to start with a default header using # doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty # and then modify the file new_header.tex. See also section "Doxygen usage" for -# information on how to generate the default header that doxygen normally uses. +# information on how to generate the default header that Doxygen normally uses. # # Note: Only use a user-defined header if you know what you are doing! # Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. The following -# commands have a special meaning inside the header (and footer): For a -# description of the possible markers and block names see the documentation. +# default header when upgrading to a newer version of Doxygen. For a description +# of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for # the generated LaTeX document. The footer should contain everything after the -# last chapter. If it is left blank doxygen will generate a standard footer. See +# last chapter. If it is left blank Doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what # special commands can be used inside the footer. See also section "Doxygen -# usage" for information on how to generate the default footer that doxygen +# usage" for information on how to generate the default footer that Doxygen # normally uses. Note: Only use a user-defined footer if you know what you are # doing! # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -2048,7 +2222,7 @@ LATEX_FOOTER = # The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined # LaTeX style sheets that are included after the standard style sheets created -# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# by Doxygen. Using this option one can overrule certain style aspects. Doxygen # will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the @@ -2074,7 +2248,7 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES -# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as +# If the USE_PDFLATEX tag is set to YES, Doxygen will use the engine as # specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX # files. Set this option to YES, to get a higher quality PDF documentation. # @@ -2084,15 +2258,22 @@ PDF_HYPERLINKS = YES USE_PDFLATEX = YES -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode -# command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. +# The LATEX_BATCHMODE tag signals the behavior of LaTeX in case of an error. +# Possible values are: NO same as ERROR_STOP, YES same as BATCH, BATCH In batch +# mode nothing is printed on the terminal, errors are scrolled as if is +# hit at every error; missing files that TeX tries to input or request from +# keyboard input (\read on a not open input stream) cause the job to abort, +# NON_STOP In nonstop mode the diagnostic message will appear on the terminal, +# but there is no possibility of user interaction just like in batch mode, +# SCROLL In scroll mode, TeX will stop only for missing files to input or if +# keyboard input is necessary and ERROR_STOP In errorstop mode, TeX will stop at +# each error, asking for user intervention. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_BATCHMODE = NO -# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the +# If the LATEX_HIDE_INDICES tag is set to YES then Doxygen will not include the # index chapters (such as File Index, Compound Index, etc.) in the output. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -2102,19 +2283,11 @@ LATEX_HIDE_INDICES = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See # https://en.wikipedia.org/wiki/BibTeX and \cite for more info. -# The default value is: plain. +# The default value is: plainnat. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_BIB_STYLE = plain -# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_TIMESTAMP = NO - # The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) # path from which the emoji images will be read. If a relative path is entered, # it will be relative to the LATEX_OUTPUT directory. If left blank the @@ -2127,7 +2300,7 @@ LATEX_EMOJI_DIRECTORY = # Configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The +# If the GENERATE_RTF tag is set to YES, Doxygen will generate RTF output. The # RTF output is optimized for Word 97 and may not look too pretty with other RTF # readers/editors. # The default value is: NO. @@ -2142,7 +2315,7 @@ GENERATE_RTF = NO RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF +# If the COMPACT_RTF tag is set to YES, Doxygen generates more compact RTF # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -2162,28 +2335,36 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's +# Load stylesheet definitions from file. Syntax is similar to Doxygen's # configuration file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. # # See also section "Doxygen usage" for information on how to generate the -# default style sheet that doxygen normally uses. +# default style sheet that Doxygen normally uses. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's configuration file. A template extensions file can be +# similar to Doxygen's configuration file. A template extensions file can be # generated using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_EXTENSIONS_FILE = +# The RTF_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the RTF_OUTPUT output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTRA_FILES = + #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for +# If the GENERATE_MAN tag is set to YES, Doxygen will generate man pages for # classes and files. # The default value is: NO. @@ -2214,7 +2395,7 @@ MAN_EXTENSION = .3 MAN_SUBDIR = -# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, then it # will generate one additional man file for each entity documented in the real # man page(s). These additional files only source the real man page, but without # them the man command would be unable to find the correct page. @@ -2227,7 +2408,7 @@ MAN_LINKS = NO # Configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that +# If the GENERATE_XML tag is set to YES, Doxygen will generate an XML file that # captures the structure of the code including all documentation. # The default value is: NO. @@ -2241,7 +2422,7 @@ GENERATE_XML = NO XML_OUTPUT = xml -# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program +# If the XML_PROGRAMLISTING tag is set to YES, Doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size # of the XML output. @@ -2250,7 +2431,7 @@ XML_OUTPUT = xml XML_PROGRAMLISTING = YES -# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, Doxygen will include # namespace members in file scope as well, matching the HTML output. # The default value is: NO. # This tag requires that the tag GENERATE_XML is set to YES. @@ -2261,7 +2442,7 @@ XML_NS_MEMB_FILE_SCOPE = NO # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- -# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files +# If the GENERATE_DOCBOOK tag is set to YES, Doxygen will generate Docbook files # that can be used to generate PDF. # The default value is: NO. @@ -2279,8 +2460,8 @@ DOCBOOK_OUTPUT = docbook # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# If the GENERATE_AUTOGEN_DEF tag is set to YES, Doxygen will generate an +# AutoGen Definitions (see https://autogen.sourceforge.net/) file that captures # the structure of the code including all documentation. Note that this feature # is still experimental and incomplete at the moment. # The default value is: NO. @@ -2291,11 +2472,33 @@ GENERATE_AUTOGEN_DEF = NO # Configuration options related to Sqlite3 output #--------------------------------------------------------------------------- +# If the GENERATE_SQLITE3 tag is set to YES Doxygen will generate a Sqlite3 +# database with symbols found by Doxygen stored in tables. +# The default value is: NO. + +GENERATE_SQLITE3 = NO + +# The SQLITE3_OUTPUT tag is used to specify where the Sqlite3 database will be +# put. If a relative path is entered the value of OUTPUT_DIRECTORY will be put +# in front of it. +# The default directory is: sqlite3. +# This tag requires that the tag GENERATE_SQLITE3 is set to YES. + +SQLITE3_OUTPUT = sqlite3 + +# The SQLITE3_RECREATE_DB tag is set to YES, the existing doxygen_sqlite3.db +# database file will be recreated with each Doxygen run. If set to NO, Doxygen +# will warn if a database file is already found and not modify it. +# The default value is: YES. +# This tag requires that the tag GENERATE_SQLITE3 is set to YES. + +SQLITE3_RECREATE_DB = YES + #--------------------------------------------------------------------------- # Configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module +# If the GENERATE_PERLMOD tag is set to YES, Doxygen will generate a Perl module # file that captures the structure of the code including all documentation. # # Note that this feature is still experimental and incomplete at the moment. @@ -2303,7 +2506,7 @@ GENERATE_AUTOGEN_DEF = NO GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary +# If the PERLMOD_LATEX tag is set to YES, Doxygen will generate the necessary # Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI # output from the Perl module output. # The default value is: NO. @@ -2333,13 +2536,13 @@ PERLMOD_MAKEVAR_PREFIX = # Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all +# If the ENABLE_PREPROCESSING tag is set to YES, Doxygen will evaluate all # C-preprocessor directives found in the sources and include files. # The default value is: YES. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# If the MACRO_EXPANSION tag is set to YES, Doxygen will expand all macro names # in the source code. If set to NO, only conditional compilation will be # performed. Macro expansion can be done in a controlled way by setting # EXPAND_ONLY_PREDEF to YES. @@ -2398,7 +2601,7 @@ PREDEFINED = EXPAND_AS_DEFINED = -# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will +# If the SKIP_FUNCTION_MACROS tag is set to YES then Doxygen's preprocessor will # remove all references to function-like macros that are alone on a line, have # an all uppercase name, and do not end with a semicolon. Such function macros # are typically used for boiler-plate code, and will confuse the parser if not @@ -2422,26 +2625,26 @@ SKIP_FUNCTION_MACROS = YES # section "Linking to external documentation" for more information about the use # of tag files. # Note: Each tag file must have a unique name (where the name does NOT include -# the path). If a tag file is not located in the directory in which doxygen is +# the path). If a tag file is not located in the directory in which Doxygen is # run, you must also specify the path to the tagfile here. TAGFILES = -# When a file name is specified after GENERATE_TAGFILE, doxygen will create a +# When a file name is specified after GENERATE_TAGFILE, Doxygen will create a # tag file that is based on the input files it reads. See section "Linking to # external documentation" for more information about the usage of tag files. GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES, all external class will be listed in -# the class index. If set to NO, only the inherited external classes will be -# listed. +# If the ALLEXTERNALS tag is set to YES, all external classes and namespaces +# will be listed in the class and namespace index. If set to NO, only the +# inherited external classes will be listed. # The default value is: NO. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will be +# in the topic index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. @@ -2455,44 +2658,50 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to diagram generator tools #--------------------------------------------------------------------------- -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. HIDE_UNDOC_RELATIONS = YES -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# If you set the HAVE_DOT tag to YES then Doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: -# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO # The default value is: NO. HAVE_DOT = YES -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed -# to run in parallel. When set to 0 doxygen will base this on the number of +# The DOT_NUM_THREADS specifies the number of dot invocations Doxygen is allowed +# to run in parallel. When set to 0 Doxygen will base this on the number of # processors available in the system. You can set it explicitly to a value # larger than 0 to get control over the balance between CPU load and processing # speed. -# Minimum value: 0, maximum value: 32, default value: 0. +# Minimum value: 0, maximum value: 512, default value: 0. # This tag requires that the tag HAVE_DOT is set to YES. DOT_NUM_THREADS = 0 +# The DOT_BATCH_SIZE specifies the number of dot graphs Doxygen is allowed to +# compile in a single invocation of dot. When set to 1 Doxygen will invoke dot +# for each graph separately, which can cause significant process creation +# overhead especially on systems with many CPU cores. Together with +# DOT_NUM_THREADS this setting can be used to optimise the dot processing speed +# for a particular system. Doxygen will try to give each thread a balanced batch +# of work. If the total number of graphs to process exceeds DOT_NUM_THREADS * +# DOT_BATCH_SIZE then additional batches will be created for dot to process. +# Minimum value: 1, maximum value: 1000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_BATCH_SIZE = 50 + # DOT_COMMON_ATTR is common attributes for nodes, edges and labels of # subgraphs. When you want a differently looking font in the dot files that -# doxygen generates you can specify fontname, fontcolor and fontsize attributes. +# Doxygen generates you can specify fontname, fontcolor and fontsize attributes. # For details please see Node, # Edge and Graph Attributes specification You need to make sure dot is able # to find the font, which can be done by putting it in a standard location or by @@ -2526,35 +2735,47 @@ DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" DOT_FONTPATH = -# If the CLASS_GRAPH tag is set to YES (or GRAPH) then doxygen will generate a -# graph for each documented class showing the direct and indirect inheritance -# relations. In case HAVE_DOT is set as well dot will be used to draw the graph, -# otherwise the built-in generator will be used. If the CLASS_GRAPH tag is set -# to TEXT the direct and indirect inheritance relations will be shown as texts / -# links. -# Possible values are: NO, YES, TEXT and GRAPH. +# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then Doxygen will +# generate a graph for each documented class showing the direct and indirect +# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and +# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case +# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the +# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used. +# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance +# relations will be shown as texts / links. Explicit enabling an inheritance +# graph or choosing a different representation for an inheritance graph of a +# specific class, can be accomplished by means of the command \inheritancegraph. +# Disabling an inheritance graph can be accomplished by means of the command +# \hideinheritancegraph. +# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN. # The default value is: YES. CLASS_GRAPH = YES -# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a +# If the COLLABORATION_GRAPH tag is set to YES then Doxygen will generate a # graph for each documented class showing the direct and indirect implementation # dependencies (inheritance, containment, and class references variables) of the -# class with other documented classes. +# class with other documented classes. Explicit enabling a collaboration graph, +# when COLLABORATION_GRAPH is set to NO, can be accomplished by means of the +# command \collaborationgraph. Disabling a collaboration graph can be +# accomplished by means of the command \hidecollaborationgraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. COLLABORATION_GRAPH = NO -# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. See also the chapter Grouping -# in the manual. +# If the GROUP_GRAPHS tag is set to YES then Doxygen will generate a graph for +# groups, showing the direct groups dependencies. Explicit enabling a group +# dependency graph, when GROUP_GRAPHS is set to NO, can be accomplished by means +# of the command \groupgraph. Disabling a directory graph can be accomplished by +# means of the command \hidegroupgraph. See also the chapter Grouping in the +# manual. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and +# If the UML_LOOK tag is set to YES, Doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. # The default value is: NO. @@ -2575,10 +2796,19 @@ UML_LOOK = NO UML_LIMIT_NUM_FIELDS = 10 -# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and +# If the UML_LOOK tag is enabled, field labels are shown along the edge between +# two class nodes. If there are many fields and many nodes the graph may become +# too cluttered. The UML_MAX_EDGE_LABELS threshold limits the number of items to +# make the size more manageable. Set this to 0 for no limit. +# Minimum value: 0, maximum value: 100, default value: 10. +# This tag requires that the tag UML_LOOK is set to YES. + +UML_MAX_EDGE_LABELS = 10 + +# If the DOT_UML_DETAILS tag is set to NO, Doxygen will show attributes and # methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS -# tag is set to YES, doxygen will add type and arguments for attributes and -# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen +# tag is set to YES, Doxygen will add type and arguments for attributes and +# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, Doxygen # will not generate fields with class member information in the UML graphs. The # class diagrams will look similar to the default class diagrams but using UML # notation for the relationships. @@ -2590,8 +2820,8 @@ DOT_UML_DETAILS = NO # The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters # to display on a single line. If the actual line length exceeds this threshold -# significantly it will wrapped across multiple lines. Some heuristics are apply -# to avoid ugly line breaks. +# significantly it will be wrapped across multiple lines. Some heuristics are +# applied to avoid ugly line breaks. # Minimum value: 0, maximum value: 1000, default value: 17. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2606,24 +2836,29 @@ DOT_WRAP_THRESHOLD = 17 TEMPLATE_RELATIONS = NO # If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to -# YES then doxygen will generate a graph for each documented file showing the +# YES then Doxygen will generate a graph for each documented file showing the # direct and indirect include dependencies of the file with other documented -# files. +# files. Explicit enabling an include graph, when INCLUDE_GRAPH is is set to NO, +# can be accomplished by means of the command \includegraph. Disabling an +# include graph can be accomplished by means of the command \hideincludegraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. INCLUDE_GRAPH = YES # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are -# set to YES then doxygen will generate a graph for each documented file showing +# set to YES then Doxygen will generate a graph for each documented file showing # the direct and indirect include dependencies of the file with other documented -# files. +# files. Explicit enabling an included by graph, when INCLUDED_BY_GRAPH is set +# to NO, can be accomplished by means of the command \includedbygraph. Disabling +# an included by graph can be accomplished by means of the command +# \hideincludedbygraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. INCLUDED_BY_GRAPH = YES -# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# If the CALL_GRAPH tag is set to YES then Doxygen will generate a call # dependency graph for every global function or class method. # # Note that enabling this option will significantly increase the time of a run. @@ -2635,7 +2870,7 @@ INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO -# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# If the CALLER_GRAPH tag is set to YES then Doxygen will generate a caller # dependency graph for every global function or class method. # # Note that enabling this option will significantly increase the time of a run. @@ -2647,17 +2882,20 @@ CALL_GRAPH = NO CALLER_GRAPH = NO -# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical +# If the GRAPHICAL_HIERARCHY tag is set to YES then Doxygen will graphical # hierarchy of all classes instead of a textual one. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the +# If the DIRECTORY_GRAPH tag is set to YES then Doxygen will show the # dependencies a directory has on other directories in a graphical way. The # dependency relations are determined by the #include relations between the -# files in the directories. +# files in the directories. Explicit enabling a directory graph, when +# DIRECTORY_GRAPH is set to NO, can be accomplished by means of the command +# \directorygraph. Disabling a directory graph can be accomplished by means of +# the command \hidedirectorygraph. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2673,25 +2911,30 @@ DIR_GRAPH_MAX_DEPTH = 1 # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: -# http://www.graphviz.org/)). -# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order -# to make the SVG files visible in IE 9+ (other browsers do not have this -# requirement). +# https://www.graphviz.org/)). +# +# Note the formats svg:cairo and svg:cairo:cairo cannot be used in combination +# with INTERACTIVE_SVG (the INTERACTIVE_SVG will be set to NO). # Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, -# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and -# png:gdiplus:gdiplus. +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus, +# png:gdiplus:gdiplus, svg:cairo, svg:cairo:cairo, svg:svg, svg:svg:core, +# gif:cairo, gif:cairo:gd, gif:cairo:gdiplus, gif:gdiplus, gif:gdiplus:gdiplus, +# gif:gd, gif:gd:gd, jpg:cairo, jpg:cairo:gd, jpg:cairo:gdiplus, jpg:gd, +# jpg:gd:gd, jpg:gdiplus and jpg:gdiplus:gdiplus. # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. DOT_IMAGE_FORMAT = svg -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. +# If DOT_IMAGE_FORMAT is set to svg or svg:svg or svg:svg:core, then this option +# can be set to YES to enable generation of interactive SVG images that allow +# zooming and panning. # # Note that this requires a modern browser other than Internet Explorer. Tested # and working are Firefox, Chrome, Safari, and Opera. -# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make -# the SVG files visible. Older versions of IE do not have SVG support. +# +# Note This option will be automatically disabled when DOT_IMAGE_FORMAT is set +# to svg:cairo or svg:cairo:cairo. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2710,11 +2953,12 @@ DOT_PATH = DOTFILE_DIRS = -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). +# You can include diagrams made with dia in Doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. -MSCFILE_DIRS = +DIA_PATH = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile @@ -2722,7 +2966,7 @@ MSCFILE_DIRS = DIAFILE_DIRS = -# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# When using PlantUML, the PLANTUML_JAR_PATH tag should be used to specify the # path where java can find the plantuml.jar file or to the filename of jar file # to be used. If left blank, it is assumed PlantUML is not used or called during # a preprocessing step. Doxygen will generate a warning when it encounters a @@ -2730,20 +2974,78 @@ DIAFILE_DIRS = PLANTUML_JAR_PATH = -# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a -# configuration file for plantuml. +# When using PlantUML, the PLANTUML_CFG_FILE tag can be used to specify a +# configuration file for PlantUML. PLANTUML_CFG_FILE = -# When using plantuml, the specified paths are searched for files specified by -# the !include statement in a plantuml block. +# When using PlantUML, the specified paths are searched for files specified by +# the !include statement in a PlantUML block. PLANTUML_INCLUDE_PATH = +# The PLANTUMLFILE_DIRS tag can be used to specify one or more directories that +# contain PlantUml files that are included in the documentation (see the +# \plantumlfile command). + +PLANTUMLFILE_DIRS = + +# When using Mermaid diagrams with CLI rendering, the MERMAID_PATH tag should be +# used to specify the directory where the mmdc (Mermaid CLI) executable can be +# found. If left blank, CLI-based rendering is disabled. For HTML output, +# client-side rendering via JavaScript is used by default and does not require +# mmdc. For LaTeX/PDF output, mmdc is required to pre-generate images. Doxygen +# will generate a warning when CLI rendering is needed but mmdc is not +# available. + +MERMAID_PATH = + +# When using Mermaid diagrams, the MERMAID_CONFIG_FILE tag can be used to +# specify a JSON configuration file for the Mermaid CLI tool (mmdc). This file +# can contain theme settings and other Mermaid configuration options. + +MERMAID_CONFIG_FILE = + +# The MERMAID_RENDER_MODE tag selects how Mermaid diagrams are rendered. +# Possible values are: AUTO (use client-side rendering for HTML and mmdc for +# LaTeX/PDF and other formats. If MERMAID_PATH is not set, non-HTML diagrams +# will produce a warning), CLI (use the mmdc tool to pre-generate images +# (requires Node.js and mermaid-js/mermaid-cli). Works for all output formats) +# and CLIENT_SIDE (embed mermaid.js in HTML output for client-side rendering. +# Does not require mmdc but only works for HTML output). +# The default value is: AUTO. + +MERMAID_RENDER_MODE = AUTO + +# The MERMAID_JS_URL tag specifies the URL to load mermaid.js from when using +# client-side rendering (MERMAID_RENDER_MODE is CLIENT_SIDE or AUTO). The +# default points to the latest Mermaid v11 release on the jsDelivr CDN. +# +# The default CDN URL requires internet access when viewing the generated +# documentation. For offline use, download mermaid.esm.min.mjs and set this to a +# relative path, or use MERMAID_RENDER_MODE=CLI to pre-generate images instead. +# Examples: +# - Latest v11 (default): +# https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs +# - Pinned version: +# https://cdn.jsdelivr.net/npm/mermaid@11.3.0/dist/mermaid.esm.min.mjs +# - Local copy: ./mermaid.esm.min.mjs (user must place file in HTML output +# directory) +# The default value is: +# https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs. + +MERMAID_JS_URL = https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs + +# The MERMAIDFILE_DIRS tag can be used to specify one or more directories that +# contain Mermaid files that are included in the documentation (see the +# \mermaidfile command). + +MERMAIDFILE_DIRS = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes -# larger than this value, doxygen will truncate the graph, which is visualized -# by representing a node as a red box. Note that doxygen if the number of direct +# larger than this value, Doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that if the number of direct # children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that # the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. @@ -2764,26 +3066,17 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) support -# this, this feature is disabled by default. -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page +# If the GENERATE_LEGEND tag is set to YES Doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. -# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal +# Note: This tag requires that UML_LOOK isn't set, i.e. the Doxygen internal # graphical representation for inheritance and collaboration diagrams is used. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate +# If the DOT_CLEANUP tag is set to YES, Doxygen will remove the intermediate # files that are used to generate the various graphs. # # Note: This setting is not only used for dot files but also for msc temporary @@ -2791,3 +3084,19 @@ GENERATE_LEGEND = YES # The default value is: YES. DOT_CLEANUP = YES + +# You can define message sequence charts within Doxygen comments using the \msc +# command. If the MSCGEN_TOOL tag is left empty (the default), then Doxygen will +# use a built-in version of mscgen tool to produce the charts. Alternatively, +# the MSCGEN_TOOL tag can also specify the name an external tool. For instance, +# specifying prog as the value, Doxygen will call the tool as prog -T +# -o . The external tool should support +# output file formats "png", "eps", "svg", and "ismap". + +MSCGEN_TOOL = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = diff --git a/thirdparty/doxygen-awesome-css/Makefile b/thirdparty/doxygen-awesome-css/Makefile index a936ece..766f61a 100644 --- a/thirdparty/doxygen-awesome-css/Makefile +++ b/thirdparty/doxygen-awesome-css/Makefile @@ -22,6 +22,7 @@ FILES = doxygen-awesome-darkmode-toggle.js \ doxygen-awesome-paragraph-link.js \ doxygen-awesome-sidebar-only-darkmode-toggle.css \ doxygen-awesome-sidebar-only.css \ + doxygen-awesome-tabs.js \ doxygen-awesome.css # Empty targets so that `make` and `make clean` do not cause errors diff --git a/thirdparty/doxygen-awesome-css/README.md b/thirdparty/doxygen-awesome-css/README.md index 3b812b5..4015722 100644 --- a/thirdparty/doxygen-awesome-css/README.md +++ b/thirdparty/doxygen-awesome-css/README.md @@ -1,4 +1,4 @@ -# Doxygen Awesome +# Doxygen Awesome [![GitHub release (latest by date)](https://img.shields.io/github/v/release/jothepro/doxygen-awesome-css)](https://github.com/jothepro/doxygen-awesome-css/releases/latest) [![GitHub](https://img.shields.io/github/license/jothepro/doxygen-awesome-css)](https://github.com/jothepro/doxygen-awesome-css/blob/main/LICENSE) @@ -10,22 +10,22 @@ -**Doxygen Awesome** is a custom **CSS theme for Doxygen HTML-documentation** with lots of customization parameters. +**Doxygen Awesome** is a custom CSS theme for [Doxygen](https://github.com/doxygen/doxygen) HTML documentation with many customization options. ## Motivation -I really like how the Doxygen HTML-documentation is structured! But IMHO it looks a bit outdated. +I really like how the Doxygen HTML documentation is structured, but IMHO it looks a bit outdated. -This theme is an attempt to update the visuals of Doxygen without changing its overall layout too much. +This theme is an attempt to modernize the visuals of Doxygen without changing its overall layout too much. ## Features - 🌈 Clean, modern design -- 🚀 Heavily customizable by adjusting CSS-variables -- 🧩 No changes to the HTML structure of Doxygen required +- 🚀 Highly customizable by adjusting CSS variables +- 🧩 No changes to the HTML structure of Doxygen are required - 📱 Improved mobile usability - 🌘 Dark mode support! -- 🥇 Works best with **doxygen 1.9.1** - **1.9.4** and **1.9.6** +- 🥇 Works best with **Doxygen 1.9.1** - **1.9.4** and **1.9.6** - **1.18.0** ## Examples @@ -35,39 +35,100 @@ Some websites using this theme: - [wxWidgets](https://docs.wxwidgets.org/3.2/) - [OpenCV 5.x](https://docs.opencv.org/5.x/) - [Zephyr](https://docs.zephyrproject.org/latest/doxygen/html/index.html) -- [FELTOR](https://mwiesenberger.github.io/feltor/dg/html/modules.html) - [Spatial Audio Framework (SAF)](https://leomccormack.github.io/Spatial_Audio_Framework/index.html) -- [libCloudSync](https://jothepro.github.io/libCloudSync/) +- [Randolf Richardson's C++ classes](https://www.randolf.ca/c++/docs/) - [libsl3](https://a4z.github.io/libsl3/) +- [DuMux](https://dumux.org/docs/doxygen/master/) +- [OpenRemise](https://openremise.at/) ## Installation -To use the theme in your documentation, copy the required CSS and JS files from this repository into your project or add the repository as submodule and check out the latest release: +To use the theme when generating your documentation, bring the required CSS and JS files from this repository into your project. -```bash +This can be done in several ways: + +- manually copying the files +- adding the project as a Git submodule +- downloading the project with CMake FetchContent +- adding the project as an npm/xpm dependency +- installing the theme system-wide + +All theme files are located in the root of this repository and start with the prefix `doxygen-awesome-`. You may not need all of them. Follow the installation instructions to determine which files are required for your setup. + +### Git submodule + +For projects that use Git, add the repository as a submodule and check out the desired release: + +```sh git submodule add https://github.com/jothepro/doxygen-awesome-css.git cd doxygen-awesome-css -git checkout v2.2.0 +git checkout v2.5.0 ``` -You can even install the theme system-wide by running `make install`. The files will be installed to `/usr/local/share/` by default, but you can customize the install location with `make PREFIX=/my/custom/path install`. +### CMake with FetchContent -All theme files are located in the root of this repository and start with the prefix `doxygen-awesome-`. You may not need all of them. Follow the install instructions to figure out what files are required for your setup. +For projects that build with CMake, the `FetchContent` module can be used to download the repository at configuration time. + +Add the following snippet to your `CMakeLists.txt`: + +```cmake +include(FetchContent) +FetchContent_Declare( + doxygen-awesome-css + URL https://github.com/jothepro/doxygen-awesome-css/archive/refs/heads/main.zip +) +FetchContent_MakeAvailable(doxygen-awesome-css) + +# Save the location the files were cloned into +# This allows us to get the path to doxygen-awesome.css +FetchContent_GetProperties(doxygen-awesome-css SOURCE_DIR AWESOME_CSS_DIR) + +# Generate the Doxyfile +set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in) +set(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) +configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY) +``` + +This downloads the latest main (but any other revision could be used) and unpacks in the build folder. The `Doxyfile.in` can reference this location in the `HTML_EXTRA_STYLESHEET` field + +```text +HTML_EXTRA_STYLESHEET = @AWESOME_CSS_DIR@/doxygen-awesome.css +``` + +When the configure stage of CMake is run, the `Doxyfile.in` is rendered to Doxyfile and Doxygen can be run as usual. + +### npm/xpm dependency + +In the npm ecosystem, this project can be added as a development dependency +to your project: + +```sh +cd your-project +npm install https://github.com/jothepro/doxygen-awesome-css#v2.5.0 --save-dev + +ls -l node_modules/@jothepro/doxygen-awesome-css +``` + +Similarly, in the [xPack](https://xpack.github.io) ecosystem, this project can be added +as a development dependency to an [`xpm`](https://xpack.github.io/xpm/) +managed project. + +### System-wide + +You can even install the theme system-wide by running `make install`. +The files will be installed to `/usr/local/share/` by default, +but you can customize the install location with `make PREFIX=/my/custom/path install`. ### Choosing a layout -There is two layout options. Choose one of them and configure Doxygen accordingly: - -
- -![Available theme variants](img/theme-variants.drawio.svg) - -
+There are two layout options. Choose one of them and configure Doxygen accordingly:
-- 1️⃣ Base Theme - Comes with the typical Doxygen titlebar. Optionally the treeview in the sidebar can be enabled. +- Base Theme
+ ![](img/theme-variants-base.drawio.svg) +
+ Comes with the typical Doxygen titlebar. Optionally the treeview in the sidebar can be enabled. Required files: `doxygen-awesome.css` @@ -80,7 +141,9 @@ There is two layout options. Choose one of them and configure Doxygen accordingl HTML_COLORSTYLE = LIGHT # required with Doxygen >= 1.9.5 ``` -- 2️⃣ Sidebar-Only Theme +- Sidebar-Only Theme
+ ![](img/theme-variants-sidebar-only.drawio.svg) +
Hides the top titlebar to give more space to the content. The treeview must be enabled in order for this theme to work. Required files: `doxygen-awesome.css`, `doxygen-awesome-sidebar-only.css` @@ -98,11 +161,13 @@ There is two layout options. Choose one of them and configure Doxygen accordingl
-**Caution**: +
+ +@warning - This theme is not compatible with the `FULL_SIDEBAR = YES` option provided by Doxygen! - `HTML_COLORSTYLE` must be set to `LIGHT` since Doxygen 1.9.5! -### Further installation instructions: +### Further installation instructions - [Installing extensions](docs/extensions.md) - [Customizing the theme (colors, spacing, border-radius, ...)](docs/customization.md) @@ -112,18 +177,19 @@ There is two layout options. Choose one of them and configure Doxygen accordingl Tested with -- Chrome 110, Chrome 109 for Android, Chrome 110 for iOS -- Safari 16, Safari for iOS 16 -- Firefox 110, Firefox 110 for Android, Firefox 109 for iOS -- Edge 110 +- Chrome 153, Chrome 152 for Android, Chrome 141 for iOS +- Safari 26, Safari for iOS 26 +- Firefox 155, Firefox 142 for Android, Firefox 148 for iOS +- Edge 152 +- Opera One 135 -The theme does not strive to be backwards compatible to (significantly) older browser versions. +The theme does not strive to be backward compatible with (significantly) older browser versions. ## Credits -Thanks for all the bug reports and inspiring feedback on github! +Thanks for all the bug reports and inspiring feedback on GitHub! Special thanks to all the contributors:

@@ -131,7 +197,11 @@ Special thanks to all the contributors: - -Read Next: [Extensions](docs/extensions.md) - \ No newline at end of file +
+ +| Read Next | +|---------------------------------:| +| [Extensions](docs/extensions.md) | + +
diff --git a/thirdparty/doxygen-awesome-css/docs/customization.md b/thirdparty/doxygen-awesome-css/docs/customization.md index 15e5014..04f7f09 100644 --- a/thirdparty/doxygen-awesome-css/docs/customization.md +++ b/thirdparty/doxygen-awesome-css/docs/customization.md @@ -5,20 +5,22 @@ ## CSS-Variables -This theme is highly customizable because a lot of things are parameterized with CSS variables. +This theme is highly customizable because many aspects are parameterized with CSS variables. -Just to give you an idea on how flexible the styling is, click this button: +To give you an idea of how flexible the styling is, click this button: -
Alter theme
+
Alter theme
+ +

### Setup -It is recommended to add your own `custom.css` and overwrite the variables there: +It is recommended to add your own `custom.css` and override the variables there: ``` HTML_EXTRA_STYLESHEET = doxygen-awesome.css custom.css ``` -Make sure to override the variables in the correct spot. All variables should be customized where they have been defined, in the `html` tag selector: +Make sure to override the variables in the correct place. All variables should be customized where they have been defined, in the `html` tag selector: ```css html { @@ -26,7 +28,7 @@ html { } ``` -For dark-mode overrides you have to choose where to put them, depending on whether the dark-mode toggle extension is installed or not: +For dark-mode overrides, you have to choose where to put them, depending on whether the dark-mode toggle extension is installed or not:
@@ -50,7 +52,7 @@ For dark-mode overrides you have to choose where to put them, depending on wheth ### Available variables -The following list gives an overview of the variables defined in [`doxygen-awesome.css`](https://github.com/jothepro/doxygen-awesome-css/blob/main/doxygen-awesome.css). +The following list provides an overview of the variables defined in [`doxygen-awesome.css`](https://github.com/jothepro/doxygen-awesome-css/blob/main/doxygen-awesome.css). The list is not complete. To explore all available variables, have a look at the CSS starting from [here](https://github.com/jothepro/doxygen-awesome-css/blob/main/doxygen-awesome.css#L30). All variables are defined at the beginning of the stylesheet. @@ -69,10 +71,11 @@ All variables are defined at the beginning of the stylesheet. | `--spacing-small` | `5px` | | | `--spacing-medium` | `10px` | | | `--spacing-large` | `16px` | | +| `--spacing-xlarge` | `20px` | | | **Border Radius**:
border radius for all rounded ui components. Will affect many components, like dropdowns, memitems, codeblocks, ... ||| -| `--border-radius-small` | `4px` | | -| `--border-radius-medium` | `6px` | | -| `--border-radius-large` | `8px` | | +| `--border-radius-small` | `5px` | | +| `--border-radius-medium` | `8px` | | +| `--border-radius-large` | `10px` | | | **Content Width**:
The content is centered and constrained in its width. To make the content fill the whole page, set the following variable to `auto`. ||| | `--content-maxwidth` | `1000px` | | | **Code Fragment Colors**:
Color-Scheme of multiline codeblocks ||| @@ -90,11 +93,11 @@ If you miss a configuration option or find a bug, please consider [opening an is The theme overrides most colors with the `--primary-color-*` variables. -But there is a few small images and graphics that the theme cannot adjust or replace. To make these blend in better with +But there are a few small images and graphics that the theme cannot adjust or replace. To make these blend in better with the rest, it is recommended to adjust the [doxygen color settings](https://www.doxygen.nl/manual/customize.html#minor_tweaks_colors) -to something that matches the chosen color-scheme. +to something that matches the chosen color scheme. -For the default color-scheme, these values work out quite well: +For the default color scheme, these values work out quite well: ``` # Doxyfile @@ -105,11 +108,15 @@ HTML_COLORSTYLE_GAMMA = 113 ## Share your customizations -If you customized the theme with custom colors, spacings, font-sizes, etc. and you want to share your creation with others, you can to this [here](https://github.com/jothepro/doxygen-awesome-css/discussions/13). +If you have customized the theme with custom colors, spacings, font-sizes, etc. and you want to share your creation with others, you can do this [here](https://github.com/jothepro/doxygen-awesome-css/discussions/13). I am always curious to learn about how you made the theme look even better! - -Read Next: [Tips & Tricks](tricks.md) - \ No newline at end of file +
+ +| Previous | Next | +|:----------------------------|---------------------------:| +| [Extensions](extensions.md) | [Tips & Tricks](tricks.md) | + +
\ No newline at end of file diff --git a/thirdparty/doxygen-awesome-css/docs/extensions.md b/thirdparty/doxygen-awesome-css/docs/extensions.md index 6597350..9d5afdf 100644 --- a/thirdparty/doxygen-awesome-css/docs/extensions.md +++ b/thirdparty/doxygen-awesome-css/docs/extensions.md @@ -2,10 +2,10 @@ [TOC] -On top of the base theme provided by `doxygen-awesome.css`, this repository comes with Javascript extensions that require additional setup steps to get them running. +In addition to the base theme provided by `doxygen-awesome.css`, this repository comes with JavaScript extensions that require additional setup steps to get them running. -The extensions require customizations in the header HTML-template. -This is how you can create the default template with Doxygen: +The extensions require customizations in the header HTML template. +Here is how you can create the default template with Doxygen: 1. Create default header template: ```sh @@ -21,10 +21,12 @@ This is how you can create the default template with Doxygen: ## Dark Mode Toggle {#extension-dark-mode-toggle} -Adds a button next to the search bar to enable and disable the dark theme variant manually: +Adds a button next to the search bar to manually enable and disable the dark theme variant:
- + +![](img/darkmode_toggle.png){width=250px} +
### Installation @@ -53,7 +55,7 @@ Changing the tooltip of the button: DoxygenAwesomeDarkModeToggle.title = "Zwischen hellem/dunklem Modus wechseln" ``` -Changing Icons. Both Emoji or SVG icons are supported: +Changing icons: Both Emoji and SVG icons are supported: ```js DoxygenAwesomeDarkModeToggle.lightModeIcon = '🌞' // icon from https://fonts.google.com/icons @@ -62,19 +64,21 @@ DoxygenAwesomeDarkModeToggle.darkModeIcon = ` - + +![](img/fragment_copy_button.png){width=490} +
### Installation 1. Add the required resources in your `Doxyfile`: - **HTML_EXTRA_FILES:** `doxygen-awesome-fragment-copy-button.js` + - **HTML_COPY_CLIPBOARD:** `NO` required with Doxygen >= 1.10.0 2. In the `header.html` template, include `doxygen-awesome-fragment-copy-button.js` at the end of the `` and then initialize it: ```html @@ -105,10 +109,12 @@ All customizations must be applied before calling `DoxygenAwesomeDarkModeToggle. ## Paragraph Linking {#extension-para} -Provides a button on hover behind every headline to allow easy creation of a permanent link to the headline: +Provides a button that appears on hover behind every headline, allowing easy creation of a permanent link to the headline:
- + +![](img/paragraph_link.png){width=220} +
Works for all headlines and for many documentation section titles. @@ -133,11 +139,13 @@ Works for all headlines and for many documentation section titles. ### Customizing The button tooltip can be changed: + ```js DoxygenAwesomeParagraphLink.title = "Abschnitt verknüpfen" ``` -The icon of the button can be changed. Both plain characters or SVG icons are supported: +The icon of the button can be changed. Both plain characters and SVG icons are supported: + ```js DoxygenAwesomeParagraphLink.icon = "¶" ``` @@ -146,17 +154,18 @@ All customizations must be applied before calling `DoxygenAwesomeParagraphLink.i ## Interactive TOC {#extension-toc} -On large screens the Table of Contents (TOC) is anchored on the top right of the page. This extension visualizes the reading progress by dynamically highlighting the currently active section. - -On small screens the extension hides the TOC by default. The user can open it manually when needed: +On large screens, the Table of Contents (TOC) is anchored at the top right of the page. This extension visualizes the reading progress by dynamically highlighting the currently active section. +On small screens, the extension hides the TOC by default. The user can open it manually when needed:
- +![](img/interactive_toc_mobile.png){width=380}
### Installation +@note Starting from Doxygen Version 1.14.0, you have to specify `PAGE_OUTLINE_PANEL=NO` in your Doxyfile to use this extension. + 1. Add the required resources in your `Doxyfile`: - **HTML_EXTRA_FILES:** `doxygen-awesome-interactive-toc.js` 2. In the `header.html` template, include `doxygen-awesome-interactive-toc.js` at the end of the `` and then initialize it: @@ -175,30 +184,32 @@ On small screens the extension hides the TOC by default. The user can open it ma ### Customizing The offset for when a headline is considered active can be changed. A smaller value means that the headline of the section must be closer to the top of the viewport before it is highlighted in the TOC: + ```js DoxygenAwesomeInteractiveToc.topOffset = 45 ``` Hiding the TOC on small screens can be disabled. It is still interactive and can be hidden by the user but will now be open by default: + ```js DoxygenAwesomeInteractiveToc.hideMobileMenu = false ``` ## Tabs {#extension-tabs} -@note Experimental feature! Please report bugs [here](https://github.com/jothepro/doxygen-awesome-css/issues). - - This extension allows to arrange list content in tabs:
-- Tab 1 This is the content of tab 1 -- Tab 2 This is the content of tab 2 +- Tab 1 + This is the content of tab 1 +- Tab 2 + This is the content of tab 2 + 1. it has a list + 2. with multiple items
- ### Installation 1. Add the required resources in your `Doxyfile`: @@ -218,8 +229,8 @@ This extension allows to arrange list content in tabs: ### Usage -Each list that is supposed to be displayed as tabs has to be wrapped with the `tabbed` CSS class. -Each item in the list must start with an element that has the class `tab-title`. It will then be used as tab title. +Each list that is supposed to be displayed as tabs must be wrapped with the `tabbed` CSS class. +Each item in the list must start with an element that has the class `tab-title`. It will then be used as the tab title. ```md
@@ -230,7 +241,98 @@ Each item in the list must start with an element that has the class `tab-title`.
``` - +## Read the Docs search {#readthedocs-search} -Read Next: [Customization](customization.md) - +Use search index from Read the Docs instead of the built-in doxygen search. This allows using search metrics from +Read the Docs and in general gives a better search experience. + +A live example is available at [doxygen-awesome-css.readthedocs.io](https://doxygen-awesome-css.readthedocs.io/). + +### Installation + +1. Add the required resources in your `Doxyfile`: + - **HTML_EXTRA_FILES:** `doxygen-awesome-readthedocs-search.js` + - **HTML_EXTRA_STYLESHEET:** `doxygen-awesome-readthedocs-search.css` + - **SEARCHENGINE:** `YES` + - **SERVER_BASED_SEARCH:** `YES` + - **EXTERNAL_SEARCH:** `YES` + - **SEARCHENGINE_URL:** `https://.readthedocs.io/` OR + - **SEARCHENGINE_URL:** `https:///` + + `SEARCHENGINE_URL` is only used when testing locally, otherwise the domain name is detected automatically. + When testing locally, search may not work without disabling CORS. This can be a security risk, so it is advised to + only test inside of Read the Docs. + +2. In the `header.html` template, include `doxygen-awesome-readthedocs-search.js` at the end of the `` and then initialize it: + ```html + + + + + + + + ``` + For the sidebar-only theme variant, initialize with left-aligned live results: + ```html + + ``` + + Read the Docs provides the project and version slugs automatically. To select the Read the Docs index used when + testing locally, provide fallback values during initialization: + ```html + + ``` + +## Page Navigation {#extension-page-navigation} + +To allow users to easily navigate from one document to another, "Next" and "Previous" buttons can be added at the end of a Markdown document. + +### Installation + +The feature is included in the default `doxygen-awesome.css`. No additional stylesheets or scripts need to be added. + +### Usage + +The following conditions must be met for the feature to work properly: + +- The navigation must be inside a Markdown table with 1-2 columns. +- The alignment of the column defines the alignment of the arrow on the navigation button. +- The table must be wrapped inside a `
` with the class `section_buttons`. + +
+ +- Code + ```md +
+ + | Previous | Next | + |:------------------|----------------------------------:| + | [Home](README.md) | [Customization](customization.md) | + +
+ ``` +- Result +
+ | Previous | Next | + |:------------------|----------------------------------:| + | [Home](README.md) | [Customization](customization.md) | +
+ +
+ +
+ +| Previous | Next | +|:------------------|----------------------------------:| +| [Home](README.md) | [Customization](customization.md) | +
diff --git a/thirdparty/doxygen-awesome-css/docs/img/testimage.png b/thirdparty/doxygen-awesome-css/docs/img/testimage.png new file mode 100644 index 0000000..c208098 Binary files /dev/null and b/thirdparty/doxygen-awesome-css/docs/img/testimage.png differ diff --git a/thirdparty/doxygen-awesome-css/docs/tricks.md b/thirdparty/doxygen-awesome-css/docs/tricks.md index 77b447c..4c0978a 100644 --- a/thirdparty/doxygen-awesome-css/docs/tricks.md +++ b/thirdparty/doxygen-awesome-css/docs/tricks.md @@ -4,7 +4,7 @@ ## Diagrams with Graphviz {#tricks-graphviz} -To get the best looking class diagrams for your documentation, generate them with Graphviz as vector graphics with transparent background: +To get the best-looking class diagrams for your documentation, generate them with Graphviz as vector graphics and a transparent background: ``` # Doxyfile @@ -13,7 +13,7 @@ DOT_IMAGE_FORMAT = svg DOT_TRANSPARENT = YES ``` -In case `INTERACTIVE_SVG = YES` is set in the Doxyfile, all user-defined dotgraphs must be wrapped with the `interactive_dotgraph` CSS class in order for them to be rendered correctly: +If `INTERACTIVE_SVG = YES` is set in the Doxyfile, all user-defined dotgraphs must be wrapped with the `interactive_dotgraph` CSS class for them to be rendered correctly: ```md
@@ -23,30 +23,30 @@ In case `INTERACTIVE_SVG = YES` is set in the Doxyfile, all user-defined dotgrap
``` -@note Both the default overflow scrolling behavior in this theme and the interactive editor enabled by `INTERACTIVE_SVG` are unsatisfying workarounds IMHO. Consider designing your graphs to be narrow enough to fit the page to avoid scrolling. +@note Both the default overflow scrolling behavior in this theme and the interactive editor enabled by `INTERACTIVE_SVG` are, in my opinion, unsatisfying workarounds. Consider designing your graphs to be narrow enough to fit the page to avoid scrolling. ## Disable Dark Mode {#tricks-darkmode} If you don't want the theme to automatically switch to dark mode depending on the browser preference, -you can disable dark mode by adding the `light-mode` class to the html-tag in the header template: +you can disable dark mode by adding the `light-mode` class to the HTML tag in the header template: ```html ``` -The same can be done to always enable dark-mode: +The same can be done to always enable dark mode: ```html ``` -@warning This only works if you don't use the dark-mode toggle extension. +@warning This only works if you do not use the dark-mode toggle extension. ## Choosing Sidebar Width {#tricks-sidebar} -If you have enabled the sidebar-only theme variant, make sure to carefully choose a proper width for your sidebar. -It should be wide enough to hold the icon, project title and version number. If the content is too wide, it will be +If you have enabled the sidebar-only theme variant, make sure to carefully choose an appropriate width for your sidebar. +It should be wide enough to hold the icon, project title, and version number. If the content is too wide, it will be cut off. ```css @@ -65,12 +65,12 @@ TREEVIEW_WIDTH = 335 ## Formatting Tables {#tricks-tables} -By default tables in this theme are left-aligned and as wide as required to fit their content. -Those properties can be changed for individual tables. +By default, tables in this theme are left-aligned and as wide as required to fit their content. +These properties can be changed for individual tables. ### Centering -Tables can be centered by wrapping them in the `
` HTML-tag. +Tables can be centered by wrapping them in the `
` HTML tag.
@@ -97,7 +97,7 @@ Tables can be centered by wrapping them in the `
` HTML-tag. To make tables span the full width of the page, no matter how wide the content is, wrap the table in the `full_width_table` CSS class. -@warning Apply with caution! This breaks the overflow scrolling of the table. Content might be cut of on small screens! +@warning Apply with caution! This breaks the overflow scrolling of the table. Content might be cut off on small screens!
@@ -118,7 +118,47 @@ To make tables span the full width of the page, no matter how wide the content i
- +### Buttons -Read Next: [Example](https://jothepro.github.io/doxygen-awesome-css/class_my_library_1_1_example.html) - \ No newline at end of file +The theme comes with a custom class to add simple buttons: + +
+ +- Code + ```md +
Click me!
+ ``` +- Result +
Click me!
+ +
+ +### Bordered Images + +The `bordered_image` class can be used to add a neat rounded border around images in the documentation. With `darkmode_inverted_image` the image is filtered to adapt to darkmode: + +
+ +- Code + ```md +
+ + ![](img/testimage.png){width=250px} + +
+ ``` +- Result +
+ ![](img/testimage.png){width=250px} +
+ +
+ + +
+ +| Previous | Next | +|:----------------------------------|---------------------------------------:| +| [Customization](customization.md) | [Example](https://jothepro.github.io/doxygen-awesome-css/class_my_library_1_1_example.html) | + +
\ No newline at end of file diff --git a/thirdparty/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js b/thirdparty/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js index 31c2460..f5d8374 100644 --- a/thirdparty/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js +++ b/thirdparty/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js @@ -1,29 +1,10 @@ +// SPDX-License-Identifier: MIT /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css -MIT License - -Copyright (c) 2021 - 2023 jothepro - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Copyright (c) 2021 - 2025 jothepro */ @@ -56,31 +37,48 @@ class DoxygenAwesomeDarkModeToggle extends HTMLElement { }() static init() { - $(function() { - $(document).ready(function() { - const toggleButton = document.createElement('doxygen-awesome-dark-mode-toggle') - toggleButton.title = DoxygenAwesomeDarkModeToggle.title + const toggleSelector = 'doxygen-awesome-dark-mode-toggle' + const existingToggle = document.querySelector(toggleSelector) + const toggleButton = existingToggle || document.createElement(toggleSelector) + if (!existingToggle) { + toggleButton.title = DoxygenAwesomeDarkModeToggle.title + toggleButton.updateIcon() + + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { toggleButton.updateIcon() - - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => { - toggleButton.updateIcon() - }) - document.addEventListener("visibilitychange", visibilityState => { - if (document.visibilityState === 'visible') { - toggleButton.updateIcon() - } - }); - - $(document).ready(function(){ - var td = document.getElementById("MSearchBox").parentNode.parentNode.insertCell(); - td.appendChild(toggleButton) - // - }) - $(window).resize(function(){ - document.getElementById("MSearchBox").parentNode.appendChild(toggleButton) - }) }) + document.addEventListener("visibilitychange", () => { + if (document.visibilityState === 'visible') { + toggleButton.updateIcon() + } + }); + } + + const moveToggle = () => { + const searchBox = document.getElementById("MSearchBox") + const toggle = document.querySelector(toggleSelector) || toggleButton + if (searchBox && searchBox.parentNode !== toggle.parentNode) { + searchBox.parentNode.appendChild(toggle) + } + } + + const containsSearchBox = node => { + return node.nodeType === Node.ELEMENT_NODE && + (node.id === "MSearchBox" || node.querySelector("#MSearchBox") !== null) + } + + const observer = new MutationObserver(mutations => { + const searchBoxChanged = mutations.some(mutation => + [...mutation.addedNodes, ...mutation.removedNodes] + .some(containsSearchBox) + ) + + if (searchBoxChanged) { + moveToggle() + } }) + observer.observe(document.documentElement, { childList: true, subtree: true }) + moveToggle() } constructor() { diff --git a/thirdparty/doxygen-awesome-css/doxygen-awesome-fragment-copy-button.js b/thirdparty/doxygen-awesome-css/doxygen-awesome-fragment-copy-button.js index 86c16fd..6659ad9 100644 --- a/thirdparty/doxygen-awesome-css/doxygen-awesome-fragment-copy-button.js +++ b/thirdparty/doxygen-awesome-css/doxygen-awesome-fragment-copy-button.js @@ -1,29 +1,10 @@ +// SPDX-License-Identifier: MIT /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css -MIT License - -Copyright (c) 2022 - 2023 jothepro - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Copyright (c) 2022 - 2025 jothepro */ @@ -33,29 +14,32 @@ class DoxygenAwesomeFragmentCopyButton extends HTMLElement { this.onclick=this.copyContent } static title = "Copy to clipboard" - static copyIcon = `` - static successIcon = `` + static copyIcon = `` + static successIcon = `` static successDuration = 980 static init() { - $(function() { - $(document).ready(function() { - if(navigator.clipboard) { - const fragments = document.getElementsByClassName("fragment") - for(const fragment of fragments) { - const fragmentWrapper = document.createElement("div") - fragmentWrapper.className = "doxygen-awesome-fragment-wrapper" - const fragmentCopyButton = document.createElement("doxygen-awesome-fragment-copy-button") - fragmentCopyButton.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon - fragmentCopyButton.title = DoxygenAwesomeFragmentCopyButton.title - - fragment.parentNode.replaceChild(fragmentWrapper, fragment) - fragmentWrapper.appendChild(fragment) - fragmentWrapper.appendChild(fragmentCopyButton) - - } + const initCopyButtons = () => { + if(navigator.clipboard) { + const fragments = document.getElementsByClassName("fragment") + for(const fragment of fragments) { + const fragmentWrapper = document.createElement("div") + fragmentWrapper.className = "doxygen-awesome-fragment-wrapper" + const fragmentCopyButton = document.createElement("doxygen-awesome-fragment-copy-button") + fragmentCopyButton.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon + fragmentCopyButton.title = DoxygenAwesomeFragmentCopyButton.title + + fragment.parentNode.replaceChild(fragmentWrapper, fragment) + fragmentWrapper.appendChild(fragment) + fragmentWrapper.appendChild(fragmentCopyButton) } - }) - }) + } + } + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", initCopyButtons) + } else { + initCopyButtons() + } } diff --git a/thirdparty/doxygen-awesome-css/doxygen-awesome-interactive-toc.js b/thirdparty/doxygen-awesome-css/doxygen-awesome-interactive-toc.js index 20a9669..70d23b7 100644 --- a/thirdparty/doxygen-awesome-css/doxygen-awesome-interactive-toc.js +++ b/thirdparty/doxygen-awesome-css/doxygen-awesome-interactive-toc.js @@ -1,29 +1,10 @@ +// SPDX-License-Identifier: MIT /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css -MIT License - -Copyright (c) 2022 - 2023 jothepro - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Copyright (c) 2022 - 2025 jothepro */ @@ -55,9 +36,7 @@ class DoxygenAwesomeInteractiveToc { headerNode: document.getElementById(id) }) - document.getElementById("doc-content")?.addEventListener("scroll", () => { - DoxygenAwesomeInteractiveToc.update() - }) + document.getElementById("doc-content")?.addEventListener("scroll",this.throttle(DoxygenAwesomeInteractiveToc.update, 100)) }) DoxygenAwesomeInteractiveToc.update() } @@ -78,4 +57,16 @@ class DoxygenAwesomeInteractiveToc { active?.classList.add("active") active?.classList.remove("aboveActive") } -} \ No newline at end of file + + static throttle(func, delay) { + let lastCall = 0; + return function (...args) { + const now = new Date().getTime(); + if (now - lastCall < delay) { + return; + } + lastCall = now; + return setTimeout(() => {func(...args)}, delay); + }; + } +} diff --git a/thirdparty/doxygen-awesome-css/doxygen-awesome-paragraph-link.js b/thirdparty/doxygen-awesome-css/doxygen-awesome-paragraph-link.js index e53d132..909675f 100644 --- a/thirdparty/doxygen-awesome-css/doxygen-awesome-paragraph-link.js +++ b/thirdparty/doxygen-awesome-css/doxygen-awesome-paragraph-link.js @@ -1,29 +1,10 @@ +// SPDX-License-Identifier: MIT /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css -MIT License - -Copyright (c) 2022 - 2023 jothepro - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Copyright (c) 2022 - 2025 jothepro */ @@ -34,18 +15,22 @@ class DoxygenAwesomeParagraphLink { static icon = `` static title = "Permanent Link" static init() { - $(function() { - $(document).ready(function() { - document.querySelectorAll(".contents a.anchor[id], .contents .groupheader > a[id]").forEach((node) => { - let anchorlink = document.createElement("a") - anchorlink.setAttribute("href", `#${node.getAttribute("id")}`) - anchorlink.setAttribute("title", DoxygenAwesomeParagraphLink.title) - anchorlink.classList.add("anchorlink") - node.classList.add("anchor") - anchorlink.innerHTML = DoxygenAwesomeParagraphLink.icon - node.parentElement.appendChild(anchorlink) - }) + const initParagraphLinks = () => { + document.querySelectorAll(".contents a.anchor[id], .contents .groupheader > a[id]").forEach((node) => { + let anchorlink = document.createElement("a") + anchorlink.setAttribute("href", `#${node.getAttribute("id")}`) + anchorlink.setAttribute("title", DoxygenAwesomeParagraphLink.title) + anchorlink.classList.add("anchorlink") + node.classList.add("anchor") + anchorlink.innerHTML = DoxygenAwesomeParagraphLink.icon + node.parentElement.appendChild(anchorlink) }) - }) + } + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", initParagraphLinks) + } else { + initParagraphLinks() + } } } diff --git a/thirdparty/doxygen-awesome-css/doxygen-awesome-readthedocs-search.css b/thirdparty/doxygen-awesome-css/doxygen-awesome-readthedocs-search.css new file mode 100644 index 0000000..4e9aa4a --- /dev/null +++ b/thirdparty/doxygen-awesome-css/doxygen-awesome-readthedocs-search.css @@ -0,0 +1,103 @@ +/* Highlight text in search results */ +span.highlighted { + background-color:var(--warning-color); + color: var(--page-foreground-color); + padding: 2px; + border-radius: 3px; +} + +/* Remove list bullets for search results */ +ul.search { + list-style-type: none; + padding: 0; +} + +/* Add horizontal divider for search results */ +ul.search li.search-result { + border-bottom: 1px solid var(--separator-color); + padding-bottom: 10px; + margin-bottom: 10px; +} + +/* Live search dropdown */ +#RTDLiveResults { + margin-top: var(--spacing-small); + display: none; + position: absolute; + z-index: 10000; + left: unset; + background: var(--page-background-color); + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-large); + box-shadow: var(--box-shadow); + max-height: 420px; + overflow-y: auto; +} + +@media screen and (max-width: 767px) { + #RTDLiveResults { + left: var(--spacing-medium); + right: var(--spacing-medium); + } +} + +#RTDLiveResults .rtd-live-list { + list-style: none; + margin: 0; + padding: 0; +} + +#RTDLiveResults .rtd-live-list li { + margin: 0; +} + +#RTDLiveResults .rtd-live-item { + display: block; + padding: var(--spacing-small) var(--spacing-medium); + margin: var(--spacing-small); + border-radius: var(--border-radius-small); + color: var(--page-foreground-color); + text-decoration: none; + outline: none; +} + +#RTDLiveResults .rtd-live-item:hover, +#RTDLiveResults .rtd-live-item:focus { + background: var(--menu-focus-background); +} + +#RTDLiveResults .rtd-live-title { + display: block; + font-weight: bold; + font-size: var(--navigation-font-size); +} + +#RTDLiveResults .rtd-live-snippet { + display: block; + font-size: calc(var(--navigation-font-size) * 0.9); + color: var(--page-secondary-foreground-color); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 400px; +} + +#RTDLiveResults .rtd-live-item:hover .rtd-live-title, +#RTDLiveResults .rtd-live-item:hover .rtd-live-snippet, +#RTDLiveResults .rtd-live-item:focus .rtd-live-title, +#RTDLiveResults .rtd-live-item:focus .rtd-live-snippet { + color: var(--menu-focus-foreground); +} + +#RTDLiveResults .rtd-live-snippet mark { + background-color: var(--warning-color); + color: var(--page-foreground-color); + padding: 0 2px; + border-radius: 2px; +} + +#RTDLiveResults .rtd-live-empty { + padding: var(--spacing-medium); + color: var(--page-secondary-foreground-color); + font-size: var(--navigation-font-size); +} diff --git a/thirdparty/doxygen-awesome-css/doxygen-awesome-readthedocs-search.js b/thirdparty/doxygen-awesome-css/doxygen-awesome-readthedocs-search.js new file mode 100644 index 0000000..4230fc9 --- /dev/null +++ b/thirdparty/doxygen-awesome-css/doxygen-awesome-readthedocs-search.js @@ -0,0 +1,454 @@ +class DoxygenAwesomeReadtheDocsSearch { + static searchResultsText=[ + "Sorry, no pages matching your query.", + "Search finished, found 1 page matching the search query.", + "Search finished, found $num pages matching the search query.", + ]; + static _liveResultsAlignment = 'right'; + static _liveResultsPositionFrame = null; + static _liveSearchAttached = false; + static _projectSlug = 'doxygen-awesome-css'; + static _versionSlug = 'latest'; + + static get serverUrl() { + const serverUrlSuffix = '_/api/v3/'; + const domainName = globalThis.location.hostname; + console.log(`Domain name: ${domainName}`); + + if (domainName === 'localhost') { + let tmpServerUrl = serverUrl; + while (tmpServerUrl.endsWith('/')) { + tmpServerUrl = tmpServerUrl.slice(0, -1); + } + console.warn('Localhost detected, you probably need to bypass CORS'); + return `${tmpServerUrl}/${serverUrlSuffix}`; + } + return `https://${domainName}/${serverUrlSuffix}`; + } + + static init(alignment = 'rightAlign', { projectSlug = 'doxygen-awesome-css', versionSlug = 'latest' } = {}) { + DoxygenAwesomeReadtheDocsSearch._liveResultsAlignment = alignment === 'leftAlign' ? 'left' : 'right'; + DoxygenAwesomeReadtheDocsSearch._projectSlug = projectSlug; + DoxygenAwesomeReadtheDocsSearch._versionSlug = versionSlug; + + const realSearchBox = globalThis.SearchBox; + globalThis.SearchBox = function(name, resultsPath, extension) { + if (realSearchBox) { + realSearchBox.call(this, name, resultsPath, extension); + } + + this.OnSearchFieldFocus = function() {}; + + const originalClose = this.CloseResultsWindow; + this.CloseResultsWindow = function() { + if (originalClose) { + originalClose.call(this); + } + const field = this.DOMSearchField ? this.DOMSearchField() : null; + if (field?.id === document.activeElement?.id) { + return; + } + }; + }; + + // Re-focus the search input if it is replaced in the DOM while focused. + // On mobile, viewport resize (triggered by the OSK opening) can cause + // menu.js resetState() to recreate the input element, losing focus. + const observer = new MutationObserver(function() { + const field = document.getElementById('MSearchField'); + if (field && DoxygenAwesomeReadtheDocsSearch._searchFieldHadFocus) { + field.focus(); + } + }); + + if (document.body) { + observer.observe(document.body, { childList: true, subtree: true }); + DoxygenAwesomeReadtheDocsSearch._attachLiveSearch(); + } else { + document.addEventListener('DOMContentLoaded', function() { + observer.observe(document.body, { childList: true, subtree: true }); + DoxygenAwesomeReadtheDocsSearch._attachLiveSearch(); + }); + } + + document.addEventListener('focusin', function(e) { + if (e.target?.id === 'MSearchField') { + DoxygenAwesomeReadtheDocsSearch._searchFieldHadFocus = true; + } + }); + document.addEventListener('focusout', function(e) { + if (e.target?.id === 'MSearchField') { + setTimeout(function() { + DoxygenAwesomeReadtheDocsSearch._searchFieldHadFocus = false; + }, 0); + } + }); + + document.addEventListener('click', function(e) { + const dropdown = document.getElementById('RTDLiveResults'); + const field = document.getElementById('MSearchField'); + if (dropdown && !dropdown.contains(e.target) && e.target !== field) { + DoxygenAwesomeReadtheDocsSearch._hideLiveResults(); + } + }); + + globalThis.searchFor = function(query, page, count) { + const results = document.getElementById('searchresults'); + + // Get the title + const pageTitle = document.querySelector('div.title'); + const originalTitle = pageTitle ? pageTitle.textContent : ''; + let pageTitleStates = ["Searching", "Searching .", "Searching ..", "Searching ..."]; + let pageTitleIndex = 0; + + // Function to update the page title + function updatePageTitle() { + if (pageTitle) pageTitle.textContent = pageTitleStates[pageTitleIndex]; + pageTitleIndex = (pageTitleIndex + 1) % pageTitleStates.length; + } + + // Start the interval to update the page title + let titleInterval = setInterval(updatePageTitle, 500); + + // The summary will be displayed at the top of the search results + let resultSummary = document.createElement('p'); + resultSummary.className = 'search-summary'; + results.appendChild(resultSummary); + + // Put all results into an unordered list + let resultList = document.createElement('ul'); + resultList.className = 'search'; + results.appendChild(resultList); + + // readthedocs metadata + const projectSlug = DoxygenAwesomeReadtheDocsSearch.projectSlug; + const projectVersion = DoxygenAwesomeReadtheDocsSearch.versionSlug; + + const ctx = { + query, resultSummary, resultList, titleInterval, pageTitle, originalTitle, firstUrl: true + }; + + // pull requests are not indexed, so use the default version + const versionReady = /^\d+$/.test(projectVersion) + ? DoxygenAwesomeReadtheDocsSearch.getReadTheDocsDefaultVersion(projectSlug) + : Promise.resolve(projectVersion); + + versionReady.then(function(resolvedVersion) { + const url = `${DoxygenAwesomeReadtheDocsSearch.serverUrl}search/?q=project:${projectSlug}/${resolvedVersion}+${query}&page=${page + 1}&page_size=${count}`; + console.log(url); + DoxygenAwesomeReadtheDocsSearch.fetchResults(url, ctx); + }); + } + } + + static _attachLiveSearch() { + if (DoxygenAwesomeReadtheDocsSearch._liveSearchAttached) return; + DoxygenAwesomeReadtheDocsSearch._liveSearchAttached = true; + + let debounceTimer = null; + + function onInput() { + clearTimeout(debounceTimer); + const field = document.getElementById('MSearchField'); + if (!field) return; + const query = field.value.trim(); + if (!query) { + DoxygenAwesomeReadtheDocsSearch._hideLiveResults(); + return; + } + debounceTimer = setTimeout(function() { + DoxygenAwesomeReadtheDocsSearch._runLiveSearch(query); + }, 300); + } + + function attachToField() { + const field = document.getElementById('MSearchField'); + if (!field || field._rtdLiveSearchAttached) return; + field._rtdLiveSearchAttached = true; + field.setAttribute('autocomplete', 'off'); + field.addEventListener('input', onInput); + field.addEventListener('keydown', DoxygenAwesomeReadtheDocsSearch._handleLiveSearchKeydown); + DoxygenAwesomeReadtheDocsSearch._scheduleLiveResultsPositionUpdate(); + } + + attachToField(); + + // Re-attach when the DOM changes (e.g. menu.js recreates the field on mobile) + const fieldObserver = new MutationObserver(attachToField); + fieldObserver.observe(document.body, { childList: true, subtree: true }); + + window.addEventListener('resize', DoxygenAwesomeReadtheDocsSearch._scheduleLiveResultsPositionUpdate); + } + + static _runLiveSearch(query) { + const projectSlug = DoxygenAwesomeReadtheDocsSearch.projectSlug; + const projectVersion = DoxygenAwesomeReadtheDocsSearch.versionSlug; + + const versionReady = /^\d+$/.test(projectVersion) + ? DoxygenAwesomeReadtheDocsSearch.getReadTheDocsDefaultVersion(projectSlug) + : Promise.resolve(projectVersion); + + versionReady.then(function(resolvedVersion) { + const url = `${DoxygenAwesomeReadtheDocsSearch.serverUrl}search/?q=project:${projectSlug}/${resolvedVersion}+${query}&page=1&page_size=5`; + fetch(url) + .then(function(response) { + if (!response.ok) throw new Error(response.statusText); + return response.json(); + }) + .then(function(data) { + DoxygenAwesomeReadtheDocsSearch._showLiveResults(query, data.results || []); + }) + .catch(function() { + DoxygenAwesomeReadtheDocsSearch._hideLiveResults(); + }); + }); + } + + static _showLiveResults(query, results) { + let dropdown = document.getElementById('RTDLiveResults'); + if (!dropdown) { + dropdown = document.createElement('div'); + dropdown.id = 'RTDLiveResults'; + dropdown.addEventListener('keydown', DoxygenAwesomeReadtheDocsSearch._handleLiveSearchKeydown); + document.body.appendChild(dropdown); + } + + dropdown.innerHTML = ''; + + if (results.length === 0) { + const empty = document.createElement('div'); + empty.className = 'rtd-live-empty'; + empty.textContent = 'No results found.'; + dropdown.appendChild(empty); + } else { + const list = document.createElement('ul'); + list.className = 'rtd-live-list'; + for (const item of results) { + const li = document.createElement('li'); + const a = document.createElement('a'); + a.className = 'rtd-live-item'; + a.href = `${item.domain}${item.path}`; + a.tabIndex = 0; + + const title = document.createElement('span'); + title.className = 'rtd-live-title'; + title.textContent = item.title; + a.appendChild(title); + + if (item.blocks && item.blocks.length > 0) { + const snippet = document.createElement('span'); + snippet.className = 'rtd-live-snippet'; + let snipHtml = item.blocks[0].highlights.content.join(' … '); + snipHtml = snipHtml.replaceAll(/(.*?)<\/span>/g, '$1'); + snippet.innerHTML = snipHtml; + a.appendChild(snippet); + } + + li.appendChild(a); + list.appendChild(li); + } + dropdown.appendChild(list); + } + + DoxygenAwesomeReadtheDocsSearch._positionLiveResults(dropdown); + dropdown.style.display = 'block'; + } + + static _positionLiveResults(dropdown) { + const field = document.getElementById('MSearchField'); + const box = document.getElementById('MSearchBox'); + const anchor = box || field; + if (!anchor) return; + const rect = anchor.getBoundingClientRect(); + const scrollX = window.scrollX; + const scrollY = window.scrollY; + const viewportWidth = document.documentElement.clientWidth; + dropdown.style.top = `${rect.bottom + scrollY}px`; + + if (window.matchMedia('(max-width: 767px)').matches) { + dropdown.style.left = ''; + dropdown.style.right = ''; + dropdown.style.minWidth = ''; + return; + } + + dropdown.style.minWidth = `${Math.max(rect.width, 260)}px`; + if (DoxygenAwesomeReadtheDocsSearch._liveResultsAlignment === 'left') { + dropdown.style.left = `${rect.left + scrollX}px`; + dropdown.style.right = ''; + } else { + dropdown.style.left = ''; + dropdown.style.right = `${viewportWidth - rect.right}px`; + } + } + + static _hideLiveResults(restoreFocus = false) { + const dropdown = document.getElementById('RTDLiveResults'); + if (dropdown) { + dropdown.style.display = 'none'; + } + if (restoreFocus) { + const field = document.getElementById('MSearchField'); + if (field) field.focus(); + } + } + + static _scheduleLiveResultsPositionUpdate() { + if (DoxygenAwesomeReadtheDocsSearch._liveResultsPositionFrame) return; + DoxygenAwesomeReadtheDocsSearch._liveResultsPositionFrame = window.requestAnimationFrame(function() { + DoxygenAwesomeReadtheDocsSearch._liveResultsPositionFrame = null; + DoxygenAwesomeReadtheDocsSearch._updateLiveResultsPosition(); + }); + } + + static _updateLiveResultsPosition() { + const dropdown = document.getElementById('RTDLiveResults'); + if (!dropdown || dropdown.style.display === 'none') return; + DoxygenAwesomeReadtheDocsSearch._positionLiveResults(dropdown); + } + + static _handleLiveSearchKeydown(e) { + if (e.key === 'Escape') { + DoxygenAwesomeReadtheDocsSearch._hideLiveResults(true); + } else if (e.key === 'ArrowDown') { + e.preventDefault(); + DoxygenAwesomeReadtheDocsSearch._moveLiveResultFocus(1); + } else if (e.key === 'ArrowUp') { + e.preventDefault(); + DoxygenAwesomeReadtheDocsSearch._moveLiveResultFocus(-1); + } else if (e.key === 'Enter') { + const focused = document.querySelector('#RTDLiveResults .rtd-live-item:focus'); + if (focused) { + e.preventDefault(); + focused.click(); + } + } + } + + static _moveLiveResultFocus(direction) { + const dropdown = document.getElementById('RTDLiveResults'); + if (!dropdown || dropdown.style.display === 'none') return; + const items = Array.from(dropdown.querySelectorAll('.rtd-live-item')); + if (items.length === 0) return; + const current = document.activeElement; + const idx = items.indexOf(current); + let next; + if (idx === -1) { + next = direction > 0 ? items[0] : items.at(-1); + } else { + next = items[idx + direction]; + } + if (next) next.focus(); + } + + static fetchResults(url, ctx) { + fetch(url) + .then(function(response) { + if (!response.ok) throw new Error(response.statusText); + return response.json(); + }) + .then(function(data) { + // Add the query to the search field + // This seems only be working if applied in the fetch success handler... + // maybe the field is not available before this point + const searchField = document.getElementById('MSearchField'); + if (searchField) searchField.value = ctx.query; + + if (ctx.firstUrl) { + if (data.count === 1) { + ctx.resultSummary.innerHTML = DoxygenAwesomeReadtheDocsSearch.searchResultsText[1]; + } else if (data.count > 1) { + ctx.resultSummary.innerHTML = DoxygenAwesomeReadtheDocsSearch.searchResultsText[2].replace(/\$num/, data.count); + } else { + ctx.resultSummary.innerHTML = DoxygenAwesomeReadtheDocsSearch.searchResultsText[0]; + } + ctx.firstUrl = false; + } + + data.results.forEach(function(item) { + DoxygenAwesomeReadtheDocsSearch.appendResultItem(ctx.resultList, item); + }); + + if (data.next) { + DoxygenAwesomeReadtheDocsSearch.fetchResults(data.next, ctx); + } else { + // Clear the interval when the search is complete + clearInterval(ctx.titleInterval); + if (ctx.pageTitle) ctx.pageTitle.textContent = ctx.originalTitle; + } + }); + } + + static appendResultItem(resultList, item) { + const resultItem = document.createElement('li'); + resultItem.className = 'search-result'; + const resultItemUrl = `${item.domain}${item.path}`; + const resultItemTitleLink = document.createElement('a'); + const resultItemTitleHeading = document.createElement('h3'); + resultItemTitleHeading.appendChild(resultItemTitleLink); + resultItemTitleLink.href = resultItemUrl; + resultItemTitleLink.textContent = item.title; + resultItem.append(resultItemTitleHeading); + resultList.append(resultItem); + + const resultItemParagraph = document.createElement('p'); + resultItemParagraph.className = 'context'; + for (const block of item.blocks) { + let blockContent = block.highlights.content.join(', '); + blockContent = blockContent.replaceAll(/(.*?)<\/span>/g, '$1'); + resultItemParagraph.innerHTML += blockContent; + + const blockName = `#${block.title.toLowerCase().replaceAll(' ', '-')}`; + const blockUrl = resultItemUrl + blockName; + const blockLink = document.createElement('a'); + blockLink.href = blockUrl; + blockLink.textContent = "More..."; + resultItemParagraph.append(document.createTextNode(' ')); + resultItemParagraph.append(blockLink); + resultItemParagraph.append(document.createElement('br')); + } + resultItem.append(resultItemParagraph); + } + + // Function to extract the value of a specified Read the Docs meta property + static getMetaValue(propertyName) { + const metaTags = document.getElementsByTagName('meta'); + + for (let meta of metaTags) { + if (meta.name === propertyName) { + return meta.content; + } + } + + return null; + } + + static get projectSlug() { + return DoxygenAwesomeReadtheDocsSearch.getMetaValue("readthedocs-project-slug") || + DoxygenAwesomeReadtheDocsSearch._projectSlug; + } + + static get versionSlug() { + return DoxygenAwesomeReadtheDocsSearch.getMetaValue("readthedocs-version-slug") || + DoxygenAwesomeReadtheDocsSearch._versionSlug; + } + + static getReadTheDocsDefaultVersion(project) { + console.log('Pull request detected, getting default version from ReadTheDocs API'); + const url = `${DoxygenAwesomeReadtheDocsSearch.serverUrl}projects/${project}/`; + return fetch(url) + .then(function(response) { + if (!response.ok) throw new Error(response.statusText); + return response.json(); + }) + .then(function(data) { + console.log(data); + return data.default_version || 'latest'; + }) + .catch(function(err) { + console.error('Error:', err); + console.log(`Cannot determine default version for ${project}, assuming "latest"`); + return 'latest'; + }); + } +} diff --git a/thirdparty/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css b/thirdparty/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css index 4f506d8..2ab5c76 100644 --- a/thirdparty/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css +++ b/thirdparty/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css @@ -1,40 +1,20 @@ - +/* SPDX-License-Identifier: MIT */ /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css -MIT License - -Copyright (c) 2021 - 2023 jothepro - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Copyright (c) 2021 - 2025 jothepro */ @media screen and (min-width: 768px) { #MSearchBox { - width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - var(--searchbar-height) - 20px); + width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - var(--searchbar-height) - 1px); } #MSearchField { - width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - 76px - var(--searchbar-height)); + width: calc(var(--side-nav-fixed-width) - calc(2 * var(--spacing-medium)) - 66px - var(--searchbar-height)); } } diff --git a/thirdparty/doxygen-awesome-css/doxygen-awesome-sidebar-only.css b/thirdparty/doxygen-awesome-css/doxygen-awesome-sidebar-only.css index 7c1e7c6..d1543f9 100644 --- a/thirdparty/doxygen-awesome-css/doxygen-awesome-sidebar-only.css +++ b/thirdparty/doxygen-awesome-css/doxygen-awesome-sidebar-only.css @@ -1,43 +1,23 @@ +/* SPDX-License-Identifier: MIT */ /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css -MIT License - -Copyright (c) 2021 - 2023 jothepro - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Copyright (c) 2021 - 2025 jothepro */ - html { +html { /* side nav width. MUST be = `TREEVIEW_WIDTH`. * Make sure it is wide enough to contain the page title (logo + title + version) */ - --side-nav-fixed-width: 350px; + --side-nav-fixed-width: 335px; --menu-display: none; - --top-height: 0px; - --toc-sticky-top: -90px; + --top-height: 120px; + --toc-sticky-top: -25px; --toc-max-height: calc(100vh - 2 * var(--spacing-medium) - 25px); - overflow: hidden; } #projectname { @@ -61,8 +41,15 @@ SOFTWARE. height: calc(100vh - var(--top-height)) !important; } - #nav-tree { - padding: 0; + #top { + display: block; + border-bottom: none; + height: var(--top-height); + margin-bottom: calc(0px - var(--top-height)); + max-width: var(--side-nav-fixed-width); + overflow: hidden; + background: var(--side-nav-background); + border-right: 1px solid var(--separator-color); } #main-nav { @@ -71,15 +58,17 @@ SOFTWARE. } .ui-resizable-handle { - cursor: default; - width: 1px !important; - box-shadow: 0 calc(-2 * var(--top-height)) 0 0 var(--separator-color); + display: none; + } + + .ui-resizable-e { + width: 0; } #nav-path { position: fixed; right: 0; - left: var(--side-nav-fixed-width); + left: calc(var(--side-nav-fixed-width) + 1px); bottom: 0; width: auto; } @@ -104,4 +93,14 @@ SOFTWARE. left: var(--spacing-medium) !important; right: auto; } + + #nav-sync { + bottom: 4px; + right: auto; + left: 300px; + width: 35px; + top: auto !important; + user-select: none; + position: fixed + } } diff --git a/thirdparty/doxygen-awesome-css/doxygen-awesome-tabs.js b/thirdparty/doxygen-awesome-css/doxygen-awesome-tabs.js index 8e725b2..9e8d3af 100644 --- a/thirdparty/doxygen-awesome-css/doxygen-awesome-tabs.js +++ b/thirdparty/doxygen-awesome-css/doxygen-awesome-tabs.js @@ -1,29 +1,10 @@ +// SPDX-License-Identifier: MIT /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css -MIT License - -Copyright (c) 2023 jothepro - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Copyright (c) 2023 - 2025 jothepro */ @@ -32,15 +13,16 @@ class DoxygenAwesomeTabs { static init() { window.addEventListener("load", () => { document.querySelectorAll(".tabbed:not(:empty)").forEach((tabbed, tabbedIndex) => { - let tabLinkList = [] - tabbed.querySelectorAll("li").forEach((tab, tabIndex) => { + let tabLinkList = [] + tabbed.querySelectorAll(":scope > ul > li").forEach((tab, tabIndex) => { tab.id = "tab_" + tabbedIndex + "_" + tabIndex let header = tab.querySelector(".tab-title") let tabLink = document.createElement("button") tabLink.classList.add("tab-button") tabLink.appendChild(header) + header.title = header.textContent tabLink.addEventListener("click", () => { - tabbed.querySelectorAll("li").forEach((tab) => { + tabbed.querySelectorAll(":scope > ul > li").forEach((tab) => { tab.classList.remove("selected") }) tabLinkList.forEach((tabLink) => { @@ -64,7 +46,26 @@ class DoxygenAwesomeTabs { }) tabsOverviewContainer.appendChild(tabsOverview) tabbed.before(tabsOverviewContainer) + + function resize() { + let maxTabHeight = 0 + tabbed.querySelectorAll(":scope > ul > li").forEach((tab, tabIndex) => { + let visibility = tab.style.display + tab.style.display = "block" + maxTabHeight = Math.max(tab.offsetHeight, maxTabHeight) + tab.style.display = visibility + }) + tabbed.style.height = `${maxTabHeight + 10}px` + } + + resize() + new ResizeObserver(resize).observe(tabbed) }) }) + + } + + static resize(tabbed) { + } } \ No newline at end of file diff --git a/thirdparty/doxygen-awesome-css/doxygen-awesome.css b/thirdparty/doxygen-awesome-css/doxygen-awesome.css index 1021abb..665f733 100644 --- a/thirdparty/doxygen-awesome-css/doxygen-awesome.css +++ b/thirdparty/doxygen-awesome-css/doxygen-awesome.css @@ -1,29 +1,10 @@ +/* SPDX-License-Identifier: MIT */ /** Doxygen Awesome https://github.com/jothepro/doxygen-awesome-css -MIT License - -Copyright (c) 2021 - 2023 jothepro - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Copyright (c) 2021 - 2025 jothepro */ @@ -32,6 +13,9 @@ html { --primary-color: #1779c4; --primary-dark-color: #335c80; --primary-light-color: #70b1e9; + --on-primary-color: #ffffff; + + --link-color: var(--primary-color); /* page base colors */ --page-background-color: #ffffff; @@ -42,14 +26,15 @@ html { --separator-color: #dedede; /* border radius for all rounded components. Will affect many components, like dropdowns, memitems, codeblocks, ... */ - --border-radius-large: 8px; - --border-radius-small: 4px; - --border-radius-medium: 6px; + --border-radius-large: 10px; + --border-radius-small: 5px; + --border-radius-medium: 8px; /* default spacings. Most components reference these values for spacing, to provide uniform spacing on the page. */ --spacing-small: 5px; --spacing-medium: 10px; --spacing-large: 16px; + --spacing-xlarge: 20px; /* default box shadow used for raising an element above the normal content. Used in dropdowns, search result, ... */ --box-shadow: 0 2px 8px 0 rgba(0,0,0,.075); @@ -80,21 +65,21 @@ html { --toc-max-height: calc(100vh - 2 * var(--spacing-medium) - 85px); /* colors for various content boxes: @warning, @note, @deprecated @bug */ - --warning-color: #f8d1cc; - --warning-color-dark: #b61825; - --warning-color-darker: #75070f; - --note-color: #faf3d8; - --note-color-dark: #f3a600; - --note-color-darker: #5f4204; - --todo-color: #e4f3ff; - --todo-color-dark: #1879C4; - --todo-color-darker: #274a5c; + --warning-color: #faf3d8; + --warning-color-dark: #f3a600; + --warning-color-darker: #5f4204; + --note-color: #e4f3ff; + --note-color-dark: #1879C4; + --note-color-darker: #274a5c; + --todo-color: #e4dafd; + --todo-color-dark: #5b2bdd; + --todo-color-darker: #2a0d72; --deprecated-color: #ecf0f3; --deprecated-color-dark: #5b6269; --deprecated-color-darker: #43454a; - --bug-color: #e4dafd; - --bug-color-dark: #5b2bdd; - --bug-color-darker: #2a0d72; + --bug-color: #f8d1cc; + --bug-color-dark: #b61825; + --bug-color-darker: #75070f; --invariant-color: #d8f1e3; --invariant-color-dark: #44b86f; --invariant-color-darker: #265532; @@ -113,7 +98,7 @@ html { */ --menu-display: block; - --menu-focus-foreground: var(--page-background-color); + --menu-focus-foreground: var(--on-primary-color); --menu-focus-background: var(--primary-color); --menu-selected-background: rgba(0,0,0,.05); @@ -135,6 +120,8 @@ html { /* code block colors */ --code-background: #f5f5f5; --code-foreground: var(--page-foreground-color); + --section-code-background: rgba(0, 0, 0, 0.06); + --section-code-border: rgba(0, 0, 0, 0.16); /* fragment colors */ --fragment-background: #F8F9FA; @@ -169,6 +156,8 @@ html { --webkit-scrollbar-size: 7px; --webkit-scrollbar-padding: 4px; --webkit-scrollbar-color: var(--separator-color); + + --animation-duration: .12s } @media screen and (max-width: 767px) { @@ -202,27 +191,29 @@ html { --side-nav-background: #252628; --code-background: #2a2c2f; + --section-code-background: rgba(255, 255, 255, 0.08); + --section-code-border: rgba(255, 255, 255, 0.18); --tablehead-background: #2a2c2f; --blockquote-background: #222325; --blockquote-foreground: #7e8c92; - --warning-color: #2e1917; - --warning-color-dark: #ad2617; - --warning-color-darker: #f5b1aa; - --note-color: #3b2e04; - --note-color-dark: #f1b602; - --note-color-darker: #ceb670; - --todo-color: #163750; - --todo-color-dark: #1982D2; - --todo-color-darker: #dcf0fa; + --warning-color: #3b2e04; + --warning-color-dark: #f1b602; + --warning-color-darker: #ceb670; + --note-color: #163750; + --note-color-dark: #1982D2; + --note-color-darker: #dcf0fa; + --todo-color: #2a2536; + --todo-color-dark: #7661b3; + --todo-color-darker: #ae9ed6; --deprecated-color: #2e323b; --deprecated-color-dark: #738396; --deprecated-color-darker: #abb0bd; - --bug-color: #2a2536; - --bug-color-dark: #7661b3; - --bug-color-darker: #ae9ed6; + --bug-color: #2e1917; + --bug-color-dark: #ad2617; + --bug-color-darker: #f5b1aa; --invariant-color: #303a35; --invariant-color-dark: #76ce96; --invariant-color-darker: #cceed5; @@ -263,27 +254,29 @@ html.dark-mode { --side-nav-background: #252628; --code-background: #2a2c2f; + --section-code-background: rgba(255, 255, 255, 0.08); + --section-code-border: rgba(255, 255, 255, 0.18); --tablehead-background: #2a2c2f; --blockquote-background: #222325; --blockquote-foreground: #7e8c92; - --warning-color: #2e1917; - --warning-color-dark: #ad2617; - --warning-color-darker: #f5b1aa; - --note-color: #3b2e04; - --note-color-dark: #f1b602; - --note-color-darker: #ceb670; - --todo-color: #163750; - --todo-color-dark: #1982D2; - --todo-color-darker: #dcf0fa; + --warning-color: #3b2e04; + --warning-color-dark: #f1b602; + --warning-color-darker: #ceb670; + --note-color: #163750; + --note-color-dark: #1982D2; + --note-color-darker: #dcf0fa; + --todo-color: #2a2536; + --todo-color-dark: #7661b3; + --todo-color-darker: #ae9ed6; --deprecated-color: #2e323b; --deprecated-color-dark: #738396; --deprecated-color-darker: #abb0bd; - --bug-color: #2a2536; - --bug-color-dark: #7661b3; - --bug-color-darker: #ae9ed6; + --bug-color: #2e1917; + --bug-color-dark: #ad2617; + --bug-color-darker: #f5b1aa; --invariant-color: #303a35; --invariant-color-dark: #76ce96; --invariant-color-darker: #cceed5; @@ -308,15 +301,16 @@ body { font-size: var(--page-font-size); } -body, table, div, p, dl, #nav-tree .label, .title, +body, table, div, p, dl, #nav-tree .label, #nav-tree a, .title, .sm-dox a, .sm-dox a:hover, .sm-dox a:focus, #projectname, .SelectItem, #MSearchField, .navpath li.navelem a, -.navpath li.navelem a:hover, p.reference, p.definition { +.navpath li.navelem a:hover, p.reference, p.definition, div.toc li, div.toc h3, +#page-nav ul.page-outline li a { font-family: var(--font-family); } h1, h2, h3, h4, h5 { - margin-top: .9em; + margin-top: 1em; font-weight: 600; line-height: initial; } @@ -330,8 +324,13 @@ p.reference, p.definition { } a:link, a:visited, a:hover, a:focus, a:active { - color: var(--primary-color) !important; + color: var(--link-color) !important; font-weight: 500; + background: none; +} + +a:hover { + text-decoration: underline; } a.anchor { @@ -346,13 +345,14 @@ a.anchor { #top { background: var(--header-background); border-bottom: 1px solid var(--separator-color); + position: relative; + z-index: 99; } @media screen and (min-width: 768px) { #top { display: flex; flex-wrap: wrap; - justify-content: space-between; align-items: center; } } @@ -360,6 +360,7 @@ a.anchor { #main-nav { flex-grow: 5; padding: var(--spacing-small) var(--spacing-medium); + border-bottom: 0; } #titlearea { @@ -439,19 +440,36 @@ a.anchor { } .sm-dox a span.sub-arrow { - border-color: var(--header-foreground) transparent transparent transparent; + top: 15px; + right: 10px; + box-sizing: content-box; + padding: 0; + margin: 0; + display: inline-block; + width: 5px; + height: 5px; + transform: rotate(45deg); + border-width: 0; + border-right: 2px solid var(--header-foreground); + border-bottom: 2px solid var(--header-foreground); + background: none; } .sm-dox a:hover span.sub-arrow { - border-color: var(--menu-focus-foreground) transparent transparent transparent; + border-color: var(--menu-focus-foreground); + background: none; } .sm-dox ul a span.sub-arrow { - border-color: transparent transparent transparent var(--page-foreground-color); + transform: rotate(-45deg); + border-width: 0; + border-right: 2px solid var(--header-foreground); + border-bottom: 2px solid var(--header-foreground); } .sm-dox ul a:hover span.sub-arrow { - border-color: transparent transparent transparent var(--menu-focus-foreground); + border-color: var(--menu-focus-foreground); + background: none; } } @@ -478,7 +496,7 @@ a.anchor { .sm-dox ul a { color: var(--page-foreground-color) !important; - background: var(--page-background-color); + background: none; font-size: var(--navigation-font-size); } @@ -550,6 +568,13 @@ a.anchor { box-shadow: none; display: block; margin-top: 0; + margin-right: 0; +} + +@media (min-width: 768px) { + .sm-dox li { + padding: 0; + } } /* until Doxygen 1.9.4 */ @@ -560,7 +585,7 @@ a.anchor { } /* Doxygen 1.9.5 */ -.left span#MSearchSelect { +.left span#MSearchSelect, .left span#MSearchSelectExt { left: 0; user-select: none; margin-left: 8px; @@ -571,6 +596,17 @@ a.anchor { padding-left: 0 } +/* Doxygen 1.14.0 */ +.search-icon::before { + background: none; + top: 5px; +} + +.search-icon::after { + background: none; + top: 12px; +} + .SelectionMark { user-select: none; } @@ -623,7 +659,7 @@ a.anchor { color: var(--searchbar-foreground); } -#MSearchSelect { +#MSearchSelect, #MSearchSelectExt { top: calc(calc(var(--searchbar-height) / 2) - 11px); } @@ -774,8 +810,13 @@ html.dark-mode iframe#MSearchResults { */ #side-nav { - padding: 0 !important; - background: var(--side-nav-background); + min-width: 8px; + max-width: 50vw; +} + + +#nav-tree { + border-right: 1px solid var(--separator-color); } @media screen and (max-width: 767px) { @@ -786,34 +827,95 @@ html.dark-mode iframe#MSearchResults { #doc-content { margin-left: 0 !important; } + + #top { + border-right: none; + } } #nav-tree { - background: transparent; - margin-right: 1px; + background: var(--side-nav-background); + margin-right: -1px; + padding: 0; } #nav-tree .label { font-size: var(--navigation-font-size); + line-height: var(--tree-item-height); +} + +#nav-tree span.label a:hover { + background: none; } #nav-tree .item { height: var(--tree-item-height); line-height: var(--tree-item-height); + overflow: hidden; + text-overflow: ellipsis; + margin: 0; + padding: 0; +} + +#nav-tree-contents { + margin: 0; +} + +#main-menu > li:last-child { + height: auto; +} + +#nav-tree .item > a:focus { + outline: none; } #nav-sync { - bottom: 12px; - right: 12px; + bottom: var(--spacing-medium); + right: var(--spacing-medium) !important; top: auto !important; user-select: none; } +div.nav-sync-icon { + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium); + background: var(--page-background-color); + width: 30px; + height: 20px; +} + +div.nav-sync-icon:hover { + background: var(--page-background-color); +} + +span.sync-icon-left, div.nav-sync-icon:hover span.sync-icon-left { + border-left: 2px solid var(--primary-color); + border-top: 2px solid var(--primary-color); + top: 5px; + left: 6px; +} +span.sync-icon-right, div.nav-sync-icon:hover span.sync-icon-right { + border-right: 2px solid var(--primary-color); + border-bottom: 2px solid var(--primary-color); + top: 5px; + left: initial; + right: 6px; +} + +div.nav-sync-icon.active::after, div.nav-sync-icon.active:hover::after { + border-top: 2px solid var(--primary-color); + top: 9px; + left: 6px; + width: 19px; +} + #nav-tree .selected { text-shadow: none; background-image: none; background-color: transparent; position: relative; + color: var(--primary-color) !important; + font-weight: 500; } #nav-tree .selected::after { @@ -838,22 +940,40 @@ html.dark-mode iframe#MSearchResults { } #nav-tree .arrow { - /* opacity: var(--side-nav-arrow-opacity); */ + opacity: var(--side-nav-arrow-opacity); + background: none; } -.arrow { +#nav-tree span.arrowhead { + margin: 0 0 1px 2px; +} + +span.arrowhead { + border-color: var(--primary-light-color); +} + +.selected span.arrowhead { + border-color: var(--primary-color); +} + +#nav-tree-contents > ul > li:first-child > div > a { + opacity: 0; + pointer-events: none; +} + +.contents .arrow { color: inherit; cursor: pointer; - font-size: 67%; + font-size: 45%; vertical-align: middle; margin-right: 2px; font-family: serif; height: auto; - text-align: right; + padding-bottom: 4px; } #nav-tree div.item:hover .arrow, #nav-tree a:focus .arrow { - /* opacity: var(--side-nav-arrow-hover-opacity); */ + opacity: var(--side-nav-arrow-hover-opacity); } #nav-tree .selected a { @@ -863,8 +983,11 @@ html.dark-mode iframe#MSearchResults { } .ui-resizable-e { + background: none; +} + +.ui-resizable-e:hover { background: var(--separator-color); - width: 1px; } /* @@ -873,7 +996,7 @@ html.dark-mode iframe#MSearchResults { div.header { border-bottom: 1px solid var(--separator-color); - background-color: var(--page-background-color); + background: none; background-image: none; } @@ -912,7 +1035,7 @@ div.headertitle { div.header .title { font-weight: 600; font-size: 225%; - padding: var(--spacing-medium) var(--spacing-large); + padding: var(--spacing-medium) var(--spacing-xlarge); word-break: break-word; } @@ -929,9 +1052,10 @@ td.memSeparator { span.mlabel { background: var(--primary-color); + color: var(--on-primary-color); border: none; padding: 4px 9px; - border-radius: 12px; + border-radius: var(--border-radius-large); margin-right: var(--spacing-medium); } @@ -940,7 +1064,7 @@ span.mlabel:last-of-type { } div.contents { - padding: 0 var(--spacing-large); + padding: 0 var(--spacing-xlarge); } div.contents p, div.contents li { @@ -951,6 +1075,16 @@ div.contents div.dyncontent { margin: var(--spacing-medium) 0; } +@media screen and (max-width: 767px) { + div.contents { + padding: 0 var(--spacing-large); + } + + div.header .title { + padding: var(--spacing-medium) var(--spacing-large); + } +} + @media (prefers-color-scheme: dark) { html:not(.light-mode) div.contents div.dyncontent img, html:not(.light-mode) div.contents center img, @@ -974,7 +1108,7 @@ html.dark-mode div.contents .dotgraph iframe filter: brightness(89%) hue-rotate(180deg) invert(); } -h2.groupheader { +td h2.groupheader, h2.groupheader { border-bottom: 0px; color: var(--page-foreground-color); box-shadow: @@ -1035,7 +1169,7 @@ blockquote::after { blockquote p { margin: var(--spacing-small) 0 var(--spacing-medium) 0; } -.paramname { +.paramname, .paramname em { font-weight: 600; color: var(--primary-dark-color); } @@ -1085,7 +1219,7 @@ div.contents .toc { border: 0; border-left: 1px solid var(--separator-color); border-radius: 0; - background-color: transparent; + background-color: var(--page-background-color); box-shadow: none; position: sticky; top: var(--toc-sticky-top); @@ -1171,7 +1305,7 @@ div.toc li a.aboveActive { margin-right: var(--spacing-small); margin-bottom: calc(var(--navigation-font-size) / 4); transform: rotate(-90deg); - transition: transform 0.25s ease-out; + transition: transform var(--animation-duration) ease-out; } div.contents .toc.interactive.open > h3::before { @@ -1193,24 +1327,115 @@ div.toc li a.aboveActive { } } +/* + Page Outline (Doxygen >= 1.14.0) +*/ + +#page-nav { + background: var(--page-background-color); + border-left: 1px solid var(--separator-color); +} + +#page-nav #page-nav-resize-handle { + background: var(--separator-color); +} + +#page-nav #page-nav-resize-handle::after { + border-left: 1px solid var(--primary-color); + border-right: 1px solid var(--primary-color); +} + +#page-nav #page-nav-tree #page-nav-contents { + top: var(--spacing-large); +} + +#page-nav ul.page-outline { + margin: 0 0 30px 0; + padding: 0; +} + +#page-nav ul.page-outline li a { + font-size: var(--toc-font-size) !important; + color: var(--page-secondary-foreground-color) !important; + display: inline-block; + line-height: calc(2 * var(--toc-font-size)); +} + +#page-nav ul.page-outline li a a.anchorlink { + display: none; +} + +#page-nav ul.page-outline li.vis ~ * a { + color: var(--page-foreground-color) !important; +} + +#page-nav ul.page-outline li.vis:not(.vis ~ .vis) a, #page-nav ul.page-outline li a:hover { + color: var(--primary-color) !important; +} + +#page-nav ul.page-outline .vis { + background: var(--page-background-color); + position: relative; +} + +#page-nav ul.page-outline .vis::after { + content: ""; + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 4px; + background: var(--page-secondary-foreground-color); +} + +#page-nav ul.page-outline .vis:not(.vis ~ .vis)::after { + top: 1px; + border-top-right-radius: var(--border-radius-small); +} + +#page-nav ul.page-outline .vis:not(:has(~ .vis))::after { + bottom: 1px; + border-bottom-right-radius: var(--border-radius-small); +} + + +#page-nav ul.page-outline .arrow { + display: inline-block; +} + +#page-nav ul.page-outline .arrow span { + display: none; +} + +@media screen and (max-width: 767px) { + #container { + grid-template-columns: initial !important; + } + + #page-nav { + display: none; + } +} + /* Code & Fragments */ -code, div.fragment, pre.fragment { - border-radius: var(--border-radius-small); +code, div.fragment, pre.fragment, span.tt { border: 1px solid var(--separator-color); overflow: hidden; } -code { +code, span.tt { display: inline; background: var(--code-background); color: var(--code-foreground); padding: 2px 6px; + border-radius: var(--border-radius-small); } div.fragment, pre.fragment { + border-radius: var(--border-radius-medium); margin: var(--spacing-medium) 0; padding: calc(var(--spacing-large) - (var(--spacing-large) / 6)) var(--spacing-large); background: var(--fragment-background); @@ -1228,9 +1453,13 @@ div.fragment, pre.fragment { .contents > div.fragment, .textblock > div.fragment, .textblock > pre.fragment, + .textblock > .tabbed > ul > li > div.fragment, + .textblock > .tabbed > ul > li > pre.fragment, .contents > .doxygen-awesome-fragment-wrapper > div.fragment, .textblock > .doxygen-awesome-fragment-wrapper > div.fragment, - .textblock > .doxygen-awesome-fragment-wrapper > pre.fragment { + .textblock > .doxygen-awesome-fragment-wrapper > pre.fragment, + .textblock > .tabbed > ul > li > .doxygen-awesome-fragment-wrapper > div.fragment, + .textblock > .tabbed > ul > li > .doxygen-awesome-fragment-wrapper > pre.fragment { margin: var(--spacing-medium) calc(0px - var(--spacing-large)); border-radius: 0; border-left: 0; @@ -1264,7 +1493,7 @@ div.fragment, pre.fragment { } } -code, code a, pre.fragment, div.fragment, div.fragment .line, div.fragment span, div.fragment .line a, div.fragment .line span { +code, code a, pre.fragment, div.fragment, div.fragment .line, div.fragment span, div.fragment .line a, div.fragment .line span, span.tt { font-family: var(--font-family-monospace); font-size: var(--code-font-size) !important; } @@ -1320,8 +1549,9 @@ div.fragment span.lineno a { color: var(--fragment-link) !important; } -div.fragment .line:first-child .lineno { +div.fragment > .line:first-child .lineno { box-shadow: -999999px 0px 0 999999px var(--fragment-linenumber-background), -999998px 0px 0 999999px var(--fragment-linenumber-border); + background-color: var(--fragment-linenumber-background) !important; } div.line { @@ -1337,6 +1567,10 @@ div.line.glow { dl warning, attention, note, deprecated, bug, ... */ +dl { + line-height: calc(1.65 * var(--page-font-size)); +} + dl.bug dt a, dl.deprecated dt a, dl.todo dt a { font-weight: bold !important; } @@ -1380,8 +1614,8 @@ dl.todo { color: var(--todo-color-darker); } -dl.todo dt { - color: var(--todo-color-dark); +dl.todo dt a { + color: var(--todo-color-dark) !important; } dl.bug dt a { @@ -1422,6 +1656,34 @@ dl.invariant dt, dl.pre dt, dl.post dt { color: var(--invariant-color-dark); } +dl.warning code, dl.warning span.tt, +dl.attention code, dl.attention span.tt, +dl.note code, dl.note span.tt, +dl.remark code, dl.remark span.tt, +dl.todo code, dl.todo span.tt, +dl.bug code, dl.bug span.tt, +dl.deprecated code, dl.deprecated span.tt, +dl.invariant code, dl.invariant span.tt, +dl.pre code, dl.pre span.tt, +dl.post code, dl.post span.tt { + background: var(--section-code-background); + border: 1px solid var(--section-code-border); +} + +dl.warning div.fragment, dl.warning pre.fragment, +dl.attention div.fragment, dl.attention pre.fragment, +dl.note div.fragment, dl.note pre.fragment, +dl.remark div.fragment, dl.remark pre.fragment, +dl.todo div.fragment, dl.todo pre.fragment, +dl.bug div.fragment, dl.bug pre.fragment, +dl.deprecated div.fragment, dl.deprecated pre.fragment, +dl.invariant div.fragment, dl.invariant pre.fragment, +dl.pre div.fragment, dl.pre pre.fragment, +dl.post div.fragment, dl.post pre.fragment { + background: var(--section-code-background); + border: 1px solid var(--section-code-border); +} + /* memitem */ @@ -1502,6 +1764,7 @@ div.memitem { border-top-right-radius: var(--border-radius-medium); border-bottom-right-radius: var(--border-radius-medium); border-bottom-left-radius: var(--border-radius-medium); + border-top-left-radius: 0; overflow: hidden; display: block !important; } @@ -1733,7 +1996,7 @@ table.fieldtable th { color: var(--tablehead-foreground); } -table.fieldtable td.fieldtype, .fieldtable td.fieldname, .fieldtable td.fielddoc, .fieldtable th { +table.fieldtable td.fieldtype, .fieldtable td.fieldname, .fieldtable td.fieldinit, .fieldtable td.fielddoc, .fieldtable th { border-bottom: 1px solid var(--separator-color); border-right: 1px solid var(--separator-color); } @@ -1768,8 +2031,10 @@ table.memberdecls tr[class^='memitem'] .memTemplParams { white-space: normal; } -table.memberdecls .memItemLeft, -table.memberdecls .memItemRight, +table.memberdecls tr.heading + tr[class^='memitem'] td.memItemLeft, +table.memberdecls tr.heading + tr[class^='memitem'] td.memItemRight, +table.memberdecls td.memItemLeft, +table.memberdecls td.memItemRight, table.memberdecls .memTemplItemLeft, table.memberdecls .memTemplItemRight, table.memberdecls .memTemplParams { @@ -1781,8 +2046,34 @@ table.memberdecls .memTemplParams { background-color: var(--fragment-background); } +@media screen and (min-width: 768px) { + + tr.heading + tr[class^='memitem'] td.memItemRight, tr.groupHeader + tr[class^='memitem'] td.memItemRight, tr.inherit_header + tr[class^='memitem'] td.memItemRight { + border-top-right-radius: var(--border-radius-small); + } + + table.memberdecls tr:last-child td.memItemRight, table.memberdecls tr:last-child td.mdescRight, table.memberdecls tr[class^='memitem']:has(+ tr.groupHeader) td.memItemRight, table.memberdecls tr[class^='memitem']:has(+ tr.inherit_header) td.memItemRight, table.memberdecls tr[class^='memdesc']:has(+ tr.groupHeader) td.mdescRight, table.memberdecls tr[class^='memdesc']:has(+ tr.inherit_header) td.mdescRight { + border-bottom-right-radius: var(--border-radius-small); + } + + table.memberdecls tr:last-child td.memItemLeft, table.memberdecls tr:last-child td.mdescLeft, table.memberdecls tr[class^='memitem']:has(+ tr.groupHeader) td.memItemLeft, table.memberdecls tr[class^='memitem']:has(+ tr.inherit_header) td.memItemLeft, table.memberdecls tr[class^='memdesc']:has(+ tr.groupHeader) td.mdescLeft, table.memberdecls tr[class^='memdesc']:has(+ tr.inherit_header) td.mdescLeft { + border-bottom-left-radius: var(--border-radius-small); + } + + tr.heading + tr[class^='memitem'] td.memItemLeft, tr.groupHeader + tr[class^='memitem'] td.memItemLeft, tr.inherit_header + tr[class^='memitem'] td.memItemLeft { + border-top-left-radius: var(--border-radius-small); + } + +} + +table.memname td.memname { + font-size: var(--memname-font-size); +} + table.memberdecls .memTemplItemLeft, -table.memberdecls .memTemplItemRight { +table.memberdecls .template .memItemLeft, +table.memberdecls .memTemplItemRight, +table.memberdecls .template .memItemRight { padding-top: 2px; } @@ -1794,13 +2085,13 @@ table.memberdecls .memTemplParams { padding-bottom: var(--spacing-small); } -table.memberdecls .memTemplItemLeft { +table.memberdecls .memTemplItemLeft, table.memberdecls .template .memItemLeft { border-radius: 0 0 0 var(--border-radius-small); border-left: 1px solid var(--separator-color); border-top: 0; } -table.memberdecls .memTemplItemRight { +table.memberdecls .memTemplItemRight, table.memberdecls .template .memItemRight { border-radius: 0 0 var(--border-radius-small) 0; border-right: 1px solid var(--separator-color); padding-left: 0; @@ -1826,8 +2117,14 @@ table.memberdecls .mdescLeft, table.memberdecls .mdescRight { background: none; color: var(--page-foreground-color); padding: var(--spacing-small) 0; + border: 0; } +table.memberdecls [class^="memdesc"] { + box-shadow: none; +} + + table.memberdecls .memItemLeft, table.memberdecls .memTemplItemLeft { padding-right: var(--spacing-medium); @@ -1850,6 +2147,10 @@ table.memberdecls .inherit_header td { color: var(--page-secondary-foreground-color); } +table.memberdecls span.dynarrow { + left: 10px; +} + table.memberdecls img[src="closed.png"], table.memberdecls img[src="open.png"], div.dynheader img[src="open.png"], @@ -1863,7 +2164,11 @@ div.dynheader img[src="closed.png"] { display: block; float: left; margin-left: -10px; - transition: transform 0.25s ease-out; + transition: transform var(--animation-duration) ease-out; +} + +tr.heading + tr[class^='memitem'] td.memItemLeft, tr.groupHeader + tr[class^='memitem'] td.memItemLeft, tr.inherit_header + tr[class^='memitem'] td.memItemLeft, tr.heading + tr[class^='memitem'] td.memItemRight, tr.groupHeader + tr[class^='memitem'] td.memItemRight, tr.inherit_header + tr[class^='memitem'] td.memItemRight { + border-top: 1px solid var(--separator-color); } table.memberdecls img { @@ -1890,7 +2195,10 @@ div.dynheader img[src="closed.png"] { table.memberdecls .mdescRight, table.memberdecls .memTemplItemLeft, table.memberdecls .memTemplItemRight, - table.memberdecls .memTemplParams { + table.memberdecls .memTemplParams, + table.memberdecls .template .memItemLeft, + table.memberdecls .template .memItemRight, + table.memberdecls .template .memParams { display: block; text-align: left; padding-left: var(--spacing-large); @@ -1903,12 +2211,14 @@ div.dynheader img[src="closed.png"] { table.memberdecls .memItemLeft, table.memberdecls .mdescLeft, - table.memberdecls .memTemplItemLeft { - border-bottom: 0; - padding-bottom: 0; + table.memberdecls .memTemplItemLeft, + table.memberdecls .template .memItemLeft { + border-bottom: 0 !important; + padding-bottom: 0 !important; } - table.memberdecls .memTemplItemLeft { + table.memberdecls .memTemplItemLeft, + table.memberdecls .template .memItemLeft { padding-top: 0; } @@ -1918,10 +2228,12 @@ div.dynheader img[src="closed.png"] { table.memberdecls .memItemRight, table.memberdecls .mdescRight, - table.memberdecls .memTemplItemRight { - border-top: 0; - padding-top: 0; + table.memberdecls .memTemplItemRight, + table.memberdecls .template .memItemRight { + border-top: 0 !important; + padding-top: 0 !important; padding-right: var(--spacing-large); + padding-bottom: var(--spacing-medium); overflow-x: auto; } @@ -1956,6 +2268,22 @@ div.dynheader img[src="closed.png"] { max-height: 200px; } } + + tr.heading + tr[class^='memitem'] td.memItemRight, tr.groupHeader + tr[class^='memitem'] td.memItemRight, tr.inherit_header + tr[class^='memitem'] td.memItemRight { + border-top-right-radius: 0; + } + + table.memberdecls tr:last-child td.memItemRight, table.memberdecls tr:last-child td.mdescRight, table.memberdecls tr[class^='memitem']:has(+ tr.groupHeader) td.memItemRight, table.memberdecls tr[class^='memitem']:has(+ tr.inherit_header) td.memItemRight, table.memberdecls tr[class^='memdesc']:has(+ tr.groupHeader) td.mdescRight, table.memberdecls tr[class^='memdesc']:has(+ tr.inherit_header) td.mdescRight { + border-bottom-right-radius: 0; + } + + table.memberdecls tr:last-child td.memItemLeft, table.memberdecls tr:last-child td.mdescLeft, table.memberdecls tr[class^='memitem']:has(+ tr.groupHeader) td.memItemLeft, table.memberdecls tr[class^='memitem']:has(+ tr.inherit_header) td.memItemLeft, table.memberdecls tr[class^='memdesc']:has(+ tr.groupHeader) td.mdescLeft, table.memberdecls tr[class^='memdesc']:has(+ tr.inherit_header) td.mdescLeft { + border-bottom-left-radius: 0; + } + + tr.heading + tr[class^='memitem'] td.memItemLeft, tr.groupHeader + tr[class^='memitem'] td.memItemLeft, tr.inherit_header + tr[class^='memitem'] td.memItemLeft { + border-top-left-radius: 0; + } } @@ -1972,14 +2300,16 @@ hr { } .contents hr { - box-shadow: 100px 0 0 var(--separator-color), - -100px 0 0 var(--separator-color), - 500px 0 0 var(--separator-color), - -500px 0 0 var(--separator-color), - 1500px 0 0 var(--separator-color), - -1500px 0 0 var(--separator-color), - 2000px 0 0 var(--separator-color), - -2000px 0 0 var(--separator-color); + box-shadow: 100px 0 var(--separator-color), + -100px 0 var(--separator-color), + 500px 0 var(--separator-color), + -500px 0 var(--separator-color), + 900px 0 var(--separator-color), + -900px 0 var(--separator-color), + 1400px 0 var(--separator-color), + -1400px 0 var(--separator-color), + 1900px 0 var(--separator-color), + -1900px 0 var(--separator-color); } .contents img, .contents .center, .contents center, .contents div.image object { @@ -2142,9 +2472,7 @@ div.qindex { background: var(--page-background-color); border: none; border-top: 1px solid var(--separator-color); - border-bottom: 1px solid var(--separator-color); border-bottom: 0; - box-shadow: 0 0.75px 0 var(--separator-color); font-size: var(--navigation-font-size); } @@ -2173,6 +2501,10 @@ address.footer { color: var(--primary-color) !important; } +.navpath li.navelem a:hover { + text-shadow: none; +} + .navpath li.navelem b { color: var(--primary-dark-color); font-weight: 500; @@ -2191,7 +2523,11 @@ li.navelem:first-child:before { display: none; } -#nav-path li.navelem:after { +#nav-path ul { + padding-left: 0; +} + +#nav-path li.navelem:has(.el):after { content: ''; border: 5px solid var(--page-background-color); border-bottom-color: transparent; @@ -2202,7 +2538,21 @@ li.navelem:first-child:before { margin-left: 6px; } -#nav-path li.navelem:before { +#nav-path li.navelem:not(:has(.el)):after { + background: var(--page-background-color); + box-shadow: 1px -1px 0 1px var(--separator-color); + border-radius: 0 var(--border-radius-medium) 0 50px; +} + +#nav-path li.navelem:not(:has(.el)) { + margin-left: 0; +} + +#nav-path li.navelem:not(:has(.el)):hover, #nav-path li.navelem:not(:has(.el)):hover:after { + background-color: var(--separator-color); +} + +#nav-path li.navelem:has(.el):before { content: ''; border: 5px solid var(--separator-color); border-bottom-color: transparent; @@ -2328,7 +2678,7 @@ doxygen-awesome-dark-mode-toggle { height: var(--searchbar-height); background: none; border: none; - border-radius: var(--searchbar-height); + border-radius: var(--searchbar-border-radius); vertical-align: middle; text-align: center; line-height: var(--searchbar-height); @@ -2341,7 +2691,7 @@ doxygen-awesome-dark-mode-toggle { } doxygen-awesome-dark-mode-toggle > svg { - transition: transform .1s ease-in-out; + transition: transform var(--animation-duration) ease-in-out; } doxygen-awesome-dark-mode-toggle:active > svg { @@ -2426,7 +2776,7 @@ a.anchorlink { text-decoration: none; opacity: .15; display: none; - transition: opacity .1s ease-in-out, color .1s ease-in-out; + transition: opacity var(--animation-duration) ease-in-out, color var(--animation-duration) ease-in-out; } a.anchorlink svg { @@ -2450,18 +2800,17 @@ h2:hover a.anchorlink, h1:hover a.anchorlink, h3:hover a.anchorlink, h4:hover a. Optional tab feature */ -.tabbed ul { +.tabbed > ul { padding-inline-start: 0px; margin: 0; padding: var(--spacing-small) 0; - border-bottom: 1px solid var(--separator-color); } -.tabbed li { +.tabbed > ul > li { display: none; } -.tabbed li.selected { +.tabbed > ul > li.selected { display: block; } @@ -2477,23 +2826,47 @@ h2:hover a.anchorlink, h1:hover a.anchorlink, h3:hover a.anchorlink, h4:hover a. flex-direction: row; } +@media screen and (max-width: 767px) { + .tabs-overview-container { + margin: 0 calc(0px - var(--spacing-large)); + } + .tabs-overview { + padding: 0 var(--spacing-large) + } +} + .tabs-overview button.tab-button { color: var(--page-foreground-color); margin: 0; border: none; background: transparent; - padding: var(--spacing-small) 0; + padding: calc(var(--spacing-large) / 2) 0; display: inline-block; font-size: var(--page-font-size); cursor: pointer; box-shadow: 0 1px 0 0 var(--separator-color); + position: relative; + + -webkit-tap-highlight-color: transparent; +} + +.tabs-overview button.tab-button .tab-title::before { + display: block; + content: attr(title); + font-weight: 600; + height: 0; + overflow: hidden; + visibility: hidden; } .tabs-overview button.tab-button .tab-title { float: left; white-space: nowrap; - padding: var(--spacing-small) var(--spacing-large); + font-weight: normal; + font-family: var(--font-family); + padding: calc(var(--spacing-large) / 2) var(--spacing-large); border-radius: var(--border-radius-medium); + transition: background-color var(--animation-duration) ease-in-out, font-weight var(--animation-duration) ease-in-out; } .tabs-overview button.tab-button:not(:last-child) .tab-title { @@ -2501,22 +2874,180 @@ h2:hover a.anchorlink, h1:hover a.anchorlink, h3:hover a.anchorlink, h4:hover a. } .tabs-overview button.tab-button:hover .tab-title { - background: var(--primary-color); - color: var(--page-background-color); + background: var(--separator-color); box-shadow: none; } -.tabs-overview button.tab-button.active { - color: var(--primary-color); - box-shadow: 0 1px 0 0 var(--primary-color), inset 0 -1px 0 0 var(--primary-color); +.tabs-overview button.tab-button.active .tab-title { + font-weight: 600; } -@media (prefers-color-scheme: dark) { - html:not(.light-mode) .tabs-overview button.tab-button:hover .tab-title { - color: var(--page-foreground-color); +.tabs-overview button.tab-button::after { + content: ''; + display: block; + position: absolute; + left: 0; + bottom: 0; + right: 0; + height: 0; + width: 0%; + margin: 0 auto; + border-radius: var(--border-radius-small) var(--border-radius-small) 0 0; + background-color: var(--primary-color); + transition: width var(--animation-duration) ease-in-out, height var(--animation-duration) ease-in-out; +} + +.tabs-overview button.tab-button.active::after { + width: 100%; + box-sizing: border-box; + height: 3px; +} + + +/* + Navigation Buttons +*/ + +.section_buttons:not(:empty) { + margin-top: calc(var(--spacing-large) * 3); +} + +.section_buttons table.markdownTable { + display: block; + width: 100%; +} + +.section_buttons table.markdownTable tbody { + display: table !important; + width: 100%; + box-shadow: none; + border-spacing: 10px; +} + +.section_buttons table.markdownTable td { + padding: 0; +} + +.section_buttons table.markdownTable th { + display: none; +} + +.section_buttons table.markdownTable tr.markdownTableHead { + border: none; +} + +.section_buttons tr th, .section_buttons tr td { + background: none; + border: none; + padding: var(--spacing-large) 0 var(--spacing-small); +} + +.section_buttons a { + display: inline-block; + border: 1px solid var(--separator-color); + border-radius: var(--border-radius-medium); + color: var(--page-secondary-foreground-color) !important; + text-decoration: none; + transition: color var(--animation-duration) ease-in-out, background-color var(--animation-duration) ease-in-out; +} + +.section_buttons a:hover { + color: var(--page-foreground-color) !important; + background-color: var(--odd-color); +} + +.section_buttons tr td.markdownTableBodyLeft a { + padding: var(--spacing-medium) var(--spacing-large) var(--spacing-medium) calc(var(--spacing-large) / 2); +} + +.section_buttons tr td.markdownTableBodyRight a { + padding: var(--spacing-medium) calc(var(--spacing-large) / 2) var(--spacing-medium) var(--spacing-large); +} + +.section_buttons tr td.markdownTableBodyLeft a::before, +.section_buttons tr td.markdownTableBodyRight a::after { + color: var(--page-secondary-foreground-color) !important; + display: inline-block; + transition: color .08s ease-in-out, transform .09s ease-in-out; +} + +.section_buttons tr td.markdownTableBodyLeft a::before { + content: '〈'; + padding-right: var(--spacing-large); +} + + +.section_buttons tr td.markdownTableBodyRight a::after { + content: '〉'; + padding-left: var(--spacing-large); +} + + +.section_buttons tr td.markdownTableBodyLeft a:hover::before { + color: var(--page-foreground-color) !important; + transform: translateX(-3px); +} + +.section_buttons tr td.markdownTableBodyRight a:hover::after { + color: var(--page-foreground-color) !important; + transform: translateX(3px); +} + +@media screen and (max-width: 450px) { + .section_buttons a { + width: 100%; + box-sizing: border-box; + } + + .section_buttons tr td:nth-of-type(1).markdownTableBodyLeft a { + border-radius: var(--border-radius-medium) 0 0 var(--border-radius-medium); + border-right: none; + } + + .section_buttons tr td:nth-of-type(2).markdownTableBodyRight a { + border-radius: 0 var(--border-radius-medium) var(--border-radius-medium) 0; } } -html.dark-mode .tabs-overview button.tab-button:hover .tab-title { - color: var(--page-foreground-color); -} \ No newline at end of file +/* + Bordered image +*/ + +html.dark-mode .darkmode_inverted_image img, /* < doxygen 1.9.3 */ +html.dark-mode .darkmode_inverted_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ { + filter: brightness(89%) hue-rotate(180deg) invert(); +} + +.bordered_image { + border-radius: var(--border-radius-small); + border: 1px solid var(--separator-color); + display: inline-block; + overflow: hidden; +} + +.bordered_image:empty { + border: none; +} + +html.dark-mode .bordered_image img, /* < doxygen 1.9.3 */ +html.dark-mode .bordered_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ { + border-radius: var(--border-radius-small); +} + +/* + Button +*/ + +.primary-button { + display: inline-block; + cursor: pointer; + background: var(--primary-color); + color: var(--page-background-color) !important; + border-radius: var(--border-radius-medium); + padding: var(--spacing-small) var(--spacing-medium); + text-decoration: none; +} + +.primary-button:hover { + background: var(--primary-dark-color); +} diff --git a/thirdparty/doxygen-awesome-css/doxygen-custom/custom.css b/thirdparty/doxygen-awesome-css/doxygen-custom/custom.css index 23b91c8..f8da385 100644 --- a/thirdparty/doxygen-awesome-css/doxygen-custom/custom.css +++ b/thirdparty/doxygen-awesome-css/doxygen-custom/custom.css @@ -15,81 +15,6 @@ } } -.alter-theme-button { - display: inline-block; - cursor: pointer; - background: var(--primary-color); - color: var(--page-background-color) !important; - border-radius: var(--border-radius-medium); - padding: var(--spacing-small) var(--spacing-medium); - text-decoration: none; -} - -.next_section_button { - display: block; - padding: var(--spacing-large) 0 var(--spacing-small) 0; - color: var(--page-background-color); - user-select: none; -} - -.next_section_button::after { - /* clearfix */ - content: ""; - clear: both; - display: table; -} - -.next_section_button a { - overflow: hidden; - float: right; - border: 1px solid var(--separator-color); - padding: var(--spacing-medium) calc(var(--spacing-large) / 2) var(--spacing-medium) var(--spacing-large); - border-radius: var(--border-radius-medium); - color: var(--page-secondary-foreground-color) !important; - text-decoration: none; - background-color: var(--page-background-color); - transition: color .08s ease-in-out, background-color .1s ease-in-out; -} - -.next_section_button a:hover { - color: var(--page-foreground-color) !important; - background-color: var(--odd-color); -} - -.next_section_button a::after { - content: '〉'; - color: var(--page-secondary-foreground-color) !important; - padding-left: var(--spacing-large); - display: inline-block; - transition: color .08s ease-in-out, transform .09s ease-in-out; -} - -.next_section_button a:hover::after { - color: var(--page-foreground-color) !important; - transform: translateX(3px); -} - -.alter-theme-button:hover { - background: var(--primary-dark-color); -} - -html.dark-mode .darkmode_inverted_image img, /* < doxygen 1.9.3 */ -html.dark-mode .darkmode_inverted_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ { - filter: brightness(89%) hue-rotate(180deg) invert(); -} - -.bordered_image { - border-radius: var(--border-radius-small); - border: 1px solid var(--separator-color); - display: inline-block; - overflow: hidden; -} - -html.dark-mode .bordered_image img, /* < doxygen 1.9.3 */ -html.dark-mode .bordered_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ { - border-radius: var(--border-radius-small); -} - .title_screenshot { filter: drop-shadow(0px 3px 10px rgba(0,0,0,0.22)); max-width: 500px; @@ -99,3 +24,106 @@ html.dark-mode .bordered_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ .title_screenshot .caption { display: none; } + +#theme-selection { + position: fixed; + bottom: 0; + left: 0; + background: var(--side-nav-background); + padding: 5px 2px 5px 8px; + box-shadow: 0 -4px 4px -2px var(--side-nav-background); + display: flex; +} + +#theme-selection label { + border: 1px solid var(--separator-color); + border-right: 0; + color: var(--page-foreground-color); + font-size: var(--toc-font-size); + padding: 0 8px; + display: inline-block; + height: 22px; + box-sizing: border-box; + border-radius: var(--border-radius-medium) 0 0 var(--border-radius-medium); + line-height: 20px; + background: var(--page-background-color); + opacity: 0.7; +} + +@media (prefers-color-scheme: dark) { + html:not(.light-mode) #theme-select { + background: url("data:image/svg+xml;utf8,") no-repeat; + background-size: 8px; + background-position: calc(100% - 6px) 65%; + background-color: var(--page-background-color); + } +} + +html.dark-mode #theme-select { + background: url("data:image/svg+xml;utf8,") no-repeat; + background-size: 8px; + background-position: calc(100% - 6px) 65%; + background-color: var(--page-background-color); +} + +#theme-select { + border: 1px solid var(--separator-color); + border-radius: 0 var(--border-radius-medium) var(--border-radius-medium) 0; + padding: 0; + height: 22px; + font-size: var(--toc-font-size); + font-family: var(--font-family); + width: 215px; + color: var(--primary-color); + border-left: 0; + display: inline-block; + opacity: 0.7; + outline: none; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background: url("data:image/svg+xml;utf8,") no-repeat; + background-size: 8px; + background-position: calc(100% - 6px) 65%; + background-repeat: no-repeat; + background-color: var(--page-background-color); +} + +#theme-selection:hover #theme-select, #theme-selection:hover label { + opacity: 1; +} + +#nav-tree-contents { + margin-bottom: 30px; +} + +@media screen and (max-width: 767px) { + #theme-selection { + box-shadow: none; + background: none; + height: 20px; + } + + #theme-select { + width: 80px; + opacity: 1; + } + + #theme-selection label { + opacity: 1; + } + + #nav-path ul li.navelem:first-child { + margin-left: 160px; + } + + ul li.footer:not(:first-child) { + display: none; + } + + #nav-path { + position: fixed; + bottom: 0; + background: var(--page-background-color); + } +} \ No newline at end of file diff --git a/thirdparty/doxygen-awesome-css/doxygen-custom/header.html b/thirdparty/doxygen-awesome-css/doxygen-custom/header.html index 7f37e6f..868e65b 100644 --- a/thirdparty/doxygen-awesome-css/doxygen-custom/header.html +++ b/thirdparty/doxygen-awesome-css/doxygen-custom/header.html @@ -23,8 +23,12 @@ $title - + + + + + @@ -47,7 +51,7 @@ $extrastylesheet - + @@ -85,6 +89,14 @@ $extrastylesheet +
+ + +
diff --git a/thirdparty/doxygen-awesome-css/doxygen-custom/theme-robot.css b/thirdparty/doxygen-awesome-css/doxygen-custom/theme-robot.css new file mode 100644 index 0000000..8dae967 --- /dev/null +++ b/thirdparty/doxygen-awesome-css/doxygen-custom/theme-robot.css @@ -0,0 +1,62 @@ +html.theme-robot { + /* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */ + --primary-color: #1c89a4; + --primary-dark-color: #1a6f84; + --primary-light-color: #5abcd4; + --primary-lighter-color: #cae1f1; + --primary-lightest-color: #e9f1f8; + + --fragment-background: #ececec; + --code-background: #ececec; + + /* page base colors */ + --page-background-color: white; + --page-foreground-color: #2c3e50; + --page-secondary-foreground-color: #67727e; + + + --border-radius-large: 0px; + --border-radius-small: 0px; + --border-radius-medium: 0px; + + --spacing-small: 3px; + --spacing-medium: 6px; + --spacing-large: 12px; + + --top-height: 125px; + + --side-nav-background: var(--page-background-color); + --side-nav-foreground: var(--page-foreground-color); + --header-foreground: var(--side-nav-foreground); + --searchbar-border-radius: var(--border-radius-medium); + --header-background: var(--side-nav-background); + --header-foreground: var(--side-nav-foreground); + + --toc-background: rgb(243, 240, 252); + --toc-foreground: var(--page-foreground-color); + + --font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace; + --page-font-size: 14px; + --box-shadow: none; + --separator-color: #cdcdcd; +} + +html.theme-robot.dark-mode { + color-scheme: dark; + + --primary-color: #49cad3; + --primary-dark-color: #8ed2d7; + --primary-light-color: #377479; + --primary-lighter-color: #191e21; + --primary-lightest-color: #191a1c; + + --fragment-background: #000000; + --code-background: #000000; + + --page-background-color: #161616; + --page-foreground-color: #d2dbde; + --page-secondary-foreground-color: #555555; + --separator-color: #545454; + --toc-background: #20142C; + +} \ No newline at end of file diff --git a/thirdparty/doxygen-awesome-css/doxygen-custom/custom-alternative.css b/thirdparty/doxygen-awesome-css/doxygen-custom/theme-round.css similarity index 89% rename from thirdparty/doxygen-awesome-css/doxygen-custom/custom-alternative.css rename to thirdparty/doxygen-awesome-css/doxygen-custom/theme-round.css index e66c1ae..4e03b15 100644 --- a/thirdparty/doxygen-awesome-css/doxygen-custom/custom-alternative.css +++ b/thirdparty/doxygen-awesome-css/doxygen-custom/theme-round.css @@ -1,8 +1,8 @@ -html.alternative { +html.theme-round { /* primary theme color. This will affect the entire websites color scheme: links, arrows, labels, ... */ --primary-color: #AF7FE4; --primary-dark-color: #9270E4; - --primary-light-color: #7aabd6; + --primary-light-color: #d2b7ef; --primary-lighter-color: #cae1f1; --primary-lightest-color: #e9f1f8; @@ -18,6 +18,7 @@ html.alternative { --spacing-small: 8px; --spacing-medium: 14px; --spacing-large: 19px; + --spacing-xlarge: 21px; --top-height: 125px; @@ -33,12 +34,12 @@ html.alternative { --toc-foreground: var(--page-foreground-color); } -html.alternative.dark-mode { +html.theme-round.dark-mode { color-scheme: dark; --primary-color: #AF7FE4; - --primary-dark-color: #9270E4; - --primary-light-color: #4779ac; + --primary-dark-color: #715292; + --primary-light-color: #ae97c7; --primary-lighter-color: #191e21; --primary-lightest-color: #191a1c; diff --git a/thirdparty/doxygen-awesome-css/doxygen-custom/toggle-alternative-theme.js b/thirdparty/doxygen-awesome-css/doxygen-custom/toggle-alternative-theme.js index 72c3731..4e231f1 100644 --- a/thirdparty/doxygen-awesome-css/doxygen-custom/toggle-alternative-theme.js +++ b/thirdparty/doxygen-awesome-css/doxygen-custom/toggle-alternative-theme.js @@ -1,12 +1,52 @@ +// Toggle zwischen drei Theme-Zuständen und speichere im localStorage +const THEME_CLASSES = ['theme-default', 'theme-round', 'theme-robot']; +// Ermögliche das Umschalten per Button/Funktion (z.B. für onclick im HTML) +function toggleThemeVariant() { + let idx = getCurrentThemeIndex(); + idx = (idx + 1) % THEME_CLASSES.length; + applyThemeClass(idx); +} -let original_theme_active = true; +// Funktion global verfügbar machen +window.toggleThemeVariant = toggleThemeVariant; -function toggle_alternative_theme() { - if(original_theme_active) { - document.documentElement.classList.add("alternative") - original_theme_active = false; - } else { - document.documentElement.classList.remove("alternative") - original_theme_active = true; - } -} \ No newline at end of file +function getCurrentThemeIndex() { + const stored = localStorage.getItem('theme-variant'); + if (stored === null) return 0; + const idx = THEME_CLASSES.indexOf(stored); + return idx === -1 ? 0 : idx; +} + +function applyThemeClass(idx) { + document.documentElement.classList.remove(...THEME_CLASSES); + if (THEME_CLASSES[idx] && THEME_CLASSES[idx] !== 'theme-default') { + document.documentElement.classList.add(THEME_CLASSES[idx]); + } + localStorage.setItem('theme-variant', THEME_CLASSES[idx] || 'theme-default'); + // Select synchronisieren, falls vorhanden + const select = document.getElementById('theme-select'); + if (select) select.value = THEME_CLASSES[idx]; +} + +function setThemeByName(themeName) { + const idx = THEME_CLASSES.indexOf(themeName); + applyThemeClass(idx === -1 ? 0 : idx); +} + + +document.addEventListener('DOMContentLoaded', () => { + const select = document.getElementById('theme-select'); + if (select) { + // Initialisiere Auswahl aus localStorage + const idx = getCurrentThemeIndex(); + select.value = THEME_CLASSES[idx]; + applyThemeClass(idx); + // Theme bei Auswahl ändern + select.addEventListener('change', e => { + setThemeByName(e.target.value); + }); + } else { + // Fallback: Theme trotzdem setzen + applyThemeClass(getCurrentThemeIndex()); + } +}); diff --git a/thirdparty/doxygen-awesome-css/environment.yml b/thirdparty/doxygen-awesome-css/environment.yml new file mode 100644 index 0000000..5b372d1 --- /dev/null +++ b/thirdparty/doxygen-awesome-css/environment.yml @@ -0,0 +1,7 @@ +--- +name: RTD +channels: + - conda-forge +dependencies: + - doxygen=1.18.0 + - graphviz=14.1.2 diff --git a/thirdparty/doxygen-awesome-css/img/testimage.png b/thirdparty/doxygen-awesome-css/img/testimage.png deleted file mode 100644 index 3f495a5..0000000 Binary files a/thirdparty/doxygen-awesome-css/img/testimage.png and /dev/null differ diff --git a/thirdparty/doxygen-awesome-css/img/theme-variants-base.drawio.svg b/thirdparty/doxygen-awesome-css/img/theme-variants-base.drawio.svg new file mode 100644 index 0000000..f6dda1d --- /dev/null +++ b/thirdparty/doxygen-awesome-css/img/theme-variants-base.drawio.svg @@ -0,0 +1,117 @@ + + + + + + + + +
+
+
+ Content +
+
+
+
+ + Content + +
+
+ + + + +
+
+
+ Titlebar (Navigation + Search) +
+
+
+
+ + Titlebar (Navigation + Search) + +
+
+ + + + +
+
+
+ Sidebar (Navigation) +
+
+
+
+ + Sidebar (Navigation) + +
+
+ + + + +
+
+
+ Footer (Breadcrumbs) +
+
+
+
+ + Footer (Breadcrumbs) + +
+
+ + + + +
+
+
+ Search +
+
+
+
+ + Search + +
+
+ + + +
+
+
+ + Title + +
+
+
+
+ + Tit... + +
+
+
+ + + + + Text is not SVG - cannot display + + + +
\ No newline at end of file diff --git a/thirdparty/doxygen-awesome-css/img/theme-variants-sidebar-only.drawio.svg b/thirdparty/doxygen-awesome-css/img/theme-variants-sidebar-only.drawio.svg new file mode 100644 index 0000000..b1a9fe2 --- /dev/null +++ b/thirdparty/doxygen-awesome-css/img/theme-variants-sidebar-only.drawio.svg @@ -0,0 +1,102 @@ + + + + + + + + +
+
+
+ Content +
+
+
+
+ + Content + +
+
+ + + + +
+
+
+ Sidebar +
+ (Title + Navigation) +
+
+
+
+ + Sidebar... + +
+
+ + + + +
+
+
+ Footer (Breadcrumbs) +
+
+
+
+ + Footer (Breadcrumbs) + +
+
+ + + + +
+
+
+ Search +
+
+
+
+ + Search + +
+
+ + + +
+
+
+ + Title + +
+
+
+
+ + Tit... + +
+
+
+ + + + + Text is not SVG - cannot display + + + +
\ No newline at end of file diff --git a/thirdparty/doxygen-awesome-css/img/theme-variants.drawio.svg b/thirdparty/doxygen-awesome-css/img/theme-variants.drawio.svg deleted file mode 100644 index f905d7d..0000000 --- a/thirdparty/doxygen-awesome-css/img/theme-variants.drawio.svg +++ /dev/null @@ -1,250 +0,0 @@ - - - - - - - -
-
-
- - - 1️⃣ - - - Base Theme -
-
-
-
- - 1️⃣ Base Theme - -
-
- - - - -
-
-
- - - 2️⃣ - - - Sidebar-Only Theme -
-
-
-
- - 2️⃣ Sidebar-Only Theme - -
-
- - - - - -
-
-
- Content -
-
-
-
- - Content - -
-
- - - - -
-
-
- Sidebar -
- (Title + Navigation) -
-
-
-
- - Sidebar... - -
-
- - - - -
-
-
- Footer (Breadcrumps) -
-
-
-
- - Footer (Breadcrumps) - -
-
- - - - -
-
-
- Search -
-
-
-
- - Search - -
-
- - - -
-
-
- - Title - -
-
-
-
- - Tit... - -
-
- - - - - -
-
-
- Content -
-
-
-
- - Content - -
-
- - - - -
-
-
- Titlebar (Navigation + Search) -
-
-
-
- - Titlebar (Navigation + Search) - -
-
- - - - -
-
-
- Sidebar (Navigation) -
-
-
-
- - Sidebar (Navigation) - -
-
- - - - -
-
-
- Footer (Breadcrumps) -
-
-
-
- - Footer (Breadcrumps) - -
-
- - - - -
-
-
- Search -
-
-
-
- - Search - -
-
- - - -
-
-
- - Title - -
-
-
-
- - Tit... - -
-
-
- - - - - Text is not SVG - cannot display - - - -
\ No newline at end of file diff --git a/thirdparty/doxygen-awesome-css/include/MyLibrary/example.hpp b/thirdparty/doxygen-awesome-css/include/MyLibrary/example.hpp index 75f4c75..c57499d 100644 --- a/thirdparty/doxygen-awesome-css/include/MyLibrary/example.hpp +++ b/thirdparty/doxygen-awesome-css/include/MyLibrary/example.hpp @@ -3,7 +3,7 @@ namespace MyLibrary { -enum Color { red, green, blue }; +enum Color { red = 1, green = 2, blue = 3 }; /** * @brief Example class to demonstrate the features of the custom CSS. @@ -26,50 +26,59 @@ public: * * ## Tables * - * The table content is scrollable if the table gets too wide. - * - * | first_column | second_column | third_column | fourth_column | fifth_column | sixth_column | seventh_column | eighth_column | ninth_column | - * |--------------|---------------|--------------|---------------|--------------|--------------|----------------|---------------|--------------| - * | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | + *
* - * A table can contain images: - * - * | Column 1 | Column 2 | - * |---------------------------|-------------------------------------------------| - * | ![doxygen](testimage.png) | ← the image should not be inverted in dark-mode | - * - * Complex [Doxygen tables](https://www.doxygen.nl/manual/tables.html) are also supported as seen in @ref multi_row "this example": - * - * - * - *
Complex table
Column 1 Column 2 Column 3 - *
cell row=1+2,col=1cell row=1,col=2cell row=1,col=3 - *
cell row=2+3,col=2 cell row=2,col=3 - *
cell row=3,col=1 cell row=3+4,col=3 - *
cell row=4,col=1+2 - *
cell row=5,col=1 cell row=5,col=2+3 - *
cell row=6+7,col=1+2 cell row=6,col=3 - *
cell row=7,col=3 - *
cell row=8,col=1 cell row=8,col=2\n + * - Basic + * This theme supports normal markdown tables:
+ * | Item | Title | Description | More | + * |-----:|-------|-----------------------|--------------------------------------------| + * | 1 | Foo | A placeholder | Some lorem ipsum to make this table wider. | + * | 2 | Bar | Also a placeholder | More lorem ipsum. | + * | 3 | Baz | The third placeholder | More lorem ipsum. | + * - Centered + *
+ * A table can be centered with the `
` html tag:
+ * | Item | Title | Description | More | + * |-----:|-------|-----------------------|--------------------------------------------| + * | 1 | Foo | A placeholder | Some lorem ipsum to make this table wider. | + * | 2 | Bar | Also a placeholder | More lorem ipsum. | + * | 3 | Baz | The third placeholder | More lorem ipsum. | + *
+ * - Stretched + * A table wrapped in `
` fills the full page width. + *
+ * | Item | Title | Description | More | + * |-----:|-------|-----------------------|--------------------------------------------| + * | 1 | Foo | A placeholder | Some lorem ipsum to make this table wider. | + * | 2 | Bar | Also a placeholder | More lorem ipsum. | + * | 3 | Baz | The third placeholder | More lorem ipsum. | + *
+ * **Caution**: This will break the overflow scrolling support! + * - Complex + * Complex [Doxygen tables](https://www.doxygen.nl/manual/tables.html) are also supported as seen in @ref multi_row "this example":
* - * + *
Inner cell row=1,col=1Inner cell row=1,col=2 - *
Inner cell row=2,col=1Inner cell row=2,col=2 + *
Complex table
Column 1 Column 2 Column 3 + *
cell row=1+2,col=1cell row=1,col=2cell row=1,col=3 + *
cell row=2+3,col=2 cell row=2,col=3 + *
cell row=3,col=1 cell row=3,col=3 *
- *
cell row=8,col=3 - *
    - *
  • Item 1 - *
  • Item 2 - *
- *
+ * - Overflow Scrolling The table content is scrollable if the table gets too wide.
+ * | first_column | second_column | third_column | fourth_column | fifth_column | sixth_column | seventh_column | eighth_column | ninth_column | + * |--------------|---------------|--------------|---------------|--------------|--------------|----------------|---------------|--------------| + * | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | + * - ImagesA table can contain images:
+ * | Column 1 | Column 2 | + * |---------------------------|-------------------------------------------------| + * | ![doxygen](testimage.png){width=250px} | ← the image should not be inverted in dark-mode | * - * A table can be centered with the `
` html tag: - *
- * | Foo | Bar | Baz | FooBar | - * |-------------|----------------|---------------------------|-------------| - * | Lorem imsum | dolor sit amet | cenectetur adipisici elit | At vero eos | - *
* - * Embedded Graphviz graphs support dark mode and can be scrolled once they get too wide: + *
+ * + * ## Diagrams + * + * Graphviz diagrams support dark mode and can be scrolled once they get too wide: + * * \dot Graphviz with a caption * digraph example { * node [fontsize="12"]; @@ -101,7 +110,7 @@ public: * ## Code block * * ```cpp - * auto x = "code within md fences (```)"; + * auto x = "code within md fences"; * ``` * * @code{.cpp} @@ -110,7 +119,6 @@ public: * auto example = std::make_shared(5); * example->test("test"); * } - * * @endcode * * // code within indented code block @@ -153,5 +161,9 @@ public: }; +class SecondExample { + std::string foo(); +} + } diff --git a/thirdparty/doxygen-awesome-css/package.json b/thirdparty/doxygen-awesome-css/package.json new file mode 100644 index 0000000..8dffcd4 --- /dev/null +++ b/thirdparty/doxygen-awesome-css/package.json @@ -0,0 +1,34 @@ +{ + "name": "@jothepro/doxygen-awesome-css", + "version": "2.5.0", + "description": "Custom CSS theme for doxygen html-documentation with lots of customization parameters.", + "main": "", + "scripts": { + "npm-pack": "npm pack", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/jothepro/doxygen-awesome-css.git" + }, + "homepage": "https://jothepro.github.io/doxygen-awesome-css/", + "bugs": { + "url": "https://github.com/jothepro/doxygen-awesome-css/issues" + }, + "keywords": [ + "doxygen", + "css", + "theme", + "awesome" + ], + "author": { + "name": "jothepro", + "url": "https://github.com/jothepro", + "git": "https://github.com/jothepro/doxygen-awesome-css" + }, + "license": "MIT", + "config": {}, + "dependencies": {}, + "devDependencies": {}, + "xpack": {} +} diff --git a/thirdparty/doxygen-awesome-css/readthedocs_build.sh b/thirdparty/doxygen-awesome-css/readthedocs_build.sh new file mode 100644 index 0000000..89c83bc --- /dev/null +++ b/thirdparty/doxygen-awesome-css/readthedocs_build.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +set -euo pipefail + +conda_env_name="doxygen-awesome-css-docs" +environment_file="environment.yml" +output_dir="${READTHEDOCS_OUTPUT:-_readthedocs}" +output_dir="${output_dir%/}" +version="${READTHEDOCS_VERSION:-local}" +canonical_url="${READTHEDOCS_CANONICAL_URL:-https://doxygen-awesome-css.readthedocs.io/}" +rtd_doxyfile="${output_dir}/Doxyfile.readthedocs" +rtd_header="${output_dir}/header.readthedocs.html" + +function setup_conda_env { + echo "Creating conda environment '${conda_env_name}' from ${environment_file}" + conda env create --quiet --name "${conda_env_name}" --file "${environment_file}" + + # activate the env in this shell so doxygen/dot below resolve to the conda versions + # shellcheck disable=SC1091 + source "$(conda info --base)/etc/profile.d/conda.sh" + conda activate "${conda_env_name}" +} + +mkdir -p "${output_dir}" + +setup_conda_env +doxygen --version +dot -V + +awk ' + /^\$search$/ { + print + print "" + print "" + next + } + { print } +' doxygen-custom/header.html > "${rtd_header}" + +cp Doxyfile "${rtd_doxyfile}" +cat >> "${rtd_doxyfile}" < None: + self.proc: subprocess.Popen[str] | None = None + self.start() + + def start(self) -> None: + if self.proc is not None: + self.proc.kill() + self.proc.wait() + self.proc = subprocess.Popen( + ["stdbuf", "-o0", "-e0", SOLLYA], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + bufsize=1, + ) + self._run("verbosity = 0;\nprec = 120;\n", "READY") + + def close(self) -> None: + if self.proc is not None: + self.proc.kill() + self.proc.wait() + self.proc = None + + def _run(self, script: str, sentinel: str) -> list[str]: + assert self.proc is not None and self.proc.stdin and self.proc.stdout + self.proc.stdin.write(script) + self.proc.stdin.write(f'print("{sentinel}");\n') + self.proc.stdin.flush() + lines: list[str] = [] + while True: + line = self.proc.stdout.readline() + if line == "": + raise RuntimeError("sollya exited") + if sentinel in line: + return lines + lines.append(line.rstrip("\n")) + + def fit( + self, name: str, left: int, right: int, k: int, q: int, tol: float + ) -> tuple[float, list[int]] | None: + # fpminimax is ill-conditioned on a tiny interval at 0 and can report + # an error above half an ulp for a one-ulp step. Taylor is the + # fallback, and the search keeps the smaller certified error. + mini = self._polynomial(name, left, right, k, q, taylor=False) + if mini is not None and mini[0] <= tol: + return mini + tay = self._polynomial(name, left, right, k, q, taylor=True) + cands = [item for item in (mini, tay) if item is not None] + if not cands: + return None + return min(cands, key=lambda item: item[0]) + + def _polynomial( + self, name: str, left: int, right: int, k: int, q: int, taylor: bool + ) -> tuple[float, list[int]] | None: + expr = EXPR[name] + if taylor: + # taylor(f, n, t) returns p such that p(x-t) is the expansion at t. + build = ( + f"t0 = (({left})+({right}))/2 * 2^(-{k});\n" + f"pshift = taylor({expr}, 3, t0);\n" + f"p = pshift(x - t0);" + ) + else: + build = ( + f"p = fpminimax({expr}, 3, [|80,80,80,80|], " + f"[{left}*2^(-{k}), {right}*2^(-{k})], absolute);" + ) + script = f""" +{build} +qbits = {q}; +i0 = nearestint(coeff(p, 0) * 2^qbits); +i1 = nearestint(coeff(p, 1) * 2^qbits); +i2 = nearestint(coeff(p, 2) * 2^qbits); +i3 = nearestint(coeff(p, 3) * 2^qbits); +pr = i0*2^(-qbits) + i1*2^(-qbits)*x + i2*2^(-qbits)*x^2 + i3*2^(-qbits)*x^3; +e = dirtyinfnorm(({expr}) - pr, [{left}*2^(-{k}), {right}*2^(-{k})]); +print(i0); +print(i1); +print(i2); +print(i3); +print(e); +""" + try: + lines = self._run(script, "FITDONE") + except RuntimeError: + self.start() + return None + if any("Error" in line or "error" in line for line in lines): + self.start() + return None + nums: list[str] = [] + for line in lines: + nums.extend(NUMBER.findall(line)) + if len(nums) < 5: + self.start() + return None + coeffs = [int(Decimal(nums[i]).to_integral_value(ROUND_HALF_UP)) for i in range(4)] + err = max(float(n) for n in nums[4:]) + if not math.isfinite(err): + return None + return err, coeffs + + def score(self, name: str, left: int, right: int, k: int, q: int, coeffs: list[int]) -> float | None: + expr = EXPR[name] + c0, c1, c2, c3 = coeffs + script = f""" +pr = ({c0})*2^(-{q}) + ({c1})*2^(-{q})*x + ({c2})*2^(-{q})*x^2 + ({c3})*2^(-{q})*x^3; +e = dirtyinfnorm(({expr}) - pr, [{left}*2^(-{k}), {right}*2^(-{k})]); +print(e); +""" + try: + lines = self._run(script, "SCOREDONE") + except RuntimeError: + self.start() + return None + if any("Error" in line or "error" in line for line in lines): + self.start() + return None + nums: list[str] = [] + for line in lines: + nums.extend(NUMBER.findall(line)) + if not nums: + return None + err = max(float(n) for n in nums) + return err if math.isfinite(err) else None + + +def half_ulp(k: int) -> float: + return 2.0 ** (-(k + 1)) + + +def q_of(k: int) -> int: + return k + 16 + + +def quantize(coeffs: list[str], q: int) -> list[int]: + scale = Decimal(2) ** q + out: list[int] = [] + for raw in coeffs: + value = Decimal(raw) * scale + if value >= 0: + out.append(int(value.to_integral_value(ROUND_HALF_UP))) + else: + out.append(-int((-value).to_integral_value(ROUND_HALF_UP))) + return out + + +def lecun_tail(k: int) -> int: + num = 17159 * (1 << k) + den = 10000 + return (num + den // 2) // den + + +def lecun_end(k: int) -> int: + """First raw at which the constant tail is within 1/4 ulp of the asymptote gap.""" + tail = lecun_tail(k) / 2**k + # f increases to 1.7159. Leave a quarter ulp for rounding the tail itself. + gap = 0.25 * (2 ** (-k)) + target = 1.7159 - gap + lo, hi = 0.0, 40.0 + for _ in range(80): + mid = (lo + hi) / 2 + if 1.7159 * math.tanh(2 * mid / 3) >= target: + hi = mid + else: + lo = mid + return max(1, math.ceil(hi * 2**k - 1e-9)) + + +def march(sollya: Sollya, name: str, start: int, end: int, k: int) -> list[Piece]: + q = q_of(k) + tol = half_ulp(k) + pieces: list[Piece] = [] + left = start + guess = 1 + while left < end: + step = max(1, guess) + last: tuple[int, float, list[int]] | None = None + fail: int | None = None + while left + step <= end: + got = sollya.fit(name, left, left + step, k, q, tol) + if got is not None and got[0] <= tol: + last = (left + step, got[0], got[1]) + step *= 2 + else: + fail = min(end, left + step) + break + else: + if last is None or last[0] != end: + got = sollya.fit(name, left, end, k, q, tol) + if got is not None and got[0] <= tol: + last = (end, got[0], got[1]) + fail = None + else: + fail = end + if fail is None and last is not None: + right, err, coeffs = last + else: + lo = last[0] if last is not None else left + hi = fail if fail is not None else end + best = last + while hi - lo > 1: + mid = (lo + hi) // 2 + got = sollya.fit(name, left, mid, k, q, tol) + if got is not None and got[0] <= tol: + best = (mid, got[0], got[1]) + lo = mid + else: + hi = mid + if best is None: + got = sollya.fit(name, left, left + 1, k, q, tol) + if got is None: + raise RuntimeError(f"{name} k={k} no cubic on [{left}, {left+1}]") + best = (left + 1, got[0], got[1]) + right, err, coeffs = best + pieces.append(Piece(left, right, coeffs, err, "sollya")) + guess = max(1, right - left) + left = right + print(f" {name} k={k} pieces={len(pieces)} span={right - pieces[-1].left} err={err:.3e}", flush=True) + return pieces + + +def write_intervals(pieces_by_key: dict[tuple[str, int], list[Piece]], path: Path) -> None: + with path.open("w") as handle: + for (name, k), pieces in pieces_by_key.items(): + q = q_of(k) + for piece in pieces: + handle.write(f"{name} {k} {piece.left} {piece.right} {q}\n") + + +def run_maple(interval_path: Path, out_path: Path) -> None: + program = WORK / "maple_batch.mpl" + program.write_text( + f""" +Digits := 40: +with(numapprox): +fd := fopen("{out_path}", WRITE): +infd := fopen("{interval_path}", READ): +while true do + line := readline(infd); + if line = 0 then break; end if; + parts := sscanf(line, "%s %d %d %d %d"); + gname := parts[1]; + a := parts[3] * 2^(-parts[2]); + b := parts[4] * 2^(-parts[2]); + try + if gname = "lecun" then + p := minimax(17159/10000*tanh(2*x/3), x = a .. b, [3, 0]); + else + p := minimax((exp(x)-1)*(x+1)/2, x = a .. b, [3, 0]); + end if; + p := expand(p); + fprintf(fd, "%.25e %.25e %.25e %.25e\\n", + evalf(coeff(p, x, 0)), evalf(coeff(p, x, 1)), + evalf(coeff(p, x, 2)), evalf(coeff(p, x, 3))); + catch: + fprintf(fd, "FAIL\\n"); + end try; +end do: +fclose(fd): +fclose(infd): +quit: +""" + ) + subprocess.run([MAPLE, "-q", str(program)], check=True, timeout=3600) + + +def run_math(interval_path: Path, out_path: Path) -> None: + program = WORK / "mma_batch.wl" + program.write_text( + r""" +pow[base_, 0] := 1; +pow[base_, n_Integer] := base^n; +lecun[x_] := 17159/10000*Tanh[2*x/3]; +hard[x_] := (Exp[x] - 1)*(x + 1)/2; +remez[ff_, a_, b_] := Module[ + {n = 3, m = 5, mid, half, nodes, coef, mat, rhs, sol, grid, err, idx, drop, tpoly, xpoly}, + mid = N[(a + b)/2, 40]; + half = N[(b - a)/2, 40]; + nodes = Sort[Table[N[Cos[Pi*(k + 1/2)/m], 40], {k, 0, m - 1}]]; + coef = {0, 0, 0, 0}; + Do[ + mat = N[Table[If[j <= n + 1, pow[nodes[[i]], j - 1], -(-1)^i], {i, m}, {j, m}], 40]; + rhs = N[Table[ff[mid + half*nodes[[i]]], {i, m}], 40]; + sol = Quiet[Check[LinearSolve[mat, rhs], $Failed]]; + If[sol === $Failed || Head[sol] =!= List, Break[]]; + coef = N[sol[[1 ;; n + 1]], 40]; + grid = N[Subdivide[-1, 1, 256], 40]; + err = Table[ + coef[[1]] + coef[[2]]*grid[[i]] + coef[[3]]*grid[[i]]^2 + coef[[4]]*grid[[i]]^3 + - ff[mid + half*grid[[i]]], + {i, Length[grid]}]; + idx = {1, Length[grid]}; + Do[ + If[Abs[err[[i]]] >= Abs[err[[i - 1]]] && Abs[err[[i]]] >= Abs[err[[i + 1]]], + AppendTo[idx, i]], + {i, 2, Length[grid] - 1}]; + While[Length[idx] > m, + drop = Ordering[Abs[err[[idx]]], 1][[1]]; + idx = Delete[idx, drop]; + ]; + If[Length[idx] == m, nodes = Sort[N[grid[[idx]], 40]]]; + , {8}]; + tpoly = coef[[1]] + coef[[2]]*((x - mid)/half) + coef[[3]]*((x - mid)/half)^2 + + coef[[4]]*((x - mid)/half)^3; + xpoly = Expand[N[tpoly, 30]]; + Table[N[Coefficient[xpoly, x, k], 20], {k, 0, 3}] +]; +lines = ReadList[""" + + f'"{interval_path}"' + + r""", String]; +out = OpenWrite[""" + + f'"{out_path}"' + + r"""]; +Do[ + parts = StringSplit[line]; + If[Length[parts] < 5, Continue[]]; + name = parts[[1]]; + kk = ToExpression[parts[[2]]]; + left = ToExpression[parts[[3]]]; + right = ToExpression[parts[[4]]]; + aa = N[left*2^(-kk), 30]; + bb = N[right*2^(-kk), 30]; + ff = If[name == "lecun", lecun, hard]; + cs = Quiet[Check[remez[ff, aa, bb], $Failed]]; + If[cs === $Failed || Head[cs] =!= List, + WriteString[out, "FAIL\n"], + WriteString[out, StringRiffle[Map[ToString[CForm[#]] &, cs], " "], "\n"] + ]; + , {line, lines}]; +Close[out]; +Exit[]; +""" + ) + subprocess.run([MATH, "-script", str(program)], check=True, timeout=3600) + + +def run_matlab(interval_path: Path, out_path: Path) -> None: + program = WORK / "matlab_batch.m" + program.write_text( + f""" +fid = fopen('{interval_path}', 'r'); +out = fopen('{out_path}', 'w'); +while true + line = fgetl(fid); + if ~ischar(line), break; end + parts = strsplit(strtrim(line)); + if numel(parts) < 5, continue; end + name = parts{{1}}; + kk = str2double(parts{{2}}); + left = str2double(parts{{3}}); + right = str2double(parts{{4}}); + aa = left * 2^(-kk); + bb = right * 2^(-kk); + try + if strcmp(name, 'lecun') + f = chebfun(@(x) 1.7159*tanh(2*x/3), [aa, bb]); + else + f = chebfun(@(x) expm1(x).*(x+1)/2, [aa, bb]); + end + p = minimax(f, 3); + c = poly(p); + c = c(:).'; + if numel(c) < 4 + c = [zeros(1, 4-numel(c)), c]; + end + fprintf(out, '%.20e %.20e %.20e %.20e\\n', c(4), c(3), c(2), c(1)); + catch + fprintf(out, 'FAIL\\n'); + end +end +fclose(fid); +fclose(out); +""" + ) + subprocess.run( + [MATLAB, "-batch", f"run('{program}')"], + check=True, + timeout=7200, + ) + + +def load_coeff_file(path: Path) -> list[list[str] | None]: + rows: list[list[str] | None] = [] + for line in path.read_text().splitlines(): + line = line.strip() + if not line or "FAIL" in line: + rows.append(None) + continue + parts = NUMBER.findall(line.replace("D", "E")) + if len(parts) < 4: + rows.append(None) + continue + rows.append(parts[:4]) + return rows + + +def tournament( + sollya: Sollya, + pieces_by_key: dict[tuple[str, int], list[Piece]], + others: dict[str, list[list[str] | None]], +) -> dict[str, int]: + wins = {"sollya": 0, "mathematica": 0, "maple": 0, "matlab": 0} + index = 0 + for key in pieces_by_key: + name, k = key + q = q_of(k) + for piece in pieces_by_key[key]: + best_err = piece.err + best_coeffs = piece.coeffs + best_source = "sollya" + for source in ("mathematica", "maple", "matlab"): + row = others[source][index] if index < len(others[source]) else None + if row is None: + continue + try: + coeffs = quantize(row, q) + except Exception: + continue + err = sollya.score(name, piece.left, piece.right, k, q, coeffs) + if err is not None and err < best_err: + best_err = err + best_coeffs = coeffs + best_source = source + piece.coeffs = best_coeffs + piece.err = best_err + piece.source = best_source + wins[best_source] += 1 + index += 1 + print(f"tournament {name} k={k} done", flush=True) + return wins + + +def split_i128(value: int) -> tuple[int, int]: + raw = value + (1 << 128) if value < 0 else value + lo = raw & ((1 << 64) - 1) + hi = (raw >> 64) & ((1 << 64) - 1) + if hi >= (1 << 63): + hi -= 1 << 64 + return hi, lo + + +TAGS = {"lecun": "LECUN", "hard": "HARDELISH"} + + +def emit_table(name: str, k: int, pieces: list[Piece]) -> str: + knots = [pieces[0].left] + [piece.right for piece in pieces] + q = q_of(k) + tag = TAGS[name] + lines = [f"static constexpr std::int64_t {tag}_K{k}_KNOTS[] = {{"] + lines.append(" " + ", ".join(str(knot) for knot in knots) + ",") + lines.append("};") + lines.append(f"static constexpr grotto::principal_detail::cubic_bits {tag}_K{k}_PIECES[] = {{") + for piece in pieces: + his, los = [], [] + for coeff in piece.coeffs: + hi, lo = split_i128(coeff) + his.append(str(hi)) + los.append(f"{lo}u") + lines.append(" {{" + ", ".join(his) + "}, {" + ", ".join(los) + "}},") + lines.append("};") + lines.append( + f"static constexpr window_table {tag}_K{k}_TABLE" + f"{{{tag}_K{k}_KNOTS, {tag}_K{k}_PIECES, {len(pieces)}, {q}}};" + ) + lines.append("") + return "\n".join(lines) + + +def emit(pieces_by_key: dict[tuple[str, int], list[Piece]], wins: dict[str, int], path: Path) -> None: + chunks = [ + "// Generated on mocha2.", + "// Sollya fpminimax chose the knots (absolute error at most half an ulp).", + "// Each cubic is the best of Sollya, Mathematica Remez, Maple numapprox[minimax],", + "// and MATLAB/Chebfun minimax after rounding coefficients to 2^{-(k+16)}.", + "// Wins: " + ", ".join(f"{name} {count}" for name, count in wins.items()) + ".", + "// lecun is the positive half of an odd map; hard covers (-1, 0).", + "// Do not edit.", + "#pragma once", + "", + ] + ks = [k for (name, k) in pieces_by_key if name == "lecun"] + for name in ("lecun", "hard"): + for k in ks: + chunks.append(emit_table(name, k, pieces_by_key[(name, k)])) + tag = TAGS[name] + refs = ",\n ".join(f"&{tag}_K{k}_TABLE" for k in ks) + chunks.append( + f"static constexpr window_table const* const {tag}[{len(ks)}] = {{\n {refs},\n}};" + ) + chunks.append("") + tails = ", ".join(str(lecun_tail(k)) for k in ks) + chunks.append(f"static constexpr std::int64_t LECUN_TAIL[{len(ks)}] = {{\n {tails},\n}};") + chunks.append("") + path.write_text("\n".join(chunks)) + + +def summarize(pieces_by_key: dict[tuple[str, int], list[Piece]], wins: dict[str, int]) -> None: + summary = {"wins": wins, "functions": {}} + for name in ("lecun", "hard"): + summary["functions"][name] = {} + for k in selected_precisions(): + pieces = pieces_by_key[(name, k)] + summary["functions"][name][str(k)] = { + "parts": len(pieces), + "max_abs_error": max(piece.err for piece in pieces), + "half_ulp": half_ulp(k), + } + (WORK / "summary.json").write_text(json.dumps(summary, indent=2)) + print(json.dumps(summary, indent=2), flush=True) + + +def self_test() -> None: + sollya = Sollya() + got = sollya.fit("lecun", 0, 1 << 15, 16, q_of(16), half_ulp(16)) + print("sollya", got[0] if got else None) + sollya.close() + + +def selected_precisions() -> tuple[int, ...]: + if "--k" in sys.argv: + return (int(sys.argv[sys.argv.index("--k") + 1]),) + return PREC + + +def main() -> None: + if len(sys.argv) > 1 and sys.argv[1] == "--self-test": + self_test() + return + WORK.mkdir(parents=True, exist_ok=True) + sollya = Sollya() + pieces_by_key: dict[tuple[str, int], list[Piece]] = {} + for k in selected_precisions(): + end = lecun_end(k) + print(f"march lecun k={k} end={end} tail={lecun_tail(k)}", flush=True) + pieces_by_key[("lecun", k)] = march(sollya, "lecun", 0, end, k) + one = 1 << k + print(f"march hard k={k}", flush=True) + pieces_by_key[("hard", k)] = march(sollya, "hard", -one, 0, k) + interval_path = WORK / "intervals.txt" + write_intervals(pieces_by_key, interval_path) + print("intervals", sum(len(v) for v in pieces_by_key.values()), flush=True) + jobs = { + "maple": (run_maple, WORK / "maple_coeffs.txt"), + "mathematica": (run_math, WORK / "mma_coeffs.txt"), + "matlab": (run_matlab, WORK / "matlab_coeffs.txt"), + } + for name, (fn, out) in jobs.items(): + # Run sequentially inside this process: MATLAB and Maple both want a license, + # and a failure is easier to see one at a time. They do not share state. + print("running", name, flush=True) + if out.exists(): + out.unlink() + fn(interval_path, out) + print("finished", name, out.stat().st_size, flush=True) + expected = sum(len(v) for v in pieces_by_key.values()) + others = { + "maple": load_coeff_file(WORK / "maple_coeffs.txt"), + "mathematica": load_coeff_file(WORK / "mma_coeffs.txt"), + "matlab": load_coeff_file(WORK / "matlab_coeffs.txt"), + } + for source, rows in others.items(): + if len(rows) != expected: + raise SystemExit(f"{source} wrote {len(rows)} rows, expected {expected}") + wins = tournament(sollya, pieces_by_key, others) + sollya.close() + emit(pieces_by_key, wins, WORK / "window_extra_tables.inc") + summarize(pieces_by_key, wins) + + +if __name__ == "__main__": + main()